diff options
Diffstat (limited to 'ui')
-rw-r--r-- | ui/Makefile.objs | 6 | ||||
-rw-r--r-- | ui/cocoa.m | 8 | ||||
-rw-r--r-- | ui/console.c | 1724 | ||||
-rw-r--r-- | ui/curses.c | 29 | ||||
-rw-r--r-- | ui/curses_keys.h | 5 | ||||
-rw-r--r-- | ui/cursor.c | 211 | ||||
-rw-r--r-- | ui/cursor_hidden.xpm | 37 | ||||
-rw-r--r-- | ui/cursor_left_ptr.xpm | 39 | ||||
-rw-r--r-- | ui/d3des.h | 4 | ||||
-rw-r--r-- | ui/input.c | 529 | ||||
-rw-r--r-- | ui/keymaps.c | 2 | ||||
-rw-r--r-- | ui/qemu-pixman.c | 80 | ||||
-rw-r--r-- | ui/qemu-spice.h | 80 | ||||
-rw-r--r-- | ui/qemu-x509.h | 9 | ||||
-rw-r--r-- | ui/sdl.c | 144 | ||||
-rw-r--r-- | ui/sdl_zoom.c | 2 | ||||
-rw-r--r-- | ui/spice-core.c | 109 | ||||
-rw-r--r-- | ui/spice-display.c | 239 | ||||
-rw-r--r-- | ui/spice-display.h | 133 | ||||
-rw-r--r-- | ui/spice-input.c | 4 | ||||
-rw-r--r-- | ui/vgafont.h | 4611 | ||||
-rw-r--r-- | ui/vnc-auth-sasl.c | 5 | ||||
-rw-r--r-- | ui/vnc-auth-sasl.h | 2 | ||||
-rw-r--r-- | ui/vnc-enc-hextile-template.h | 23 | ||||
-rw-r--r-- | ui/vnc-enc-hextile.c | 53 | ||||
-rw-r--r-- | ui/vnc-enc-tight.c | 284 | ||||
-rw-r--r-- | ui/vnc-enc-zrle.c | 18 | ||||
-rw-r--r-- | ui/vnc-jobs.c | 31 | ||||
-rw-r--r-- | ui/vnc-jobs.h | 1 | ||||
-rw-r--r-- | ui/vnc-palette.c | 2 | ||||
-rw-r--r-- | ui/vnc-palette.h | 5 | ||||
-rw-r--r-- | ui/vnc-tls.c | 4 | ||||
-rw-r--r-- | ui/vnc-tls.h | 2 | ||||
-rw-r--r-- | ui/vnc.c | 382 | ||||
-rw-r--r-- | ui/vnc.h | 34 |
35 files changed, 7878 insertions, 973 deletions
diff --git a/ui/Makefile.objs b/ui/Makefile.objs index adc07be761..6768bb7f7e 100644 --- a/ui/Makefile.objs +++ b/ui/Makefile.objs @@ -6,9 +6,13 @@ vnc-obj-$(CONFIG_VNC_TLS) += vnc-tls.o vnc-auth-vencrypt.o vnc-obj-$(CONFIG_VNC_SASL) += vnc-auth-sasl.o vnc-obj-y += vnc-jobs.o -common-obj-y += keymaps.o +common-obj-y += keymaps.o console.o cursor.o input.o qemu-pixman.o common-obj-$(CONFIG_SPICE) += spice-core.o spice-input.o spice-display.o common-obj-$(CONFIG_SDL) += sdl.o sdl_zoom.o x_keymap.o common-obj-$(CONFIG_COCOA) += cocoa.o common-obj-$(CONFIG_CURSES) += curses.o common-obj-$(CONFIG_VNC) += $(vnc-obj-y) + +$(obj)/sdl.o $(obj)/sdl_zoom.o: QEMU_CFLAGS += $(SDL_CFLAGS) + +$(obj)/cocoa.o: $(SRC_PATH)/$(obj)/cocoa.m diff --git a/ui/cocoa.m b/ui/cocoa.m index 2383646dc0..3bf1c6e890 100644 --- a/ui/cocoa.m +++ b/ui/cocoa.m @@ -26,8 +26,8 @@ #include <crt_externs.h> #include "qemu-common.h" -#include "console.h" -#include "sysemu.h" +#include "ui/console.h" +#include "sysemu/sysemu.h" #ifndef MAC_OS_X_VERSION_10_4 #define MAC_OS_X_VERSION_10_4 1040 @@ -1017,8 +1017,8 @@ void cocoa_display_init(DisplayState *ds, int full_screen) dcl = g_malloc0(sizeof(DisplayChangeListener)); // register vga output callbacks - dcl->dpy_update = cocoa_update; - dcl->dpy_resize = cocoa_resize; + dcl->dpy_gfx_update = cocoa_update; + dcl->dpy_gfx_resize = cocoa_resize; dcl->dpy_refresh = cocoa_refresh; register_displaychangelistener(ds, dcl); diff --git a/ui/console.c b/ui/console.c new file mode 100644 index 0000000000..d880ebff07 --- /dev/null +++ b/ui/console.c @@ -0,0 +1,1724 @@ +/* + * QEMU graphical console + * + * Copyright (c) 2004 Fabrice Bellard + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include "qemu-common.h" +#include "ui/console.h" +#include "qemu/timer.h" +#include "qmp-commands.h" +#include "char/char.h" + +//#define DEBUG_CONSOLE +#define DEFAULT_BACKSCROLL 512 +#define MAX_CONSOLES 12 +#define CONSOLE_CURSOR_PERIOD 500 + +#define QEMU_RGBA(r, g, b, a) (((a) << 24) | ((r) << 16) | ((g) << 8) | (b)) +#define QEMU_RGB(r, g, b) QEMU_RGBA(r, g, b, 0xff) + +typedef struct TextAttributes { + uint8_t fgcol:4; + uint8_t bgcol:4; + uint8_t bold:1; + uint8_t uline:1; + uint8_t blink:1; + uint8_t invers:1; + uint8_t unvisible:1; +} TextAttributes; + +typedef struct TextCell { + uint8_t ch; + TextAttributes t_attrib; +} TextCell; + +#define MAX_ESC_PARAMS 3 + +enum TTYState { + TTY_STATE_NORM, + TTY_STATE_ESC, + TTY_STATE_CSI, +}; + +typedef struct QEMUFIFO { + uint8_t *buf; + int buf_size; + int count, wptr, rptr; +} QEMUFIFO; + +static int qemu_fifo_write(QEMUFIFO *f, const uint8_t *buf, int len1) +{ + int l, len; + + l = f->buf_size - f->count; + if (len1 > l) + len1 = l; + len = len1; + while (len > 0) { + l = f->buf_size - f->wptr; + if (l > len) + l = len; + memcpy(f->buf + f->wptr, buf, l); + f->wptr += l; + if (f->wptr >= f->buf_size) + f->wptr = 0; + buf += l; + len -= l; + } + f->count += len1; + return len1; +} + +static int qemu_fifo_read(QEMUFIFO *f, uint8_t *buf, int len1) +{ + int l, len; + + if (len1 > f->count) + len1 = f->count; + len = len1; + while (len > 0) { + l = f->buf_size - f->rptr; + if (l > len) + l = len; + memcpy(buf, f->buf + f->rptr, l); + f->rptr += l; + if (f->rptr >= f->buf_size) + f->rptr = 0; + buf += l; + len -= l; + } + f->count -= len1; + return len1; +} + +typedef enum { + GRAPHIC_CONSOLE, + TEXT_CONSOLE, + TEXT_CONSOLE_FIXED_SIZE +} console_type_t; + +struct QemuConsole { + int index; + console_type_t console_type; + DisplayState *ds; + + /* Graphic console state. */ + vga_hw_update_ptr hw_update; + vga_hw_invalidate_ptr hw_invalidate; + vga_hw_screen_dump_ptr hw_screen_dump; + vga_hw_text_update_ptr hw_text_update; + void *hw; + int g_width, g_height; + + /* Text console state */ + int width; + int height; + int total_height; + int backscroll_height; + int x, y; + int x_saved, y_saved; + int y_displayed; + int y_base; + TextAttributes t_attrib_default; /* default text attributes */ + TextAttributes t_attrib; /* currently active text attributes */ + TextCell *cells; + int text_x[2], text_y[2], cursor_invalidate; + int echo; + bool cursor_visible_phase; + QEMUTimer *cursor_timer; + + int update_x0; + int update_y0; + int update_x1; + int update_y1; + + enum TTYState state; + int esc_params[MAX_ESC_PARAMS]; + int nb_esc_params; + + CharDriverState *chr; + /* fifo for key pressed */ + QEMUFIFO out_fifo; + uint8_t out_fifo_buf[16]; + QEMUTimer *kbd_timer; +}; + +static DisplayState *display_state; +static QemuConsole *active_console; +static QemuConsole *consoles[MAX_CONSOLES]; +static int nb_consoles = 0; + +void vga_hw_update(void) +{ + if (active_console && active_console->hw_update) + active_console->hw_update(active_console->hw); +} + +void vga_hw_invalidate(void) +{ + if (active_console && active_console->hw_invalidate) + active_console->hw_invalidate(active_console->hw); +} + +void qmp_screendump(const char *filename, Error **errp) +{ + QemuConsole *previous_active_console; + bool cswitch; + + previous_active_console = active_console; + cswitch = previous_active_console && previous_active_console->index != 0; + + /* There is currently no way of specifying which screen we want to dump, + so always dump the first one. */ + if (cswitch) { + console_select(0); + } + if (consoles[0] && consoles[0]->hw_screen_dump) { + consoles[0]->hw_screen_dump(consoles[0]->hw, filename, cswitch, errp); + } else { + error_setg(errp, "device doesn't support screendump\n"); + } + + if (cswitch) { + console_select(previous_active_console->index); + } +} + +void vga_hw_text_update(console_ch_t *chardata) +{ + if (active_console && active_console->hw_text_update) + active_console->hw_text_update(active_console->hw, chardata); +} + +/* convert a RGBA color to a color index usable in graphic primitives */ +static unsigned int vga_get_color(DisplayState *ds, unsigned int rgba) +{ + unsigned int r, g, b, color; + + switch(ds_get_bits_per_pixel(ds)) { +#if 0 + case 8: + r = (rgba >> 16) & 0xff; + g = (rgba >> 8) & 0xff; + b = (rgba) & 0xff; + color = (rgb_to_index[r] * 6 * 6) + + (rgb_to_index[g] * 6) + + (rgb_to_index[b]); + break; +#endif + case 15: + r = (rgba >> 16) & 0xff; + g = (rgba >> 8) & 0xff; + b = (rgba) & 0xff; + color = ((r >> 3) << 10) | ((g >> 3) << 5) | (b >> 3); + break; + case 16: + r = (rgba >> 16) & 0xff; + g = (rgba >> 8) & 0xff; + b = (rgba) & 0xff; + color = ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3); + break; + case 32: + default: + color = rgba; + break; + } + return color; +} + +static void vga_fill_rect (DisplayState *ds, + int posx, int posy, int width, int height, uint32_t color) +{ + uint8_t *d, *d1; + int x, y, bpp; + + bpp = (ds_get_bits_per_pixel(ds) + 7) >> 3; + d1 = ds_get_data(ds) + + ds_get_linesize(ds) * posy + bpp * posx; + for (y = 0; y < height; y++) { + d = d1; + switch(bpp) { + case 1: + for (x = 0; x < width; x++) { + *((uint8_t *)d) = color; + d++; + } + break; + case 2: + for (x = 0; x < width; x++) { + *((uint16_t *)d) = color; + d += 2; + } + break; + case 4: + for (x = 0; x < width; x++) { + *((uint32_t *)d) = color; + d += 4; + } + break; + } + d1 += ds_get_linesize(ds); + } +} + +/* copy from (xs, ys) to (xd, yd) a rectangle of size (w, h) */ +static void vga_bitblt(DisplayState *ds, int xs, int ys, int xd, int yd, int w, int h) +{ + const uint8_t *s; + uint8_t *d; + int wb, y, bpp; + + bpp = (ds_get_bits_per_pixel(ds) + 7) >> 3; + wb = w * bpp; + if (yd <= ys) { + s = ds_get_data(ds) + + ds_get_linesize(ds) * ys + bpp * xs; + d = ds_get_data(ds) + + ds_get_linesize(ds) * yd + bpp * xd; + for (y = 0; y < h; y++) { + memmove(d, s, wb); + d += ds_get_linesize(ds); + s += ds_get_linesize(ds); + } + } else { + s = ds_get_data(ds) + + ds_get_linesize(ds) * (ys + h - 1) + bpp * xs; + d = ds_get_data(ds) + + ds_get_linesize(ds) * (yd + h - 1) + bpp * xd; + for (y = 0; y < h; y++) { + memmove(d, s, wb); + d -= ds_get_linesize(ds); + s -= ds_get_linesize(ds); + } + } +} + +/***********************************************************/ +/* basic char display */ + +#define FONT_HEIGHT 16 +#define FONT_WIDTH 8 + +#include "vgafont.h" + +#define cbswap_32(__x) \ +((uint32_t)( \ + (((uint32_t)(__x) & (uint32_t)0x000000ffUL) << 24) | \ + (((uint32_t)(__x) & (uint32_t)0x0000ff00UL) << 8) | \ + (((uint32_t)(__x) & (uint32_t)0x00ff0000UL) >> 8) | \ + (((uint32_t)(__x) & (uint32_t)0xff000000UL) >> 24) )) + +#ifdef HOST_WORDS_BIGENDIAN +#define PAT(x) x +#else +#define PAT(x) cbswap_32(x) +#endif + +static const uint32_t dmask16[16] = { + PAT(0x00000000), + PAT(0x000000ff), + PAT(0x0000ff00), + PAT(0x0000ffff), + PAT(0x00ff0000), + PAT(0x00ff00ff), + PAT(0x00ffff00), + PAT(0x00ffffff), + PAT(0xff000000), + PAT(0xff0000ff), + PAT(0xff00ff00), + PAT(0xff00ffff), + PAT(0xffff0000), + PAT(0xffff00ff), + PAT(0xffffff00), + PAT(0xffffffff), +}; + +static const uint32_t dmask4[4] = { + PAT(0x00000000), + PAT(0x0000ffff), + PAT(0xffff0000), + PAT(0xffffffff), +}; + +static uint32_t color_table[2][8]; + +#ifndef CONFIG_CURSES +enum color_names { + COLOR_BLACK = 0, + COLOR_RED = 1, + COLOR_GREEN = 2, + COLOR_YELLOW = 3, + COLOR_BLUE = 4, + COLOR_MAGENTA = 5, + COLOR_CYAN = 6, + COLOR_WHITE = 7 +}; +#endif + +static const uint32_t color_table_rgb[2][8] = { + { /* dark */ + QEMU_RGB(0x00, 0x00, 0x00), /* black */ + QEMU_RGB(0xaa, 0x00, 0x00), /* red */ + QEMU_RGB(0x00, 0xaa, 0x00), /* green */ + QEMU_RGB(0xaa, 0xaa, 0x00), /* yellow */ + QEMU_RGB(0x00, 0x00, 0xaa), /* blue */ + QEMU_RGB(0xaa, 0x00, 0xaa), /* magenta */ + QEMU_RGB(0x00, 0xaa, 0xaa), /* cyan */ + QEMU_RGB(0xaa, 0xaa, 0xaa), /* white */ + }, + { /* bright */ + QEMU_RGB(0x00, 0x00, 0x00), /* black */ + QEMU_RGB(0xff, 0x00, 0x00), /* red */ + QEMU_RGB(0x00, 0xff, 0x00), /* green */ + QEMU_RGB(0xff, 0xff, 0x00), /* yellow */ + QEMU_RGB(0x00, 0x00, 0xff), /* blue */ + QEMU_RGB(0xff, 0x00, 0xff), /* magenta */ + QEMU_RGB(0x00, 0xff, 0xff), /* cyan */ + QEMU_RGB(0xff, 0xff, 0xff), /* white */ + } +}; + +static inline unsigned int col_expand(DisplayState *ds, unsigned int col) +{ + switch(ds_get_bits_per_pixel(ds)) { + case 8: + col |= col << 8; + col |= col << 16; + break; + case 15: + case 16: + col |= col << 16; + break; + default: + break; + } + + return col; +} +#ifdef DEBUG_CONSOLE +static void console_print_text_attributes(TextAttributes *t_attrib, char ch) +{ + if (t_attrib->bold) { + printf("b"); + } else { + printf(" "); + } + if (t_attrib->uline) { + printf("u"); + } else { + printf(" "); + } + if (t_attrib->blink) { + printf("l"); + } else { + printf(" "); + } + if (t_attrib->invers) { + printf("i"); + } else { + printf(" "); + } + if (t_attrib->unvisible) { + printf("n"); + } else { + printf(" "); + } + + printf(" fg: %d bg: %d ch:'%2X' '%c'\n", t_attrib->fgcol, t_attrib->bgcol, ch, ch); +} +#endif + +static void vga_putcharxy(DisplayState *ds, int x, int y, int ch, + TextAttributes *t_attrib) +{ + uint8_t *d; + const uint8_t *font_ptr; + unsigned int font_data, linesize, xorcol, bpp; + int i; + unsigned int fgcol, bgcol; + +#ifdef DEBUG_CONSOLE + printf("x: %2i y: %2i", x, y); + console_print_text_attributes(t_attrib, ch); +#endif + + if (t_attrib->invers) { + bgcol = color_table[t_attrib->bold][t_attrib->fgcol]; + fgcol = color_table[t_attrib->bold][t_attrib->bgcol]; + } else { + fgcol = color_table[t_attrib->bold][t_attrib->fgcol]; + bgcol = color_table[t_attrib->bold][t_attrib->bgcol]; + } + + bpp = (ds_get_bits_per_pixel(ds) + 7) >> 3; + d = ds_get_data(ds) + + ds_get_linesize(ds) * y * FONT_HEIGHT + bpp * x * FONT_WIDTH; + linesize = ds_get_linesize(ds); + font_ptr = vgafont16 + FONT_HEIGHT * ch; + xorcol = bgcol ^ fgcol; + switch(ds_get_bits_per_pixel(ds)) { + case 8: + for(i = 0; i < FONT_HEIGHT; i++) { + font_data = *font_ptr++; + if (t_attrib->uline + && ((i == FONT_HEIGHT - 2) || (i == FONT_HEIGHT - 3))) { + font_data = 0xFF; + } + ((uint32_t *)d)[0] = (dmask16[(font_data >> 4)] & xorcol) ^ bgcol; + ((uint32_t *)d)[1] = (dmask16[(font_data >> 0) & 0xf] & xorcol) ^ bgcol; + d += linesize; + } + break; + case 16: + case 15: + for(i = 0; i < FONT_HEIGHT; i++) { + font_data = *font_ptr++; + if (t_attrib->uline + && ((i == FONT_HEIGHT - 2) || (i == FONT_HEIGHT - 3))) { + font_data = 0xFF; + } + ((uint32_t *)d)[0] = (dmask4[(font_data >> 6)] & xorcol) ^ bgcol; + ((uint32_t *)d)[1] = (dmask4[(font_data >> 4) & 3] & xorcol) ^ bgcol; + ((uint32_t *)d)[2] = (dmask4[(font_data >> 2) & 3] & xorcol) ^ bgcol; + ((uint32_t *)d)[3] = (dmask4[(font_data >> 0) & 3] & xorcol) ^ bgcol; + d += linesize; + } + break; + case 32: + for(i = 0; i < FONT_HEIGHT; i++) { + font_data = *font_ptr++; + if (t_attrib->uline && ((i == FONT_HEIGHT - 2) || (i == FONT_HEIGHT - 3))) { + font_data = 0xFF; + } + ((uint32_t *)d)[0] = (-((font_data >> 7)) & xorcol) ^ bgcol; + ((uint32_t *)d)[1] = (-((font_data >> 6) & 1) & xorcol) ^ bgcol; + ((uint32_t *)d)[2] = (-((font_data >> 5) & 1) & xorcol) ^ bgcol; + ((uint32_t *)d)[3] = (-((font_data >> 4) & 1) & xorcol) ^ bgcol; + ((uint32_t *)d)[4] = (-((font_data >> 3) & 1) & xorcol) ^ bgcol; + ((uint32_t *)d)[5] = (-((font_data >> 2) & 1) & xorcol) ^ bgcol; + ((uint32_t *)d)[6] = (-((font_data >> 1) & 1) & xorcol) ^ bgcol; + ((uint32_t *)d)[7] = (-((font_data >> 0) & 1) & xorcol) ^ bgcol; + d += linesize; + } + break; + } +} + +static void text_console_resize(QemuConsole *s) +{ + TextCell *cells, *c, *c1; + int w1, x, y, last_width; + + last_width = s->width; + s->width = s->g_width / FONT_WIDTH; + s->height = s->g_height / FONT_HEIGHT; + + w1 = last_width; + if (s->width < w1) + w1 = s->width; + + cells = g_malloc(s->width * s->total_height * sizeof(TextCell)); + for(y = 0; y < s->total_height; y++) { + c = &cells[y * s->width]; + if (w1 > 0) { + c1 = &s->cells[y * last_width]; + for(x = 0; x < w1; x++) { + *c++ = *c1++; + } + } + for(x = w1; x < s->width; x++) { + c->ch = ' '; + c->t_attrib = s->t_attrib_default; + c++; + } + } + g_free(s->cells); + s->cells = cells; +} + +static inline void text_update_xy(QemuConsole *s, int x, int y) +{ + s->text_x[0] = MIN(s->text_x[0], x); + s->text_x[1] = MAX(s->text_x[1], x); + s->text_y[0] = MIN(s->text_y[0], y); + s->text_y[1] = MAX(s->text_y[1], y); +} + +static void invalidate_xy(QemuConsole *s, int x, int y) +{ + if (s->update_x0 > x * FONT_WIDTH) + s->update_x0 = x * FONT_WIDTH; + if (s->update_y0 > y * FONT_HEIGHT) + s->update_y0 = y * FONT_HEIGHT; + if (s->update_x1 < (x + 1) * FONT_WIDTH) + s->update_x1 = (x + 1) * FONT_WIDTH; + if (s->update_y1 < (y + 1) * FONT_HEIGHT) + s->update_y1 = (y + 1) * FONT_HEIGHT; +} + +static void update_xy(QemuConsole *s, int x, int y) +{ + TextCell *c; + int y1, y2; + + if (s == active_console) { + if (!ds_get_bits_per_pixel(s->ds)) { + text_update_xy(s, x, y); + return; + } + + y1 = (s->y_base + y) % s->total_height; + y2 = y1 - s->y_displayed; + if (y2 < 0) + y2 += s->total_height; + if (y2 < s->height) { + c = &s->cells[y1 * s->width + x]; + vga_putcharxy(s->ds, x, y2, c->ch, + &(c->t_attrib)); + invalidate_xy(s, x, y2); + } + } +} + +static void console_show_cursor(QemuConsole *s, int show) +{ + TextCell *c; + int y, y1; + + if (s == active_console) { + int x = s->x; + + if (!ds_get_bits_per_pixel(s->ds)) { + s->cursor_invalidate = 1; + return; + } + + if (x >= s->width) { + x = s->width - 1; + } + y1 = (s->y_base + s->y) % s->total_height; + y = y1 - s->y_displayed; + if (y < 0) + y += s->total_height; + if (y < s->height) { + c = &s->cells[y1 * s->width + x]; + if (show && s->cursor_visible_phase) { + TextAttributes t_attrib = s->t_attrib_default; + t_attrib.invers = !(t_attrib.invers); /* invert fg and bg */ + vga_putcharxy(s->ds, x, y, c->ch, &t_attrib); + } else { + vga_putcharxy(s->ds, x, y, c->ch, &(c->t_attrib)); + } + invalidate_xy(s, x, y); + } + } +} + +static void console_refresh(QemuConsole *s) +{ + TextCell *c; + int x, y, y1; + + if (s != active_console) + return; + + if (s->ds->have_text) { + s->text_x[0] = 0; + s->text_y[0] = 0; + s->text_x[1] = s->width - 1; + s->text_y[1] = s->height - 1; + s->cursor_invalidate = 1; + } + + if (s->ds->have_gfx) { + vga_fill_rect(s->ds, 0, 0, ds_get_width(s->ds), ds_get_height(s->ds), + color_table[0][COLOR_BLACK]); + y1 = s->y_displayed; + for (y = 0; y < s->height; y++) { + c = s->cells + y1 * s->width; + for (x = 0; x < s->width; x++) { + vga_putcharxy(s->ds, x, y, c->ch, + &(c->t_attrib)); + c++; + } + if (++y1 == s->total_height) { + y1 = 0; + } + } + console_show_cursor(s, 1); + dpy_gfx_update(s->ds, 0, 0, ds_get_width(s->ds), ds_get_height(s->ds)); + } +} + +static void console_scroll(int ydelta) +{ + QemuConsole *s; + int i, y1; + + s = active_console; + if (!s || (s->console_type == GRAPHIC_CONSOLE)) + return; + + if (ydelta > 0) { + for(i = 0; i < ydelta; i++) { + if (s->y_displayed == s->y_base) + break; + if (++s->y_displayed == s->total_height) + s->y_displayed = 0; + } + } else { + ydelta = -ydelta; + i = s->backscroll_height; + if (i > s->total_height - s->height) + i = s->total_height - s->height; + y1 = s->y_base - i; + if (y1 < 0) + y1 += s->total_height; + for(i = 0; i < ydelta; i++) { + if (s->y_displayed == y1) + break; + if (--s->y_displayed < 0) + s->y_displayed = s->total_height - 1; + } + } + console_refresh(s); +} + +static void console_put_lf(QemuConsole *s) +{ + TextCell *c; + int x, y1; + + s->y++; + if (s->y >= s->height) { + s->y = s->height - 1; + + if (s->y_displayed == s->y_base) { + if (++s->y_displayed == s->total_height) + s->y_displayed = 0; + } + if (++s->y_base == s->total_height) + s->y_base = 0; + if (s->backscroll_height < s->total_height) + s->backscroll_height++; + y1 = (s->y_base + s->height - 1) % s->total_height; + c = &s->cells[y1 * s->width]; + for(x = 0; x < s->width; x++) { + c->ch = ' '; + c->t_attrib = s->t_attrib_default; + c++; + } + if (s == active_console && s->y_displayed == s->y_base) { + if (!ds_get_bits_per_pixel(s->ds)) { + s->text_x[0] = 0; + s->text_y[0] = 0; + s->text_x[1] = s->width - 1; + s->text_y[1] = s->height - 1; + return; + } + + vga_bitblt(s->ds, 0, FONT_HEIGHT, 0, 0, + s->width * FONT_WIDTH, + (s->height - 1) * FONT_HEIGHT); + vga_fill_rect(s->ds, 0, (s->height - 1) * FONT_HEIGHT, + s->width * FONT_WIDTH, FONT_HEIGHT, + color_table[0][s->t_attrib_default.bgcol]); + s->update_x0 = 0; + s->update_y0 = 0; + s->update_x1 = s->width * FONT_WIDTH; + s->update_y1 = s->height * FONT_HEIGHT; + } + } +} + +/* Set console attributes depending on the current escape codes. + * NOTE: I know this code is not very efficient (checking every color for it + * self) but it is more readable and better maintainable. + */ +static void console_handle_escape(QemuConsole *s) +{ + int i; + + for (i=0; i<s->nb_esc_params; i++) { + switch (s->esc_params[i]) { + case 0: /* reset all console attributes to default */ + s->t_attrib = s->t_attrib_default; + break; + case 1: + s->t_attrib.bold = 1; + break; + case 4: + s->t_attrib.uline = 1; + break; + case 5: + s->t_attrib.blink = 1; + break; + case 7: + s->t_attrib.invers = 1; + break; + case 8: + s->t_attrib.unvisible = 1; + break; + case 22: + s->t_attrib.bold = 0; + break; + case 24: + s->t_attrib.uline = 0; + break; + case 25: + s->t_attrib.blink = 0; + break; + case 27: + s->t_attrib.invers = 0; + break; + case 28: + s->t_attrib.unvisible = 0; + break; + /* set foreground color */ + case 30: + s->t_attrib.fgcol=COLOR_BLACK; + break; + case 31: + s->t_attrib.fgcol=COLOR_RED; + break; + case 32: + s->t_attrib.fgcol=COLOR_GREEN; + break; + case 33: + s->t_attrib.fgcol=COLOR_YELLOW; + break; + case 34: + s->t_attrib.fgcol=COLOR_BLUE; + break; + case 35: + s->t_attrib.fgcol=COLOR_MAGENTA; + break; + case 36: + s->t_attrib.fgcol=COLOR_CYAN; + break; + case 37: + s->t_attrib.fgcol=COLOR_WHITE; + break; + /* set background color */ + case 40: + s->t_attrib.bgcol=COLOR_BLACK; + break; + case 41: + s->t_attrib.bgcol=COLOR_RED; + break; + case 42: + s->t_attrib.bgcol=COLOR_GREEN; + break; + case 43: + s->t_attrib.bgcol=COLOR_YELLOW; + break; + case 44: + s->t_attrib.bgcol=COLOR_BLUE; + break; + case 45: + s->t_attrib.bgcol=COLOR_MAGENTA; + break; + case 46: + s->t_attrib.bgcol=COLOR_CYAN; + break; + case 47: + s->t_attrib.bgcol=COLOR_WHITE; + break; + } + } +} + +static void console_clear_xy(QemuConsole *s, int x, int y) +{ + int y1 = (s->y_base + y) % s->total_height; + TextCell *c = &s->cells[y1 * s->width + x]; + c->ch = ' '; + c->t_attrib = s->t_attrib_default; + update_xy(s, x, y); +} + +/* set cursor, checking bounds */ +static void set_cursor(QemuConsole *s, int x, int y) +{ + if (x < 0) { + x = 0; + } + if (y < 0) { + y = 0; + } + if (y >= s->height) { + y = s->height - 1; + } + if (x >= s->width) { + x = s->width - 1; + } + + s->x = x; + s->y = y; +} + +static void console_putchar(QemuConsole *s, int ch) +{ + TextCell *c; + int y1, i; + int x, y; + + switch(s->state) { + case TTY_STATE_NORM: + switch(ch) { + case '\r': /* carriage return */ + s->x = 0; + break; + case '\n': /* newline */ + console_put_lf(s); + break; + case '\b': /* backspace */ + if (s->x > 0) + s->x--; + break; + case '\t': /* tabspace */ + if (s->x + (8 - (s->x % 8)) > s->width) { + s->x = 0; + console_put_lf(s); + } else { + s->x = s->x + (8 - (s->x % 8)); + } + break; + case '\a': /* alert aka. bell */ + /* TODO: has to be implemented */ + break; + case 14: + /* SI (shift in), character set 0 (ignored) */ + break; + case 15: + /* SO (shift out), character set 1 (ignored) */ + break; + case 27: /* esc (introducing an escape sequence) */ + s->state = TTY_STATE_ESC; + break; + default: + if (s->x >= s->width) { + /* line wrap */ + s->x = 0; + console_put_lf(s); + } + y1 = (s->y_base + s->y) % s->total_height; + c = &s->cells[y1 * s->width + s->x]; + c->ch = ch; + c->t_attrib = s->t_attrib; + update_xy(s, s->x, s->y); + s->x++; + break; + } + break; + case TTY_STATE_ESC: /* check if it is a terminal escape sequence */ + if (ch == '[') { + for(i=0;i<MAX_ESC_PARAMS;i++) + s->esc_params[i] = 0; + s->nb_esc_params = 0; + s->state = TTY_STATE_CSI; + } else { + s->state = TTY_STATE_NORM; + } + break; + case TTY_STATE_CSI: /* handle escape sequence parameters */ + if (ch >= '0' && ch <= '9') { + if (s->nb_esc_params < MAX_ESC_PARAMS) { + int *param = &s->esc_params[s->nb_esc_params]; + int digit = (ch - '0'); + + *param = (*param <= (INT_MAX - digit) / 10) ? + *param * 10 + digit : INT_MAX; + } + } else { + if (s->nb_esc_params < MAX_ESC_PARAMS) + s->nb_esc_params++; + if (ch == ';') + break; +#ifdef DEBUG_CONSOLE + fprintf(stderr, "escape sequence CSI%d;%d%c, %d parameters\n", + s->esc_params[0], s->esc_params[1], ch, s->nb_esc_params); +#endif + s->state = TTY_STATE_NORM; + switch(ch) { + case 'A': + /* move cursor up */ + if (s->esc_params[0] == 0) { + s->esc_params[0] = 1; + } + set_cursor(s, s->x, s->y - s->esc_params[0]); + break; + case 'B': + /* move cursor down */ + if (s->esc_params[0] == 0) { + s->esc_params[0] = 1; + } + set_cursor(s, s->x, s->y + s->esc_params[0]); + break; + case 'C': + /* move cursor right */ + if (s->esc_params[0] == 0) { + s->esc_params[0] = 1; + } + set_cursor(s, s->x + s->esc_params[0], s->y); + break; + case 'D': + /* move cursor left */ + if (s->esc_params[0] == 0) { + s->esc_params[0] = 1; + } + set_cursor(s, s->x - s->esc_params[0], s->y); + break; + case 'G': + /* move cursor to column */ + set_cursor(s, s->esc_params[0] - 1, s->y); + break; + case 'f': + case 'H': + /* move cursor to row, column */ + set_cursor(s, s->esc_params[1] - 1, s->esc_params[0] - 1); + break; + case 'J': + switch (s->esc_params[0]) { + case 0: + /* clear to end of screen */ + for (y = s->y; y < s->height; y++) { + for (x = 0; x < s->width; x++) { + if (y == s->y && x < s->x) { + continue; + } + console_clear_xy(s, x, y); + } + } + break; + case 1: + /* clear from beginning of screen */ + for (y = 0; y <= s->y; y++) { + for (x = 0; x < s->width; x++) { + if (y == s->y && x > s->x) { + break; + } + console_clear_xy(s, x, y); + } + } + break; + case 2: + /* clear entire screen */ + for (y = 0; y <= s->height; y++) { + for (x = 0; x < s->width; x++) { + console_clear_xy(s, x, y); + } + } + break; + } + break; + case 'K': + switch (s->esc_params[0]) { + case 0: + /* clear to eol */ + for(x = s->x; x < s->width; x++) { + console_clear_xy(s, x, s->y); + } + break; + case 1: + /* clear from beginning of line */ + for (x = 0; x <= s->x; x++) { + console_clear_xy(s, x, s->y); + } + break; + case 2: + /* clear entire line */ + for(x = 0; x < s->width; x++) { + console_clear_xy(s, x, s->y); + } + break; + } + break; + case 'm': + console_handle_escape(s); + break; + case 'n': + /* report cursor position */ + /* TODO: send ESC[row;colR */ + break; + case 's': + /* save cursor position */ + s->x_saved = s->x; + s->y_saved = s->y; + break; + case 'u': + /* restore cursor position */ + s->x = s->x_saved; + s->y = s->y_saved; + break; + default: +#ifdef DEBUG_CONSOLE + fprintf(stderr, "unhandled escape character '%c'\n", ch); +#endif + break; + } + break; + } + } +} + +void console_select(unsigned int index) +{ + QemuConsole *s; + + if (index >= MAX_CONSOLES) + return; + if (active_console) { + active_console->g_width = ds_get_width(active_console->ds); + active_console->g_height = ds_get_height(active_console->ds); + } + s = consoles[index]; + if (s) { + DisplayState *ds = s->ds; + + if (active_console && active_console->cursor_timer) { + qemu_del_timer(active_console->cursor_timer); + } + active_console = s; + if (ds->have_gfx) { + ds->surface = qemu_resize_displaysurface(ds, s->g_width, s->g_height); + dpy_gfx_resize(ds); + } + if (ds->have_text) { + dpy_text_resize(ds, s->width, s->height); + } + if (s->cursor_timer) { + qemu_mod_timer(s->cursor_timer, + qemu_get_clock_ms(rt_clock) + CONSOLE_CURSOR_PERIOD / 2); + } + vga_hw_invalidate(); + } +} + +static int console_puts(CharDriverState *chr, const uint8_t *buf, int len) +{ + QemuConsole *s = chr->opaque; + int i; + + s->update_x0 = s->width * FONT_WIDTH; + s->update_y0 = s->height * FONT_HEIGHT; + s->update_x1 = 0; + s->update_y1 = 0; + console_show_cursor(s, 0); + for(i = 0; i < len; i++) { + console_putchar(s, buf[i]); + } + console_show_cursor(s, 1); + if (s->ds->have_gfx && s->update_x0 < s->update_x1) { + dpy_gfx_update(s->ds, s->update_x0, s->update_y0, + s->update_x1 - s->update_x0, + s->update_y1 - s->update_y0); + } + return len; +} + +static void kbd_send_chars(void *opaque) +{ + QemuConsole *s = opaque; + int len; + uint8_t buf[16]; + + len = qemu_chr_be_can_write(s->chr); + if (len > s->out_fifo.count) + len = s->out_fifo.count; + if (len > 0) { + if (len > sizeof(buf)) + len = sizeof(buf); + qemu_fifo_read(&s->out_fifo, buf, len); + qemu_chr_be_write(s->chr, buf, len); + } + /* characters are pending: we send them a bit later (XXX: + horrible, should change char device API) */ + if (s->out_fifo.count > 0) { + qemu_mod_timer(s->kbd_timer, qemu_get_clock_ms(rt_clock) + 1); + } +} + +/* called when an ascii key is pressed */ +void kbd_put_keysym(int keysym) +{ + QemuConsole *s; + uint8_t buf[16], *q; + int c; + + s = active_console; + if (!s || (s->console_type == GRAPHIC_CONSOLE)) + return; + + switch(keysym) { + case QEMU_KEY_CTRL_UP: + console_scroll(-1); + break; + case QEMU_KEY_CTRL_DOWN: + console_scroll(1); + break; + case QEMU_KEY_CTRL_PAGEUP: + console_scroll(-10); + break; + case QEMU_KEY_CTRL_PAGEDOWN: + console_scroll(10); + break; + default: + /* convert the QEMU keysym to VT100 key string */ + q = buf; + if (keysym >= 0xe100 && keysym <= 0xe11f) { + *q++ = '\033'; + *q++ = '['; + c = keysym - 0xe100; + if (c >= 10) + *q++ = '0' + (c / 10); + *q++ = '0' + (c % 10); + *q++ = '~'; + } else if (keysym >= 0xe120 && keysym <= 0xe17f) { + *q++ = '\033'; + *q++ = '['; + *q++ = keysym & 0xff; + } else if (s->echo && (keysym == '\r' || keysym == '\n')) { + console_puts(s->chr, (const uint8_t *) "\r", 1); + *q++ = '\n'; + } else { + *q++ = keysym; + } + if (s->echo) { + console_puts(s->chr, buf, q - buf); + } + if (s->chr->chr_read) { + qemu_fifo_write(&s->out_fifo, buf, q - buf); + kbd_send_chars(s); + } + break; + } +} + +static void text_console_invalidate(void *opaque) +{ + QemuConsole *s = (QemuConsole *) opaque; + if (!ds_get_bits_per_pixel(s->ds) && s->console_type == TEXT_CONSOLE) { + s->g_width = ds_get_width(s->ds); + s->g_height = ds_get_height(s->ds); + text_console_resize(s); + } + console_refresh(s); +} + +static void text_console_update(void *opaque, console_ch_t *chardata) +{ + QemuConsole *s = (QemuConsole *) opaque; + int i, j, src; + + if (s->text_x[0] <= s->text_x[1]) { + src = (s->y_base + s->text_y[0]) * s->width; + chardata += s->text_y[0] * s->width; + for (i = s->text_y[0]; i <= s->text_y[1]; i ++) + for (j = 0; j < s->width; j ++, src ++) + console_write_ch(chardata ++, s->cells[src].ch | + (s->cells[src].t_attrib.fgcol << 12) | + (s->cells[src].t_attrib.bgcol << 8) | + (s->cells[src].t_attrib.bold << 21)); + dpy_text_update(s->ds, s->text_x[0], s->text_y[0], + s->text_x[1] - s->text_x[0], i - s->text_y[0]); + s->text_x[0] = s->width; + s->text_y[0] = s->height; + s->text_x[1] = 0; + s->text_y[1] = 0; + } + if (s->cursor_invalidate) { + dpy_text_cursor(s->ds, s->x, s->y); + s->cursor_invalidate = 0; + } +} + +static QemuConsole *get_graphic_console(DisplayState *ds) +{ + int i; + QemuConsole *s; + for (i = 0; i < nb_consoles; i++) { + s = consoles[i]; + if (s->console_type == GRAPHIC_CONSOLE && s->ds == ds) + return s; + } + return NULL; +} + +static QemuConsole *new_console(DisplayState *ds, console_type_t console_type) +{ + QemuConsole *s; + int i; + + if (nb_consoles >= MAX_CONSOLES) + return NULL; + s = g_malloc0(sizeof(QemuConsole)); + if (!active_console || ((active_console->console_type != GRAPHIC_CONSOLE) && + (console_type == GRAPHIC_CONSOLE))) { + active_console = s; + } + s->ds = ds; + s->console_type = console_type; + if (console_type != GRAPHIC_CONSOLE) { + s->index = nb_consoles; + consoles[nb_consoles++] = s; + } else { + /* HACK: Put graphical consoles before text consoles. */ + for (i = nb_consoles; i > 0; i--) { + if (consoles[i - 1]->console_type == GRAPHIC_CONSOLE) + break; + consoles[i] = consoles[i - 1]; + consoles[i]->index = i; + } + s->index = i; + consoles[i] = s; + nb_consoles++; + } + return s; +} + +static void qemu_alloc_display(DisplaySurface *surface, int width, int height, + int linesize, PixelFormat pf, int newflags) +{ + surface->pf = pf; + + qemu_pixman_image_unref(surface->image); + surface->image = NULL; + + surface->format = qemu_pixman_get_format(&pf); + assert(surface->format != 0); + surface->image = pixman_image_create_bits(surface->format, + width, height, + NULL, linesize); + assert(surface->image != NULL); + + surface->flags = newflags | QEMU_ALLOCATED_FLAG; +#ifdef HOST_WORDS_BIGENDIAN + surface->flags |= QEMU_BIG_ENDIAN_FLAG; +#endif +} + +DisplaySurface *qemu_create_displaysurface(DisplayState *ds, + int width, int height) +{ + DisplaySurface *surface = g_new0(DisplaySurface, 1); + + int linesize = width * 4; + qemu_alloc_display(surface, width, height, linesize, + qemu_default_pixelformat(32), 0); + return surface; +} + +DisplaySurface *qemu_resize_displaysurface(DisplayState *ds, + int width, int height) +{ + int linesize = width * 4; + + trace_displaysurface_resize(ds, ds->surface, width, height); + qemu_alloc_display(ds->surface, width, height, linesize, + qemu_default_pixelformat(32), 0); + return ds->surface; +} + +DisplaySurface *qemu_create_displaysurface_from(int width, int height, int bpp, + int linesize, uint8_t *data) +{ + DisplaySurface *surface = g_new0(DisplaySurface, 1); + + surface->pf = qemu_default_pixelformat(bpp); + + surface->format = qemu_pixman_get_format(&surface->pf); + assert(surface->format != 0); + surface->image = pixman_image_create_bits(surface->format, + width, height, + (void *)data, linesize); + assert(surface->image != NULL); + +#ifdef HOST_WORDS_BIGENDIAN + surface->flags = QEMU_BIG_ENDIAN_FLAG; +#endif + + return surface; +} + +void qemu_free_displaysurface(DisplayState *ds) +{ + trace_displaysurface_free(ds, ds->surface); + if (ds->surface == NULL) { + return; + } + qemu_pixman_image_unref(ds->surface->image); + g_free(ds->surface); +} + +static void dumb_display_init(void) +{ + DisplayState *ds = g_malloc0(sizeof(DisplayState)); + int width = 640; + int height = 480; + + if (is_fixedsize_console()) { + width = active_console->g_width; + height = active_console->g_height; + } + ds->surface = qemu_create_displaysurface(ds, width, height); + register_displaystate(ds); +} + +/***********************************************************/ +/* register display */ + +void register_displaystate(DisplayState *ds) +{ + DisplayState **s; + s = &display_state; + while (*s != NULL) + s = &(*s)->next; + ds->next = NULL; + *s = ds; +} + +DisplayState *get_displaystate(void) +{ + if (!display_state) { + dumb_display_init (); + } + return display_state; +} + +DisplayState *graphic_console_init(vga_hw_update_ptr update, + vga_hw_invalidate_ptr invalidate, + vga_hw_screen_dump_ptr screen_dump, + vga_hw_text_update_ptr text_update, + void *opaque) +{ + QemuConsole *s; + DisplayState *ds; + + ds = (DisplayState *) g_malloc0(sizeof(DisplayState)); + ds->surface = qemu_create_displaysurface(ds, 640, 480); + + s = new_console(ds, GRAPHIC_CONSOLE); + if (s == NULL) { + qemu_free_displaysurface(ds); + g_free(ds); + return NULL; + } + s->hw_update = update; + s->hw_invalidate = invalidate; + s->hw_screen_dump = screen_dump; + s->hw_text_update = text_update; + s->hw = opaque; + + register_displaystate(ds); + return ds; +} + +int is_graphic_console(void) +{ + return active_console && active_console->console_type == GRAPHIC_CONSOLE; +} + +int is_fixedsize_console(void) +{ + return active_console && active_console->console_type != TEXT_CONSOLE; +} + +void console_color_init(DisplayState *ds) +{ + int i, j; + for (j = 0; j < 2; j++) { + for (i = 0; i < 8; i++) { + color_table[j][i] = col_expand(ds, + vga_get_color(ds, color_table_rgb[j][i])); + } + } +} + +static void text_console_set_echo(CharDriverState *chr, bool echo) +{ + QemuConsole *s = chr->opaque; + + s->echo = echo; +} + +static void text_console_update_cursor(void *opaque) +{ + QemuConsole *s = opaque; + + s->cursor_visible_phase = !s->cursor_visible_phase; + vga_hw_invalidate(); + qemu_mod_timer(s->cursor_timer, + qemu_get_clock_ms(rt_clock) + CONSOLE_CURSOR_PERIOD / 2); +} + +static void text_console_do_init(CharDriverState *chr, DisplayState *ds) +{ + QemuConsole *s; + static int color_inited; + + s = chr->opaque; + + chr->chr_write = console_puts; + + s->out_fifo.buf = s->out_fifo_buf; + s->out_fifo.buf_size = sizeof(s->out_fifo_buf); + s->kbd_timer = qemu_new_timer_ms(rt_clock, kbd_send_chars, s); + s->ds = ds; + + if (!color_inited) { + color_inited = 1; + console_color_init(s->ds); + } + s->y_displayed = 0; + s->y_base = 0; + s->total_height = DEFAULT_BACKSCROLL; + s->x = 0; + s->y = 0; + if (s->console_type == TEXT_CONSOLE) { + s->g_width = ds_get_width(s->ds); + s->g_height = ds_get_height(s->ds); + } + + s->cursor_timer = + qemu_new_timer_ms(rt_clock, text_console_update_cursor, s); + + s->hw_invalidate = text_console_invalidate; + s->hw_text_update = text_console_update; + s->hw = s; + + /* Set text attribute defaults */ + s->t_attrib_default.bold = 0; + s->t_attrib_default.uline = 0; + s->t_attrib_default.blink = 0; + s->t_attrib_default.invers = 0; + s->t_attrib_default.unvisible = 0; + s->t_attrib_default.fgcol = COLOR_WHITE; + s->t_attrib_default.bgcol = COLOR_BLACK; + /* set current text attributes to default */ + s->t_attrib = s->t_attrib_default; + text_console_resize(s); + + if (chr->label) { + char msg[128]; + int len; + + s->t_attrib.bgcol = COLOR_BLUE; + len = snprintf(msg, sizeof(msg), "%s console\r\n", chr->label); + console_puts(chr, (uint8_t*)msg, len); + s->t_attrib = s->t_attrib_default; + } + + qemu_chr_generic_open(chr); + if (chr->init) + chr->init(chr); +} + +CharDriverState *text_console_init(QemuOpts *opts) +{ + CharDriverState *chr; + QemuConsole *s; + unsigned width; + unsigned height; + + chr = g_malloc0(sizeof(CharDriverState)); + + width = qemu_opt_get_number(opts, "width", 0); + if (width == 0) + width = qemu_opt_get_number(opts, "cols", 0) * FONT_WIDTH; + + height = qemu_opt_get_number(opts, "height", 0); + if (height == 0) + height = qemu_opt_get_number(opts, "rows", 0) * FONT_HEIGHT; + + if (width == 0 || height == 0) { + s = new_console(NULL, TEXT_CONSOLE); + } else { + s = new_console(NULL, TEXT_CONSOLE_FIXED_SIZE); + } + + if (!s) { + g_free(chr); + return NULL; + } + + s->chr = chr; + s->g_width = width; + s->g_height = height; + chr->opaque = s; + chr->chr_set_echo = text_console_set_echo; + return chr; +} + +void text_consoles_set_display(DisplayState *ds) +{ + int i; + + for (i = 0; i < nb_consoles; i++) { + if (consoles[i]->console_type != GRAPHIC_CONSOLE) { + text_console_do_init(consoles[i]->chr, ds); + } + } +} + +void qemu_console_resize(DisplayState *ds, int width, int height) +{ + QemuConsole *s = get_graphic_console(ds); + if (!s) return; + + s->g_width = width; + s->g_height = height; + if (is_graphic_console()) { + ds->surface = qemu_resize_displaysurface(ds, width, height); + dpy_gfx_resize(ds); + } +} + +void qemu_console_copy(DisplayState *ds, int src_x, int src_y, + int dst_x, int dst_y, int w, int h) +{ + if (is_graphic_console()) { + dpy_gfx_copy(ds, src_x, src_y, dst_x, dst_y, w, h); + } +} + +PixelFormat qemu_different_endianness_pixelformat(int bpp) +{ + PixelFormat pf; + + memset(&pf, 0x00, sizeof(PixelFormat)); + + pf.bits_per_pixel = bpp; + pf.bytes_per_pixel = DIV_ROUND_UP(bpp, 8); + pf.depth = bpp == 32 ? 24 : bpp; + + switch (bpp) { + case 24: + pf.rmask = 0x000000FF; + pf.gmask = 0x0000FF00; + pf.bmask = 0x00FF0000; + pf.rmax = 255; + pf.gmax = 255; + pf.bmax = 255; + pf.rshift = 0; + pf.gshift = 8; + pf.bshift = 16; + pf.rbits = 8; + pf.gbits = 8; + pf.bbits = 8; + break; + case 32: + pf.rmask = 0x0000FF00; + pf.gmask = 0x00FF0000; + pf.bmask = 0xFF000000; + pf.amask = 0x00000000; + pf.amax = 255; + pf.rmax = 255; + pf.gmax = 255; + pf.bmax = 255; + pf.ashift = 0; + pf.rshift = 8; + pf.gshift = 16; + pf.bshift = 24; + pf.rbits = 8; + pf.gbits = 8; + pf.bbits = 8; + pf.abits = 8; + break; + default: + break; + } + return pf; +} + +PixelFormat qemu_default_pixelformat(int bpp) +{ + PixelFormat pf; + + memset(&pf, 0x00, sizeof(PixelFormat)); + + pf.bits_per_pixel = bpp; + pf.bytes_per_pixel = DIV_ROUND_UP(bpp, 8); + pf.depth = bpp == 32 ? 24 : bpp; + + switch (bpp) { + case 15: + pf.bits_per_pixel = 16; + pf.rmask = 0x00007c00; + pf.gmask = 0x000003E0; + pf.bmask = 0x0000001F; + pf.rmax = 31; + pf.gmax = 31; + pf.bmax = 31; + pf.rshift = 10; + pf.gshift = 5; + pf.bshift = 0; + pf.rbits = 5; + pf.gbits = 5; + pf.bbits = 5; + break; + case 16: + pf.rmask = 0x0000F800; + pf.gmask = 0x000007E0; + pf.bmask = 0x0000001F; + pf.rmax = 31; + pf.gmax = 63; + pf.bmax = 31; + pf.rshift = 11; + pf.gshift = 5; + pf.bshift = 0; + pf.rbits = 5; + pf.gbits = 6; + pf.bbits = 5; + break; + case 24: + pf.rmask = 0x00FF0000; + pf.gmask = 0x0000FF00; + pf.bmask = 0x000000FF; + pf.rmax = 255; + pf.gmax = 255; + pf.bmax = 255; + pf.rshift = 16; + pf.gshift = 8; + pf.bshift = 0; + pf.rbits = 8; + pf.gbits = 8; + pf.bbits = 8; + break; + case 32: + pf.rmask = 0x00FF0000; + pf.gmask = 0x0000FF00; + pf.bmask = 0x000000FF; + pf.rmax = 255; + pf.gmax = 255; + pf.bmax = 255; + pf.rshift = 16; + pf.gshift = 8; + pf.bshift = 0; + pf.rbits = 8; + pf.gbits = 8; + pf.bbits = 8; + break; + default: + break; + } + return pf; +} diff --git a/ui/curses.c b/ui/curses.c index c2be2c641a..d78e378440 100644 --- a/ui/curses.c +++ b/ui/curses.c @@ -28,13 +28,9 @@ #include <termios.h> #endif -#ifdef __OpenBSD__ -#define resize_term resizeterm -#endif - #include "qemu-common.h" -#include "console.h" -#include "sysemu.h" +#include "ui/console.h" +#include "sysemu/sysemu.h" #define FONT_HEIGHT 16 #define FONT_WIDTH 8 @@ -95,17 +91,16 @@ static void curses_calc_pad(void) } } -static void curses_resize(DisplayState *ds) +static void curses_resize(DisplayState *ds, int width, int height) { - if (ds_get_width(ds) == gwidth && ds_get_height(ds) == gheight) + if (width == gwidth && height == gheight) { return; + } - gwidth = ds_get_width(ds); - gheight = ds_get_height(ds); + gwidth = width; + gheight = height; curses_calc_pad(); - ds->surface->width = width * FONT_WIDTH; - ds->surface->height = height * FONT_HEIGHT; } #ifndef _WIN32 @@ -167,8 +162,6 @@ static void curses_refresh(DisplayState *ds) clear(); refresh(); curses_calc_pad(); - ds->surface->width = FONT_WIDTH * width; - ds->surface->height = FONT_HEIGHT * height; vga_hw_invalidate(); invalidate = 0; } @@ -195,8 +188,6 @@ static void curses_refresh(DisplayState *ds) refresh(); curses_calc_pad(); curses_update(ds, 0, 0, width, height); - ds->surface->width = FONT_WIDTH * width; - ds->surface->height = FONT_HEIGHT * height; continue; } #endif @@ -355,13 +346,11 @@ void curses_display_init(DisplayState *ds, int full_screen) #endif dcl = (DisplayChangeListener *) g_malloc0(sizeof(DisplayChangeListener)); - dcl->dpy_update = curses_update; - dcl->dpy_resize = curses_resize; + dcl->dpy_text_update = curses_update; + dcl->dpy_text_resize = curses_resize; dcl->dpy_refresh = curses_refresh; dcl->dpy_text_cursor = curses_cursor_position; register_displaychangelistener(ds, dcl); - qemu_free_displaysurface(ds); - ds->surface = qemu_create_displaysurface_from(640, 400, 0, 0, (uint8_t*) screen); invalidate = 1; } diff --git a/ui/curses_keys.h b/ui/curses_keys.h index c0d5eb452f..18ce6dceee 100644 --- a/ui/curses_keys.h +++ b/ui/curses_keys.h @@ -22,6 +22,9 @@ * THE SOFTWARE. */ +#ifndef QEMU_CURSES_KEYS_H +#define QEMU_CURSES_KEYS_H 1 + #include <curses.h> #include "keymaps.h" @@ -507,3 +510,5 @@ static const name2keysym_t name2keysym[] = { { NULL, 0 }, }; + +#endif diff --git a/ui/cursor.c b/ui/cursor.c new file mode 100644 index 0000000000..2b8dd3fa50 --- /dev/null +++ b/ui/cursor.c @@ -0,0 +1,211 @@ +#include "qemu-common.h" +#include "ui/console.h" + +#include "cursor_hidden.xpm" +#include "cursor_left_ptr.xpm" + +/* for creating built-in cursors */ +static QEMUCursor *cursor_parse_xpm(const char *xpm[]) +{ + QEMUCursor *c; + uint32_t ctab[128]; + unsigned int width, height, colors, chars; + unsigned int line = 0, i, r, g, b, x, y, pixel; + char name[16]; + uint8_t idx; + + /* parse header line: width, height, #colors, #chars */ + if (sscanf(xpm[line], "%u %u %u %u", + &width, &height, &colors, &chars) != 4) { + fprintf(stderr, "%s: header parse error: \"%s\"\n", + __FUNCTION__, xpm[line]); + return NULL; + } + if (chars != 1) { + fprintf(stderr, "%s: chars != 1 not supported\n", __FUNCTION__); + return NULL; + } + line++; + + /* parse color table */ + for (i = 0; i < colors; i++, line++) { + if (sscanf(xpm[line], "%c c %15s", &idx, name) == 2) { + if (sscanf(name, "#%02x%02x%02x", &r, &g, &b) == 3) { + ctab[idx] = (0xff << 24) | (b << 16) | (g << 8) | r; + continue; + } + if (strcmp(name, "None") == 0) { + ctab[idx] = 0x00000000; + continue; + } + } + fprintf(stderr, "%s: color parse error: \"%s\"\n", + __FUNCTION__, xpm[line]); + return NULL; + } + + /* parse pixel data */ + c = cursor_alloc(width, height); + for (pixel = 0, y = 0; y < height; y++, line++) { + for (x = 0; x < height; x++, pixel++) { + idx = xpm[line][x]; + c->data[pixel] = ctab[idx]; + } + } + return c; +} + +/* nice for debugging */ +void cursor_print_ascii_art(QEMUCursor *c, const char *prefix) +{ + uint32_t *data = c->data; + int x,y; + + for (y = 0; y < c->height; y++) { + fprintf(stderr, "%s: %2d: |", prefix, y); + for (x = 0; x < c->width; x++, data++) { + if ((*data & 0xff000000) != 0xff000000) { + fprintf(stderr, " "); /* transparent */ + } else if ((*data & 0x00ffffff) == 0x00ffffff) { + fprintf(stderr, "."); /* white */ + } else if ((*data & 0x00ffffff) == 0x00000000) { + fprintf(stderr, "X"); /* black */ + } else { + fprintf(stderr, "o"); /* other */ + } + } + fprintf(stderr, "|\n"); + } +} + +QEMUCursor *cursor_builtin_hidden(void) +{ + QEMUCursor *c; + + c = cursor_parse_xpm(cursor_hidden_xpm); + return c; +} + +QEMUCursor *cursor_builtin_left_ptr(void) +{ + QEMUCursor *c; + + c = cursor_parse_xpm(cursor_left_ptr_xpm); + return c; +} + +QEMUCursor *cursor_alloc(int width, int height) +{ + QEMUCursor *c; + int datasize = width * height * sizeof(uint32_t); + + c = g_malloc0(sizeof(QEMUCursor) + datasize); + c->width = width; + c->height = height; + c->refcount = 1; + return c; +} + +void cursor_get(QEMUCursor *c) +{ + c->refcount++; +} + +void cursor_put(QEMUCursor *c) +{ + if (c == NULL) + return; + c->refcount--; + if (c->refcount) + return; + g_free(c); +} + +int cursor_get_mono_bpl(QEMUCursor *c) +{ + return (c->width + 7) / 8; +} + +void cursor_set_mono(QEMUCursor *c, + uint32_t foreground, uint32_t background, uint8_t *image, + int transparent, uint8_t *mask) +{ + uint32_t *data = c->data; + uint8_t bit; + int x,y,bpl; + + bpl = cursor_get_mono_bpl(c); + for (y = 0; y < c->height; y++) { + bit = 0x80; + for (x = 0; x < c->width; x++, data++) { + if (transparent && mask[x/8] & bit) { + *data = 0x00000000; + } else if (!transparent && !(mask[x/8] & bit)) { + *data = 0x00000000; + } else if (image[x/8] & bit) { + *data = 0xff000000 | foreground; + } else { + *data = 0xff000000 | background; + } + bit >>= 1; + if (bit == 0) { + bit = 0x80; + } + } + mask += bpl; + image += bpl; + } +} + +void cursor_get_mono_image(QEMUCursor *c, int foreground, uint8_t *image) +{ + uint32_t *data = c->data; + uint8_t bit; + int x,y,bpl; + + bpl = cursor_get_mono_bpl(c); + memset(image, 0, bpl * c->height); + for (y = 0; y < c->height; y++) { + bit = 0x80; + for (x = 0; x < c->width; x++, data++) { + if (((*data & 0xff000000) == 0xff000000) && + ((*data & 0x00ffffff) == foreground)) { + image[x/8] |= bit; + } + bit >>= 1; + if (bit == 0) { + bit = 0x80; + } + } + image += bpl; + } +} + +void cursor_get_mono_mask(QEMUCursor *c, int transparent, uint8_t *mask) +{ + uint32_t *data = c->data; + uint8_t bit; + int x,y,bpl; + + bpl = cursor_get_mono_bpl(c); + memset(mask, 0, bpl * c->height); + for (y = 0; y < c->height; y++) { + bit = 0x80; + for (x = 0; x < c->width; x++, data++) { + if ((*data & 0xff000000) != 0xff000000) { + if (transparent != 0) { + mask[x/8] |= bit; + } + } else { + if (transparent == 0) { + mask[x/8] |= bit; + } + } + bit >>= 1; + if (bit == 0) { + bit = 0x80; + } + } + mask += bpl; + } +} diff --git a/ui/cursor_hidden.xpm b/ui/cursor_hidden.xpm new file mode 100644 index 0000000000..354e7a9391 --- /dev/null +++ b/ui/cursor_hidden.xpm @@ -0,0 +1,37 @@ +/* XPM */ +static const char *cursor_hidden_xpm[] = { + "32 32 1 1", + " c None", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", +}; diff --git a/ui/cursor_left_ptr.xpm b/ui/cursor_left_ptr.xpm new file mode 100644 index 0000000000..6c9ada9020 --- /dev/null +++ b/ui/cursor_left_ptr.xpm @@ -0,0 +1,39 @@ +/* XPM */ +static const char *cursor_left_ptr_xpm[] = { + "32 32 3 1", + "X c #000000", + ". c #ffffff", + " c None", + "X ", + "XX ", + "X.X ", + "X..X ", + "X...X ", + "X....X ", + "X.....X ", + "X......X ", + "X.......X ", + "X........X ", + "X.....XXXXX ", + "X..X..X ", + "X.X X..X ", + "XX X..X ", + "X X..X ", + " X..X ", + " X..X ", + " X..X ", + " XX ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", +}; diff --git a/ui/d3des.h b/ui/d3des.h index 78d546f7d8..70cb6b57ea 100644 --- a/ui/d3des.h +++ b/ui/d3des.h @@ -9,6 +9,8 @@ * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. */ +#ifndef D3DES_H +#define D3DES_H 1 /* d3des.h - * @@ -49,3 +51,5 @@ void des(unsigned char *, unsigned char *); /* d3des.h V5.09 rwo 9208.04 15:06 Graven Imagery ********************************************************************/ + +#endif diff --git a/ui/input.c b/ui/input.c new file mode 100644 index 0000000000..259fd1808d --- /dev/null +++ b/ui/input.c @@ -0,0 +1,529 @@ +/* + * QEMU System Emulator + * + * Copyright (c) 2003-2008 Fabrice Bellard + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "sysemu/sysemu.h" +#include "monitor/monitor.h" +#include "ui/console.h" +#include "qapi/error.h" +#include "qmp-commands.h" +#include "qapi-types.h" + +static QEMUPutKBDEvent *qemu_put_kbd_event; +static void *qemu_put_kbd_event_opaque; +static QTAILQ_HEAD(, QEMUPutLEDEntry) led_handlers = QTAILQ_HEAD_INITIALIZER(led_handlers); +static QTAILQ_HEAD(, QEMUPutMouseEntry) mouse_handlers = + QTAILQ_HEAD_INITIALIZER(mouse_handlers); +static NotifierList mouse_mode_notifiers = + NOTIFIER_LIST_INITIALIZER(mouse_mode_notifiers); + +static const int key_defs[] = { + [Q_KEY_CODE_SHIFT] = 0x2a, + [Q_KEY_CODE_SHIFT_R] = 0x36, + + [Q_KEY_CODE_ALT] = 0x38, + [Q_KEY_CODE_ALT_R] = 0xb8, + [Q_KEY_CODE_ALTGR] = 0x64, + [Q_KEY_CODE_ALTGR_R] = 0xe4, + [Q_KEY_CODE_CTRL] = 0x1d, + [Q_KEY_CODE_CTRL_R] = 0x9d, + + [Q_KEY_CODE_MENU] = 0xdd, + + [Q_KEY_CODE_ESC] = 0x01, + + [Q_KEY_CODE_1] = 0x02, + [Q_KEY_CODE_2] = 0x03, + [Q_KEY_CODE_3] = 0x04, + [Q_KEY_CODE_4] = 0x05, + [Q_KEY_CODE_5] = 0x06, + [Q_KEY_CODE_6] = 0x07, + [Q_KEY_CODE_7] = 0x08, + [Q_KEY_CODE_8] = 0x09, + [Q_KEY_CODE_9] = 0x0a, + [Q_KEY_CODE_0] = 0x0b, + [Q_KEY_CODE_MINUS] = 0x0c, + [Q_KEY_CODE_EQUAL] = 0x0d, + [Q_KEY_CODE_BACKSPACE] = 0x0e, + + [Q_KEY_CODE_TAB] = 0x0f, + [Q_KEY_CODE_Q] = 0x10, + [Q_KEY_CODE_W] = 0x11, + [Q_KEY_CODE_E] = 0x12, + [Q_KEY_CODE_R] = 0x13, + [Q_KEY_CODE_T] = 0x14, + [Q_KEY_CODE_Y] = 0x15, + [Q_KEY_CODE_U] = 0x16, + [Q_KEY_CODE_I] = 0x17, + [Q_KEY_CODE_O] = 0x18, + [Q_KEY_CODE_P] = 0x19, + [Q_KEY_CODE_BRACKET_LEFT] = 0x1a, + [Q_KEY_CODE_BRACKET_RIGHT] = 0x1b, + [Q_KEY_CODE_RET] = 0x1c, + + [Q_KEY_CODE_A] = 0x1e, + [Q_KEY_CODE_S] = 0x1f, + [Q_KEY_CODE_D] = 0x20, + [Q_KEY_CODE_F] = 0x21, + [Q_KEY_CODE_G] = 0x22, + [Q_KEY_CODE_H] = 0x23, + [Q_KEY_CODE_J] = 0x24, + [Q_KEY_CODE_K] = 0x25, + [Q_KEY_CODE_L] = 0x26, + [Q_KEY_CODE_SEMICOLON] = 0x27, + [Q_KEY_CODE_APOSTROPHE] = 0x28, + [Q_KEY_CODE_GRAVE_ACCENT] = 0x29, + + [Q_KEY_CODE_BACKSLASH] = 0x2b, + [Q_KEY_CODE_Z] = 0x2c, + [Q_KEY_CODE_X] = 0x2d, + [Q_KEY_CODE_C] = 0x2e, + [Q_KEY_CODE_V] = 0x2f, + [Q_KEY_CODE_B] = 0x30, + [Q_KEY_CODE_N] = 0x31, + [Q_KEY_CODE_M] = 0x32, + [Q_KEY_CODE_COMMA] = 0x33, + [Q_KEY_CODE_DOT] = 0x34, + [Q_KEY_CODE_SLASH] = 0x35, + + [Q_KEY_CODE_ASTERISK] = 0x37, + + [Q_KEY_CODE_SPC] = 0x39, + [Q_KEY_CODE_CAPS_LOCK] = 0x3a, + [Q_KEY_CODE_F1] = 0x3b, + [Q_KEY_CODE_F2] = 0x3c, + [Q_KEY_CODE_F3] = 0x3d, + [Q_KEY_CODE_F4] = 0x3e, + [Q_KEY_CODE_F5] = 0x3f, + [Q_KEY_CODE_F6] = 0x40, + [Q_KEY_CODE_F7] = 0x41, + [Q_KEY_CODE_F8] = 0x42, + [Q_KEY_CODE_F9] = 0x43, + [Q_KEY_CODE_F10] = 0x44, + [Q_KEY_CODE_NUM_LOCK] = 0x45, + [Q_KEY_CODE_SCROLL_LOCK] = 0x46, + + [Q_KEY_CODE_KP_DIVIDE] = 0xb5, + [Q_KEY_CODE_KP_MULTIPLY] = 0x37, + [Q_KEY_CODE_KP_SUBTRACT] = 0x4a, + [Q_KEY_CODE_KP_ADD] = 0x4e, + [Q_KEY_CODE_KP_ENTER] = 0x9c, + [Q_KEY_CODE_KP_DECIMAL] = 0x53, + [Q_KEY_CODE_SYSRQ] = 0x54, + + [Q_KEY_CODE_KP_0] = 0x52, + [Q_KEY_CODE_KP_1] = 0x4f, + [Q_KEY_CODE_KP_2] = 0x50, + [Q_KEY_CODE_KP_3] = 0x51, + [Q_KEY_CODE_KP_4] = 0x4b, + [Q_KEY_CODE_KP_5] = 0x4c, + [Q_KEY_CODE_KP_6] = 0x4d, + [Q_KEY_CODE_KP_7] = 0x47, + [Q_KEY_CODE_KP_8] = 0x48, + [Q_KEY_CODE_KP_9] = 0x49, + + [Q_KEY_CODE_LESS] = 0x56, + + [Q_KEY_CODE_F11] = 0x57, + [Q_KEY_CODE_F12] = 0x58, + + [Q_KEY_CODE_PRINT] = 0xb7, + + [Q_KEY_CODE_HOME] = 0xc7, + [Q_KEY_CODE_PGUP] = 0xc9, + [Q_KEY_CODE_PGDN] = 0xd1, + [Q_KEY_CODE_END] = 0xcf, + + [Q_KEY_CODE_LEFT] = 0xcb, + [Q_KEY_CODE_UP] = 0xc8, + [Q_KEY_CODE_DOWN] = 0xd0, + [Q_KEY_CODE_RIGHT] = 0xcd, + + [Q_KEY_CODE_INSERT] = 0xd2, + [Q_KEY_CODE_DELETE] = 0xd3, +#ifdef NEED_CPU_H +#if defined(TARGET_SPARC) && !defined(TARGET_SPARC64) + [Q_KEY_CODE_STOP] = 0xf0, + [Q_KEY_CODE_AGAIN] = 0xf1, + [Q_KEY_CODE_PROPS] = 0xf2, + [Q_KEY_CODE_UNDO] = 0xf3, + [Q_KEY_CODE_FRONT] = 0xf4, + [Q_KEY_CODE_COPY] = 0xf5, + [Q_KEY_CODE_OPEN] = 0xf6, + [Q_KEY_CODE_PASTE] = 0xf7, + [Q_KEY_CODE_FIND] = 0xf8, + [Q_KEY_CODE_CUT] = 0xf9, + [Q_KEY_CODE_LF] = 0xfa, + [Q_KEY_CODE_HELP] = 0xfb, + [Q_KEY_CODE_META_L] = 0xfc, + [Q_KEY_CODE_META_R] = 0xfd, + [Q_KEY_CODE_COMPOSE] = 0xfe, +#endif +#endif + [Q_KEY_CODE_MAX] = 0, +}; + +int index_from_key(const char *key) +{ + int i; + + for (i = 0; QKeyCode_lookup[i] != NULL; i++) { + if (!strcmp(key, QKeyCode_lookup[i])) { + break; + } + } + + /* Return Q_KEY_CODE_MAX if the key is invalid */ + return i; +} + +int index_from_keycode(int code) +{ + int i; + + for (i = 0; i < Q_KEY_CODE_MAX; i++) { + if (key_defs[i] == code) { + break; + } + } + + /* Return Q_KEY_CODE_MAX if the code is invalid */ + return i; +} + +static int *keycodes; +static int keycodes_size; +static QEMUTimer *key_timer; + +static int keycode_from_keyvalue(const KeyValue *value) +{ + if (value->kind == KEY_VALUE_KIND_QCODE) { + return key_defs[value->qcode]; + } else { + assert(value->kind == KEY_VALUE_KIND_NUMBER); + return value->number; + } +} + +static void free_keycodes(void) +{ + g_free(keycodes); + keycodes = NULL; + keycodes_size = 0; +} + +static void release_keys(void *opaque) +{ + int i; + + for (i = 0; i < keycodes_size; i++) { + if (keycodes[i] & 0x80) { + kbd_put_keycode(0xe0); + } + kbd_put_keycode(keycodes[i]| 0x80); + } + + free_keycodes(); +} + +void qmp_send_key(KeyValueList *keys, bool has_hold_time, int64_t hold_time, + Error **errp) +{ + int keycode; + KeyValueList *p; + + if (!key_timer) { + key_timer = qemu_new_timer_ns(vm_clock, release_keys, NULL); + } + + if (keycodes != NULL) { + qemu_del_timer(key_timer); + release_keys(NULL); + } + + if (!has_hold_time) { + hold_time = 100; + } + + for (p = keys; p != NULL; p = p->next) { + /* key down events */ + keycode = keycode_from_keyvalue(p->value); + if (keycode < 0x01 || keycode > 0xff) { + error_setg(errp, "invalid hex keycode 0x%x\n", keycode); + free_keycodes(); + return; + } + + if (keycode & 0x80) { + kbd_put_keycode(0xe0); + } + kbd_put_keycode(keycode & 0x7f); + + keycodes = g_realloc(keycodes, sizeof(int) * (keycodes_size + 1)); + keycodes[keycodes_size++] = keycode; + } + + /* delayed key up events */ + qemu_mod_timer(key_timer, qemu_get_clock_ns(vm_clock) + + muldiv64(get_ticks_per_sec(), hold_time, 1000)); +} + +void qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque) +{ + qemu_put_kbd_event_opaque = opaque; + qemu_put_kbd_event = func; +} + +void qemu_remove_kbd_event_handler(void) +{ + qemu_put_kbd_event_opaque = NULL; + qemu_put_kbd_event = NULL; +} + +static void check_mode_change(void) +{ + static int current_is_absolute, current_has_absolute; + int is_absolute; + int has_absolute; + + is_absolute = kbd_mouse_is_absolute(); + has_absolute = kbd_mouse_has_absolute(); + + if (is_absolute != current_is_absolute || + has_absolute != current_has_absolute) { + notifier_list_notify(&mouse_mode_notifiers, NULL); + } + + current_is_absolute = is_absolute; + current_has_absolute = has_absolute; +} + +QEMUPutMouseEntry *qemu_add_mouse_event_handler(QEMUPutMouseEvent *func, + void *opaque, int absolute, + const char *name) +{ + QEMUPutMouseEntry *s; + static int mouse_index = 0; + + s = g_malloc0(sizeof(QEMUPutMouseEntry)); + + s->qemu_put_mouse_event = func; + s->qemu_put_mouse_event_opaque = opaque; + s->qemu_put_mouse_event_absolute = absolute; + s->qemu_put_mouse_event_name = g_strdup(name); + s->index = mouse_index++; + + QTAILQ_INSERT_TAIL(&mouse_handlers, s, node); + + check_mode_change(); + + return s; +} + +void qemu_activate_mouse_event_handler(QEMUPutMouseEntry *entry) +{ + QTAILQ_REMOVE(&mouse_handlers, entry, node); + QTAILQ_INSERT_HEAD(&mouse_handlers, entry, node); + + check_mode_change(); +} + +void qemu_remove_mouse_event_handler(QEMUPutMouseEntry *entry) +{ + QTAILQ_REMOVE(&mouse_handlers, entry, node); + + g_free(entry->qemu_put_mouse_event_name); + g_free(entry); + + check_mode_change(); +} + +QEMUPutLEDEntry *qemu_add_led_event_handler(QEMUPutLEDEvent *func, + void *opaque) +{ + QEMUPutLEDEntry *s; + + s = g_malloc0(sizeof(QEMUPutLEDEntry)); + + s->put_led = func; + s->opaque = opaque; + QTAILQ_INSERT_TAIL(&led_handlers, s, next); + return s; +} + +void qemu_remove_led_event_handler(QEMUPutLEDEntry *entry) +{ + if (entry == NULL) + return; + QTAILQ_REMOVE(&led_handlers, entry, next); + g_free(entry); +} + +void kbd_put_keycode(int keycode) +{ + if (!runstate_is_running() && !runstate_check(RUN_STATE_SUSPENDED)) { + return; + } + if (qemu_put_kbd_event) { + qemu_put_kbd_event(qemu_put_kbd_event_opaque, keycode); + } +} + +void kbd_put_ledstate(int ledstate) +{ + QEMUPutLEDEntry *cursor; + + QTAILQ_FOREACH(cursor, &led_handlers, next) { + cursor->put_led(cursor->opaque, ledstate); + } +} + +void kbd_mouse_event(int dx, int dy, int dz, int buttons_state) +{ + QEMUPutMouseEntry *entry; + QEMUPutMouseEvent *mouse_event; + void *mouse_event_opaque; + int width, height; + + if (!runstate_is_running() && !runstate_check(RUN_STATE_SUSPENDED)) { + return; + } + if (QTAILQ_EMPTY(&mouse_handlers)) { + return; + } + + entry = QTAILQ_FIRST(&mouse_handlers); + + mouse_event = entry->qemu_put_mouse_event; + mouse_event_opaque = entry->qemu_put_mouse_event_opaque; + + if (mouse_event) { + if (entry->qemu_put_mouse_event_absolute) { + width = 0x7fff; + height = 0x7fff; + } else { + width = graphic_width - 1; + height = graphic_height - 1; + } + + switch (graphic_rotate) { + case 0: + mouse_event(mouse_event_opaque, + dx, dy, dz, buttons_state); + break; + case 90: + mouse_event(mouse_event_opaque, + width - dy, dx, dz, buttons_state); + break; + case 180: + mouse_event(mouse_event_opaque, + width - dx, height - dy, dz, buttons_state); + break; + case 270: + mouse_event(mouse_event_opaque, + dy, height - dx, dz, buttons_state); + break; + } + } +} + +int kbd_mouse_is_absolute(void) +{ + if (QTAILQ_EMPTY(&mouse_handlers)) { + return 0; + } + + return QTAILQ_FIRST(&mouse_handlers)->qemu_put_mouse_event_absolute; +} + +int kbd_mouse_has_absolute(void) +{ + QEMUPutMouseEntry *entry; + + QTAILQ_FOREACH(entry, &mouse_handlers, node) { + if (entry->qemu_put_mouse_event_absolute) { + return 1; + } + } + + return 0; +} + +MouseInfoList *qmp_query_mice(Error **errp) +{ + MouseInfoList *mice_list = NULL; + QEMUPutMouseEntry *cursor; + bool current = true; + + QTAILQ_FOREACH(cursor, &mouse_handlers, node) { + MouseInfoList *info = g_malloc0(sizeof(*info)); + info->value = g_malloc0(sizeof(*info->value)); + info->value->name = g_strdup(cursor->qemu_put_mouse_event_name); + info->value->index = cursor->index; + info->value->absolute = !!cursor->qemu_put_mouse_event_absolute; + info->value->current = current; + + current = false; + + info->next = mice_list; + mice_list = info; + } + + return mice_list; +} + +void do_mouse_set(Monitor *mon, const QDict *qdict) +{ + QEMUPutMouseEntry *cursor; + int index = qdict_get_int(qdict, "index"); + int found = 0; + + if (QTAILQ_EMPTY(&mouse_handlers)) { + monitor_printf(mon, "No mouse devices connected\n"); + return; + } + + QTAILQ_FOREACH(cursor, &mouse_handlers, node) { + if (cursor->index == index) { + found = 1; + qemu_activate_mouse_event_handler(cursor); + break; + } + } + + if (!found) { + monitor_printf(mon, "Mouse at given index not found\n"); + } + + check_mode_change(); +} + +void qemu_add_mouse_mode_change_notifier(Notifier *notify) +{ + notifier_list_add(&mouse_mode_notifiers, notify); +} + +void qemu_remove_mouse_mode_change_notifier(Notifier *notify) +{ + notifier_remove(notify); +} diff --git a/ui/keymaps.c b/ui/keymaps.c index f55a2aa464..9625d82fa1 100644 --- a/ui/keymaps.c +++ b/ui/keymaps.c @@ -23,7 +23,7 @@ */ #include "keymaps.h" -#include "sysemu.h" +#include "sysemu/sysemu.h" static int get_keysym(const name2keysym_t *table, const char *name) diff --git a/ui/qemu-pixman.c b/ui/qemu-pixman.c new file mode 100644 index 0000000000..609335ab11 --- /dev/null +++ b/ui/qemu-pixman.c @@ -0,0 +1,80 @@ +/* + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +#include "ui/qemu-pixman.h" + +int qemu_pixman_get_type(int rshift, int gshift, int bshift) +{ + int type = PIXMAN_TYPE_OTHER; + + if (rshift > gshift && gshift > bshift) { + if (bshift == 0) { + type = PIXMAN_TYPE_ARGB; + } else { +#if PIXMAN_VERSION >= PIXMAN_VERSION_ENCODE(0, 21, 8) + type = PIXMAN_TYPE_RGBA; +#endif + } + } else if (rshift < gshift && gshift < bshift) { + if (rshift == 0) { + type = PIXMAN_TYPE_ABGR; + } else { +#if PIXMAN_VERSION >= PIXMAN_VERSION_ENCODE(0, 16, 0) + type = PIXMAN_TYPE_BGRA; +#endif + } + } + return type; +} + +pixman_format_code_t qemu_pixman_get_format(PixelFormat *pf) +{ + pixman_format_code_t format; + int type; + + type = qemu_pixman_get_type(pf->rshift, pf->gshift, pf->bshift); + format = PIXMAN_FORMAT(pf->bits_per_pixel, type, + pf->abits, pf->rbits, pf->gbits, pf->bbits); + if (!pixman_format_supported_source(format)) { + return 0; + } + return format; +} + +pixman_image_t *qemu_pixman_linebuf_create(pixman_format_code_t format, + int width) +{ + pixman_image_t *image = pixman_image_create_bits(format, width, 1, NULL, 0); + assert(image != NULL); + return image; +} + +void qemu_pixman_linebuf_fill(pixman_image_t *linebuf, pixman_image_t *fb, + int width, int x, int y) +{ + pixman_image_composite(PIXMAN_OP_SRC, fb, NULL, linebuf, + x, y, 0, 0, 0, 0, width, 1); +} + +pixman_image_t *qemu_pixman_mirror_create(pixman_format_code_t format, + pixman_image_t *image) +{ + pixman_image_t *mirror; + + mirror = pixman_image_create_bits(format, + pixman_image_get_width(image), + pixman_image_get_height(image), + NULL, + pixman_image_get_stride(image)); + return mirror; +} + +void qemu_pixman_image_unref(pixman_image_t *image) +{ + if (image == NULL) { + return; + } + pixman_image_unref(image); +} diff --git a/ui/qemu-spice.h b/ui/qemu-spice.h deleted file mode 100644 index 3299da87d6..0000000000 --- a/ui/qemu-spice.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (C) 2010 Red Hat, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 or - * (at your option) version 3 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see <http://www.gnu.org/licenses/>. - */ - -#ifndef QEMU_SPICE_H -#define QEMU_SPICE_H - -#ifdef CONFIG_SPICE - -#include <spice.h> - -#include "qemu-option.h" -#include "qemu-config.h" -#include "qemu-char.h" -#include "monitor.h" - -extern int using_spice; - -void qemu_spice_init(void); -void qemu_spice_input_init(void); -void qemu_spice_audio_init(void); -void qemu_spice_display_init(DisplayState *ds); -int qemu_spice_display_add_client(int csock, int skipauth, int tls); -int qemu_spice_add_interface(SpiceBaseInstance *sin); -int qemu_spice_set_passwd(const char *passwd, - bool fail_if_connected, bool disconnect_if_connected); -int qemu_spice_set_pw_expire(time_t expires); -int qemu_spice_migrate_info(const char *hostname, int port, int tls_port, - const char *subject, - MonitorCompletion cb, void *opaque); - -void do_info_spice_print(Monitor *mon, const QObject *data); -void do_info_spice(Monitor *mon, QObject **ret_data); - -CharDriverState *qemu_chr_open_spice(QemuOpts *opts); - -#else /* CONFIG_SPICE */ -#include "monitor.h" - -#define using_spice 0 -static inline int qemu_spice_set_passwd(const char *passwd, - bool fail_if_connected, - bool disconnect_if_connected) -{ - return -1; -} -static inline int qemu_spice_set_pw_expire(time_t expires) -{ - return -1; -} -static inline int qemu_spice_migrate_info(const char *h, int p, int t, - const char *s, - MonitorCompletion cb, void *opaque) -{ - cb(opaque, NULL); - return -1; -} - -static inline int qemu_spice_display_add_client(int csock, int skipauth, - int tls) -{ - return -1; -} - -#endif /* CONFIG_SPICE */ - -#endif /* QEMU_SPICE_H */ diff --git a/ui/qemu-x509.h b/ui/qemu-x509.h new file mode 100644 index 0000000000..095aec161d --- /dev/null +++ b/ui/qemu-x509.h @@ -0,0 +1,9 @@ +#ifndef QEMU_X509_H +#define QEMU_X509_H + +#define X509_CA_CERT_FILE "ca-cert.pem" +#define X509_CA_CRL_FILE "ca-crl.pem" +#define X509_SERVER_KEY_FILE "server-key.pem" +#define X509_SERVER_CERT_FILE "server-cert.pem" + +#endif /* QEMU_X509_H */ @@ -29,8 +29,8 @@ #include <SDL_syswm.h> #include "qemu-common.h" -#include "console.h" -#include "sysemu.h" +#include "ui/console.h" +#include "sysemu/sysemu.h" #include "x_keymap.h" #include "sdl_zoom.h" @@ -55,7 +55,6 @@ static int absolute_enabled = 0; static int guest_cursor = 0; static int guest_x, guest_y; static SDL_Cursor *guest_sprite = NULL; -static uint8_t allocator; static SDL_PixelFormat host_format; static int scaling_active = 0; static Notifier mouse_mode_notifier; @@ -117,108 +116,13 @@ static void do_sdl_resize(int width, int height, int bpp) static void sdl_resize(DisplayState *ds) { - if (!allocator) { - if (!scaling_active) - do_sdl_resize(ds_get_width(ds), ds_get_height(ds), 0); - else if (real_screen->format->BitsPerPixel != ds_get_bits_per_pixel(ds)) - do_sdl_resize(real_screen->w, real_screen->h, ds_get_bits_per_pixel(ds)); - sdl_setdata(ds); - } else { - if (guest_screen != NULL) { - SDL_FreeSurface(guest_screen); - guest_screen = NULL; - } - } -} - -static PixelFormat sdl_to_qemu_pixelformat(SDL_PixelFormat *sdl_pf) -{ - PixelFormat qemu_pf; - - memset(&qemu_pf, 0x00, sizeof(PixelFormat)); - - qemu_pf.bits_per_pixel = sdl_pf->BitsPerPixel; - qemu_pf.bytes_per_pixel = sdl_pf->BytesPerPixel; - qemu_pf.depth = (qemu_pf.bits_per_pixel) == 32 ? 24 : (qemu_pf.bits_per_pixel); - - qemu_pf.rmask = sdl_pf->Rmask; - qemu_pf.gmask = sdl_pf->Gmask; - qemu_pf.bmask = sdl_pf->Bmask; - qemu_pf.amask = sdl_pf->Amask; - - qemu_pf.rshift = sdl_pf->Rshift; - qemu_pf.gshift = sdl_pf->Gshift; - qemu_pf.bshift = sdl_pf->Bshift; - qemu_pf.ashift = sdl_pf->Ashift; - - qemu_pf.rbits = 8 - sdl_pf->Rloss; - qemu_pf.gbits = 8 - sdl_pf->Gloss; - qemu_pf.bbits = 8 - sdl_pf->Bloss; - qemu_pf.abits = 8 - sdl_pf->Aloss; - - qemu_pf.rmax = ((1 << qemu_pf.rbits) - 1); - qemu_pf.gmax = ((1 << qemu_pf.gbits) - 1); - qemu_pf.bmax = ((1 << qemu_pf.bbits) - 1); - qemu_pf.amax = ((1 << qemu_pf.abits) - 1); - - return qemu_pf; -} - -static DisplaySurface* sdl_create_displaysurface(int width, int height) -{ - DisplaySurface *surface = (DisplaySurface*) g_malloc0(sizeof(DisplaySurface)); - - surface->width = width; - surface->height = height; - - if (scaling_active) { - int linesize; - PixelFormat pf; - if (host_format.BytesPerPixel != 2 && host_format.BytesPerPixel != 4) { - linesize = width * 4; - pf = qemu_default_pixelformat(32); - } else { - linesize = width * host_format.BytesPerPixel; - pf = sdl_to_qemu_pixelformat(&host_format); - } - qemu_alloc_display(surface, width, height, linesize, pf, 0); - return surface; + if (!scaling_active) { + do_sdl_resize(ds_get_width(ds), ds_get_height(ds), 0); + } else if (real_screen->format->BitsPerPixel != ds_get_bits_per_pixel(ds)) { + do_sdl_resize(real_screen->w, real_screen->h, + ds_get_bits_per_pixel(ds)); } - - if (host_format.BitsPerPixel == 16) - do_sdl_resize(width, height, 16); - else - do_sdl_resize(width, height, 32); - - surface->pf = sdl_to_qemu_pixelformat(real_screen->format); - surface->linesize = real_screen->pitch; - surface->data = real_screen->pixels; - -#ifdef HOST_WORDS_BIGENDIAN - surface->flags = QEMU_REALPIXELS_FLAG | QEMU_BIG_ENDIAN_FLAG; -#else - surface->flags = QEMU_REALPIXELS_FLAG; -#endif - allocator = 1; - - return surface; -} - -static void sdl_free_displaysurface(DisplaySurface *surface) -{ - allocator = 0; - if (surface == NULL) - return; - - if (surface->flags & QEMU_ALLOCATED_FLAG) - g_free(surface->data); - g_free(surface); -} - -static DisplaySurface* sdl_resize_displaysurface(DisplaySurface *surface, int width, int height) -{ - sdl_free_displaysurface(surface); - return sdl_create_displaysurface(width, height); + sdl_setdata(ds); } /* generic keyboard conversion */ @@ -553,7 +457,7 @@ static void sdl_scale(DisplayState *ds, int width, int height) if (!is_buffer_shared(ds->surface)) { ds->surface = qemu_resize_displaysurface(ds, ds_get_width(ds), ds_get_height(ds)); - dpy_resize(ds); + dpy_gfx_resize(ds); } } @@ -899,13 +803,7 @@ static void sdl_refresh(DisplayState *ds) } } -static void sdl_fill(DisplayState *ds, int x, int y, int w, int h, uint32_t c) -{ - SDL_Rect dst = { x, y, w, h }; - SDL_FillRect(real_screen, &dst, c); -} - -static void sdl_mouse_warp(int x, int y, int on) +static void sdl_mouse_warp(DisplayState *ds, int x, int y, int on) { if (on) { if (!guest_cursor) @@ -921,7 +819,7 @@ static void sdl_mouse_warp(int x, int y, int on) guest_x = x, guest_y = y; } -static void sdl_mouse_define(QEMUCursor *c) +static void sdl_mouse_define(DisplayState *ds, QEMUCursor *c) { uint8_t *image, *mask; int bpl; @@ -955,7 +853,6 @@ void sdl_display_init(DisplayState *ds, int full_screen, int no_frame) { int flags; uint8_t data = 0; - DisplayAllocator *da; const SDL_VideoInfo *vi; char *filename; @@ -1020,23 +917,14 @@ void sdl_display_init(DisplayState *ds, int full_screen, int no_frame) } dcl = g_malloc0(sizeof(DisplayChangeListener)); - dcl->dpy_update = sdl_update; - dcl->dpy_resize = sdl_resize; + dcl->dpy_gfx_update = sdl_update; + dcl->dpy_gfx_resize = sdl_resize; dcl->dpy_refresh = sdl_refresh; - dcl->dpy_setdata = sdl_setdata; - dcl->dpy_fill = sdl_fill; - ds->mouse_set = sdl_mouse_warp; - ds->cursor_define = sdl_mouse_define; + dcl->dpy_gfx_setdata = sdl_setdata; + dcl->dpy_mouse_set = sdl_mouse_warp; + dcl->dpy_cursor_define = sdl_mouse_define; register_displaychangelistener(ds, dcl); - da = g_malloc0(sizeof(DisplayAllocator)); - da->create_displaysurface = sdl_create_displaysurface; - da->resize_displaysurface = sdl_resize_displaysurface; - da->free_displaysurface = sdl_free_displaysurface; - if (register_displayallocator(ds, da) == da) { - dpy_resize(ds); - } - mouse_mode_notifier.notify = sdl_mouse_mode_change; qemu_add_mouse_mode_change_notifier(&mouse_mode_notifier); diff --git a/ui/sdl_zoom.c b/ui/sdl_zoom.c index a986c7c14c..122027cb36 100644 --- a/ui/sdl_zoom.c +++ b/ui/sdl_zoom.c @@ -12,7 +12,7 @@ */ #include "sdl_zoom.h" -#include "osdep.h" +#include "qemu/osdep.h" #include <stdint.h> #include <stdio.h> diff --git a/ui/spice-core.c b/ui/spice-core.c index 4fc48f8902..d83de2a46e 100644 --- a/ui/spice-core.c +++ b/ui/spice-core.c @@ -19,24 +19,25 @@ #include <spice-experimental.h> #include <netdb.h> -#include "sysemu.h" +#include "sysemu/sysemu.h" #include "qemu-common.h" -#include "qemu-spice.h" -#include "qemu-thread.h" -#include "qemu-timer.h" -#include "qemu-queue.h" +#include "ui/qemu-spice.h" +#include "qemu/thread.h" +#include "qemu/timer.h" +#include "qemu/queue.h" #include "qemu-x509.h" -#include "qemu_socket.h" +#include "qemu/sockets.h" #include "qmp-commands.h" -#include "qint.h" -#include "qbool.h" -#include "qstring.h" -#include "qjson.h" -#include "notify.h" -#include "migration.h" -#include "monitor.h" +#include "qapi/qmp/qint.h" +#include "qapi/qmp/qbool.h" +#include "qapi/qmp/qstring.h" +#include "qapi/qmp/qjson.h" +#include "qemu/notify.h" +#include "migration/migration.h" +#include "monitor/monitor.h" #include "hw/hw.h" +#include "ui/spice-display.h" /* core bits */ @@ -45,6 +46,7 @@ static Notifier migration_state; static const char *auth = "spice"; static char *auth_passwd; static time_t auth_expires = TIME_MAX; +static int spice_migration_completed; int using_spice = 0; static QemuThread me; @@ -221,7 +223,6 @@ static void channel_event(int event, SpiceChannelEventInfo *info) client = qdict_new(); server = qdict_new(); -#ifdef SPICE_CHANNEL_EVENT_FLAG_ADDR_EXT if (info->flags & SPICE_CHANNEL_EVENT_FLAG_ADDR_EXT) { add_addr_info(client, (struct sockaddr *)&info->paddr_ext, info->plen_ext); @@ -230,12 +231,7 @@ static void channel_event(int event, SpiceChannelEventInfo *info) } else { error_report("spice: %s, extended address is expected", __func__); -#endif - add_addr_info(client, &info->paddr, info->plen); - add_addr_info(server, &info->laddr, info->llen); -#ifdef SPICE_CHANNEL_EVENT_FLAG_ADDR_EXT } -#endif if (event == SPICE_CHANNEL_EVENT_INITIALIZED) { qdict_put(server, "auth", qstring_from_str(auth)); @@ -274,7 +270,6 @@ static SpiceCoreInterface core_interface = { .channel_event = channel_event, }; -#ifdef SPICE_INTERFACE_MIGRATION typedef struct SpiceMigration { SpiceMigrateInstance sin; struct { @@ -284,6 +279,7 @@ typedef struct SpiceMigration { } SpiceMigration; static void migrate_connect_complete_cb(SpiceMigrateInstance *sin); +static void migrate_end_complete_cb(SpiceMigrateInstance *sin); static const SpiceMigrateInterface migrate_interface = { .base.type = SPICE_INTERFACE_MIGRATION, @@ -291,7 +287,7 @@ static const SpiceMigrateInterface migrate_interface = { .base.major_version = SPICE_INTERFACE_MIGRATION_MAJOR, .base.minor_version = SPICE_INTERFACE_MIGRATION_MINOR, .migrate_connect_complete = migrate_connect_complete_cb, - .migrate_end_complete = NULL, + .migrate_end_complete = migrate_end_complete_cb, }; static SpiceMigration spice_migrate; @@ -304,7 +300,12 @@ static void migrate_connect_complete_cb(SpiceMigrateInstance *sin) } sm->connect_complete.cb = NULL; } -#endif + +static void migrate_end_complete_cb(SpiceMigrateInstance *sin) +{ + monitor_protocol_event(QEVENT_SPICE_MIGRATE_COMPLETED, NULL); + spice_migration_completed = true; +} /* config string parsing */ @@ -344,7 +345,8 @@ static const char *stream_video_names[] = { [ SPICE_STREAM_VIDEO_FILTER ] = "filter", }; #define parse_stream_video(_name) \ - name2enum(_name, stream_video_names, ARRAY_SIZE(stream_video_names)) + parse_name(_name, "stream video control", \ + stream_video_names, ARRAY_SIZE(stream_video_names)) static const char *compression_names[] = { [ SPICE_IMAGE_COMPRESS_OFF ] = "off", @@ -383,17 +385,13 @@ static SpiceChannelList *qmp_query_spice_channels(void) chan = g_malloc0(sizeof(*chan)); chan->value = g_malloc0(sizeof(*chan->value)); -#ifdef SPICE_CHANNEL_EVENT_FLAG_ADDR_EXT if (item->info->flags & SPICE_CHANNEL_EVENT_FLAG_ADDR_EXT) { paddr = (struct sockaddr *)&item->info->paddr_ext; plen = item->info->plen_ext; } else { -#endif paddr = &item->info->paddr; plen = item->info->plen; -#ifdef SPICE_CHANNEL_EVENT_FLAG_ADDR_EXT } -#endif getnameinfo(paddr, plen, host, sizeof(host), port, sizeof(port), @@ -435,6 +433,7 @@ SpiceInfo *qmp_query_spice(Error **errp) } info->enabled = true; + info->migrated = spice_migration_completed; addr = qemu_opt_get(opts, "addr"); port = qemu_opt_get_number(opts, "port", 0); @@ -462,13 +461,10 @@ SpiceInfo *qmp_query_spice(Error **errp) info->tls_port = tls_port; } -#if SPICE_SERVER_VERSION >= 0x000a03 /* 0.10.3 */ info->mouse_mode = spice_server_is_server_mouse(spice_server) ? SPICE_QUERY_MOUSE_MODE_SERVER : SPICE_QUERY_MOUSE_MODE_CLIENT; -#else - info->mouse_mode = SPICE_QUERY_MOUSE_MODE_UNKNOWN; -#endif + /* for compatibility with the original command */ info->has_channels = true; info->channels = qmp_query_spice_channels(); @@ -481,17 +477,11 @@ static void migration_state_notifier(Notifier *notifier, void *data) MigrationState *s = data; if (migration_is_active(s)) { -#ifdef SPICE_INTERFACE_MIGRATION spice_server_migrate_start(spice_server); -#endif } else if (migration_has_finished(s)) { -#ifndef SPICE_INTERFACE_MIGRATION - spice_server_migrate_switch(spice_server); -#else spice_server_migrate_end(spice_server, true); } else if (migration_has_failed(s)) { spice_server_migrate_end(spice_server, false); -#endif } } @@ -500,16 +490,11 @@ int qemu_spice_migrate_info(const char *hostname, int port, int tls_port, MonitorCompletion *cb, void *opaque) { int ret; -#ifdef SPICE_INTERFACE_MIGRATION + spice_migrate.connect_complete.cb = cb; spice_migrate.connect_complete.opaque = opaque; ret = spice_server_migrate_connect(spice_server, hostname, port, tls_port, subject); -#else - ret = spice_server_migrate_info(spice_server, hostname, - port, tls_port, subject); - cb(opaque, NULL); -#endif return ret; } @@ -545,6 +530,18 @@ static int add_channel(const char *name, const char *value, void *opaque) return 0; } +static void vm_change_state_handler(void *opaque, int running, + RunState state) +{ + if (running) { + qemu_spice_display_start(); + spice_server_vm_start(spice_server); + } else { + spice_server_vm_stop(spice_server); + qemu_spice_display_stop(); + } +} + void qemu_spice_init(void) { QemuOpts *opts = QTAILQ_FIRST(&qemu_spice_opts.head); @@ -558,6 +555,7 @@ void qemu_spice_init(void) int port, tls_port, len, addr_flags; spice_image_compression_t compression; spice_wan_compression_t wan_compr; + bool seamless_migration; qemu_thread_get_self(&me); @@ -612,7 +610,7 @@ void qemu_spice_init(void) } x509_key_password = qemu_opt_get(opts, "x509-key-password"); - x509_dh_file = qemu_opt_get(opts, "x509-dh-file"); + x509_dh_file = qemu_opt_get(opts, "x509-dh-key-file"); tls_ciphers = qemu_opt_get(opts, "tls-ciphers"); } @@ -642,16 +640,11 @@ void qemu_spice_init(void) spice_server_set_ticket(spice_server, password, 0, 0, 0); } if (qemu_opt_get_bool(opts, "sasl", 0)) { -#if SPICE_SERVER_VERSION >= 0x000900 /* 0.9.0 */ if (spice_server_set_sasl_appname(spice_server, "qemu") == -1 || spice_server_set_sasl(spice_server, 1) == -1) { error_report("spice: failed to enable sasl"); exit(1); } -#else - error_report("spice: sasl is not available (spice >= 0.9 required)"); - exit(1); -#endif } if (qemu_opt_get_bool(opts, "disable-ticketing", 0)) { auth = "none"; @@ -696,11 +689,11 @@ void qemu_spice_init(void) qemu_opt_foreach(opts, add_channel, &tls_port, 0); -#if SPICE_SERVER_VERSION >= 0x000a02 /* 0.10.2 */ spice_server_set_name(spice_server, qemu_name); spice_server_set_uuid(spice_server, qemu_uuid); -#endif + seamless_migration = qemu_opt_get_bool(opts, "seamless-migration", 0); + spice_server_set_seamless_migration(spice_server, seamless_migration); if (0 != spice_server_init(spice_server, &core_interface)) { error_report("failed to initialize spice server"); exit(1); @@ -709,18 +702,22 @@ void qemu_spice_init(void) migration_state.notify = migration_state_notifier; add_migration_state_change_notifier(&migration_state); -#ifdef SPICE_INTERFACE_MIGRATION spice_migrate.sin.base.sif = &migrate_interface.base; spice_migrate.connect_complete.cb = NULL; qemu_spice_add_interface(&spice_migrate.sin.base); -#endif qemu_spice_input_init(); qemu_spice_audio_init(); + qemu_add_vm_change_state_handler(vm_change_state_handler, NULL); + g_free(x509_key_file); g_free(x509_cert_file); g_free(x509_cacert_file); + +#if SPICE_SERVER_VERSION >= 0x000c02 + qemu_spice_register_ports(); +#endif } int qemu_spice_add_interface(SpiceBaseInstance *sin) @@ -739,7 +736,9 @@ int qemu_spice_add_interface(SpiceBaseInstance *sin) */ spice_server = spice_server_new(); spice_server_init(spice_server, &core_interface); + qemu_add_vm_change_state_handler(vm_change_state_handler, NULL); } + return spice_server_add_interface(spice_server, sin); } @@ -778,15 +777,11 @@ int qemu_spice_set_pw_expire(time_t expires) int qemu_spice_display_add_client(int csock, int skipauth, int tls) { -#if SPICE_SERVER_VERSION >= 0x000a01 if (tls) { return spice_server_add_ssl_client(spice_server, csock, skipauth); } else { return spice_server_add_client(spice_server, csock, skipauth); } -#else - return -1; -#endif } static void spice_register_config(void) diff --git a/ui/spice-display.c b/ui/spice-display.c index 3e8f0b3ad5..dc7e58d0ed 100644 --- a/ui/spice-display.c +++ b/ui/spice-display.c @@ -16,15 +16,15 @@ */ #include "qemu-common.h" -#include "qemu-spice.h" -#include "qemu-timer.h" -#include "qemu-queue.h" -#include "monitor.h" -#include "console.h" -#include "sysemu.h" +#include "ui/qemu-spice.h" +#include "qemu/timer.h" +#include "qemu/queue.h" +#include "monitor/monitor.h" +#include "ui/console.h" +#include "sysemu/sysemu.h" #include "trace.h" -#include "spice-display.h" +#include "ui/spice-display.h" static int debug = 0; @@ -126,46 +126,48 @@ void qemu_spice_wakeup(SimpleSpiceDisplay *ssd) ssd->worker->wakeup(ssd->worker); } -void qemu_spice_start(SimpleSpiceDisplay *ssd) +static int spice_display_is_running; + +void qemu_spice_display_start(void) +{ + spice_display_is_running = true; +} + +void qemu_spice_display_stop(void) { - trace_qemu_spice_start(ssd->qxl.id); - ssd->worker->start(ssd->worker); + spice_display_is_running = false; } -void qemu_spice_stop(SimpleSpiceDisplay *ssd) +int qemu_spice_display_is_running(SimpleSpiceDisplay *ssd) { - trace_qemu_spice_stop(ssd->qxl.id); - ssd->worker->stop(ssd->worker); + return spice_display_is_running; } -static SimpleSpiceUpdate *qemu_spice_create_update(SimpleSpiceDisplay *ssd) +static void qemu_spice_create_one_update(SimpleSpiceDisplay *ssd, + QXLRect *rect) { SimpleSpiceUpdate *update; QXLDrawable *drawable; QXLImage *image; QXLCommand *cmd; - uint8_t *src, *dst; - int by, bw, bh; + int bw, bh; struct timespec time_space; - - if (qemu_spice_rect_is_empty(&ssd->dirty)) { - return NULL; - }; + pixman_image_t *dest; trace_qemu_spice_create_update( - ssd->dirty.left, ssd->dirty.right, - ssd->dirty.top, ssd->dirty.bottom); + rect->left, rect->right, + rect->top, rect->bottom); update = g_malloc0(sizeof(*update)); drawable = &update->drawable; image = &update->image; cmd = &update->ext.cmd; - bw = ssd->dirty.right - ssd->dirty.left; - bh = ssd->dirty.bottom - ssd->dirty.top; + bw = rect->right - rect->left; + bh = rect->bottom - rect->top; update->bitmap = g_malloc(bw * bh * 4); - drawable->bbox = ssd->dirty; + drawable->bbox = *rect; drawable->clip.type = SPICE_CLIP_TYPE_NONE; drawable->effect = QXL_EFFECT_OPAQUE; drawable->release_info.id = (uintptr_t)update; @@ -193,31 +195,94 @@ static SimpleSpiceUpdate *qemu_spice_create_update(SimpleSpiceDisplay *ssd) image->bitmap.palette = 0; image->bitmap.format = SPICE_BITMAP_FMT_32BIT; - if (ssd->conv == NULL) { - PixelFormat dst = qemu_default_pixelformat(32); - ssd->conv = qemu_pf_conv_get(&dst, &ssd->ds->surface->pf); - assert(ssd->conv); + dest = pixman_image_create_bits(PIXMAN_x8r8g8b8, bw, bh, + (void *)update->bitmap, bw * 4); + pixman_image_composite(PIXMAN_OP_SRC, ssd->surface, NULL, ssd->mirror, + rect->left, rect->top, 0, 0, + rect->left, rect->top, bw, bh); + pixman_image_composite(PIXMAN_OP_SRC, ssd->mirror, NULL, dest, + rect->left, rect->top, 0, 0, + 0, 0, bw, bh); + pixman_image_unref(dest); + + cmd->type = QXL_CMD_DRAW; + cmd->data = (uintptr_t)drawable; + + QTAILQ_INSERT_TAIL(&ssd->updates, update, next); +} + +static void qemu_spice_create_update(SimpleSpiceDisplay *ssd) +{ + static const int blksize = 32; + int blocks = (ds_get_width(ssd->ds) + blksize - 1) / blksize; + int dirty_top[blocks]; + int y, yoff, x, xoff, blk, bw; + int bpp = ds_get_bytes_per_pixel(ssd->ds); + uint8_t *guest, *mirror; + + if (qemu_spice_rect_is_empty(&ssd->dirty)) { + return; + }; + + if (ssd->surface == NULL) { + ssd->surface = pixman_image_ref(ds_get_image(ssd->ds)); + ssd->mirror = qemu_pixman_mirror_create(ds_get_format(ssd->ds), + ds_get_image(ssd->ds)); } - src = ds_get_data(ssd->ds) + - ssd->dirty.top * ds_get_linesize(ssd->ds) + - ssd->dirty.left * ds_get_bytes_per_pixel(ssd->ds); - dst = update->bitmap; - for (by = 0; by < bh; by++) { - qemu_pf_conv_run(ssd->conv, dst, src, bw); - src += ds_get_linesize(ssd->ds); - dst += image->bitmap.stride; + for (blk = 0; blk < blocks; blk++) { + dirty_top[blk] = -1; } - cmd->type = QXL_CMD_DRAW; - cmd->data = (uintptr_t)drawable; + guest = ds_get_data(ssd->ds); + mirror = (void *)pixman_image_get_data(ssd->mirror); + for (y = ssd->dirty.top; y < ssd->dirty.bottom; y++) { + yoff = y * ds_get_linesize(ssd->ds); + for (x = ssd->dirty.left; x < ssd->dirty.right; x += blksize) { + xoff = x * bpp; + blk = x / blksize; + bw = MIN(blksize, ssd->dirty.right - x); + if (memcmp(guest + yoff + xoff, + mirror + yoff + xoff, + bw * bpp) == 0) { + if (dirty_top[blk] != -1) { + QXLRect update = { + .top = dirty_top[blk], + .bottom = y, + .left = x, + .right = x + bw, + }; + qemu_spice_create_one_update(ssd, &update); + dirty_top[blk] = -1; + } + } else { + if (dirty_top[blk] == -1) { + dirty_top[blk] = y; + } + } + } + } + + for (x = ssd->dirty.left; x < ssd->dirty.right; x += blksize) { + blk = x / blksize; + bw = MIN(blksize, ssd->dirty.right - x); + if (dirty_top[blk] != -1) { + QXLRect update = { + .top = dirty_top[blk], + .bottom = ssd->dirty.bottom, + .left = x, + .right = x + bw, + }; + qemu_spice_create_one_update(ssd, &update); + dirty_top[blk] = -1; + } + } memset(&ssd->dirty, 0, sizeof(ssd->dirty)); - return update; } /* - * Called from spice server thread context (via interface_release_ressource) + * Called from spice server thread context (via interface_release_resource) * We do *not* hold the global qemu mutex here, so extra care is needed * when calling qemu functions. QEMU interfaces used: * - g_free (underlying glibc free is re-entrant). @@ -269,26 +334,16 @@ void qemu_spice_destroy_host_primary(SimpleSpiceDisplay *ssd) qemu_spice_destroy_primary_surface(ssd, 0, QXL_SYNC); } -void qemu_spice_vm_change_state_handler(void *opaque, int running, - RunState state) -{ - SimpleSpiceDisplay *ssd = opaque; - - if (running) { - ssd->running = true; - qemu_spice_start(ssd); - } else { - qemu_spice_stop(ssd); - ssd->running = false; - } -} - void qemu_spice_display_init_common(SimpleSpiceDisplay *ssd, DisplayState *ds) { ssd->ds = ds; qemu_mutex_init(&ssd->lock); + QTAILQ_INIT(&ssd->updates); ssd->mouse_x = -1; ssd->mouse_y = -1; + if (ssd->num_surfaces == 0) { + ssd->num_surfaces = 1024; + } ssd->bufsize = (16 * 1024 * 1024); ssd->buf = g_malloc(ssd->bufsize); } @@ -314,16 +369,22 @@ void qemu_spice_display_update(SimpleSpiceDisplay *ssd, void qemu_spice_display_resize(SimpleSpiceDisplay *ssd) { + SimpleSpiceUpdate *update; + dprint(1, "%s:\n", __FUNCTION__); memset(&ssd->dirty, 0, sizeof(ssd->dirty)); - qemu_pf_conv_put(ssd->conv); - ssd->conv = NULL; + if (ssd->surface) { + pixman_image_unref(ssd->surface); + ssd->surface = NULL; + pixman_image_unref(ssd->mirror); + ssd->mirror = NULL; + } qemu_mutex_lock(&ssd->lock); - if (ssd->update != NULL) { - qemu_spice_destroy_update(ssd, ssd->update); - ssd->update = NULL; + while ((update = QTAILQ_FIRST(&ssd->updates)) != NULL) { + QTAILQ_REMOVE(&ssd->updates, update, next); + qemu_spice_destroy_update(ssd, update); } qemu_mutex_unlock(&ssd->lock); qemu_spice_destroy_host_primary(ssd); @@ -336,12 +397,12 @@ void qemu_spice_display_resize(SimpleSpiceDisplay *ssd) void qemu_spice_cursor_refresh_unlocked(SimpleSpiceDisplay *ssd) { if (ssd->cursor) { - ssd->ds->cursor_define(ssd->cursor); + dpy_cursor_define(ssd->ds, ssd->cursor); cursor_put(ssd->cursor); ssd->cursor = NULL; } if (ssd->mouse_x != -1 && ssd->mouse_y != -1) { - ssd->ds->mouse_set(ssd->mouse_x, ssd->mouse_y, 1); + dpy_mouse_set(ssd->ds, ssd->mouse_x, ssd->mouse_y, 1); ssd->mouse_x = -1; ssd->mouse_y = -1; } @@ -353,8 +414,8 @@ void qemu_spice_display_refresh(SimpleSpiceDisplay *ssd) vga_hw_update(); qemu_mutex_lock(&ssd->lock); - if (ssd->update == NULL) { - ssd->update = qemu_spice_create_update(ssd); + if (QTAILQ_EMPTY(&ssd->updates)) { + qemu_spice_create_update(ssd); ssd->notify++; } qemu_spice_cursor_refresh_unlocked(ssd); @@ -399,7 +460,7 @@ static void interface_get_init_info(QXLInstance *sin, QXLDevInitInfo *info) info->num_memslots_groups = NUM_MEMSLOTS_GROUPS; info->internal_groupslot_id = 0; info->qxl_ram_size = ssd->bufsize; - info->n_surfaces = NUM_SURFACES; + info->n_surfaces = ssd->num_surfaces; } static int interface_get_command(QXLInstance *sin, struct QXLCommandExt *ext) @@ -411,9 +472,9 @@ static int interface_get_command(QXLInstance *sin, struct QXLCommandExt *ext) dprint(3, "%s:\n", __FUNCTION__); qemu_mutex_lock(&ssd->lock); - if (ssd->update != NULL) { - update = ssd->update; - ssd->update = NULL; + update = QTAILQ_FIRST(&ssd->updates); + if (update != NULL) { + QTAILQ_REMOVE(&ssd->updates, update, next); *ext = update->ext; ret = true; } @@ -464,6 +525,37 @@ static int interface_flush_resources(QXLInstance *sin) return 0; } +static void interface_update_area_complete(QXLInstance *sin, + uint32_t surface_id, + QXLRect *dirty, uint32_t num_updated_rects) +{ + /* should never be called, used in qxl native mode only */ + fprintf(stderr, "%s: abort()\n", __func__); + abort(); +} + +/* called from spice server thread context only */ +static void interface_async_complete(QXLInstance *sin, uint64_t cookie_token) +{ + /* should never be called, used in qxl native mode only */ + fprintf(stderr, "%s: abort()\n", __func__); + abort(); +} + +static void interface_set_client_capabilities(QXLInstance *sin, + uint8_t client_present, + uint8_t caps[58]) +{ + dprint(3, "%s:\n", __func__); +} + +static int interface_client_monitors_config(QXLInstance *sin, + VDAgentMonitorsConfig *monitors_config) +{ + dprint(3, "%s:\n", __func__); + return 0; /* == not supported by guest */ +} + static const QXLInterface dpy_interface = { .base.type = SPICE_INTERFACE_QXL, .base.description = "qemu simple display", @@ -483,6 +575,10 @@ static const QXLInterface dpy_interface = { .req_cursor_notification = interface_req_cursor_notification, .notify_update = interface_notify_update, .flush_resources = interface_flush_resources, + .async_complete = interface_async_complete, + .update_area_complete = interface_update_area_complete, + .set_client_capabilities = interface_set_client_capabilities, + .client_monitors_config = interface_client_monitors_config, }; static SimpleSpiceDisplay sdpy; @@ -503,8 +599,8 @@ static void display_refresh(struct DisplayState *ds) } static DisplayChangeListener display_listener = { - .dpy_update = display_update, - .dpy_resize = display_resize, + .dpy_gfx_update = display_update, + .dpy_gfx_resize = display_resize, .dpy_refresh = display_refresh, }; @@ -512,13 +608,12 @@ void qemu_spice_display_init(DisplayState *ds) { assert(sdpy.ds == NULL); qemu_spice_display_init_common(&sdpy, ds); - register_displaychangelistener(ds, &display_listener); sdpy.qxl.base.sif = &dpy_interface.base; qemu_spice_add_interface(&sdpy.qxl.base); assert(sdpy.worker); - qemu_add_vm_change_state_handler(qemu_spice_vm_change_state_handler, &sdpy); qemu_spice_create_host_memslot(&sdpy); qemu_spice_create_host_primary(&sdpy); + register_displaychangelistener(ds, &display_listener); } diff --git a/ui/spice-display.h b/ui/spice-display.h deleted file mode 100644 index 12e50b6efc..0000000000 --- a/ui/spice-display.h +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright (C) 2010 Red Hat, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 or - * (at your option) version 3 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see <http://www.gnu.org/licenses/>. - */ - -#include <spice/ipc_ring.h> -#include <spice/enums.h> -#include <spice/qxl_dev.h> - -#include "qemu-thread.h" -#include "console.h" -#include "pflib.h" -#include "sysemu.h" - -#define NUM_MEMSLOTS 8 -#define MEMSLOT_GENERATION_BITS 8 -#define MEMSLOT_SLOT_BITS 8 - -#define MEMSLOT_GROUP_HOST 0 -#define MEMSLOT_GROUP_GUEST 1 -#define NUM_MEMSLOTS_GROUPS 2 - -#define NUM_SURFACES 1024 - -/* - * Internal enum to differenciate between options for - * io calls that have a sync (old) version and an _async (new) - * version: - * QXL_SYNC: use the old version - * QXL_ASYNC: use the new version and make sure there are no two - * happening at the same time. This is used for guest initiated - * calls - */ -typedef enum qxl_async_io { - QXL_SYNC, - QXL_ASYNC, -} qxl_async_io; - -enum { - QXL_COOKIE_TYPE_IO, - QXL_COOKIE_TYPE_RENDER_UPDATE_AREA, -}; - -typedef struct QXLCookie { - int type; - uint64_t io; - union { - uint32_t surface_id; - QXLRect area; - struct { - QXLRect area; - int redraw; - } render; - } u; -} QXLCookie; - -QXLCookie *qxl_cookie_new(int type, uint64_t io); - -typedef struct SimpleSpiceDisplay SimpleSpiceDisplay; -typedef struct SimpleSpiceUpdate SimpleSpiceUpdate; - -struct SimpleSpiceDisplay { - DisplayState *ds; - void *buf; - int bufsize; - QXLWorker *worker; - QXLInstance qxl; - uint32_t unique; - QemuPfConv *conv; - - QXLRect dirty; - int notify; - int running; - - /* - * All struct members below this comment can be accessed from - * both spice server and qemu (iothread) context and any access - * to them must be protected by the lock. - */ - QemuMutex lock; - SimpleSpiceUpdate *update; - QEMUCursor *cursor; - int mouse_x, mouse_y; -}; - -struct SimpleSpiceUpdate { - QXLDrawable drawable; - QXLImage image; - QXLCommandExt ext; - uint8_t *bitmap; -}; - -int qemu_spice_rect_is_empty(const QXLRect* r); -void qemu_spice_rect_union(QXLRect *dest, const QXLRect *r); - -void qemu_spice_destroy_update(SimpleSpiceDisplay *sdpy, SimpleSpiceUpdate *update); -void qemu_spice_create_host_memslot(SimpleSpiceDisplay *ssd); -void qemu_spice_create_host_primary(SimpleSpiceDisplay *ssd); -void qemu_spice_destroy_host_primary(SimpleSpiceDisplay *ssd); -void qemu_spice_vm_change_state_handler(void *opaque, int running, - RunState state); -void qemu_spice_display_init_common(SimpleSpiceDisplay *ssd, DisplayState *ds); - -void qemu_spice_display_update(SimpleSpiceDisplay *ssd, - int x, int y, int w, int h); -void qemu_spice_display_resize(SimpleSpiceDisplay *ssd); -void qemu_spice_display_refresh(SimpleSpiceDisplay *ssd); -void qemu_spice_cursor_refresh_unlocked(SimpleSpiceDisplay *ssd); - -void qemu_spice_add_memslot(SimpleSpiceDisplay *ssd, QXLDevMemSlot *memslot, - qxl_async_io async); -void qemu_spice_del_memslot(SimpleSpiceDisplay *ssd, uint32_t gid, - uint32_t sid); -void qemu_spice_create_primary_surface(SimpleSpiceDisplay *ssd, uint32_t id, - QXLDevSurfaceCreate *surface, - qxl_async_io async); -void qemu_spice_destroy_primary_surface(SimpleSpiceDisplay *ssd, - uint32_t id, qxl_async_io async); -void qemu_spice_wakeup(SimpleSpiceDisplay *ssd); -void qemu_spice_start(SimpleSpiceDisplay *ssd); -void qemu_spice_stop(SimpleSpiceDisplay *ssd); diff --git a/ui/spice-input.c b/ui/spice-input.c index af4223d442..3beb8deadb 100644 --- a/ui/spice-input.c +++ b/ui/spice-input.c @@ -24,8 +24,8 @@ #include <spice/enums.h> #include "qemu-common.h" -#include "qemu-spice.h" -#include "console.h" +#include "ui/qemu-spice.h" +#include "ui/console.h" /* keyboard bits */ diff --git a/ui/vgafont.h b/ui/vgafont.h new file mode 100644 index 0000000000..3606dd7338 --- /dev/null +++ b/ui/vgafont.h @@ -0,0 +1,4611 @@ +static const uint8_t vgafont16[256 * 16] = { + + /* 0 0x00 '^@' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 1 0x01 '^A' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x81, /* 10000001 */ + 0xa5, /* 10100101 */ + 0x81, /* 10000001 */ + 0x81, /* 10000001 */ + 0xbd, /* 10111101 */ + 0x99, /* 10011001 */ + 0x81, /* 10000001 */ + 0x81, /* 10000001 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 2 0x02 '^B' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0xff, /* 11111111 */ + 0xdb, /* 11011011 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xc3, /* 11000011 */ + 0xe7, /* 11100111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 3 0x03 '^C' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x6c, /* 01101100 */ + 0xfe, /* 11111110 */ + 0xfe, /* 11111110 */ + 0xfe, /* 11111110 */ + 0xfe, /* 11111110 */ + 0x7c, /* 01111100 */ + 0x38, /* 00111000 */ + 0x10, /* 00010000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 4 0x04 '^D' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x10, /* 00010000 */ + 0x38, /* 00111000 */ + 0x7c, /* 01111100 */ + 0xfe, /* 11111110 */ + 0x7c, /* 01111100 */ + 0x38, /* 00111000 */ + 0x10, /* 00010000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 5 0x05 '^E' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x3c, /* 00111100 */ + 0xe7, /* 11100111 */ + 0xe7, /* 11100111 */ + 0xe7, /* 11100111 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 6 0x06 '^F' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x7e, /* 01111110 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 7 0x07 '^G' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 8 0x08 '^H' */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xe7, /* 11100111 */ + 0xc3, /* 11000011 */ + 0xc3, /* 11000011 */ + 0xe7, /* 11100111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + + /* 9 0x09 '^I' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0x42, /* 01000010 */ + 0x42, /* 01000010 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 10 0x0a '^J' */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xc3, /* 11000011 */ + 0x99, /* 10011001 */ + 0xbd, /* 10111101 */ + 0xbd, /* 10111101 */ + 0x99, /* 10011001 */ + 0xc3, /* 11000011 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + + /* 11 0x0b '^K' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x1e, /* 00011110 */ + 0x0e, /* 00001110 */ + 0x1a, /* 00011010 */ + 0x32, /* 00110010 */ + 0x78, /* 01111000 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x78, /* 01111000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 12 0x0c '^L' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 13 0x0d '^M' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x3f, /* 00111111 */ + 0x33, /* 00110011 */ + 0x3f, /* 00111111 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x70, /* 01110000 */ + 0xf0, /* 11110000 */ + 0xe0, /* 11100000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 14 0x0e '^N' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7f, /* 01111111 */ + 0x63, /* 01100011 */ + 0x7f, /* 01111111 */ + 0x63, /* 01100011 */ + 0x63, /* 01100011 */ + 0x63, /* 01100011 */ + 0x63, /* 01100011 */ + 0x67, /* 01100111 */ + 0xe7, /* 11100111 */ + 0xe6, /* 11100110 */ + 0xc0, /* 11000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 15 0x0f '^O' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0xdb, /* 11011011 */ + 0x3c, /* 00111100 */ + 0xe7, /* 11100111 */ + 0x3c, /* 00111100 */ + 0xdb, /* 11011011 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 16 0x10 '^P' */ + 0x00, /* 00000000 */ + 0x80, /* 10000000 */ + 0xc0, /* 11000000 */ + 0xe0, /* 11100000 */ + 0xf0, /* 11110000 */ + 0xf8, /* 11111000 */ + 0xfe, /* 11111110 */ + 0xf8, /* 11111000 */ + 0xf0, /* 11110000 */ + 0xe0, /* 11100000 */ + 0xc0, /* 11000000 */ + 0x80, /* 10000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 17 0x11 '^Q' */ + 0x00, /* 00000000 */ + 0x02, /* 00000010 */ + 0x06, /* 00000110 */ + 0x0e, /* 00001110 */ + 0x1e, /* 00011110 */ + 0x3e, /* 00111110 */ + 0xfe, /* 11111110 */ + 0x3e, /* 00111110 */ + 0x1e, /* 00011110 */ + 0x0e, /* 00001110 */ + 0x06, /* 00000110 */ + 0x02, /* 00000010 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 18 0x12 '^R' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 19 0x13 '^S' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x00, /* 00000000 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 20 0x14 '^T' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7f, /* 01111111 */ + 0xdb, /* 11011011 */ + 0xdb, /* 11011011 */ + 0xdb, /* 11011011 */ + 0x7b, /* 01111011 */ + 0x1b, /* 00011011 */ + 0x1b, /* 00011011 */ + 0x1b, /* 00011011 */ + 0x1b, /* 00011011 */ + 0x1b, /* 00011011 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 21 0x15 '^U' */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0x60, /* 01100000 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x6c, /* 01101100 */ + 0x38, /* 00111000 */ + 0x0c, /* 00001100 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 22 0x16 '^V' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0xfe, /* 11111110 */ + 0xfe, /* 11111110 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 23 0x17 '^W' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 24 0x18 '^X' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 25 0x19 '^Y' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 26 0x1a '^Z' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0xfe, /* 11111110 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 27 0x1b '^[' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0xfe, /* 11111110 */ + 0x60, /* 01100000 */ + 0x30, /* 00110000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 28 0x1c '^\' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 29 0x1d '^]' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x28, /* 00101000 */ + 0x6c, /* 01101100 */ + 0xfe, /* 11111110 */ + 0x6c, /* 01101100 */ + 0x28, /* 00101000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 30 0x1e '^^' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x10, /* 00010000 */ + 0x38, /* 00111000 */ + 0x38, /* 00111000 */ + 0x7c, /* 01111100 */ + 0x7c, /* 01111100 */ + 0xfe, /* 11111110 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 31 0x1f '^_' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0xfe, /* 11111110 */ + 0x7c, /* 01111100 */ + 0x7c, /* 01111100 */ + 0x38, /* 00111000 */ + 0x38, /* 00111000 */ + 0x10, /* 00010000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 32 0x20 ' ' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 33 0x21 '!' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x3c, /* 00111100 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 34 0x22 '"' */ + 0x00, /* 00000000 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x24, /* 00100100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 35 0x23 '#' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0xfe, /* 11111110 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0xfe, /* 11111110 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 36 0x24 '$' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc2, /* 11000010 */ + 0xc0, /* 11000000 */ + 0x7c, /* 01111100 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0x86, /* 10000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 37 0x25 '%' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc2, /* 11000010 */ + 0xc6, /* 11000110 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0xc6, /* 11000110 */ + 0x86, /* 10000110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 38 0x26 '&' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x38, /* 00111000 */ + 0x76, /* 01110110 */ + 0xdc, /* 11011100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 39 0x27 ''' */ + 0x00, /* 00000000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 40 0x28 '(' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 41 0x29 ')' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 42 0x2a '*' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0xff, /* 11111111 */ + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 43 0x2b '+' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 44 0x2c ',' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 45 0x2d '-' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 46 0x2e '.' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 47 0x2f '/' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x02, /* 00000010 */ + 0x06, /* 00000110 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0xc0, /* 11000000 */ + 0x80, /* 10000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 48 0x30 '0' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xd6, /* 11010110 */ + 0xd6, /* 11010110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x6c, /* 01101100 */ + 0x38, /* 00111000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 49 0x31 '1' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x38, /* 00111000 */ + 0x78, /* 01111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 50 0x32 '2' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0x06, /* 00000110 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0xc0, /* 11000000 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 51 0x33 '3' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0x3c, /* 00111100 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 52 0x34 '4' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x0c, /* 00001100 */ + 0x1c, /* 00011100 */ + 0x3c, /* 00111100 */ + 0x6c, /* 01101100 */ + 0xcc, /* 11001100 */ + 0xfe, /* 11111110 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x1e, /* 00011110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 53 0x35 '5' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xfc, /* 11111100 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 54 0x36 '6' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x38, /* 00111000 */ + 0x60, /* 01100000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xfc, /* 11111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 55 0x37 '7' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0xc6, /* 11000110 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 56 0x38 '8' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 57 0x39 '9' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7e, /* 01111110 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0x0c, /* 00001100 */ + 0x78, /* 01111000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 58 0x3a ':' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 59 0x3b ';' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 60 0x3c '<' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x06, /* 00000110 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0x06, /* 00000110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 61 0x3d '=' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 62 0x3e '>' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x60, /* 01100000 */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0x06, /* 00000110 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 63 0x3f '?' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 64 0x40 '@' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xde, /* 11011110 */ + 0xde, /* 11011110 */ + 0xde, /* 11011110 */ + 0xdc, /* 11011100 */ + 0xc0, /* 11000000 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 65 0x41 'A' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x10, /* 00010000 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 66 0x42 'B' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfc, /* 11111100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x7c, /* 01111100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0xfc, /* 11111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 67 0x43 'C' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0xc2, /* 11000010 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc2, /* 11000010 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 68 0x44 'D' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xf8, /* 11111000 */ + 0x6c, /* 01101100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x6c, /* 01101100 */ + 0xf8, /* 11111000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 69 0x45 'E' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0x66, /* 01100110 */ + 0x62, /* 01100010 */ + 0x68, /* 01101000 */ + 0x78, /* 01111000 */ + 0x68, /* 01101000 */ + 0x60, /* 01100000 */ + 0x62, /* 01100010 */ + 0x66, /* 01100110 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 70 0x46 'F' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0x66, /* 01100110 */ + 0x62, /* 01100010 */ + 0x68, /* 01101000 */ + 0x78, /* 01111000 */ + 0x68, /* 01101000 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0xf0, /* 11110000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 71 0x47 'G' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0xc2, /* 11000010 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xde, /* 11011110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x66, /* 01100110 */ + 0x3a, /* 00111010 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 72 0x48 'H' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 73 0x49 'I' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 74 0x4a 'J' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x1e, /* 00011110 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x78, /* 01111000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 75 0x4b 'K' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xe6, /* 11100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x6c, /* 01101100 */ + 0x78, /* 01111000 */ + 0x78, /* 01111000 */ + 0x6c, /* 01101100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0xe6, /* 11100110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 76 0x4c 'L' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xf0, /* 11110000 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0x62, /* 01100010 */ + 0x66, /* 01100110 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 77 0x4d 'M' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0xee, /* 11101110 */ + 0xfe, /* 11111110 */ + 0xfe, /* 11111110 */ + 0xd6, /* 11010110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 78 0x4e 'N' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0xe6, /* 11100110 */ + 0xf6, /* 11110110 */ + 0xfe, /* 11111110 */ + 0xde, /* 11011110 */ + 0xce, /* 11001110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 79 0x4f 'O' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 80 0x50 'P' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfc, /* 11111100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x7c, /* 01111100 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0xf0, /* 11110000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 81 0x51 'Q' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xd6, /* 11010110 */ + 0xde, /* 11011110 */ + 0x7c, /* 01111100 */ + 0x0c, /* 00001100 */ + 0x0e, /* 00001110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 82 0x52 'R' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfc, /* 11111100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x7c, /* 01111100 */ + 0x6c, /* 01101100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0xe6, /* 11100110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 83 0x53 'S' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x60, /* 01100000 */ + 0x38, /* 00111000 */ + 0x0c, /* 00001100 */ + 0x06, /* 00000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 84 0x54 'T' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x7e, /* 01111110 */ + 0x5a, /* 01011010 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 85 0x55 'U' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 86 0x56 'V' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x6c, /* 01101100 */ + 0x38, /* 00111000 */ + 0x10, /* 00010000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 87 0x57 'W' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xd6, /* 11010110 */ + 0xd6, /* 11010110 */ + 0xd6, /* 11010110 */ + 0xfe, /* 11111110 */ + 0xee, /* 11101110 */ + 0x6c, /* 01101100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 88 0x58 'X' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x6c, /* 01101100 */ + 0x7c, /* 01111100 */ + 0x38, /* 00111000 */ + 0x38, /* 00111000 */ + 0x7c, /* 01111100 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 89 0x59 'Y' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 90 0x5a 'Z' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0xc6, /* 11000110 */ + 0x86, /* 10000110 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0xc2, /* 11000010 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 91 0x5b '[' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x3c, /* 00111100 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 92 0x5c '\' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x80, /* 10000000 */ + 0xc0, /* 11000000 */ + 0xe0, /* 11100000 */ + 0x70, /* 01110000 */ + 0x38, /* 00111000 */ + 0x1c, /* 00011100 */ + 0x0e, /* 00001110 */ + 0x06, /* 00000110 */ + 0x02, /* 00000010 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 93 0x5d ']' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x3c, /* 00111100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 94 0x5e '^' */ + 0x10, /* 00010000 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 95 0x5f '_' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 96 0x60 '`' */ + 0x00, /* 00000000 */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 97 0x61 'a' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x78, /* 01111000 */ + 0x0c, /* 00001100 */ + 0x7c, /* 01111100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 98 0x62 'b' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xe0, /* 11100000 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0x78, /* 01111000 */ + 0x6c, /* 01101100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 99 0x63 'c' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 100 0x64 'd' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x1c, /* 00011100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x3c, /* 00111100 */ + 0x6c, /* 01101100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 101 0x65 'e' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 102 0x66 'f' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x1c, /* 00011100 */ + 0x36, /* 00110110 */ + 0x32, /* 00110010 */ + 0x30, /* 00110000 */ + 0x78, /* 01111000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x78, /* 01111000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 103 0x67 'g' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x76, /* 01110110 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x7c, /* 01111100 */ + 0x0c, /* 00001100 */ + 0xcc, /* 11001100 */ + 0x78, /* 01111000 */ + 0x00, /* 00000000 */ + + /* 104 0x68 'h' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xe0, /* 11100000 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0x6c, /* 01101100 */ + 0x76, /* 01110110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0xe6, /* 11100110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 105 0x69 'i' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x38, /* 00111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 106 0x6a 'j' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0x00, /* 00000000 */ + 0x0e, /* 00001110 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + + /* 107 0x6b 'k' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xe0, /* 11100000 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0x66, /* 01100110 */ + 0x6c, /* 01101100 */ + 0x78, /* 01111000 */ + 0x78, /* 01111000 */ + 0x6c, /* 01101100 */ + 0x66, /* 01100110 */ + 0xe6, /* 11100110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 108 0x6c 'l' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x38, /* 00111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 109 0x6d 'm' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xec, /* 11101100 */ + 0xfe, /* 11111110 */ + 0xd6, /* 11010110 */ + 0xd6, /* 11010110 */ + 0xd6, /* 11010110 */ + 0xd6, /* 11010110 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 110 0x6e 'n' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xdc, /* 11011100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 111 0x6f 'o' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 112 0x70 'p' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xdc, /* 11011100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x7c, /* 01111100 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0xf0, /* 11110000 */ + 0x00, /* 00000000 */ + + /* 113 0x71 'q' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x76, /* 01110110 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x7c, /* 01111100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x1e, /* 00011110 */ + 0x00, /* 00000000 */ + + /* 114 0x72 'r' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xdc, /* 11011100 */ + 0x76, /* 01110110 */ + 0x66, /* 01100110 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0xf0, /* 11110000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 115 0x73 's' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0x60, /* 01100000 */ + 0x38, /* 00111000 */ + 0x0c, /* 00001100 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 116 0x74 't' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x10, /* 00010000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0xfc, /* 11111100 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x36, /* 00110110 */ + 0x1c, /* 00011100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 117 0x75 'u' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 118 0x76 'v' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x6c, /* 01101100 */ + 0x38, /* 00111000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 119 0x77 'w' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xd6, /* 11010110 */ + 0xd6, /* 11010110 */ + 0xd6, /* 11010110 */ + 0xfe, /* 11111110 */ + 0x6c, /* 01101100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 120 0x78 'x' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0x6c, /* 01101100 */ + 0x38, /* 00111000 */ + 0x38, /* 00111000 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 121 0x79 'y' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7e, /* 01111110 */ + 0x06, /* 00000110 */ + 0x0c, /* 00001100 */ + 0xf8, /* 11111000 */ + 0x00, /* 00000000 */ + + /* 122 0x7a 'z' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0xcc, /* 11001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 123 0x7b '{' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x0e, /* 00001110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x70, /* 01110000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x0e, /* 00001110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 124 0x7c '|' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 125 0x7d '}' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x70, /* 01110000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x0e, /* 00001110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x70, /* 01110000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 126 0x7e '~' */ + 0x00, /* 00000000 */ + 0x76, /* 01110110 */ + 0xdc, /* 11011100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 127 0x7f '' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x10, /* 00010000 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 128 0x80 '' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0xc2, /* 11000010 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc2, /* 11000010 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x70, /* 01110000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 129 0x81 '' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xcc, /* 11001100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 130 0x82 '' */ + 0x00, /* 00000000 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 131 0x83 '' */ + 0x00, /* 00000000 */ + 0x10, /* 00010000 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0x00, /* 00000000 */ + 0x78, /* 01111000 */ + 0x0c, /* 00001100 */ + 0x7c, /* 01111100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 132 0x84 '' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xcc, /* 11001100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x78, /* 01111000 */ + 0x0c, /* 00001100 */ + 0x7c, /* 01111100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 133 0x85 '
' */ + 0x00, /* 00000000 */ + 0x60, /* 01100000 */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x78, /* 01111000 */ + 0x0c, /* 00001100 */ + 0x7c, /* 01111100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 134 0x86 '' */ + 0x00, /* 00000000 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0x38, /* 00111000 */ + 0x00, /* 00000000 */ + 0x78, /* 01111000 */ + 0x0c, /* 00001100 */ + 0x7c, /* 01111100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 135 0x87 '' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x18, /* 00011000 */ + 0x70, /* 01110000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 136 0x88 '' */ + 0x00, /* 00000000 */ + 0x10, /* 00010000 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 137 0x89 '' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 138 0x8a '' */ + 0x00, /* 00000000 */ + 0x60, /* 01100000 */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 139 0x8b '' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x66, /* 01100110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x38, /* 00111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 140 0x8c '' */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0x00, /* 00000000 */ + 0x38, /* 00111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 141 0x8d '' */ + 0x00, /* 00000000 */ + 0x60, /* 01100000 */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x38, /* 00111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 142 0x8e '' */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0x10, /* 00010000 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 143 0x8f '' */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0x38, /* 00111000 */ + 0x10, /* 00010000 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 144 0x90 '' */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0x66, /* 01100110 */ + 0x62, /* 01100010 */ + 0x68, /* 01101000 */ + 0x78, /* 01111000 */ + 0x68, /* 01101000 */ + 0x62, /* 01100010 */ + 0x66, /* 01100110 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 145 0x91 '' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xec, /* 11101100 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x7e, /* 01111110 */ + 0xd8, /* 11011000 */ + 0xd8, /* 11011000 */ + 0x6e, /* 01101110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 146 0x92 '' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x3e, /* 00111110 */ + 0x6c, /* 01101100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xfe, /* 11111110 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xce, /* 11001110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 147 0x93 '' */ + 0x00, /* 00000000 */ + 0x10, /* 00010000 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 148 0x94 '' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 149 0x95 '' */ + 0x00, /* 00000000 */ + 0x60, /* 01100000 */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 150 0x96 '' */ + 0x00, /* 00000000 */ + 0x30, /* 00110000 */ + 0x78, /* 01111000 */ + 0xcc, /* 11001100 */ + 0x00, /* 00000000 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 151 0x97 '' */ + 0x00, /* 00000000 */ + 0x60, /* 01100000 */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 152 0x98 '' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7e, /* 01111110 */ + 0x06, /* 00000110 */ + 0x0c, /* 00001100 */ + 0x78, /* 01111000 */ + 0x00, /* 00000000 */ + + /* 153 0x99 '' */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 154 0x9a '' */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 155 0x9b '' */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 156 0x9c '' */ + 0x00, /* 00000000 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0x64, /* 01100100 */ + 0x60, /* 01100000 */ + 0xf0, /* 11110000 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0xe6, /* 11100110 */ + 0xfc, /* 11111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 157 0x9d '' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 158 0x9e '' */ + 0x00, /* 00000000 */ + 0xf8, /* 11111000 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xf8, /* 11111000 */ + 0xc4, /* 11000100 */ + 0xcc, /* 11001100 */ + 0xde, /* 11011110 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 159 0x9f '' */ + 0x00, /* 00000000 */ + 0x0e, /* 00001110 */ + 0x1b, /* 00011011 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0xd8, /* 11011000 */ + 0x70, /* 01110000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 160 0xa0 ' ' */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0x00, /* 00000000 */ + 0x78, /* 01111000 */ + 0x0c, /* 00001100 */ + 0x7c, /* 01111100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 161 0xa1 '¡' */ + 0x00, /* 00000000 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x00, /* 00000000 */ + 0x38, /* 00111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 162 0xa2 '¢' */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 163 0xa3 '£' */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0x00, /* 00000000 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 164 0xa4 '¤' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x76, /* 01110110 */ + 0xdc, /* 11011100 */ + 0x00, /* 00000000 */ + 0xdc, /* 11011100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 165 0xa5 '¥' */ + 0x76, /* 01110110 */ + 0xdc, /* 11011100 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0xe6, /* 11100110 */ + 0xf6, /* 11110110 */ + 0xfe, /* 11111110 */ + 0xde, /* 11011110 */ + 0xce, /* 11001110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 166 0xa6 '¦' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x3c, /* 00111100 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x3e, /* 00111110 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 167 0xa7 '§' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x38, /* 00111000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 168 0xa8 '¨' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x00, /* 00000000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0xc0, /* 11000000 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 169 0xa9 '©' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 170 0xaa 'ª' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 171 0xab '«' */ + 0x00, /* 00000000 */ + 0x60, /* 01100000 */ + 0xe0, /* 11100000 */ + 0x62, /* 01100010 */ + 0x66, /* 01100110 */ + 0x6c, /* 01101100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0xdc, /* 11011100 */ + 0x86, /* 10000110 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x3e, /* 00111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 172 0xac '¬' */ + 0x00, /* 00000000 */ + 0x60, /* 01100000 */ + 0xe0, /* 11100000 */ + 0x62, /* 01100010 */ + 0x66, /* 01100110 */ + 0x6c, /* 01101100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x66, /* 01100110 */ + 0xce, /* 11001110 */ + 0x9a, /* 10011010 */ + 0x3f, /* 00111111 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 173 0xad '' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x3c, /* 00111100 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 174 0xae '®' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x36, /* 00110110 */ + 0x6c, /* 01101100 */ + 0xd8, /* 11011000 */ + 0x6c, /* 01101100 */ + 0x36, /* 00110110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 175 0xaf '¯' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xd8, /* 11011000 */ + 0x6c, /* 01101100 */ + 0x36, /* 00110110 */ + 0x6c, /* 01101100 */ + 0xd8, /* 11011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 176 0xb0 '°' */ + 0x11, /* 00010001 */ + 0x44, /* 01000100 */ + 0x11, /* 00010001 */ + 0x44, /* 01000100 */ + 0x11, /* 00010001 */ + 0x44, /* 01000100 */ + 0x11, /* 00010001 */ + 0x44, /* 01000100 */ + 0x11, /* 00010001 */ + 0x44, /* 01000100 */ + 0x11, /* 00010001 */ + 0x44, /* 01000100 */ + 0x11, /* 00010001 */ + 0x44, /* 01000100 */ + 0x11, /* 00010001 */ + 0x44, /* 01000100 */ + + /* 177 0xb1 '±' */ + 0x55, /* 01010101 */ + 0xaa, /* 10101010 */ + 0x55, /* 01010101 */ + 0xaa, /* 10101010 */ + 0x55, /* 01010101 */ + 0xaa, /* 10101010 */ + 0x55, /* 01010101 */ + 0xaa, /* 10101010 */ + 0x55, /* 01010101 */ + 0xaa, /* 10101010 */ + 0x55, /* 01010101 */ + 0xaa, /* 10101010 */ + 0x55, /* 01010101 */ + 0xaa, /* 10101010 */ + 0x55, /* 01010101 */ + 0xaa, /* 10101010 */ + + /* 178 0xb2 '²' */ + 0xdd, /* 11011101 */ + 0x77, /* 01110111 */ + 0xdd, /* 11011101 */ + 0x77, /* 01110111 */ + 0xdd, /* 11011101 */ + 0x77, /* 01110111 */ + 0xdd, /* 11011101 */ + 0x77, /* 01110111 */ + 0xdd, /* 11011101 */ + 0x77, /* 01110111 */ + 0xdd, /* 11011101 */ + 0x77, /* 01110111 */ + 0xdd, /* 11011101 */ + 0x77, /* 01110111 */ + 0xdd, /* 11011101 */ + 0x77, /* 01110111 */ + + /* 179 0xb3 '³' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 180 0xb4 '´' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0xf8, /* 11111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 181 0xb5 'µ' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0xf8, /* 11111000 */ + 0x18, /* 00011000 */ + 0xf8, /* 11111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 182 0xb6 '¶' */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0xf6, /* 11110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 183 0xb7 '·' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 184 0xb8 '¸' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xf8, /* 11111000 */ + 0x18, /* 00011000 */ + 0xf8, /* 11111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 185 0xb9 '¹' */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0xf6, /* 11110110 */ + 0x06, /* 00000110 */ + 0xf6, /* 11110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 186 0xba 'º' */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 187 0xbb '»' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0x06, /* 00000110 */ + 0xf6, /* 11110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 188 0xbc '¼' */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0xf6, /* 11110110 */ + 0x06, /* 00000110 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 189 0xbd '½' */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 190 0xbe '¾' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0xf8, /* 11111000 */ + 0x18, /* 00011000 */ + 0xf8, /* 11111000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 191 0xbf '¿' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xf8, /* 11111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 192 0xc0 'À' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x1f, /* 00011111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 193 0xc1 'Á' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 194 0xc2 'Â' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 195 0xc3 'Ã' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x1f, /* 00011111 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 196 0xc4 'Ä' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 197 0xc5 'Å' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0xff, /* 11111111 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 198 0xc6 'Æ' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x1f, /* 00011111 */ + 0x18, /* 00011000 */ + 0x1f, /* 00011111 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 199 0xc7 'Ç' */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x37, /* 00110111 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 200 0xc8 'È' */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x37, /* 00110111 */ + 0x30, /* 00110000 */ + 0x3f, /* 00111111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 201 0xc9 'É' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x3f, /* 00111111 */ + 0x30, /* 00110000 */ + 0x37, /* 00110111 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 202 0xca 'Ê' */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0xf7, /* 11110111 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 203 0xcb 'Ë' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0xf7, /* 11110111 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 204 0xcc 'Ì' */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x37, /* 00110111 */ + 0x30, /* 00110000 */ + 0x37, /* 00110111 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 205 0xcd 'Í' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 206 0xce 'Î' */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0xf7, /* 11110111 */ + 0x00, /* 00000000 */ + 0xf7, /* 11110111 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 207 0xcf 'Ï' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 208 0xd0 'Ð' */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 209 0xd1 'Ñ' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 210 0xd2 'Ò' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 211 0xd3 'Ó' */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x3f, /* 00111111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 212 0xd4 'Ô' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x1f, /* 00011111 */ + 0x18, /* 00011000 */ + 0x1f, /* 00011111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 213 0xd5 'Õ' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x1f, /* 00011111 */ + 0x18, /* 00011000 */ + 0x1f, /* 00011111 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 214 0xd6 'Ö' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x3f, /* 00111111 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 215 0xd7 '×' */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0xff, /* 11111111 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 216 0xd8 'Ø' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0xff, /* 11111111 */ + 0x18, /* 00011000 */ + 0xff, /* 11111111 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 217 0xd9 'Ù' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0xf8, /* 11111000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 218 0xda 'Ú' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x1f, /* 00011111 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 219 0xdb 'Û' */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + + /* 220 0xdc 'Ü' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + + /* 221 0xdd 'Ý' */ + 0xf0, /* 11110000 */ + 0xf0, /* 11110000 */ + 0xf0, /* 11110000 */ + 0xf0, /* 11110000 */ + 0xf0, /* 11110000 */ + 0xf0, /* 11110000 */ + 0xf0, /* 11110000 */ + 0xf0, /* 11110000 */ + 0xf0, /* 11110000 */ + 0xf0, /* 11110000 */ + 0xf0, /* 11110000 */ + 0xf0, /* 11110000 */ + 0xf0, /* 11110000 */ + 0xf0, /* 11110000 */ + 0xf0, /* 11110000 */ + 0xf0, /* 11110000 */ + + /* 222 0xde 'Þ' */ + 0x0f, /* 00001111 */ + 0x0f, /* 00001111 */ + 0x0f, /* 00001111 */ + 0x0f, /* 00001111 */ + 0x0f, /* 00001111 */ + 0x0f, /* 00001111 */ + 0x0f, /* 00001111 */ + 0x0f, /* 00001111 */ + 0x0f, /* 00001111 */ + 0x0f, /* 00001111 */ + 0x0f, /* 00001111 */ + 0x0f, /* 00001111 */ + 0x0f, /* 00001111 */ + 0x0f, /* 00001111 */ + 0x0f, /* 00001111 */ + 0x0f, /* 00001111 */ + + /* 223 0xdf 'ß' */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 224 0xe0 'à' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x76, /* 01110110 */ + 0xdc, /* 11011100 */ + 0xd8, /* 11011000 */ + 0xd8, /* 11011000 */ + 0xd8, /* 11011000 */ + 0xdc, /* 11011100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 225 0xe1 'á' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x78, /* 01111000 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xd8, /* 11011000 */ + 0xcc, /* 11001100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xcc, /* 11001100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 226 0xe2 'â' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 227 0xe3 'ã' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 228 0xe4 'ä' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0xc6, /* 11000110 */ + 0x60, /* 01100000 */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 229 0xe5 'å' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0xd8, /* 11011000 */ + 0xd8, /* 11011000 */ + 0xd8, /* 11011000 */ + 0xd8, /* 11011000 */ + 0xd8, /* 11011000 */ + 0x70, /* 01110000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 230 0xe6 'æ' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x7c, /* 01111100 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0xc0, /* 11000000 */ + 0x00, /* 00000000 */ + + /* 231 0xe7 'ç' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x76, /* 01110110 */ + 0xdc, /* 11011100 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 232 0xe8 'è' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 233 0xe9 'é' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x6c, /* 01101100 */ + 0x38, /* 00111000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 234 0xea 'ê' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0xee, /* 11101110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 235 0xeb 'ë' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x1e, /* 00011110 */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0x3e, /* 00111110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 236 0xec 'ì' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0xdb, /* 11011011 */ + 0xdb, /* 11011011 */ + 0xdb, /* 11011011 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 237 0xed 'í' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x03, /* 00000011 */ + 0x06, /* 00000110 */ + 0x7e, /* 01111110 */ + 0xdb, /* 11011011 */ + 0xdb, /* 11011011 */ + 0xf3, /* 11110011 */ + 0x7e, /* 01111110 */ + 0x60, /* 01100000 */ + 0xc0, /* 11000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 238 0xee 'î' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x1c, /* 00011100 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0x7c, /* 01111100 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0x30, /* 00110000 */ + 0x1c, /* 00011100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 239 0xef 'ï' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 240 0xf0 'ð' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 241 0xf1 'ñ' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 242 0xf2 'ò' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0x06, /* 00000110 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 243 0xf3 'ó' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 244 0xf4 'ô' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x0e, /* 00001110 */ + 0x1b, /* 00011011 */ + 0x1b, /* 00011011 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 245 0xf5 'õ' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0xd8, /* 11011000 */ + 0xd8, /* 11011000 */ + 0xd8, /* 11011000 */ + 0x70, /* 01110000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 246 0xf6 'ö' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 247 0xf7 '÷' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x76, /* 01110110 */ + 0xdc, /* 11011100 */ + 0x00, /* 00000000 */ + 0x76, /* 01110110 */ + 0xdc, /* 11011100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 248 0xf8 'ø' */ + 0x00, /* 00000000 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x38, /* 00111000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 249 0xf9 'ù' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 250 0xfa 'ú' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 251 0xfb 'û' */ + 0x00, /* 00000000 */ + 0x0f, /* 00001111 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0xec, /* 11101100 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x3c, /* 00111100 */ + 0x1c, /* 00011100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 252 0xfc 'ü' */ + 0x00, /* 00000000 */ + 0x6c, /* 01101100 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 253 0xfd 'ý' */ + 0x00, /* 00000000 */ + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x32, /* 00110010 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 254 0xfe 'þ' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x7e, /* 01111110 */ + 0x7e, /* 01111110 */ + 0x7e, /* 01111110 */ + 0x7e, /* 01111110 */ + 0x7e, /* 01111110 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 255 0xff 'ÿ' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + +}; diff --git a/ui/vnc-auth-sasl.c b/ui/vnc-auth-sasl.c index 8fba7702c2..f3ad75d52b 100644 --- a/ui/vnc-auth-sasl.c +++ b/ui/vnc-auth-sasl.c @@ -432,9 +432,7 @@ static int protocol_client_auth_sasl_start_len(VncState *vs, uint8_t *data, size static int protocol_client_auth_sasl_mechname(VncState *vs, uint8_t *data, size_t len) { - char *mechname = g_malloc(len + 1); - strncpy(mechname, (char*)data, len); - mechname[len] = '\0'; + char *mechname = g_strndup((const char *) data, len); VNC_DEBUG("Got client mechname '%s' check against '%s'\n", mechname, vs->sasl.mechlist); @@ -619,7 +617,6 @@ void start_auth_sasl(VncState *vs) authabort: vnc_client_error(vs); - return; } diff --git a/ui/vnc-auth-sasl.h b/ui/vnc-auth-sasl.h index ee243a9d64..8091d689cb 100644 --- a/ui/vnc-auth-sasl.h +++ b/ui/vnc-auth-sasl.h @@ -32,7 +32,7 @@ typedef struct VncStateSASL VncStateSASL; typedef struct VncDisplaySASL VncDisplaySASL; -#include "acl.h" +#include "qemu/acl.h" struct VncStateSASL { sasl_conn_t *conn; diff --git a/ui/vnc-enc-hextile-template.h b/ui/vnc-enc-hextile-template.h index a7310e1947..d868d75720 100644 --- a/ui/vnc-enc-hextile-template.h +++ b/ui/vnc-enc-hextile-template.h @@ -14,7 +14,7 @@ static void CONCAT(send_hextile_tile_, NAME)(VncState *vs, int *has_bg, int *has_fg) { VncDisplay *vd = vs->vd; - uint8_t *row = vd->server->data + y * ds_get_linesize(vs->ds) + x * ds_get_bytes_per_pixel(vs->ds); + uint8_t *row = vnc_server_fb_ptr(vd, x, y); pixel_t *irow = (pixel_t *)row; int j, i; pixel_t *last_bg = (pixel_t *)last_bg_; @@ -25,7 +25,7 @@ static void CONCAT(send_hextile_tile_, NAME)(VncState *vs, int bg_count = 0; int fg_count = 0; int flags = 0; - uint8_t data[(vs->clientds.pf.bytes_per_pixel + 2) * 16 * 16]; + uint8_t data[(vs->client_pf.bytes_per_pixel + 2) * 16 * 16]; int n_data = 0; int n_subtiles = 0; @@ -58,7 +58,7 @@ static void CONCAT(send_hextile_tile_, NAME)(VncState *vs, } if (n_colors > 2) break; - irow += ds_get_linesize(vs->ds) / sizeof(pixel_t); + irow += vnc_server_fb_stride(vd) / sizeof(pixel_t); } if (n_colors > 1 && fg_count > bg_count) { @@ -106,7 +106,7 @@ static void CONCAT(send_hextile_tile_, NAME)(VncState *vs, n_data += 2; n_subtiles++; } - irow += ds_get_linesize(vs->ds) / sizeof(pixel_t); + irow += vnc_server_fb_stride(vd) / sizeof(pixel_t); } break; case 3: @@ -133,7 +133,7 @@ static void CONCAT(send_hextile_tile_, NAME)(VncState *vs, has_color = 0; #ifdef GENERIC vnc_convert_pixel(vs, data + n_data, color); - n_data += vs->clientds.pf.bytes_per_pixel; + n_data += vs->client_pf.bytes_per_pixel; #else memcpy(data + n_data, &color, sizeof(color)); n_data += sizeof(pixel_t); @@ -153,7 +153,7 @@ static void CONCAT(send_hextile_tile_, NAME)(VncState *vs, if (has_color) { #ifdef GENERIC vnc_convert_pixel(vs, data + n_data, color); - n_data += vs->clientds.pf.bytes_per_pixel; + n_data += vs->client_pf.bytes_per_pixel; #else memcpy(data + n_data, &color, sizeof(color)); n_data += sizeof(pixel_t); @@ -162,7 +162,7 @@ static void CONCAT(send_hextile_tile_, NAME)(VncState *vs, n_data += 2; n_subtiles++; } - irow += ds_get_linesize(vs->ds) / sizeof(pixel_t); + irow += vnc_server_fb_stride(vd) / sizeof(pixel_t); } /* A SubrectsColoured subtile invalidates the foreground color */ @@ -190,18 +190,17 @@ static void CONCAT(send_hextile_tile_, NAME)(VncState *vs, vnc_write_u8(vs, flags); if (n_colors < 4) { if (flags & 0x02) - vs->write_pixels(vs, &vd->server->pf, last_bg, sizeof(pixel_t)); + vs->write_pixels(vs, last_bg, sizeof(pixel_t)); if (flags & 0x04) - vs->write_pixels(vs, &vd->server->pf, last_fg, sizeof(pixel_t)); + vs->write_pixels(vs, last_fg, sizeof(pixel_t)); if (n_subtiles) { vnc_write_u8(vs, n_subtiles); vnc_write(vs, data, n_data); } } else { for (j = 0; j < h; j++) { - vs->write_pixels(vs, &vd->server->pf, row, - w * ds_get_bytes_per_pixel(vs->ds)); - row += ds_get_linesize(vs->ds); + vs->write_pixels(vs, row, w * 4); + row += vnc_server_fb_stride(vd); } } } diff --git a/ui/vnc-enc-hextile.c b/ui/vnc-enc-hextile.c index c860dbb2e5..2e768fd899 100644 --- a/ui/vnc-enc-hextile.c +++ b/ui/vnc-enc-hextile.c @@ -32,31 +32,11 @@ static void hextile_enc_cord(uint8_t *ptr, int x, int y, int w, int h) ptr[1] = (((w - 1) & 0x0F) << 4) | ((h - 1) & 0x0F); } -#define BPP 8 -#include "vnc-enc-hextile-template.h" -#undef BPP - -#define BPP 16 -#include "vnc-enc-hextile-template.h" -#undef BPP - #define BPP 32 #include "vnc-enc-hextile-template.h" #undef BPP #define GENERIC -#define BPP 8 -#include "vnc-enc-hextile-template.h" -#undef BPP -#undef GENERIC - -#define GENERIC -#define BPP 16 -#include "vnc-enc-hextile-template.h" -#undef BPP -#undef GENERIC - -#define GENERIC #define BPP 32 #include "vnc-enc-hextile-template.h" #undef BPP @@ -68,10 +48,9 @@ int vnc_hextile_send_framebuffer_update(VncState *vs, int x, int i, j; int has_fg, has_bg; uint8_t *last_fg, *last_bg; - VncDisplay *vd = vs->vd; - last_fg = (uint8_t *) g_malloc(vd->server->pf.bytes_per_pixel); - last_bg = (uint8_t *) g_malloc(vd->server->pf.bytes_per_pixel); + last_fg = (uint8_t *) g_malloc(VNC_SERVER_FB_BYTES); + last_bg = (uint8_t *) g_malloc(VNC_SERVER_FB_BYTES); has_fg = has_bg = 0; for (j = y; j < (y + h); j += 16) { for (i = x; i < (x + w); i += 16) { @@ -89,28 +68,16 @@ int vnc_hextile_send_framebuffer_update(VncState *vs, int x, void vnc_hextile_set_pixel_conversion(VncState *vs, int generic) { if (!generic) { - switch (vs->ds->surface->pf.bits_per_pixel) { - case 8: - vs->hextile.send_tile = send_hextile_tile_8; - break; - case 16: - vs->hextile.send_tile = send_hextile_tile_16; - break; - case 32: - vs->hextile.send_tile = send_hextile_tile_32; - break; + switch (VNC_SERVER_FB_BITS) { + case 32: + vs->hextile.send_tile = send_hextile_tile_32; + break; } } else { - switch (vs->ds->surface->pf.bits_per_pixel) { - case 8: - vs->hextile.send_tile = send_hextile_tile_generic_8; - break; - case 16: - vs->hextile.send_tile = send_hextile_tile_generic_16; - break; - case 32: - vs->hextile.send_tile = send_hextile_tile_generic_32; - break; + switch (VNC_SERVER_FB_BITS) { + case 32: + vs->hextile.send_tile = send_hextile_tile_generic_32; + break; } } } diff --git a/ui/vnc-enc-tight.c b/ui/vnc-enc-tight.c index 5d492abe92..4ddea7d4f5 100644 --- a/ui/vnc-enc-tight.c +++ b/ui/vnc-enc-tight.c @@ -44,8 +44,8 @@ #include <jpeglib.h> #endif -#include "bswap.h" -#include "qint.h" +#include "qemu/bswap.h" +#include "qapi/qmp/qint.h" #include "vnc.h" #include "vnc-enc-tight.h" #include "vnc-palette.h" @@ -124,7 +124,7 @@ static bool tight_can_send_png_rect(VncState *vs, int w, int h) } if (ds_get_bytes_per_pixel(vs->ds) == 1 || - vs->clientds.pf.bytes_per_pixel == 1) { + vs->client_pf.bytes_per_pixel == 1) { return false; } @@ -153,7 +153,7 @@ tight_detect_smooth_image24(VncState *vs, int w, int h) * If client is big-endian, color samples begin from the second * byte (offset 1) of a 32-bit pixel value. */ - off = !!(vs->clientds.flags & QEMU_BIG_ENDIAN_FLAG); + off = vs->client_be; memset(stats, 0, sizeof (stats)); @@ -216,16 +216,16 @@ tight_detect_smooth_image24(VncState *vs, int w, int h) unsigned int errors; \ unsigned char *buf = vs->tight.tight.buffer; \ \ - endian = ((vs->clientds.flags & QEMU_BIG_ENDIAN_FLAG) != \ - (vs->ds->surface->flags & QEMU_BIG_ENDIAN_FLAG)); \ + endian = 0; /* FIXME: ((vs->clientds.flags & QEMU_BIG_ENDIAN_FLAG) != \ + (vs->ds->surface->flags & QEMU_BIG_ENDIAN_FLAG)); */ \ \ \ - max[0] = vs->clientds.pf.rmax; \ - max[1] = vs->clientds.pf.gmax; \ - max[2] = vs->clientds.pf.bmax; \ - shift[0] = vs->clientds.pf.rshift; \ - shift[1] = vs->clientds.pf.gshift; \ - shift[2] = vs->clientds.pf.bshift; \ + max[0] = vs->client_pf.rmax; \ + max[1] = vs->client_pf.gmax; \ + max[2] = vs->client_pf.bmax; \ + shift[0] = vs->client_pf.rshift; \ + shift[1] = vs->client_pf.gshift; \ + shift[2] = vs->client_pf.bshift; \ \ memset(stats, 0, sizeof(stats)); \ \ @@ -302,7 +302,7 @@ tight_detect_smooth_image(VncState *vs, int w, int h) } if (ds_get_bytes_per_pixel(vs->ds) == 1 || - vs->clientds.pf.bytes_per_pixel == 1 || + vs->client_pf.bytes_per_pixel == 1 || w < VNC_TIGHT_DETECT_MIN_WIDTH || h < VNC_TIGHT_DETECT_MIN_HEIGHT) { return 0; } @@ -317,7 +317,7 @@ tight_detect_smooth_image(VncState *vs, int w, int h) } } - if (vs->clientds.pf.bytes_per_pixel == 4) { + if (vs->client_pf.bytes_per_pixel == 4) { if (vs->tight.pixel24) { errors = tight_detect_smooth_image24(vs, w, h); if (vs->tight.quality != (uint8_t)-1) { @@ -430,7 +430,7 @@ static int tight_fill_palette(VncState *vs, int x, int y, max = 256; } - switch(vs->clientds.pf.bytes_per_pixel) { + switch (vs->client_pf.bytes_per_pixel) { case 4: return tight_fill_palette32(vs, x, y, max, count, bg, fg, palette); case 2: @@ -557,15 +557,15 @@ tight_filter_gradient24(VncState *vs, uint8_t *buf, int w, int h) buf32 = (uint32_t *)buf; memset(vs->tight.gradient.buffer, 0, w * 3 * sizeof(int)); - if ((vs->clientds.flags & QEMU_BIG_ENDIAN_FLAG) == - (vs->ds->surface->flags & QEMU_BIG_ENDIAN_FLAG)) { - shift[0] = vs->clientds.pf.rshift; - shift[1] = vs->clientds.pf.gshift; - shift[2] = vs->clientds.pf.bshift; + if (1 /* FIXME: (vs->clientds.flags & QEMU_BIG_ENDIAN_FLAG) == + (vs->ds->surface->flags & QEMU_BIG_ENDIAN_FLAG) */) { + shift[0] = vs->client_pf.rshift; + shift[1] = vs->client_pf.gshift; + shift[2] = vs->client_pf.bshift; } else { - shift[0] = 24 - vs->clientds.pf.rshift; - shift[1] = 24 - vs->clientds.pf.gshift; - shift[2] = 24 - vs->clientds.pf.bshift; + shift[0] = 24 - vs->client_pf.rshift; + shift[1] = 24 - vs->client_pf.gshift; + shift[2] = 24 - vs->client_pf.bshift; } for (y = 0; y < h; y++) { @@ -615,15 +615,15 @@ tight_filter_gradient24(VncState *vs, uint8_t *buf, int w, int h) \ memset (vs->tight.gradient.buffer, 0, w * 3 * sizeof(int)); \ \ - endian = ((vs->clientds.flags & QEMU_BIG_ENDIAN_FLAG) != \ - (vs->ds->surface->flags & QEMU_BIG_ENDIAN_FLAG)); \ + endian = 0; /* FIXME: ((vs->clientds.flags & QEMU_BIG_ENDIAN_FLAG) != \ + (vs->ds->surface->flags & QEMU_BIG_ENDIAN_FLAG)); */ \ \ - max[0] = vs->clientds.pf.rmax; \ - max[1] = vs->clientds.pf.gmax; \ - max[2] = vs->clientds.pf.bmax; \ - shift[0] = vs->clientds.pf.rshift; \ - shift[1] = vs->clientds.pf.gshift; \ - shift[2] = vs->clientds.pf.bshift; \ + max[0] = vs->client_pf.rmax; \ + max[1] = vs->client_pf.gmax; \ + max[2] = vs->client_pf.bmax; \ + shift[0] = vs->client_pf.rshift; \ + shift[1] = vs->client_pf.gshift; \ + shift[2] = vs->client_pf.bshift; \ \ for (y = 0; y < h; y++) { \ for (c = 0; c < 3; c++) { \ @@ -671,56 +671,42 @@ DEFINE_GRADIENT_FILTER_FUNCTION(32) * that case new color will be stored in *colorPtr. */ -#define DEFINE_CHECK_SOLID_FUNCTION(bpp) \ - \ - static bool \ - check_solid_tile##bpp(VncState *vs, int x, int y, int w, int h, \ - uint32_t* color, bool samecolor) \ - { \ - VncDisplay *vd = vs->vd; \ - uint##bpp##_t *fbptr; \ - uint##bpp##_t c; \ - int dx, dy; \ - \ - fbptr = (uint##bpp##_t *) \ - (vd->server->data + y * ds_get_linesize(vs->ds) + \ - x * ds_get_bytes_per_pixel(vs->ds)); \ - \ - c = *fbptr; \ - if (samecolor && (uint32_t)c != *color) { \ - return false; \ - } \ - \ - for (dy = 0; dy < h; dy++) { \ - for (dx = 0; dx < w; dx++) { \ - if (c != fbptr[dx]) { \ - return false; \ - } \ - } \ - fbptr = (uint##bpp##_t *) \ - ((uint8_t *)fbptr + ds_get_linesize(vs->ds)); \ - } \ - \ - *color = (uint32_t)c; \ - return true; \ +static bool +check_solid_tile32(VncState *vs, int x, int y, int w, int h, + uint32_t *color, bool samecolor) +{ + VncDisplay *vd = vs->vd; + uint32_t *fbptr; + uint32_t c; + int dx, dy; + + fbptr = vnc_server_fb_ptr(vd, x, y); + + c = *fbptr; + if (samecolor && (uint32_t)c != *color) { + return false; + } + + for (dy = 0; dy < h; dy++) { + for (dx = 0; dx < w; dx++) { + if (c != fbptr[dx]) { + return false; + } + } + fbptr = (uint32_t *) + ((uint8_t *)fbptr + vnc_server_fb_stride(vd)); } -DEFINE_CHECK_SOLID_FUNCTION(32) -DEFINE_CHECK_SOLID_FUNCTION(16) -DEFINE_CHECK_SOLID_FUNCTION(8) + *color = (uint32_t)c; + return true; +} static bool check_solid_tile(VncState *vs, int x, int y, int w, int h, uint32_t* color, bool samecolor) { - VncDisplay *vd = vs->vd; - - switch(vd->server->pf.bytes_per_pixel) { + switch (VNC_SERVER_FB_BYTES) { case 4: return check_solid_tile32(vs, x, y, w, h, color, samecolor); - case 2: - return check_solid_tile16(vs, x, y, w, h, color, samecolor); - default: - return check_solid_tile8(vs, x, y, w, h, color, samecolor); } } @@ -906,15 +892,15 @@ static void tight_pack24(VncState *vs, uint8_t *buf, size_t count, size_t *ret) buf32 = (uint32_t *)buf; - if ((vs->clientds.flags & QEMU_BIG_ENDIAN_FLAG) == - (vs->ds->surface->flags & QEMU_BIG_ENDIAN_FLAG)) { - rshift = vs->clientds.pf.rshift; - gshift = vs->clientds.pf.gshift; - bshift = vs->clientds.pf.bshift; + if (1 /* FIXME: (vs->clientds.flags & QEMU_BIG_ENDIAN_FLAG) == + (vs->ds->surface->flags & QEMU_BIG_ENDIAN_FLAG) */) { + rshift = vs->client_pf.rshift; + gshift = vs->client_pf.gshift; + bshift = vs->client_pf.bshift; } else { - rshift = 24 - vs->clientds.pf.rshift; - gshift = 24 - vs->clientds.pf.gshift; - bshift = 24 - vs->clientds.pf.bshift; + rshift = 24 - vs->client_pf.rshift; + gshift = 24 - vs->client_pf.gshift; + bshift = 24 - vs->client_pf.bshift; } if (ret) { @@ -946,7 +932,7 @@ static int send_full_color_rect(VncState *vs, int x, int y, int w, int h) tight_pack24(vs, vs->tight.tight.buffer, w * h, &vs->tight.tight.offset); bytes = 3; } else { - bytes = vs->clientds.pf.bytes_per_pixel; + bytes = vs->client_pf.bytes_per_pixel; } bytes = tight_compress_data(vs, stream, w * h * bytes, @@ -966,7 +952,7 @@ static int send_solid_rect(VncState *vs) tight_pack24(vs, vs->tight.tight.buffer, 1, &vs->tight.tight.offset); bytes = 3; } else { - bytes = vs->clientds.pf.bytes_per_pixel; + bytes = vs->client_pf.bytes_per_pixel; } vnc_write(vs, vs->tight.tight.buffer, bytes); @@ -983,7 +969,7 @@ static int send_mono_rect(VncState *vs, int x, int y, #ifdef CONFIG_VNC_PNG if (tight_can_send_png_rect(vs, w, h)) { int ret; - int bpp = vs->clientds.pf.bytes_per_pixel * 8; + int bpp = vs->client_pf.bytes_per_pixel * 8; VncPalette *palette = palette_new(2, bpp); palette_put(palette, bg); @@ -1000,7 +986,7 @@ static int send_mono_rect(VncState *vs, int x, int y, vnc_write_u8(vs, VNC_TIGHT_FILTER_PALETTE); vnc_write_u8(vs, 1); - switch(vs->clientds.pf.bytes_per_pixel) { + switch (vs->client_pf.bytes_per_pixel) { case 4: { uint32_t buf[2] = {bg, fg}; @@ -1043,7 +1029,7 @@ static void write_palette(int idx, uint32_t color, void *opaque) { struct palette_cb_priv *priv = opaque; VncState *vs = priv->vs; - uint32_t bytes = vs->clientds.pf.bytes_per_pixel; + uint32_t bytes = vs->client_pf.bytes_per_pixel; if (bytes == 4) { ((uint32_t*)priv->header)[idx] = color; @@ -1058,8 +1044,9 @@ static bool send_gradient_rect(VncState *vs, int x, int y, int w, int h) int level = tight_conf[vs->tight.compression].gradient_zlib_level; ssize_t bytes; - if (vs->clientds.pf.bytes_per_pixel == 1) + if (vs->client_pf.bytes_per_pixel == 1) { return send_full_color_rect(vs, x, y, w, h); + } vnc_write_u8(vs, (stream | VNC_TIGHT_EXPLICIT_FILTER) << 4); vnc_write_u8(vs, VNC_TIGHT_FILTER_GRADIENT); @@ -1069,7 +1056,7 @@ static bool send_gradient_rect(VncState *vs, int x, int y, int w, int h) if (vs->tight.pixel24) { tight_filter_gradient24(vs, vs->tight.tight.buffer, w, h); bytes = 3; - } else if (vs->clientds.pf.bytes_per_pixel == 4) { + } else if (vs->client_pf.bytes_per_pixel == 4) { tight_filter_gradient32(vs, (uint32_t *)vs->tight.tight.buffer, w, h); bytes = 4; } else { @@ -1107,7 +1094,7 @@ static int send_palette_rect(VncState *vs, int x, int y, vnc_write_u8(vs, VNC_TIGHT_FILTER_PALETTE); vnc_write_u8(vs, colors - 1); - switch(vs->clientds.pf.bytes_per_pixel) { + switch (vs->client_pf.bytes_per_pixel) { case 4: { size_t old_offset, offset; @@ -1148,79 +1135,6 @@ static int send_palette_rect(VncState *vs, int x, int y, return (bytes >= 0); } -#if defined(CONFIG_VNC_JPEG) || defined(CONFIG_VNC_PNG) -static void rgb_prepare_row24(VncState *vs, uint8_t *dst, int x, int y, - int count) -{ - VncDisplay *vd = vs->vd; - uint32_t *fbptr; - uint32_t pix; - - fbptr = (uint32_t *)(vd->server->data + y * ds_get_linesize(vs->ds) + - x * ds_get_bytes_per_pixel(vs->ds)); - - while (count--) { - pix = *fbptr++; - *dst++ = (uint8_t)(pix >> vs->ds->surface->pf.rshift); - *dst++ = (uint8_t)(pix >> vs->ds->surface->pf.gshift); - *dst++ = (uint8_t)(pix >> vs->ds->surface->pf.bshift); - } -} - -#define DEFINE_RGB_GET_ROW_FUNCTION(bpp) \ - \ - static void \ - rgb_prepare_row##bpp(VncState *vs, uint8_t *dst, \ - int x, int y, int count) \ - { \ - VncDisplay *vd = vs->vd; \ - uint##bpp##_t *fbptr; \ - uint##bpp##_t pix; \ - int r, g, b; \ - \ - fbptr = (uint##bpp##_t *) \ - (vd->server->data + y * ds_get_linesize(vs->ds) + \ - x * ds_get_bytes_per_pixel(vs->ds)); \ - \ - while (count--) { \ - pix = *fbptr++; \ - \ - r = (int)((pix >> vs->ds->surface->pf.rshift) \ - & vs->ds->surface->pf.rmax); \ - g = (int)((pix >> vs->ds->surface->pf.gshift) \ - & vs->ds->surface->pf.gmax); \ - b = (int)((pix >> vs->ds->surface->pf.bshift) \ - & vs->ds->surface->pf.bmax); \ - \ - *dst++ = (uint8_t)((r * 255 + vs->ds->surface->pf.rmax / 2) \ - / vs->ds->surface->pf.rmax); \ - *dst++ = (uint8_t)((g * 255 + vs->ds->surface->pf.gmax / 2) \ - / vs->ds->surface->pf.gmax); \ - *dst++ = (uint8_t)((b * 255 + vs->ds->surface->pf.bmax / 2) \ - / vs->ds->surface->pf.bmax); \ - } \ - } - -DEFINE_RGB_GET_ROW_FUNCTION(16) -DEFINE_RGB_GET_ROW_FUNCTION(32) - -static void rgb_prepare_row(VncState *vs, uint8_t *dst, int x, int y, - int count) -{ - if (ds_get_bytes_per_pixel(vs->ds) == 4) { - if (vs->ds->surface->pf.rmax == 0xFF && - vs->ds->surface->pf.gmax == 0xFF && - vs->ds->surface->pf.bmax == 0xFF) { - rgb_prepare_row24(vs, dst, x, y, count); - } else { - rgb_prepare_row32(vs, dst, x, y, count); - } - } else { - rgb_prepare_row16(vs, dst, x, y, count); - } -} -#endif /* CONFIG_VNC_JPEG or CONFIG_VNC_PNG */ - /* * JPEG compression stuff. */ @@ -1265,6 +1179,7 @@ static int send_jpeg_rect(VncState *vs, int x, int y, int w, int h, int quality) struct jpeg_compress_struct cinfo; struct jpeg_error_mgr jerr; struct jpeg_destination_mgr manager; + pixman_image_t *linebuf; JSAMPROW row[1]; uint8_t *buf; int dy; @@ -1293,13 +1208,14 @@ static int send_jpeg_rect(VncState *vs, int x, int y, int w, int h, int quality) jpeg_start_compress(&cinfo, true); - buf = g_malloc(w * 3); + linebuf = qemu_pixman_linebuf_create(PIXMAN_BE_r8g8b8, w); + buf = (uint8_t *)pixman_image_get_data(linebuf); row[0] = buf; for (dy = 0; dy < h; dy++) { - rgb_prepare_row(vs, buf, x, y + dy, w); + qemu_pixman_linebuf_fill(linebuf, vs->vd->server, w, x, y + dy); jpeg_write_scanlines(&cinfo, row, 1); } - g_free(buf); + qemu_pixman_image_unref(linebuf); jpeg_finish_compress(&cinfo); jpeg_destroy_compress(&cinfo); @@ -1326,23 +1242,23 @@ static void write_png_palette(int idx, uint32_t pix, void *opaque) if (vs->tight.pixel24) { - color->red = (pix >> vs->clientds.pf.rshift) & vs->clientds.pf.rmax; - color->green = (pix >> vs->clientds.pf.gshift) & vs->clientds.pf.gmax; - color->blue = (pix >> vs->clientds.pf.bshift) & vs->clientds.pf.bmax; + color->red = (pix >> vs->client_pf.rshift) & vs->client_pf.rmax; + color->green = (pix >> vs->client_pf.gshift) & vs->client_pf.gmax; + color->blue = (pix >> vs->client_pf.bshift) & vs->client_pf.bmax; } else { int red, green, blue; - red = (pix >> vs->clientds.pf.rshift) & vs->clientds.pf.rmax; - green = (pix >> vs->clientds.pf.gshift) & vs->clientds.pf.gmax; - blue = (pix >> vs->clientds.pf.bshift) & vs->clientds.pf.bmax; - color->red = ((red * 255 + vs->clientds.pf.rmax / 2) / - vs->clientds.pf.rmax); - color->green = ((green * 255 + vs->clientds.pf.gmax / 2) / - vs->clientds.pf.gmax); - color->blue = ((blue * 255 + vs->clientds.pf.bmax / 2) / - vs->clientds.pf.bmax); + red = (pix >> vs->client_pf.rshift) & vs->client_pf.rmax; + green = (pix >> vs->client_pf.gshift) & vs->client_pf.gmax; + blue = (pix >> vs->client_pf.bshift) & vs->client_pf.bmax; + color->red = ((red * 255 + vs->client_pf.rmax / 2) / + vs->client_pf.rmax); + color->green = ((green * 255 + vs->client_pf.gmax / 2) / + vs->client_pf.gmax); + color->blue = ((blue * 255 + vs->client_pf.bmax / 2) / + vs->client_pf.bmax); } } @@ -1378,6 +1294,7 @@ static int send_png_rect(VncState *vs, int x, int y, int w, int h, png_structp png_ptr; png_infop info_ptr; png_colorp png_palette = NULL; + pixman_image_t *linebuf; int level = tight_png_conf[vs->tight.compression].png_zlib_level; int filters = tight_png_conf[vs->tight.compression].png_filters; uint8_t *buf; @@ -1422,7 +1339,7 @@ static int send_png_rect(VncState *vs, int x, int y, int w, int h, png_set_PLTE(png_ptr, info_ptr, png_palette, palette_size(palette)); - if (vs->clientds.pf.bytes_per_pixel == 4) { + if (vs->client_pf.bytes_per_pixel == 4) { tight_encode_indexed_rect32(vs->tight.tight.buffer, w * h, palette); } else { tight_encode_indexed_rect16(vs->tight.tight.buffer, w * h, palette); @@ -1432,17 +1349,18 @@ static int send_png_rect(VncState *vs, int x, int y, int w, int h, png_write_info(png_ptr, info_ptr); buffer_reserve(&vs->tight.png, 2048); - buf = g_malloc(w * 3); + linebuf = qemu_pixman_linebuf_create(PIXMAN_BE_r8g8b8, w); + buf = (uint8_t *)pixman_image_get_data(linebuf); for (dy = 0; dy < h; dy++) { if (color_type == PNG_COLOR_TYPE_PALETTE) { memcpy(buf, vs->tight.tight.buffer + (dy * w), w); } else { - rgb_prepare_row(vs, buf, x, y + dy, w); + qemu_pixman_linebuf_fill(linebuf, vs->vd->server, w, x, y + dy); } png_write_row(png_ptr, buf); } - g_free(buf); + qemu_pixman_image_unref(linebuf); png_write_end(png_ptr, NULL); @@ -1713,8 +1631,8 @@ static int tight_send_framebuffer_update(VncState *vs, int x, int y, { int max_rows; - if (vs->clientds.pf.bytes_per_pixel == 4 && vs->clientds.pf.rmax == 0xFF && - vs->clientds.pf.bmax == 0xFF && vs->clientds.pf.gmax == 0xFF) { + if (vs->client_pf.bytes_per_pixel == 4 && vs->client_pf.rmax == 0xFF && + vs->client_pf.bmax == 0xFF && vs->client_pf.gmax == 0xFF) { vs->tight.pixel24 = true; } else { vs->tight.pixel24 = false; diff --git a/ui/vnc-enc-zrle.c b/ui/vnc-enc-zrle.c index 917d384f57..ed3b48465d 100644 --- a/ui/vnc-enc-zrle.c +++ b/ui/vnc-enc-zrle.c @@ -255,7 +255,7 @@ static void zrle_write_u8(VncState *vs, uint8_t value) static int zrle_send_framebuffer_update(VncState *vs, int x, int y, int w, int h) { - bool be = !!(vs->clientds.flags & QEMU_BIG_ENDIAN_FLAG); + bool be = vs->client_be; size_t bytes; int zywrle_level; @@ -277,13 +277,13 @@ static int zrle_send_framebuffer_update(VncState *vs, int x, int y, vnc_zrle_start(vs); - switch(vs->clientds.pf.bytes_per_pixel) { + switch (vs->client_pf.bytes_per_pixel) { case 1: zrle_encode_8ne(vs, x, y, w, h, zywrle_level); break; case 2: - if (vs->clientds.pf.gmax > 0x1F) { + if (vs->client_pf.gmax > 0x1F) { if (be) { zrle_encode_16be(vs, x, y, w, h, zywrle_level); } else { @@ -304,13 +304,13 @@ static int zrle_send_framebuffer_update(VncState *vs, int x, int y, bool fits_in_ms3bytes; fits_in_ls3bytes = - ((vs->clientds.pf.rmax << vs->clientds.pf.rshift) < (1 << 24) && - (vs->clientds.pf.gmax << vs->clientds.pf.gshift) < (1 << 24) && - (vs->clientds.pf.bmax << vs->clientds.pf.bshift) < (1 << 24)); + ((vs->client_pf.rmax << vs->client_pf.rshift) < (1 << 24) && + (vs->client_pf.gmax << vs->client_pf.gshift) < (1 << 24) && + (vs->client_pf.bmax << vs->client_pf.bshift) < (1 << 24)); - fits_in_ms3bytes = (vs->clientds.pf.rshift > 7 && - vs->clientds.pf.gshift > 7 && - vs->clientds.pf.bshift > 7); + fits_in_ms3bytes = (vs->client_pf.rshift > 7 && + vs->client_pf.gshift > 7 && + vs->client_pf.bshift > 7); if ((fits_in_ls3bytes && !be) || (fits_in_ms3bytes && be)) { if (be) { diff --git a/ui/vnc-jobs.c b/ui/vnc-jobs.c index 087b84d319..0bfc0c5485 100644 --- a/ui/vnc-jobs.c +++ b/ui/vnc-jobs.c @@ -28,26 +28,26 @@ #include "vnc.h" #include "vnc-jobs.h" -#include "qemu_socket.h" +#include "qemu/sockets.h" /* * Locking: * - * There is three levels of locking: + * There are three levels of locking: * - jobs queue lock: for each operation on the queue (push, pop, isEmpty?) * - VncDisplay global lock: mainly used for framebuffer updates to avoid * screen corruption if the framebuffer is updated - * while the worker is doing something. + * while the worker is doing something. * - VncState::output lock: used to make sure the output buffer is not corrupted - * if two threads try to write on it at the same time + * if two threads try to write on it at the same time * - * While the VNC worker thread is working, the VncDisplay global lock is hold - * to avoid screen corruptions (this does not block vnc_refresh() because it - * uses trylock()) but the output lock is not hold because the thread work on + * While the VNC worker thread is working, the VncDisplay global lock is held + * to avoid screen corruption (this does not block vnc_refresh() because it + * uses trylock()) but the output lock is not held because the thread works on * its own output buffer. * When the encoding job is done, the worker thread will hold the output lock * and copy its output buffer in vs->output. -*/ + */ struct VncJobQueue { QemuCond cond; @@ -62,7 +62,7 @@ typedef struct VncJobQueue VncJobQueue; /* * We use a single global queue, but most of the functions are - * already reetrant, so we can easilly add more than one encoding thread + * already reentrant, so we can easily add more than one encoding thread */ static VncJobQueue *queue; @@ -187,7 +187,8 @@ static void vnc_async_encoding_start(VncState *orig, VncState *local) local->vd = orig->vd; local->lossy_rect = orig->lossy_rect; local->write_pixels = orig->write_pixels; - local->clientds = orig->clientds; + local->client_pf = orig->client_pf; + local->client_be = orig->client_be; local->tight = orig->tight; local->zlib = orig->zlib; local->hextile = orig->hextile; @@ -320,6 +321,11 @@ static void *vnc_worker_thread(void *arg) return NULL; } +static bool vnc_worker_thread_running(void) +{ + return queue; /* Check global queue */ +} + void vnc_start_worker_thread(void) { VncJobQueue *q; @@ -332,11 +338,6 @@ void vnc_start_worker_thread(void) queue = q; /* Set global queue */ } -bool vnc_worker_thread_running(void) -{ - return queue; /* Check global queue */ -} - void vnc_stop_worker_thread(void) { if (!vnc_worker_thread_running()) diff --git a/ui/vnc-jobs.h b/ui/vnc-jobs.h index 86e6d888c6..31da103fac 100644 --- a/ui/vnc-jobs.h +++ b/ui/vnc-jobs.h @@ -40,7 +40,6 @@ void vnc_jobs_join(VncState *vs); void vnc_jobs_consume_buffer(VncState *vs); void vnc_start_worker_thread(void); -bool vnc_worker_thread_running(void); void vnc_stop_worker_thread(void); /* Locks */ diff --git a/ui/vnc-palette.c b/ui/vnc-palette.c index 63d5f64917..c130deee9d 100644 --- a/ui/vnc-palette.c +++ b/ui/vnc-palette.c @@ -27,6 +27,8 @@ */ #include "vnc-palette.h" +#include <glib.h> +#include <string.h> static VncPaletteEntry *palette_find(const VncPalette *palette, uint32_t color, unsigned int hash) diff --git a/ui/vnc-palette.h b/ui/vnc-palette.h index 3260885ff0..d02f0236c1 100644 --- a/ui/vnc-palette.h +++ b/ui/vnc-palette.h @@ -29,9 +29,10 @@ #ifndef VNC_PALETTE_H #define VNC_PALETTE_H -#include "qlist.h" -#include "qemu-queue.h" +#include "qapi/qmp/qlist.h" +#include "qemu/queue.h" #include <stdint.h> +#include <stdbool.h> #define VNC_PALETTE_HASH_SIZE 256 #define VNC_PALETTE_MAX_SIZE 256 diff --git a/ui/vnc-tls.c b/ui/vnc-tls.c index 3aaa93928a..56292636d7 100644 --- a/ui/vnc-tls.c +++ b/ui/vnc-tls.c @@ -26,7 +26,7 @@ #include "qemu-x509.h" #include "vnc.h" -#include "qemu_socket.h" +#include "qemu/sockets.h" #if defined(_VNC_DEBUG) && _VNC_DEBUG >= 2 /* Very verbose, so only enabled for _VNC_DEBUG >= 2 */ @@ -49,7 +49,7 @@ static int vnc_tls_initialize(void) if (gnutls_global_init () < 0) return 0; - /* XXX ought to re-generate diffie-hellmen params periodically */ + /* XXX ought to re-generate diffie-hellman params periodically */ if (gnutls_dh_params_init (&dh_params) < 0) return 0; if (gnutls_dh_params_generate2 (dh_params, DH_BITS) < 0) diff --git a/ui/vnc-tls.h b/ui/vnc-tls.h index 2b93633896..36a2227fec 100644 --- a/ui/vnc-tls.h +++ b/ui/vnc-tls.h @@ -31,7 +31,7 @@ #include <gnutls/gnutls.h> #include <gnutls/x509.h> -#include "acl.h" +#include "qemu/acl.h" enum { VNC_WIREMODE_CLEAR, @@ -26,13 +26,13 @@ #include "vnc.h" #include "vnc-jobs.h" -#include "sysemu.h" -#include "qemu_socket.h" -#include "qemu-timer.h" -#include "acl.h" -#include "qemu-objects.h" +#include "sysemu/sysemu.h" +#include "qemu/sockets.h" +#include "qemu/timer.h" +#include "qemu/acl.h" +#include "qapi/qmp/types.h" #include "qmp-commands.h" -#include "osdep.h" +#include "qemu/osdep.h" #define VNC_REFRESH_INTERVAL_BASE 30 #define VNC_REFRESH_INTERVAL_INC 50 @@ -372,6 +372,10 @@ VncInfo *qmp_query_vnc(Error **errp) } } + if (vnc_display->lsock == -1) { + return info; + } + if (getsockname(vnc_display->lsock, (struct sockaddr *)&sa, &salen) == -1) { error_set(errp, QERR_UNDEFINED_ERROR); @@ -432,6 +436,8 @@ static void vnc_dpy_update(DisplayState *ds, int x, int y, int w, int h) int i; VncDisplay *vd = ds->opaque; struct VncSurface *s = &vd->guest; + int width = ds_get_width(ds); + int height = ds_get_height(ds); h += y; @@ -442,10 +448,10 @@ static void vnc_dpy_update(DisplayState *ds, int x, int y, int w, int h) w += (x % 16); x -= (x % 16); - x = MIN(x, s->ds->width); - y = MIN(y, s->ds->height); - w = MIN(x + w, s->ds->width) - x; - h = MIN(h, s->ds->height); + x = MIN(x, width); + y = MIN(y, height); + w = MIN(x + w, width) - x; + h = MIN(h, height); for (; y < h; y++) for (i = 0; i < w; i += 16) @@ -475,12 +481,12 @@ void buffer_reserve(Buffer *buffer, size_t len) } } -int buffer_empty(Buffer *buffer) +static int buffer_empty(Buffer *buffer) { return buffer->offset == 0; } -uint8_t *buffer_end(Buffer *buffer) +static uint8_t *buffer_end(Buffer *buffer) { return buffer->buffer + buffer->offset; } @@ -546,6 +552,21 @@ static void vnc_abort_display_jobs(VncDisplay *vd) } } +int vnc_server_fb_stride(VncDisplay *vd) +{ + return pixman_image_get_stride(vd->server); +} + +void *vnc_server_fb_ptr(VncDisplay *vd, int x, int y) +{ + uint8_t *ptr; + + ptr = (uint8_t *)pixman_image_get_data(vd->server); + ptr += y * vnc_server_fb_stride(vd); + ptr += x * VNC_SERVER_FB_BYTES; + return ptr; +} + static void vnc_dpy_resize(DisplayState *ds) { VncDisplay *vd = ds->opaque; @@ -554,20 +575,20 @@ static void vnc_dpy_resize(DisplayState *ds) vnc_abort_display_jobs(vd); /* server surface */ - if (!vd->server) - vd->server = g_malloc0(sizeof(*vd->server)); - if (vd->server->data) - g_free(vd->server->data); - *(vd->server) = *(ds->surface); - vd->server->data = g_malloc0(vd->server->linesize * - vd->server->height); + qemu_pixman_image_unref(vd->server); + vd->server = pixman_image_create_bits(VNC_SERVER_FB_FORMAT, + ds_get_width(ds), + ds_get_height(ds), + NULL, 0); /* guest surface */ - if (!vd->guest.ds) - vd->guest.ds = g_malloc0(sizeof(*vd->guest.ds)); +#if 0 /* FIXME */ if (ds_get_bytes_per_pixel(ds) != vd->guest.ds->pf.bytes_per_pixel) console_color_init(ds); - *(vd->guest.ds) = *(ds->surface); +#endif + qemu_pixman_image_unref(vd->guest.fb); + vd->guest.fb = pixman_image_ref(ds->surface->image); + vd->guest.format = ds->surface->format; memset(vd->guest.dirty, 0xFF, sizeof(vd->guest.dirty)); QTAILQ_FOREACH(vs, &vd->clients, next) { @@ -581,7 +602,7 @@ static void vnc_dpy_resize(DisplayState *ds) } /* fastest code */ -static void vnc_write_pixels_copy(VncState *vs, struct PixelFormat *pf, +static void vnc_write_pixels_copy(VncState *vs, void *pixels, int size) { vnc_write(vs, pixels, size); @@ -591,23 +612,23 @@ static void vnc_write_pixels_copy(VncState *vs, struct PixelFormat *pf, void vnc_convert_pixel(VncState *vs, uint8_t *buf, uint32_t v) { uint8_t r, g, b; - VncDisplay *vd = vs->vd; - r = ((((v & vd->server->pf.rmask) >> vd->server->pf.rshift) << vs->clientds.pf.rbits) >> - vd->server->pf.rbits); - g = ((((v & vd->server->pf.gmask) >> vd->server->pf.gshift) << vs->clientds.pf.gbits) >> - vd->server->pf.gbits); - b = ((((v & vd->server->pf.bmask) >> vd->server->pf.bshift) << vs->clientds.pf.bbits) >> - vd->server->pf.bbits); - v = (r << vs->clientds.pf.rshift) | - (g << vs->clientds.pf.gshift) | - (b << vs->clientds.pf.bshift); - switch(vs->clientds.pf.bytes_per_pixel) { +#if VNC_SERVER_FB_FORMAT == PIXMAN_FORMAT(32, PIXMAN_TYPE_ARGB, 0, 8, 8, 8) + r = (((v & 0x00ff0000) >> 16) << vs->client_pf.rbits) >> 8; + g = (((v & 0x0000ff00) >> 8) << vs->client_pf.gbits) >> 8; + b = (((v & 0x000000ff) >> 0) << vs->client_pf.bbits) >> 8; +#else +# error need some bits here if you change VNC_SERVER_FB_FORMAT +#endif + v = (r << vs->client_pf.rshift) | + (g << vs->client_pf.gshift) | + (b << vs->client_pf.bshift); + switch (vs->client_pf.bytes_per_pixel) { case 1: buf[0] = v; break; case 2: - if (vs->clientds.flags & QEMU_BIG_ENDIAN_FLAG) { + if (vs->client_be) { buf[0] = v >> 8; buf[1] = v; } else { @@ -617,7 +638,7 @@ void vnc_convert_pixel(VncState *vs, uint8_t *buf, uint32_t v) break; default: case 4: - if (vs->clientds.flags & QEMU_BIG_ENDIAN_FLAG) { + if (vs->client_be) { buf[0] = v >> 24; buf[1] = v >> 16; buf[2] = v >> 8; @@ -632,37 +653,19 @@ void vnc_convert_pixel(VncState *vs, uint8_t *buf, uint32_t v) } } -static void vnc_write_pixels_generic(VncState *vs, struct PixelFormat *pf, +static void vnc_write_pixels_generic(VncState *vs, void *pixels1, int size) { uint8_t buf[4]; - if (pf->bytes_per_pixel == 4) { + if (VNC_SERVER_FB_BYTES == 4) { uint32_t *pixels = pixels1; int n, i; n = size >> 2; - for(i = 0; i < n; i++) { + for (i = 0; i < n; i++) { vnc_convert_pixel(vs, buf, pixels[i]); - vnc_write(vs, buf, vs->clientds.pf.bytes_per_pixel); + vnc_write(vs, buf, vs->client_pf.bytes_per_pixel); } - } else if (pf->bytes_per_pixel == 2) { - uint16_t *pixels = pixels1; - int n, i; - n = size >> 1; - for(i = 0; i < n; i++) { - vnc_convert_pixel(vs, buf, pixels[i]); - vnc_write(vs, buf, vs->clientds.pf.bytes_per_pixel); - } - } else if (pf->bytes_per_pixel == 1) { - uint8_t *pixels = pixels1; - int n, i; - n = size; - for(i = 0; i < n; i++) { - vnc_convert_pixel(vs, buf, pixels[i]); - vnc_write(vs, buf, vs->clientds.pf.bytes_per_pixel); - } - } else { - fprintf(stderr, "vnc_write_pixels_generic: VncState color depth not supported\n"); } } @@ -672,10 +675,10 @@ int vnc_raw_send_framebuffer_update(VncState *vs, int x, int y, int w, int h) uint8_t *row; VncDisplay *vd = vs->vd; - row = vd->server->data + y * ds_get_linesize(vs->ds) + x * ds_get_bytes_per_pixel(vs->ds); + row = vnc_server_fb_ptr(vd, x, y); for (i = 0; i < h; i++) { - vs->write_pixels(vs, &vd->server->pf, row, w * ds_get_bytes_per_pixel(vs->ds)); - row += ds_get_linesize(vs->ds); + vs->write_pixels(vs, row, w * VNC_SERVER_FB_BYTES); + row += vnc_server_fb_stride(vd); } return 1; } @@ -732,7 +735,7 @@ static void vnc_dpy_copy(DisplayState *ds, int src_x, int src_y, int dst_x, int VncState *vs, *vn; uint8_t *src_row; uint8_t *dst_row; - int i,x,y,pitch,depth,inc,w_lim,s; + int i, x, y, pitch, inc, w_lim, s; int cmp_bytes; vnc_refresh_server_surface(vd); @@ -745,10 +748,9 @@ static void vnc_dpy_copy(DisplayState *ds, int src_x, int src_y, int dst_x, int } /* do bitblit op on the local surface too */ - pitch = ds_get_linesize(vd->ds); - depth = ds_get_bytes_per_pixel(vd->ds); - src_row = vd->server->data + pitch * src_y + depth * src_x; - dst_row = vd->server->data + pitch * dst_y + depth * dst_x; + pitch = vnc_server_fb_stride(vd); + src_row = vnc_server_fb_ptr(vd, src_x, src_y); + dst_row = vnc_server_fb_ptr(vd, dst_x, dst_y); y = dst_y; inc = 1; if (dst_y > src_y) { @@ -776,7 +778,7 @@ static void vnc_dpy_copy(DisplayState *ds, int src_x, int src_y, int dst_x, int } else { s = 16; } - cmp_bytes = s * depth; + cmp_bytes = s * VNC_SERVER_FB_BYTES; if (memcmp(src_row, dst_row, cmp_bytes) == 0) continue; memmove(dst_row, src_row, cmp_bytes); @@ -786,8 +788,8 @@ static void vnc_dpy_copy(DisplayState *ds, int src_x, int src_y, int dst_x, int } } } - src_row += pitch - w * depth; - dst_row += pitch - w * depth; + src_row += pitch - w * VNC_SERVER_FB_BYTES; + dst_row += pitch - w * VNC_SERVER_FB_BYTES; y += inc; } @@ -798,7 +800,7 @@ static void vnc_dpy_copy(DisplayState *ds, int src_x, int src_y, int dst_x, int } } -static void vnc_mouse_set(int x, int y, int visible) +static void vnc_mouse_set(DisplayState *ds, int x, int y, int visible) { /* can we ask the client(s) to move the pointer ??? */ } @@ -806,7 +808,6 @@ static void vnc_mouse_set(int x, int y, int visible) static int vnc_cursor_define(VncState *vs) { QEMUCursor *c = vs->vd->cursor; - PixelFormat pf = qemu_default_pixelformat(32); int isize; if (vnc_has_feature(vs, VNC_FEATURE_RICH_CURSOR)) { @@ -816,8 +817,8 @@ static int vnc_cursor_define(VncState *vs) vnc_write_u16(vs, 1); /* # of rects */ vnc_framebuffer_update(vs, c->hot_x, c->hot_y, c->width, c->height, VNC_ENCODING_RICH_CURSOR); - isize = c->width * c->height * vs->clientds.pf.bytes_per_pixel; - vnc_write_pixels_generic(vs, &pf, c->data, isize); + isize = c->width * c->height * vs->client_pf.bytes_per_pixel; + vnc_write_pixels_generic(vs, c->data, isize); vnc_write(vs, vs->vd->cursor_mask, vs->vd->cursor_msize); vnc_unlock_output(vs); return 0; @@ -825,7 +826,7 @@ static int vnc_cursor_define(VncState *vs) return -1; } -static void vnc_dpy_cursor_define(QEMUCursor *c) +static void vnc_dpy_cursor_define(DisplayState *ds, QEMUCursor *c) { VncDisplay *vd = vnc_display; VncState *vs; @@ -894,8 +895,8 @@ static int vnc_update_client(VncState *vs, int has_dirty) */ job = vnc_job_new(vs); - width = MIN(vd->server->width, vs->client_width); - height = MIN(vd->server->height, vs->client_height); + width = MIN(pixman_image_get_width(vd->server), vs->client_width); + height = MIN(pixman_image_get_height(vd->server), vs->client_height); for (y = 0; y < height; y++) { int x; @@ -1372,17 +1373,17 @@ void vnc_flush(VncState *vs) vnc_unlock_output(vs); } -uint8_t read_u8(uint8_t *data, size_t offset) +static uint8_t read_u8(uint8_t *data, size_t offset) { return data[offset]; } -uint16_t read_u16(uint8_t *data, size_t offset) +static uint16_t read_u16(uint8_t *data, size_t offset) { return ((data[offset] & 0xFF) << 8) | (data[offset + 1] & 0xFF); } -int32_t read_s32(uint8_t *data, size_t offset) +static int32_t read_s32(uint8_t *data, size_t offset) { return (int32_t)((data[offset] << 24) | (data[offset + 1] << 16) | (data[offset + 2] << 8) | data[offset + 3]); @@ -1802,10 +1803,12 @@ static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings) vs->features |= VNC_FEATURE_TIGHT_MASK; vs->vnc_encoding = enc; break; +#ifdef CONFIG_VNC_PNG case VNC_ENCODING_TIGHT_PNG: vs->features |= VNC_FEATURE_TIGHT_PNG_MASK; vs->vnc_encoding = enc; break; +#endif case VNC_ENCODING_ZLIB: vs->features |= VNC_FEATURE_ZLIB_MASK; vs->vnc_encoding = enc; @@ -1855,9 +1858,9 @@ static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings) static void set_pixel_conversion(VncState *vs) { - if ((vs->clientds.flags & QEMU_BIG_ENDIAN_FLAG) == - (vs->ds->surface->flags & QEMU_BIG_ENDIAN_FLAG) && - !memcmp(&(vs->clientds.pf), &(vs->ds->surface->pf), sizeof(PixelFormat))) { + pixman_format_code_t fmt = qemu_pixman_get_format(&vs->client_pf); + + if (fmt == VNC_SERVER_FB_FORMAT) { vs->write_pixels = vnc_write_pixels_copy; vnc_hextile_set_pixel_conversion(vs, 0); } else { @@ -1877,23 +1880,22 @@ static void set_pixel_format(VncState *vs, return; } - vs->clientds = *(vs->vd->guest.ds); - vs->clientds.pf.rmax = red_max; - vs->clientds.pf.rbits = hweight_long(red_max); - vs->clientds.pf.rshift = red_shift; - vs->clientds.pf.rmask = red_max << red_shift; - vs->clientds.pf.gmax = green_max; - vs->clientds.pf.gbits = hweight_long(green_max); - vs->clientds.pf.gshift = green_shift; - vs->clientds.pf.gmask = green_max << green_shift; - vs->clientds.pf.bmax = blue_max; - vs->clientds.pf.bbits = hweight_long(blue_max); - vs->clientds.pf.bshift = blue_shift; - vs->clientds.pf.bmask = blue_max << blue_shift; - vs->clientds.pf.bits_per_pixel = bits_per_pixel; - vs->clientds.pf.bytes_per_pixel = bits_per_pixel / 8; - vs->clientds.pf.depth = bits_per_pixel == 32 ? 24 : bits_per_pixel; - vs->clientds.flags = big_endian_flag ? QEMU_BIG_ENDIAN_FLAG : 0x00; + vs->client_pf.rmax = red_max; + vs->client_pf.rbits = hweight_long(red_max); + vs->client_pf.rshift = red_shift; + vs->client_pf.rmask = red_max << red_shift; + vs->client_pf.gmax = green_max; + vs->client_pf.gbits = hweight_long(green_max); + vs->client_pf.gshift = green_shift; + vs->client_pf.gmask = green_max << green_shift; + vs->client_pf.bmax = blue_max; + vs->client_pf.bbits = hweight_long(blue_max); + vs->client_pf.bshift = blue_shift; + vs->client_pf.bmask = blue_max << blue_shift; + vs->client_pf.bits_per_pixel = bits_per_pixel; + vs->client_pf.bytes_per_pixel = bits_per_pixel / 8; + vs->client_pf.depth = bits_per_pixel == 32 ? 24 : bits_per_pixel; + vs->client_be = big_endian_flag; set_pixel_conversion(vs); @@ -1904,8 +1906,10 @@ static void set_pixel_format(VncState *vs, static void pixel_format_message (VncState *vs) { char pad[3] = { 0, 0, 0 }; - vnc_write_u8(vs, vs->ds->surface->pf.bits_per_pixel); /* bits-per-pixel */ - vnc_write_u8(vs, vs->ds->surface->pf.depth); /* depth */ + vs->client_pf = qemu_default_pixelformat(32); + + vnc_write_u8(vs, vs->client_pf.bits_per_pixel); /* bits-per-pixel */ + vnc_write_u8(vs, vs->client_pf.depth); /* depth */ #ifdef HOST_WORDS_BIGENDIAN vnc_write_u8(vs, 1); /* big-endian-flag */ @@ -1913,27 +1917,25 @@ static void pixel_format_message (VncState *vs) { vnc_write_u8(vs, 0); /* big-endian-flag */ #endif vnc_write_u8(vs, 1); /* true-color-flag */ - vnc_write_u16(vs, vs->ds->surface->pf.rmax); /* red-max */ - vnc_write_u16(vs, vs->ds->surface->pf.gmax); /* green-max */ - vnc_write_u16(vs, vs->ds->surface->pf.bmax); /* blue-max */ - vnc_write_u8(vs, vs->ds->surface->pf.rshift); /* red-shift */ - vnc_write_u8(vs, vs->ds->surface->pf.gshift); /* green-shift */ - vnc_write_u8(vs, vs->ds->surface->pf.bshift); /* blue-shift */ + vnc_write_u16(vs, vs->client_pf.rmax); /* red-max */ + vnc_write_u16(vs, vs->client_pf.gmax); /* green-max */ + vnc_write_u16(vs, vs->client_pf.bmax); /* blue-max */ + vnc_write_u8(vs, vs->client_pf.rshift); /* red-shift */ + vnc_write_u8(vs, vs->client_pf.gshift); /* green-shift */ + vnc_write_u8(vs, vs->client_pf.bshift); /* blue-shift */ + vnc_write(vs, pad, 3); /* padding */ vnc_hextile_set_pixel_conversion(vs, 0); - - vs->clientds = *(vs->ds->surface); - vs->clientds.flags &= ~QEMU_ALLOCATED_FLAG; vs->write_pixels = vnc_write_pixels_copy; - - vnc_write(vs, pad, 3); /* padding */ } static void vnc_dpy_setdata(DisplayState *ds) { VncDisplay *vd = ds->opaque; - *(vd->guest.ds) = *(ds->surface); + qemu_pixman_image_unref(vd->guest.fb); + vd->guest.fb = pixman_image_ref(ds->surface->image); + vd->guest.format = ds->surface->format; vnc_dpy_update(ds, 0, 0, ds_get_width(ds), ds_get_height(ds)); } @@ -2437,12 +2439,14 @@ static int vnc_refresh_lossy_rect(VncDisplay *vd, int x, int y) static int vnc_update_stats(VncDisplay *vd, struct timeval * tv) { + int width = pixman_image_get_width(vd->guest.fb); + int height = pixman_image_get_height(vd->guest.fb); int x, y; struct timeval res; int has_dirty = 0; - for (y = 0; y < vd->guest.ds->height; y += VNC_STAT_RECT) { - for (x = 0; x < vd->guest.ds->width; x += VNC_STAT_RECT) { + for (y = 0; y < height; y += VNC_STAT_RECT) { + for (x = 0; x < width; x += VNC_STAT_RECT) { VncRectStat *rect = vnc_stat_rect(vd, x, y); rect->updated = false; @@ -2456,8 +2460,8 @@ static int vnc_update_stats(VncDisplay *vd, struct timeval * tv) } vd->guest.last_freq_check = *tv; - for (y = 0; y < vd->guest.ds->height; y += VNC_STAT_RECT) { - for (x = 0; x < vd->guest.ds->width; x += VNC_STAT_RECT) { + for (y = 0; y < height; y += VNC_STAT_RECT) { + for (x = 0; x < width; x += VNC_STAT_RECT) { VncRectStat *rect= vnc_stat_rect(vd, x, y); int count = ARRAY_SIZE(rect->times); struct timeval min, max; @@ -2526,12 +2530,15 @@ static void vnc_rect_updated(VncDisplay *vd, int x, int y, struct timeval * tv) static int vnc_refresh_server_surface(VncDisplay *vd) { + int width = pixman_image_get_width(vd->guest.fb); + int height = pixman_image_get_height(vd->guest.fb); int y; uint8_t *guest_row; uint8_t *server_row; int cmp_bytes; VncState *vs; int has_dirty = 0; + pixman_image_t *tmpbuf = NULL; struct timeval tv = { 0, 0 }; @@ -2545,22 +2552,31 @@ static int vnc_refresh_server_surface(VncDisplay *vd) * Check and copy modified bits from guest to server surface. * Update server dirty map. */ - cmp_bytes = 16 * ds_get_bytes_per_pixel(vd->ds); - if (cmp_bytes > vd->ds->surface->linesize) { - cmp_bytes = vd->ds->surface->linesize; + cmp_bytes = 64; + if (cmp_bytes > vnc_server_fb_stride(vd)) { + cmp_bytes = vnc_server_fb_stride(vd); + } + if (vd->guest.format != VNC_SERVER_FB_FORMAT) { + int width = pixman_image_get_width(vd->server); + tmpbuf = qemu_pixman_linebuf_create(VNC_SERVER_FB_FORMAT, width); } - guest_row = vd->guest.ds->data; - server_row = vd->server->data; - for (y = 0; y < vd->guest.ds->height; y++) { + guest_row = (uint8_t *)pixman_image_get_data(vd->guest.fb); + server_row = (uint8_t *)pixman_image_get_data(vd->server); + for (y = 0; y < height; y++) { if (!bitmap_empty(vd->guest.dirty[y], VNC_DIRTY_BITS)) { int x; uint8_t *guest_ptr; uint8_t *server_ptr; - guest_ptr = guest_row; + if (vd->guest.format != VNC_SERVER_FB_FORMAT) { + qemu_pixman_linebuf_fill(tmpbuf, vd->guest.fb, width, 0, y); + guest_ptr = (uint8_t *)pixman_image_get_data(tmpbuf); + } else { + guest_ptr = guest_row; + } server_ptr = server_row; - for (x = 0; x + 15 < vd->guest.ds->width; + for (x = 0; x + 15 < width; x += 16, guest_ptr += cmp_bytes, server_ptr += cmp_bytes) { if (!test_and_clear_bit((x / 16), vd->guest.dirty[y])) continue; @@ -2575,9 +2591,10 @@ static int vnc_refresh_server_surface(VncDisplay *vd) has_dirty++; } } - guest_row += ds_get_linesize(vd->ds); - server_row += ds_get_linesize(vd->ds); + guest_row += pixman_image_get_stride(vd->guest.fb); + server_row += pixman_image_get_stride(vd->server); } + qemu_pixman_image_unref(tmpbuf); return has_dirty; } @@ -2747,17 +2764,17 @@ void vnc_display_init(DisplayState *ds) qemu_mutex_init(&vs->mutex); vnc_start_worker_thread(); - dcl->dpy_copy = vnc_dpy_copy; - dcl->dpy_update = vnc_dpy_update; - dcl->dpy_resize = vnc_dpy_resize; - dcl->dpy_setdata = vnc_dpy_setdata; + dcl->dpy_gfx_copy = vnc_dpy_copy; + dcl->dpy_gfx_update = vnc_dpy_update; + dcl->dpy_gfx_resize = vnc_dpy_resize; + dcl->dpy_gfx_setdata = vnc_dpy_setdata; + dcl->dpy_mouse_set = vnc_mouse_set; + dcl->dpy_cursor_define = vnc_dpy_cursor_define; register_displaychangelistener(ds, dcl); - ds->mouse_set = vnc_mouse_set; - ds->cursor_define = vnc_dpy_cursor_define; } -void vnc_display_close(DisplayState *ds) +static void vnc_display_close(DisplayState *ds) { VncDisplay *vs = ds ? (VncDisplay *)ds->opaque : vnc_display; @@ -2779,7 +2796,7 @@ void vnc_display_close(DisplayState *ds) #endif } -int vnc_display_disable_login(DisplayState *ds) +static int vnc_display_disable_login(DisplayState *ds) { VncDisplay *vs = ds ? (VncDisplay *)ds->opaque : vnc_display; @@ -2844,7 +2861,7 @@ char *vnc_display_local_addr(DisplayState *ds) return vnc_socket_local_addr("%s:%s", vs->lsock); } -int vnc_display_open(DisplayState *ds, const char *display) +void vnc_display_open(DisplayState *ds, const char *display, Error **errp) { VncDisplay *vs = ds ? (VncDisplay *)ds->opaque : vnc_display; const char *options; @@ -2862,14 +2879,15 @@ int vnc_display_open(DisplayState *ds, const char *display) #endif int lock_key_sync = 1; - if (!vnc_display) - return -1; + if (!vnc_display) { + error_setg(errp, "VNC display not active"); + return; + } vnc_display_close(ds); if (strcmp(display, "none") == 0) - return 0; + return; - if (!(vs->display = strdup(display))) - return -1; + vs->display = g_strdup(display); vs->share_policy = VNC_SHARE_POLICY_ALLOW_EXCLUSIVE; options = display; @@ -2877,13 +2895,11 @@ int vnc_display_open(DisplayState *ds, const char *display) options++; if (strncmp(options, "password", 8) == 0) { if (fips_get_state()) { - fprintf(stderr, - "VNC password auth disabled due to FIPS mode, " - "consider using the VeNCrypt or SASL authentication " - "methods as an alternative\n"); - g_free(vs->display); - vs->display = NULL; - return -1; + error_setg(errp, + "VNC password auth disabled due to FIPS mode, " + "consider using the VeNCrypt or SASL authentication " + "methods as an alternative"); + goto fail; } password = 1; /* Require password auth */ } else if (strncmp(options, "reverse", 7) == 0) { @@ -2913,18 +2929,14 @@ int vnc_display_open(DisplayState *ds, const char *display) VNC_DEBUG("Trying certificate path '%s'\n", path); if (vnc_tls_set_x509_creds_dir(vs, path) < 0) { - fprintf(stderr, "Failed to find x509 certificates/keys in %s\n", path); + error_setg(errp, "Failed to find x509 certificates/keys in %s", path); g_free(path); - g_free(vs->display); - vs->display = NULL; - return -1; + goto fail; } g_free(path); } else { - fprintf(stderr, "No certificate path provided\n"); - g_free(vs->display); - vs->display = NULL; - return -1; + error_setg(errp, "No certificate path provided"); + goto fail; } #endif #if defined(CONFIG_VNC_TLS) || defined(CONFIG_VNC_SASL) @@ -2933,7 +2945,7 @@ int vnc_display_open(DisplayState *ds, const char *display) #endif } else if (strncmp(options, "lossy", 5) == 0) { vs->lossy = true; - } else if (strncmp(options, "non-adapative", 13) == 0) { + } else if (strncmp(options, "non-adaptive", 12) == 0) { vs->non_adaptive = true; } else if (strncmp(options, "share=", 6) == 0) { if (strncmp(options+6, "ignore", 6) == 0) { @@ -2943,10 +2955,8 @@ int vnc_display_open(DisplayState *ds, const char *display) } else if (strncmp(options+6, "force-shared", 12) == 0) { vs->share_policy = VNC_SHARE_POLICY_FORCE_SHARED; } else { - fprintf(stderr, "unknown vnc share= option\n"); - g_free(vs->display); - vs->display = NULL; - return -1; + error_setg(errp, "unknown vnc share= option"); + goto fail; } } } @@ -3047,52 +3057,50 @@ int vnc_display_open(DisplayState *ds, const char *display) #ifdef CONFIG_VNC_SASL if ((saslErr = sasl_server_init(NULL, "qemu")) != SASL_OK) { - fprintf(stderr, "Failed to initialize SASL auth %s", - sasl_errstring(saslErr, NULL, NULL)); - g_free(vs->display); - vs->display = NULL; - return -1; + error_setg(errp, "Failed to initialize SASL auth: %s", + sasl_errstring(saslErr, NULL, NULL)); + goto fail; } #endif vs->lock_key_sync = lock_key_sync; if (reverse) { /* connect to viewer */ - if (strncmp(display, "unix:", 5) == 0) - vs->lsock = unix_connect(display+5); - else - vs->lsock = inet_connect(display, true, NULL, NULL); - if (-1 == vs->lsock) { - g_free(vs->display); - vs->display = NULL; - return -1; + int csock; + vs->lsock = -1; + if (strncmp(display, "unix:", 5) == 0) { + csock = unix_connect(display+5, errp); } else { - int csock = vs->lsock; - vs->lsock = -1; - vnc_connect(vs, csock, 0); + csock = inet_connect(display, errp); } - return 0; - + if (csock < 0) { + goto fail; + } + vnc_connect(vs, csock, 0); } else { /* listen for connects */ char *dpy; dpy = g_malloc(256); if (strncmp(display, "unix:", 5) == 0) { pstrcpy(dpy, 256, "unix:"); - vs->lsock = unix_listen(display+5, dpy+5, 256-5); + vs->lsock = unix_listen(display+5, dpy+5, 256-5, errp); } else { vs->lsock = inet_listen(display, dpy, 256, - SOCK_STREAM, 5900, NULL); + SOCK_STREAM, 5900, errp); } - if (-1 == vs->lsock) { + if (vs->lsock < 0) { g_free(dpy); - return -1; - } else { - g_free(vs->display); - vs->display = dpy; + goto fail; } + g_free(vs->display); + vs->display = dpy; + qemu_set_fd_handler2(vs->lsock, NULL, vnc_listen_read, NULL, vs); } - return qemu_set_fd_handler2(vs->lsock, NULL, vnc_listen_read, NULL, vs); + return; + +fail: + g_free(vs->display); + vs->display = NULL; } void vnc_display_add_client(DisplayState *ds, int csock, int skipauth) @@ -28,12 +28,12 @@ #define __QEMU_VNC_H #include "qemu-common.h" -#include "qemu-queue.h" -#include "qemu-thread.h" -#include "console.h" -#include "monitor.h" +#include "qemu/queue.h" +#include "qemu/thread.h" +#include "ui/console.h" +#include "monitor/monitor.h" #include "audio/audio.h" -#include "bitmap.h" +#include "qemu/bitmap.h" #include <zlib.h> #include <stdbool.h> @@ -69,7 +69,7 @@ typedef struct VncRectEntry VncRectEntry; typedef int VncReadEvent(VncState *vs, uint8_t *data, size_t len); -typedef void VncWritePixels(VncState *vs, struct PixelFormat *pf, void *data, int size); +typedef void VncWritePixels(VncState *vs, void *data, int size); typedef void VncSendHextileTile(VncState *vs, int x, int y, int w, int h, @@ -117,7 +117,8 @@ struct VncSurface struct timeval last_freq_check; DECLARE_BITMAP(dirty[VNC_MAX_HEIGHT], VNC_MAX_WIDTH / 16); VncRectStat stats[VNC_STAT_ROWS][VNC_STAT_COLS]; - DisplaySurface *ds; + pixman_image_t *fb; + pixman_format_code_t format; }; typedef enum VncShareMode { @@ -151,7 +152,7 @@ struct VncDisplay uint8_t *cursor_mask; struct VncSurface guest; /* guest visible surface (aka ds->surface) */ - DisplaySurface *server; /* vnc server surface */ + pixman_image_t *server; /* vnc server surface */ char *display; char *password; @@ -275,7 +276,9 @@ struct VncState Buffer input; /* current output mode information */ VncWritePixels *write_pixels; - DisplaySurface clientds; + PixelFormat client_pf; + pixman_format_code_t client_format; + bool client_be; CaptureVoiceOut *audio_cap; struct audsettings as; @@ -493,9 +496,6 @@ void vnc_read_when(VncState *vs, VncReadEvent *func, size_t expecting); /* Buffer I/O functions */ -uint8_t read_u8(uint8_t *data, size_t offset); -uint16_t read_u16(uint8_t *data, size_t offset); -int32_t read_s32(uint8_t *data, size_t offset); uint32_t read_u32(uint8_t *data, size_t offset); /* Protocol stage functions */ @@ -507,8 +507,6 @@ void start_auth_vnc(VncState *vs); /* Buffer management */ void buffer_reserve(Buffer *buffer, size_t len); -int buffer_empty(Buffer *buffer); -uint8_t *buffer_end(Buffer *buffer); void buffer_reset(Buffer *buffer); void buffer_free(Buffer *buffer); void buffer_append(Buffer *buffer, const void *data, size_t len); @@ -527,6 +525,14 @@ static inline uint32_t vnc_has_feature(VncState *vs, int feature) { void vnc_framebuffer_update(VncState *vs, int x, int y, int w, int h, int32_t encoding); +/* server fb is in PIXMAN_x8r8g8b8 */ +#define VNC_SERVER_FB_FORMAT PIXMAN_FORMAT(32, PIXMAN_TYPE_ARGB, 0, 8, 8, 8) +#define VNC_SERVER_FB_BITS (PIXMAN_FORMAT_BPP(VNC_SERVER_FB_FORMAT)) +#define VNC_SERVER_FB_BYTES ((VNC_SERVER_FB_BITS+7)/8) + +void *vnc_server_fb_ptr(VncDisplay *vd, int x, int y); +int vnc_server_fb_stride(VncDisplay *vd); + void vnc_convert_pixel(VncState *vs, uint8_t *buf, uint32_t v); double vnc_update_freq(VncState *vs, int x, int y, int w, int h); void vnc_sent_lossy_rect(VncState *vs, int x, int y, int w, int h); |