Commit 4ba79505 authored by Anthony Liguori's avatar Anthony Liguori
Browse files

Merge remote-tracking branch 'kraxel/pixman.v3' into staging



* kraxel/pixman.v3: (22 commits)
  pixman: drop obsolete fields from DisplaySurface
  pixman/vnc: remove dead code.
  pixman/vnc: remove rgb_prepare_row* functions
  pixman/vnc: use pixman images in vnc.
  pixman: switch screendump function.
  vga: stop direct access to DisplaySurface fields.
  qxl: stop direct access to DisplaySurface fields.
  console: don't set PixelFormat alpha fields for 32bpp
  console: make qemu_alloc_display static
  pixman: add pixman image to DisplaySurface
  pixman: helper functions
  pixman: windup in configure & makefiles
  pixman: add submodule
  console: remove DisplayAllocator
  console: remove dpy_gfx_fill
  vga: fix text mode updating
  console: init displaychangelisteners on register
  console: untangle gfx & txt updates
  console: s/TextConsole/QemuConsole/
  console: move set_mouse + cursor_define callbacks
  ...
Signed-off-by: default avatarAnthony Liguori <aliguori@us.ibm.com>
parents d971919f 64f73592
......@@ -19,3 +19,6 @@
[submodule "roms/sgabios"]
path = roms/sgabios
url = git://git.qemu.org/sgabios.git
[submodule "pixman"]
path = pixman
url = git://anongit.freedesktop.org/pixman
......@@ -118,6 +118,15 @@ endif
subdir-libcacard: $(oslib-obj-y) $(trace-obj-y) qemu-timer-common.o
subdir-pixman: pixman/Makefile
$(call quiet-command,$(MAKE) $(SUBDIR_MAKEFLAGS) -C pixman V="$(V)" all,)
pixman/Makefile: $(SRC_PATH)/pixman/configure
(cd pixman; $(SRC_PATH)/pixman/configure --disable-shared --enable-static)
$(SRC_PATH)/pixman/configure:
(cd $(SRC_PATH)/pixman; autoreconf -v --install)
$(filter %-softmmu,$(SUBDIR_RULES)): $(universal-obj-y) $(trace-obj-y) $(common-obj-y) $(extra-obj-y) subdir-libdis
$(filter %-user,$(SUBDIR_RULES)): $(universal-obj-y) $(trace-obj-y) subdir-libdis-user subdir-libuser
......
......@@ -65,6 +65,7 @@ common-obj-y = $(block-obj-y) blockdev.o blockdev-nbd.o block/
common-obj-y += net.o net/
common-obj-y += qom/
common-obj-y += readline.o console.o cursor.o
common-obj-y += qemu-pixman.o
common-obj-y += $(oslib-obj-y)
common-obj-$(CONFIG_WIN32) += os-win32.o
common-obj-$(CONFIG_POSIX) += os-posix.o
......
......@@ -147,6 +147,7 @@ curses=""
docs=""
fdt=""
nptl=""
pixman=""
sdl=""
virtfs=""
vnc="yes"
......@@ -642,6 +643,10 @@ for opt do
# configure to be used by RPM and similar macros that set
# lots of directory switches by default.
;;
--with-system-pixman) pixman="system"
;;
--without-system-pixman) pixman="internal"
;;
--disable-sdl) sdl="no"
;;
--enable-sdl) sdl="yes"
......@@ -2094,6 +2099,34 @@ else
exit 1
fi
##########################################
# pixman support probe
if test "$pixman" = ""; then
if $pkg_config pixman-1 > /dev/null 2>&1; then
pixman="system"
else
pixman="internal"
fi
fi
if test "$pixman" = "system"; then
pixman_cflags=`$pkg_config --cflags pixman-1 2>/dev/null`
pixman_libs=`$pkg_config --libs pixman-1 2>/dev/null`
else
if test ! -d ${source_path}/pixman/pixman; then
echo "ERROR: pixman not present. Your options:"
echo " (1) Prefered: Install the pixman devel package (any recent"
echo " distro should have packages as Xorg needs pixman too)."
echo " (2) Fetch the pixman submodule, using:"
echo " git submodule update --init pixman"
exit 1
fi
pixman_cflags="-I${source_path}/pixman/pixman"
pixman_libs="-Lpixman/pixman/.libs -lpixman-1"
fi
QEMU_CFLAGS="$QEMU_CFLAGS $pixman_cflags"
libs_softmmu="$libs_softmmu $pixman_libs"
##########################################
# libcap probe
......@@ -3142,6 +3175,7 @@ echo "-Werror enabled $werror"
if test "$darwin" = "yes" ; then
echo "Cocoa support $cocoa"
fi
echo "pixman $pixman"
echo "SDL support $sdl"
echo "curses support $curses"
echo "curl support $curl"
......@@ -3908,6 +3942,9 @@ if test "$target_softmmu" = "yes" ; then
if test "$smartcard_nss" = "yes" ; then
echo "subdir-$target: subdir-libcacard" >> $config_host_mak
fi
if test "$pixman" = "internal" ; then
echo "subdir-$target: subdir-pixman" >> $config_host_mak
fi
case "$target_arch2" in
i386|x86_64)
echo "CONFIG_HAVE_CORE_DUMP=y" >> $config_target_mak
......@@ -4111,6 +4148,7 @@ DIRS="$DIRS pc-bios/optionrom pc-bios/spapr-rtas"
DIRS="$DIRS roms/seabios roms/vgabios"
DIRS="$DIRS qapi-generated"
DIRS="$DIRS libcacard libcacard/libcacard libcacard/trace"
DIRS="$DIRS pixman"
FILES="Makefile tests/tcg/Makefile qdict-test-data.txt"
FILES="$FILES tests/tcg/cris/Makefile tests/tcg/cris/.gdbinit"
FILES="$FILES tests/tcg/lm32/Makefile libcacard/Makefile"
......
......@@ -114,20 +114,20 @@ typedef enum {
TEXT_CONSOLE_FIXED_SIZE
} console_type_t;
/* ??? This is mis-named.
It is used for both text and graphical consoles. */
struct TextConsole {
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;
......@@ -161,8 +161,8 @@ struct TextConsole {
};
static DisplayState *display_state;
static TextConsole *active_console;
static TextConsole *consoles[MAX_CONSOLES];
static QemuConsole *active_console;
static QemuConsole *consoles[MAX_CONSOLES];
static int nb_consoles = 0;
void vga_hw_update(void)
......@@ -179,7 +179,7 @@ void vga_hw_invalidate(void)
void qmp_screendump(const char *filename, Error **errp)
{
TextConsole *previous_active_console;
QemuConsole *previous_active_console;
bool cswitch;
previous_active_console = active_console;
......@@ -521,7 +521,7 @@ static void vga_putcharxy(DisplayState *ds, int x, int y, int ch,
}
}
static void text_console_resize(TextConsole *s)
static void text_console_resize(QemuConsole *s)
{
TextCell *cells, *c, *c1;
int w1, x, y, last_width;
......@@ -553,7 +553,7 @@ static void text_console_resize(TextConsole *s)
s->cells = cells;
}
static inline void text_update_xy(TextConsole *s, int x, int y)
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);
......@@ -561,7 +561,7 @@ static inline void text_update_xy(TextConsole *s, int x, int y)
s->text_y[1] = MAX(s->text_y[1], y);
}
static void invalidate_xy(TextConsole *s, int x, int y)
static void invalidate_xy(QemuConsole *s, int x, int y)
{
if (s->update_x0 > x * FONT_WIDTH)
s->update_x0 = x * FONT_WIDTH;
......@@ -573,7 +573,7 @@ static void invalidate_xy(TextConsole *s, int x, int y)
s->update_y1 = (y + 1) * FONT_HEIGHT;
}
static void update_xy(TextConsole *s, int x, int y)
static void update_xy(QemuConsole *s, int x, int y)
{
TextCell *c;
int y1, y2;
......@@ -597,7 +597,7 @@ static void update_xy(TextConsole *s, int x, int y)
}
}
static void console_show_cursor(TextConsole *s, int show)
static void console_show_cursor(QemuConsole *s, int show)
{
TextCell *c;
int y, y1;
......@@ -631,42 +631,45 @@ static void console_show_cursor(TextConsole *s, int show)
}
}
static void console_refresh(TextConsole *s)
static void console_refresh(QemuConsole *s)
{
TextCell *c;
int x, y, y1;
if (s != active_console)
return;
if (!ds_get_bits_per_pixel(s->ds)) {
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;
return;
}
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 (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;
}
}
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));
}
console_show_cursor(s, 1);
dpy_update(s->ds, 0, 0, ds_get_width(s->ds), ds_get_height(s->ds));
}
static void console_scroll(int ydelta)
{
TextConsole *s;
QemuConsole *s;
int i, y1;
s = active_console;
......@@ -698,7 +701,7 @@ static void console_scroll(int ydelta)
console_refresh(s);
}
static void console_put_lf(TextConsole *s)
static void console_put_lf(QemuConsole *s)
{
TextCell *c;
int x, y1;
......@@ -749,7 +752,7 @@ static void console_put_lf(TextConsole *s)
* 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(TextConsole *s)
static void console_handle_escape(QemuConsole *s)
{
int i;
......@@ -842,7 +845,7 @@ static void console_handle_escape(TextConsole *s)
}
}
static void console_clear_xy(TextConsole *s, int x, int y)
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];
......@@ -852,7 +855,7 @@ static void console_clear_xy(TextConsole *s, int x, int y)
}
/* set cursor, checking bounds */
static void set_cursor(TextConsole *s, int x, int y)
static void set_cursor(QemuConsole *s, int x, int y)
{
if (x < 0) {
x = 0;
......@@ -871,7 +874,7 @@ static void set_cursor(TextConsole *s, int x, int y)
s->y = y;
}
static void console_putchar(TextConsole *s, int ch)
static void console_putchar(QemuConsole *s, int ch)
{
TextCell *c;
int y1, i;
......@@ -1078,7 +1081,7 @@ static void console_putchar(TextConsole *s, int ch)
void console_select(unsigned int index)
{
TextConsole *s;
QemuConsole *s;
if (index >= MAX_CONSOLES)
return;
......@@ -1094,24 +1097,24 @@ void console_select(unsigned int index)
qemu_del_timer(active_console->cursor_timer);
}
active_console = s;
if (ds_get_bits_per_pixel(s->ds)) {
if (ds->have_gfx) {
ds->surface = qemu_resize_displaysurface(ds, s->g_width, s->g_height);
} else {
s->ds->surface->width = s->width;
s->ds->surface->height = s->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);
}
dpy_resize(s->ds);
vga_hw_invalidate();
}
}
static int console_puts(CharDriverState *chr, const uint8_t *buf, int len)
{
TextConsole *s = chr->opaque;
QemuConsole *s = chr->opaque;
int i;
s->update_x0 = s->width * FONT_WIDTH;
......@@ -1123,17 +1126,17 @@ static int console_puts(CharDriverState *chr, const uint8_t *buf, int len)
console_putchar(s, buf[i]);
}
console_show_cursor(s, 1);
if (ds_get_bits_per_pixel(s->ds) && s->update_x0 < s->update_x1) {
dpy_update(s->ds, s->update_x0, s->update_y0,
s->update_x1 - s->update_x0,
s->update_y1 - s->update_y0);
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)
{
TextConsole *s = opaque;
QemuConsole *s = opaque;
int len;
uint8_t buf[16];
......@@ -1156,7 +1159,7 @@ static void kbd_send_chars(void *opaque)
/* called when an ascii key is pressed */
void kbd_put_keysym(int keysym)
{
TextConsole *s;
QemuConsole *s;
uint8_t buf[16], *q;
int c;
......@@ -1211,7 +1214,7 @@ void kbd_put_keysym(int keysym)
static void text_console_invalidate(void *opaque)
{
TextConsole *s = (TextConsole *) 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);
......@@ -1222,7 +1225,7 @@ static void text_console_invalidate(void *opaque)
static void text_console_update(void *opaque, console_ch_t *chardata)
{
TextConsole *s = (TextConsole *) opaque;
QemuConsole *s = (QemuConsole *) opaque;
int i, j, src;
if (s->text_x[0] <= s->text_x[1]) {
......@@ -1234,23 +1237,23 @@ static void text_console_update(void *opaque, console_ch_t *chardata)
(s->cells[src].t_attrib.fgcol << 12) |
(s->cells[src].t_attrib.bgcol << 8) |
(s->cells[src].t_attrib.bold << 21));
dpy_update(s->ds, s->text_x[0], s->text_y[0],
s->text_x[1] - s->text_x[0], i - s->text_y[0]);
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_cursor(s->ds, s->x, s->y);
dpy_text_cursor(s->ds, s->x, s->y);
s->cursor_invalidate = 0;
}
}
static TextConsole *get_graphic_console(DisplayState *ds)
static QemuConsole *get_graphic_console(DisplayState *ds)
{
int i;
TextConsole *s;
QemuConsole *s;
for (i = 0; i < nb_consoles; i++) {
s = consoles[i];
if (s->console_type == GRAPHIC_CONSOLE && s->ds == ds)
......@@ -1259,14 +1262,14 @@ static TextConsole *get_graphic_console(DisplayState *ds)
return NULL;
}
static TextConsole *new_console(DisplayState *ds, console_type_t console_type)
static QemuConsole *new_console(DisplayState *ds, console_type_t console_type)
{
TextConsole *s;
QemuConsole *s;
int i;
if (nb_consoles >= MAX_CONSOLES)
return NULL;
s = g_malloc0(sizeof(TextConsole));
s = g_malloc0(sizeof(QemuConsole));
if (!active_console || ((active_console->console_type != GRAPHIC_CONSOLE) &&
(console_type == GRAPHIC_CONSOLE))) {
active_console = s;
......@@ -1291,85 +1294,86 @@ static TextConsole *new_console(DisplayState *ds, console_type_t console_type)
return s;
}
static DisplaySurface* defaultallocator_create_displaysurface(int width, int height)
static void qemu_alloc_display(DisplaySurface *surface, int width, int height,
int linesize, PixelFormat pf, int newflags)
{
DisplaySurface *surface = (DisplaySurface*) g_malloc0(sizeof(DisplaySurface));
surface->pf = pf;
int linesize = width * 4;
qemu_alloc_display(surface, width, height, linesize,
qemu_default_pixelformat(32), 0);
return surface;
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
}
static DisplaySurface* defaultallocator_resize_displaysurface(DisplaySurface *surface,
int width, int height)
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;
}
void qemu_alloc_display(DisplaySurface *surface, int width, int height,
int linesize, PixelFormat pf, int newflags)
DisplaySurface *qemu_resize_displaysurface(DisplayState *ds,
int width, int height)
{
void *data;
surface->width = width;
surface->height = height;
surface->linesize = linesize;
surface->pf = pf;
if (surface->flags & QEMU_ALLOCATED_FLAG) {
data = g_realloc(surface->data,
surface->linesize * surface->height);
} else {
data = g_malloc(surface->linesize * surface->height);
}
surface->data = (uint8_t *)data;
surface->flags = newflags | QEMU_ALLOCATED_FLAG;
#ifdef HOST_WORDS_BIGENDIAN
surface->flags |= QEMU_BIG_ENDIAN_FLAG;
#endif
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 *qemu_create_displaysurface_from(int width, int height, int bpp,
int linesize, uint8_t *data)
{
DisplaySurface *surface = (DisplaySurface*) g_malloc0(sizeof(DisplaySurface));
DisplaySurface *surface = g_new0(DisplaySurface, 1);
surface->width = width;
surface->height = height;
surface->linesize = linesize;
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
surface->data = data;
return surface;
}
static void defaultallocator_free_displaysurface(DisplaySurface *surface)
void qemu_free_displaysurface(DisplayState *ds)
{
if (surface == NULL)
trace_displaysurface_free(ds, ds->surface);
if (ds->surface == NULL) {
return;
if (surface->flags & QEMU_ALLOCATED_FLAG)
g_free(surface->data);
g_free(surface);
}
qemu_pixman_image_unref(ds->surface->image);
g_free(ds->surface);
}
static struct DisplayAllocator default_allocator = {
defaultallocator_create_displaysurface,
defaultallocator_resize_displaysurface,
defaultallocator_free_displaysurface
};
static void dumb_display_init(void)
{
DisplayState *ds = g_malloc0(sizeof(DisplayState));
int width = 640;
int height = 480;
ds->allocator = &default_allocator;
if (is_fixedsize_console()) {
width = active_console->g_width;
height = active_console->g_height;
......@@ -1399,29 +1403,16 @@ DisplayState *get_displaystate(void)
return display_state;
}
DisplayAllocator *register_displayallocator(DisplayState *ds, DisplayAllocator *da)
{
if(ds->allocator == &default_allocator) {
DisplaySurface *surf;
surf = da->create_displaysurface(ds_get_width(ds), ds_get_height(ds));
defaultallocator_free_displaysurface(ds->surface);
ds->surface = surf;
ds->allocator = da;
}
return ds->allocator;
}
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)
{
TextConsole *s;
QemuConsole *s;
DisplayState *ds;
ds = (DisplayState *) g_malloc0(sizeof(DisplayState));
ds->allocator = &default_allocator;
ds->surface = qemu_create_displaysurface(ds, 640, 480);
s = new_console(ds, GRAPHIC_CONSOLE);
......@@ -1463,14 +1454,14 @@ void console_color_init(DisplayState *ds)
static void text_console_set_echo(CharDriverState *chr, bool echo)
{
TextConsole *s = chr->opaque;
QemuConsole *s = chr->opaque;
s->echo = echo;
}
static void text_console_update_cursor(void *opaque)
{
TextConsole *s = opaque;
QemuConsole *s = opaque;
s->cursor_visible_phase = !s->cursor_visible_phase;
vga_hw_invalidate();
......@@ -1480,7 +1471,7 @@ static void text_console_update_cursor(void *opaque)
static void text_console_do_init(CharDriverState *chr, DisplayState *ds)
{
TextConsole *s;
QemuConsole *s;
static int color_inited;
s = chr->opaque;
......@@ -1543,7 +1534,7 @@ static void text_console_do_init(CharDriverState *chr, DisplayState *ds)
CharDriverState *text_console_init(QemuOpts *opts)
{