blob: b25328a6ba00a5136bd5161233122e29746a2ab0 [file] [log] [blame]
Gerd Hoffmanna3e22262010-08-25 15:32:06 +02001/*
2 * Copyright (C) 2010 Red Hat, Inc.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 or
7 * (at your option) version 3 of the License.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, see <http://www.gnu.org/licenses/>.
16 */
17
18#include <spice/ipc_ring.h>
19#include <spice/enums.h>
20#include <spice/qxl_dev.h>
21
Paolo Bonzini1de7afc2012-12-17 18:20:00 +010022#include "qemu/thread.h"
Paolo Bonzini28ecbae2012-11-28 12:06:30 +010023#include "ui/qemu-pixman.h"
Peter Maydell0b087862013-01-21 12:03:47 +000024#include "ui/console.h"
Paolo Bonzini9c17d612012-12-17 18:20:04 +010025#include "sysemu/sysemu.h"
Gerd Hoffmanna3e22262010-08-25 15:32:06 +020026
27#define NUM_MEMSLOTS 8
28#define MEMSLOT_GENERATION_BITS 8
29#define MEMSLOT_SLOT_BITS 8
30
31#define MEMSLOT_GROUP_HOST 0
32#define MEMSLOT_GROUP_GUEST 1
33#define NUM_MEMSLOTS_GROUPS 2
34
Alon Levy5ff4e362011-07-20 12:20:58 +030035/*
36 * Internal enum to differenciate between options for
37 * io calls that have a sync (old) version and an _async (new)
38 * version:
39 * QXL_SYNC: use the old version
40 * QXL_ASYNC: use the new version and make sure there are no two
41 * happening at the same time. This is used for guest initiated
42 * calls
43 */
44typedef enum qxl_async_io {
45 QXL_SYNC,
46 QXL_ASYNC,
47} qxl_async_io;
48
Alon Levy2e1a98c2012-02-24 23:19:30 +020049enum {
50 QXL_COOKIE_TYPE_IO,
Alon Levy81fb6f12012-02-24 23:19:31 +020051 QXL_COOKIE_TYPE_RENDER_UPDATE_AREA,
Alon Levy020af1c2012-08-22 11:16:25 +030052 QXL_COOKIE_TYPE_POST_LOAD_MONITORS_CONFIG,
Alon Levy2e1a98c2012-02-24 23:19:30 +020053};
54
55typedef struct QXLCookie {
56 int type;
57 uint64_t io;
58 union {
59 uint32_t surface_id;
Alon Levy81fb6f12012-02-24 23:19:31 +020060 QXLRect area;
61 struct {
62 QXLRect area;
63 int redraw;
64 } render;
Alon Levy2e1a98c2012-02-24 23:19:30 +020065 } u;
66} QXLCookie;
67
68QXLCookie *qxl_cookie_new(int type, uint64_t io);
69
Gerd Hoffmanne0c64d02011-04-27 15:21:51 +020070typedef struct SimpleSpiceDisplay SimpleSpiceDisplay;
71typedef struct SimpleSpiceUpdate SimpleSpiceUpdate;
Gerd Hoffmann5643fc02014-06-07 13:03:10 +020072typedef struct SimpleSpiceCursor SimpleSpiceCursor;
Gerd Hoffmanne0c64d02011-04-27 15:21:51 +020073
74struct SimpleSpiceDisplay {
Gerd Hoffmann71874c12013-02-28 16:42:28 +010075 DisplaySurface *ds;
Gerd Hoffmann7c20b4a2012-11-13 14:51:41 +010076 DisplayChangeListener dcl;
Gerd Hoffmanna3e22262010-08-25 15:32:06 +020077 void *buf;
78 int bufsize;
79 QXLWorker *worker;
80 QXLInstance qxl;
81 uint32_t unique;
Gerd Hoffmannd9a86562012-11-02 09:12:49 +010082 pixman_image_t *surface;
83 pixman_image_t *mirror;
Gerd Hoffmannddd8fdc2012-09-04 11:39:41 +020084 int32_t num_surfaces;
Gerd Hoffmanna3e22262010-08-25 15:32:06 +020085
Gerd Hoffmanna3e22262010-08-25 15:32:06 +020086 QXLRect dirty;
87 int notify;
Gerd Hoffmanna3e22262010-08-25 15:32:06 +020088
Gerd Hoffmanne0c64d02011-04-27 15:21:51 +020089 /*
90 * All struct members below this comment can be accessed from
91 * both spice server and qemu (iothread) context and any access
92 * to them must be protected by the lock.
93 */
94 QemuMutex lock;
Gerd Hoffmannb1af98b2012-09-05 08:25:08 +020095 QTAILQ_HEAD(, SimpleSpiceUpdate) updates;
Gerd Hoffmann5643fc02014-06-07 13:03:10 +020096
97 /* cursor (without qxl): displaychangelistener -> spice server */
98 SimpleSpiceCursor *ptr_define;
99 SimpleSpiceCursor *ptr_move;
Marc-André Lureaudc8dcee2015-03-24 17:50:12 +0100100 int16_t ptr_x, ptr_y;
101 int16_t hot_x, hot_y;
Gerd Hoffmann5643fc02014-06-07 13:03:10 +0200102
103 /* cursor (with qxl): qxl local renderer -> displaychangelistener */
Gerd Hoffmann07536092011-04-27 15:50:32 +0200104 QEMUCursor *cursor;
105 int mouse_x, mouse_y;
Gerd Hoffmann0b2824e2014-11-04 13:59:59 +0100106 QEMUBH *cursor_bh;
Gerd Hoffmanne0c64d02011-04-27 15:21:51 +0200107};
108
109struct SimpleSpiceUpdate {
Gerd Hoffmanna3e22262010-08-25 15:32:06 +0200110 QXLDrawable drawable;
111 QXLImage image;
112 QXLCommandExt ext;
113 uint8_t *bitmap;
Gerd Hoffmannb1af98b2012-09-05 08:25:08 +0200114 QTAILQ_ENTRY(SimpleSpiceUpdate) next;
Gerd Hoffmanne0c64d02011-04-27 15:21:51 +0200115};
Gerd Hoffmanna3e22262010-08-25 15:32:06 +0200116
Gerd Hoffmann5643fc02014-06-07 13:03:10 +0200117struct SimpleSpiceCursor {
118 QXLCursorCmd cmd;
119 QXLCommandExt ext;
120 QXLCursor cursor;
121};
122
Gerd Hoffmanna3e22262010-08-25 15:32:06 +0200123int qemu_spice_rect_is_empty(const QXLRect* r);
124void qemu_spice_rect_union(QXLRect *dest, const QXLRect *r);
125
Gerd Hoffmanna3e22262010-08-25 15:32:06 +0200126void qemu_spice_destroy_update(SimpleSpiceDisplay *sdpy, SimpleSpiceUpdate *update);
127void qemu_spice_create_host_memslot(SimpleSpiceDisplay *ssd);
128void qemu_spice_create_host_primary(SimpleSpiceDisplay *ssd);
129void qemu_spice_destroy_host_primary(SimpleSpiceDisplay *ssd);
Luiz Capitulino1dfb4dd2011-07-29 14:26:33 -0300130void qemu_spice_vm_change_state_handler(void *opaque, int running,
131 RunState state);
Gerd Hoffmannc78f7132013-03-05 15:24:14 +0100132void qemu_spice_display_init_common(SimpleSpiceDisplay *ssd);
Gerd Hoffmanna3e22262010-08-25 15:32:06 +0200133
134void qemu_spice_display_update(SimpleSpiceDisplay *ssd,
135 int x, int y, int w, int h);
Gerd Hoffmannc12aeb82013-02-28 15:03:04 +0100136void qemu_spice_display_switch(SimpleSpiceDisplay *ssd,
137 DisplaySurface *surface);
Gerd Hoffmanna3e22262010-08-25 15:32:06 +0200138void qemu_spice_display_refresh(SimpleSpiceDisplay *ssd);
Gerd Hoffmann0b2824e2014-11-04 13:59:59 +0100139void qemu_spice_cursor_refresh_bh(void *opaque);
Gerd Hoffmann5c59d112011-07-20 12:20:50 +0300140
Alon Levy5ff4e362011-07-20 12:20:58 +0300141void qemu_spice_add_memslot(SimpleSpiceDisplay *ssd, QXLDevMemSlot *memslot,
142 qxl_async_io async);
Gerd Hoffmann5c59d112011-07-20 12:20:50 +0300143void qemu_spice_del_memslot(SimpleSpiceDisplay *ssd, uint32_t gid,
144 uint32_t sid);
145void qemu_spice_create_primary_surface(SimpleSpiceDisplay *ssd, uint32_t id,
Alon Levy5ff4e362011-07-20 12:20:58 +0300146 QXLDevSurfaceCreate *surface,
147 qxl_async_io async);
148void qemu_spice_destroy_primary_surface(SimpleSpiceDisplay *ssd,
149 uint32_t id, qxl_async_io async);
Gerd Hoffmann5c59d112011-07-20 12:20:50 +0300150void qemu_spice_wakeup(SimpleSpiceDisplay *ssd);
Yonit Halperin71d388d2012-08-21 11:51:56 +0300151void qemu_spice_display_start(void);
152void qemu_spice_display_stop(void);
Yonit Halperin71d388d2012-08-21 11:51:56 +0300153int qemu_spice_display_is_running(SimpleSpiceDisplay *ssd);