blob: 6e69f7f8899b44070a7497b61414511bc2f46304 [file] [log] [blame]
pbrook87ecb682007-11-17 17:14:51 +00001#ifndef CONSOLE_H
2#define CONSOLE_H
3
Paolo Bonzini28ecbae2012-11-28 12:06:30 +01004#include "ui/qemu-pixman.h"
Gerd Hoffmann95be0662013-04-17 09:45:10 +02005#include "qom/object.h"
Paolo Bonzini7b1b5d12012-12-17 18:19:43 +01006#include "qapi/qmp/qdict.h"
Paolo Bonzini1de7afc2012-12-17 18:20:00 +01007#include "qemu/notify.h"
Paolo Bonzini83c90892012-12-17 18:19:49 +01008#include "monitor/monitor.h"
Alon Levycdbc19d2012-03-11 18:11:26 +02009#include "trace.h"
Amos Kong1048c882012-08-31 10:56:25 +080010#include "qapi-types.h"
Paolo Bonzini7b1b5d12012-12-17 18:19:43 +010011#include "qapi/error.h"
pbrook87ecb682007-11-17 17:14:51 +000012
13/* keyboard/mouse support */
14
15#define MOUSE_EVENT_LBUTTON 0x01
16#define MOUSE_EVENT_RBUTTON 0x02
17#define MOUSE_EVENT_MBUTTON 0x04
18
Gerd Hoffmann03a23a82010-02-26 17:17:36 +010019/* identical to the ps/2 keyboard bits */
20#define QEMU_SCROLL_LOCK_LED (1 << 0)
21#define QEMU_NUM_LOCK_LED (1 << 1)
22#define QEMU_CAPS_LOCK_LED (1 << 2)
23
aliguori7ed9eba2008-08-21 20:12:05 +000024/* in ms */
Gerd Hoffmann0f7b2862013-03-14 11:56:16 +010025#define GUI_REFRESH_INTERVAL_DEFAULT 30
26#define GUI_REFRESH_INTERVAL_IDLE 3000
aliguori7ed9eba2008-08-21 20:12:05 +000027
pbrook87ecb682007-11-17 17:14:51 +000028typedef void QEMUPutKBDEvent(void *opaque, int keycode);
Gerd Hoffmann03a23a82010-02-26 17:17:36 +010029typedef void QEMUPutLEDEvent(void *opaque, int ledstate);
pbrook87ecb682007-11-17 17:14:51 +000030typedef void QEMUPutMouseEvent(void *opaque, int dx, int dy, int dz, int buttons_state);
31
Gerd Hoffmann72711ef2013-04-24 12:08:37 +020032typedef struct QEMUPutMouseEntry QEMUPutMouseEntry;
Gerd Hoffmann5a375322013-04-24 12:08:38 +020033typedef struct QEMUPutKbdEntry QEMUPutKbdEntry;
Gerd Hoffmann72711ef2013-04-24 12:08:37 +020034typedef struct QEMUPutLEDEntry QEMUPutLEDEntry;
Gerd Hoffmann03a23a82010-02-26 17:17:36 +010035
Gerd Hoffmann5a375322013-04-24 12:08:38 +020036QEMUPutKbdEntry *qemu_add_kbd_event_handler(QEMUPutKBDEvent *func,
37 void *opaque);
38void qemu_remove_kbd_event_handler(QEMUPutKbdEntry *entry);
pbrook87ecb682007-11-17 17:14:51 +000039QEMUPutMouseEntry *qemu_add_mouse_event_handler(QEMUPutMouseEvent *func,
40 void *opaque, int absolute,
41 const char *name);
42void qemu_remove_mouse_event_handler(QEMUPutMouseEntry *entry);
Anthony Liguori6fef28e2010-03-09 20:52:22 -060043void qemu_activate_mouse_event_handler(QEMUPutMouseEntry *entry);
44
Gerd Hoffmann03a23a82010-02-26 17:17:36 +010045QEMUPutLEDEntry *qemu_add_led_event_handler(QEMUPutLEDEvent *func, void *opaque);
46void qemu_remove_led_event_handler(QEMUPutLEDEntry *entry);
pbrook87ecb682007-11-17 17:14:51 +000047
48void kbd_put_keycode(int keycode);
Gerd Hoffmann03a23a82010-02-26 17:17:36 +010049void kbd_put_ledstate(int ledstate);
pbrook87ecb682007-11-17 17:14:51 +000050void kbd_mouse_event(int dx, int dy, int dz, int buttons_state);
Anthony Liguorieb2e2592010-03-09 14:26:40 -060051
52/* Does the current mouse generate absolute events */
pbrook87ecb682007-11-17 17:14:51 +000053int kbd_mouse_is_absolute(void);
Anthony Liguori7e581fb2010-03-09 13:25:00 -060054void qemu_add_mouse_mode_change_notifier(Notifier *notify);
55void qemu_remove_mouse_mode_change_notifier(Notifier *notify);
pbrook87ecb682007-11-17 17:14:51 +000056
Anthony Liguorieb2e2592010-03-09 14:26:40 -060057/* Of all the mice, is there one that generates absolute events */
58int kbd_mouse_has_absolute(void);
59
Paul Brookbc24a222009-05-10 01:44:56 +010060struct MouseTransformInfo {
balroga5d7eb62008-04-14 21:28:11 +000061 /* Touchscreen resolution */
62 int x;
63 int y;
64 /* Calibration values as used/generated by tslib */
65 int a[7];
66};
67
Luiz Capitulinod54908a2009-08-28 15:27:13 -030068void do_mouse_set(Monitor *mon, const QDict *qdict);
pbrook87ecb682007-11-17 17:14:51 +000069
70/* keysym is a unicode code except for special keys (see QEMU_KEY_xxx
71 constants) */
72#define QEMU_KEY_ESC1(c) ((c) | 0xe100)
73#define QEMU_KEY_BACKSPACE 0x007f
74#define QEMU_KEY_UP QEMU_KEY_ESC1('A')
75#define QEMU_KEY_DOWN QEMU_KEY_ESC1('B')
76#define QEMU_KEY_RIGHT QEMU_KEY_ESC1('C')
77#define QEMU_KEY_LEFT QEMU_KEY_ESC1('D')
78#define QEMU_KEY_HOME QEMU_KEY_ESC1(1)
79#define QEMU_KEY_END QEMU_KEY_ESC1(4)
80#define QEMU_KEY_PAGEUP QEMU_KEY_ESC1(5)
81#define QEMU_KEY_PAGEDOWN QEMU_KEY_ESC1(6)
82#define QEMU_KEY_DELETE QEMU_KEY_ESC1(3)
83
84#define QEMU_KEY_CTRL_UP 0xe400
85#define QEMU_KEY_CTRL_DOWN 0xe401
86#define QEMU_KEY_CTRL_LEFT 0xe402
87#define QEMU_KEY_CTRL_RIGHT 0xe403
88#define QEMU_KEY_CTRL_HOME 0xe404
89#define QEMU_KEY_CTRL_END 0xe405
90#define QEMU_KEY_CTRL_PAGEUP 0xe406
91#define QEMU_KEY_CTRL_PAGEDOWN 0xe407
92
93void kbd_put_keysym(int keysym);
94
95/* consoles */
96
Gerd Hoffmann95be0662013-04-17 09:45:10 +020097#define TYPE_QEMU_CONSOLE "qemu-console"
98#define QEMU_CONSOLE(obj) \
99 OBJECT_CHECK(QemuConsole, (obj), TYPE_QEMU_CONSOLE)
100#define QEMU_CONSOLE_GET_CLASS(obj) \
101 OBJECT_GET_CLASS(QemuConsoleClass, (obj), TYPE_QEMU_CONSOLE)
102#define QEMU_CONSOLE_CLASS(klass) \
103 OBJECT_CLASS_CHECK(QemuConsoleClass, (klass), TYPE_QEMU_CONSOLE)
104
105typedef struct QemuConsoleClass QemuConsoleClass;
106
107struct QemuConsoleClass {
108 ObjectClass parent_class;
109};
110
aliguori7d957bd2009-01-15 22:14:11 +0000111#define QEMU_BIG_ENDIAN_FLAG 0x01
112#define QEMU_ALLOCATED_FLAG 0x02
113
114struct PixelFormat {
115 uint8_t bits_per_pixel;
116 uint8_t bytes_per_pixel;
117 uint8_t depth; /* color depth in bits */
118 uint32_t rmask, gmask, bmask, amask;
119 uint8_t rshift, gshift, bshift, ashift;
120 uint8_t rmax, gmax, bmax, amax;
aliguori90a1e3c2009-01-26 15:37:30 +0000121 uint8_t rbits, gbits, bbits, abits;
aliguori7d957bd2009-01-15 22:14:11 +0000122};
123
124struct DisplaySurface {
Gerd Hoffmann69c77772012-09-26 15:20:05 +0200125 pixman_format_code_t format;
126 pixman_image_t *image;
aliguori7d957bd2009-01-15 22:14:11 +0000127 uint8_t flags;
aliguori7d957bd2009-01-15 22:14:11 +0000128
129 struct PixelFormat pf;
130};
131
Gerd Hoffmann254e5952010-05-21 11:54:32 +0200132/* cursor data format is 32bit RGBA */
133typedef struct QEMUCursor {
134 int width, height;
135 int hot_x, hot_y;
136 int refcount;
137 uint32_t data[];
138} QEMUCursor;
139
140QEMUCursor *cursor_alloc(int width, int height);
141void cursor_get(QEMUCursor *c);
142void cursor_put(QEMUCursor *c);
143QEMUCursor *cursor_builtin_hidden(void);
144QEMUCursor *cursor_builtin_left_ptr(void);
145void cursor_print_ascii_art(QEMUCursor *c, const char *prefix);
146int cursor_get_mono_bpl(QEMUCursor *c);
147void cursor_set_mono(QEMUCursor *c,
148 uint32_t foreground, uint32_t background, uint8_t *image,
149 int transparent, uint8_t *mask);
150void cursor_get_mono_image(QEMUCursor *c, int foreground, uint8_t *mask);
151void cursor_get_mono_mask(QEMUCursor *c, int transparent, uint8_t *mask);
152
Gerd Hoffmann7c20b4a2012-11-13 14:51:41 +0100153typedef struct DisplayChangeListenerOps {
154 const char *dpy_name;
155
Gerd Hoffmannbc2ed972013-03-01 13:03:04 +0100156 void (*dpy_refresh)(DisplayChangeListener *dcl);
Gerd Hoffmann7c20b4a2012-11-13 14:51:41 +0100157
158 void (*dpy_gfx_update)(DisplayChangeListener *dcl,
Gerd Hoffmann7c20b4a2012-11-13 14:51:41 +0100159 int x, int y, int w, int h);
Gerd Hoffmannc12aeb82013-02-28 15:03:04 +0100160 void (*dpy_gfx_switch)(DisplayChangeListener *dcl,
Gerd Hoffmannc12aeb82013-02-28 15:03:04 +0100161 struct DisplaySurface *new_surface);
Gerd Hoffmann7c20b4a2012-11-13 14:51:41 +0100162 void (*dpy_gfx_copy)(DisplayChangeListener *dcl,
Gerd Hoffmannbc2ed972013-03-01 13:03:04 +0100163 int src_x, int src_y,
Gerd Hoffmann7c20b4a2012-11-13 14:51:41 +0100164 int dst_x, int dst_y, int w, int h);
165
166 void (*dpy_text_cursor)(DisplayChangeListener *dcl,
Gerd Hoffmann7c20b4a2012-11-13 14:51:41 +0100167 int x, int y);
168 void (*dpy_text_resize)(DisplayChangeListener *dcl,
Gerd Hoffmann7c20b4a2012-11-13 14:51:41 +0100169 int w, int h);
170 void (*dpy_text_update)(DisplayChangeListener *dcl,
Gerd Hoffmann7c20b4a2012-11-13 14:51:41 +0100171 int x, int y, int w, int h);
172
173 void (*dpy_mouse_set)(DisplayChangeListener *dcl,
Gerd Hoffmann7c20b4a2012-11-13 14:51:41 +0100174 int x, int y, int on);
175 void (*dpy_cursor_define)(DisplayChangeListener *dcl,
Gerd Hoffmann7c20b4a2012-11-13 14:51:41 +0100176 QEMUCursor *cursor);
177} DisplayChangeListenerOps;
178
aliguori7d957bd2009-01-15 22:14:11 +0000179struct DisplayChangeListener {
Gerd Hoffmann0f7b2862013-03-14 11:56:16 +0100180 uint64_t update_interval;
Gerd Hoffmann7c20b4a2012-11-13 14:51:41 +0100181 const DisplayChangeListenerOps *ops;
182 DisplayState *ds;
Gerd Hoffmann284d1c62013-03-15 15:45:54 +0100183 QemuConsole *con;
Gerd Hoffmannbf2fde72012-09-12 07:56:45 +0200184
Gerd Hoffmann87e487a2010-06-04 11:46:35 +0200185 QLIST_ENTRY(DisplayChangeListener) next;
aliguori7d957bd2009-01-15 22:14:11 +0000186};
187
Gerd Hoffmann64840c62013-03-07 17:08:29 +0100188DisplayState *init_displaystate(void);
aliguori7d957bd2009-01-15 22:14:11 +0000189DisplaySurface* qemu_create_displaysurface_from(int width, int height, int bpp,
Gerd Hoffmannb1424e02013-02-20 09:37:12 +0100190 int linesize, uint8_t *data,
191 bool byteswap);
malc0da2ea12009-01-23 19:56:19 +0000192PixelFormat qemu_different_endianness_pixelformat(int bpp);
193PixelFormat qemu_default_pixelformat(int bpp);
aliguori7d957bd2009-01-15 22:14:11 +0000194
Gerd Hoffmannda229ef2013-02-28 10:48:02 +0100195DisplaySurface *qemu_create_displaysurface(int width, int height);
196void qemu_free_displaysurface(DisplaySurface *surface);
aliguori7b5d76d2009-03-13 15:02:13 +0000197
198static inline int is_surface_bgr(DisplaySurface *surface)
199{
200 if (surface->pf.bits_per_pixel == 32 && surface->pf.rshift == 0)
201 return 1;
202 else
203 return 0;
204}
205
aliguori7d957bd2009-01-15 22:14:11 +0000206static inline int is_buffer_shared(DisplaySurface *surface)
207{
Gerd Hoffmann187cd1d2012-09-26 07:46:20 +0200208 return !(surface->flags & QEMU_ALLOCATED_FLAG);
aliguori7d957bd2009-01-15 22:14:11 +0000209}
210
Gerd Hoffmann7c20b4a2012-11-13 14:51:41 +0100211void register_displaychangelistener(DisplayState *ds,
212 DisplayChangeListener *dcl);
Gerd Hoffmann0f7b2862013-03-14 11:56:16 +0100213void update_displaychangelistener(DisplayChangeListener *dcl,
214 uint64_t interval);
Gerd Hoffmann7c20b4a2012-11-13 14:51:41 +0100215void unregister_displaychangelistener(DisplayChangeListener *dcl);
Gerd Hoffmann35c9e0a2010-06-04 11:51:31 +0200216
Gerd Hoffmannc78f7132013-03-05 15:24:14 +0100217void dpy_gfx_update(QemuConsole *con, int x, int y, int w, int h);
218void dpy_gfx_replace_surface(QemuConsole *con,
Gerd Hoffmannda229ef2013-02-28 10:48:02 +0100219 DisplaySurface *surface);
Gerd Hoffmannc78f7132013-03-05 15:24:14 +0100220void dpy_gfx_copy(QemuConsole *con, int src_x, int src_y,
Gerd Hoffmann7c20b4a2012-11-13 14:51:41 +0100221 int dst_x, int dst_y, int w, int h);
Gerd Hoffmannc78f7132013-03-05 15:24:14 +0100222void dpy_text_cursor(QemuConsole *con, int x, int y);
223void dpy_text_update(QemuConsole *con, int x, int y, int w, int h);
224void dpy_text_resize(QemuConsole *con, int w, int h);
225void dpy_mouse_set(QemuConsole *con, int x, int y, int on);
226void dpy_cursor_define(QemuConsole *con, QEMUCursor *cursor);
227bool dpy_cursor_define_supported(QemuConsole *con);
Gerd Hoffmannbf2fde72012-09-12 07:56:45 +0200228
Gerd Hoffmann626e3b32013-02-28 15:24:14 +0100229static inline int surface_stride(DisplaySurface *s)
230{
231 return pixman_image_get_stride(s->image);
232}
233
234static inline void *surface_data(DisplaySurface *s)
235{
236 return pixman_image_get_data(s->image);
237}
238
239static inline int surface_width(DisplaySurface *s)
240{
241 return pixman_image_get_width(s->image);
242}
243
244static inline int surface_height(DisplaySurface *s)
245{
246 return pixman_image_get_height(s->image);
247}
248
249static inline int surface_bits_per_pixel(DisplaySurface *s)
250{
251 int bits = PIXMAN_FORMAT_BPP(s->format);
252 return bits;
253}
254
255static inline int surface_bytes_per_pixel(DisplaySurface *s)
256{
257 int bits = PIXMAN_FORMAT_BPP(s->format);
258 return (bits + 7) / 8;
259}
260
Devin J. Pohlydf00bed2011-09-07 15:44:36 -0400261#ifdef CONFIG_CURSES
262#include <curses.h>
263typedef chtype console_ch_t;
264#else
Anthony Liguoric227f092009-10-01 16:12:16 -0500265typedef unsigned long console_ch_t;
Devin J. Pohlydf00bed2011-09-07 15:44:36 -0400266#endif
Anthony Liguoric227f092009-10-01 16:12:16 -0500267static inline void console_write_ch(console_ch_t *dest, uint32_t ch)
balrog4d3b6f62008-02-10 16:33:14 +0000268{
Bernhard Kauerf6d20d02010-05-21 14:05:55 +0200269 if (!(ch & 0xff))
270 ch |= ' ';
Aurelien Jarno9ae19b62011-01-04 21:58:24 +0100271 *dest = ch;
balrog4d3b6f62008-02-10 16:33:14 +0000272}
273
Gerd Hoffmann380cd052013-03-13 14:04:18 +0100274typedef struct GraphicHwOps {
275 void (*invalidate)(void *opaque);
276 void (*gfx_update)(void *opaque);
277 void (*text_update)(void *opaque, console_ch_t *text);
Gerd Hoffmanndea1b0b2013-03-19 15:01:02 +0100278 void (*update_interval)(void *opaque, uint64_t interval);
Gerd Hoffmann380cd052013-03-13 14:04:18 +0100279} GraphicHwOps;
pbrook87ecb682007-11-17 17:14:51 +0000280
Gerd Hoffmannaa2beaa2013-04-17 10:21:27 +0200281QemuConsole *graphic_console_init(DeviceState *dev,
282 const GraphicHwOps *ops,
Gerd Hoffmannc78f7132013-03-05 15:24:14 +0100283 void *opaque);
aliguori3023f332009-01-16 19:04:14 +0000284
Gerd Hoffmann1dbfa002013-03-12 13:44:38 +0100285void graphic_hw_update(QemuConsole *con);
286void graphic_hw_invalidate(QemuConsole *con);
287void graphic_hw_text_update(QemuConsole *con, console_ch_t *chardata);
pbrook87ecb682007-11-17 17:14:51 +0000288
Gerd Hoffmann284d1c62013-03-15 15:45:54 +0100289QemuConsole *qemu_console_lookup_by_index(unsigned int index);
Gerd Hoffmann81c0d5a2013-03-14 14:27:08 +0100290bool qemu_console_is_visible(QemuConsole *con);
291bool qemu_console_is_graphic(QemuConsole *con);
292bool qemu_console_is_fixedsize(QemuConsole *con);
293
aliguori2796dae2009-01-16 20:23:27 +0000294void text_consoles_set_display(DisplayState *ds);
pbrook87ecb682007-11-17 17:14:51 +0000295void console_select(unsigned int index);
296void console_color_init(DisplayState *ds);
Gerd Hoffmannc78f7132013-03-05 15:24:14 +0100297void qemu_console_resize(QemuConsole *con, int width, int height);
298void qemu_console_copy(QemuConsole *con, int src_x, int src_y,
aliguori3023f332009-01-16 19:04:14 +0000299 int dst_x, int dst_y, int w, int h);
Gerd Hoffmannc78f7132013-03-05 15:24:14 +0100300DisplaySurface *qemu_console_surface(QemuConsole *con);
301DisplayState *qemu_console_displaystate(QemuConsole *console);
pbrook87ecb682007-11-17 17:14:51 +0000302
Gerd Hoffmann702ec692013-02-25 15:52:32 +0100303typedef CharDriverState *(VcHandler)(ChardevVC *vc);
Anthony Liguorid82831d2013-02-20 07:43:19 -0600304
Gerd Hoffmann702ec692013-02-25 15:52:32 +0100305CharDriverState *vc_init(ChardevVC *vc);
Anthony Liguorid82831d2013-02-20 07:43:19 -0600306void register_vc_handler(VcHandler *handler);
307
pbrook87ecb682007-11-17 17:14:51 +0000308/* sdl.c */
309void sdl_display_init(DisplayState *ds, int full_screen, int no_frame);
310
311/* cocoa.m */
312void cocoa_display_init(DisplayState *ds, int full_screen);
313
314/* vnc.c */
315void vnc_display_init(DisplayState *ds);
Paolo Bonzini007fcd3e2012-10-18 09:01:01 +0200316void vnc_display_open(DisplayState *ds, const char *display, Error **errp);
Daniel P. Berrange13661082011-06-23 13:31:42 +0100317void vnc_display_add_client(DisplayState *ds, int csock, int skipauth);
Jes Sorensen821601e2011-03-16 13:33:36 +0100318char *vnc_display_local_addr(DisplayState *ds);
319#ifdef CONFIG_VNC
320int vnc_display_password(DisplayState *ds, const char *password);
Gerd Hoffmann3c9405a2010-10-07 11:50:45 +0200321int vnc_display_pw_expire(DisplayState *ds, time_t expires);
Jes Sorensen821601e2011-03-16 13:33:36 +0100322#else
323static inline int vnc_display_password(DisplayState *ds, const char *password)
324{
Jes Sorensen821601e2011-03-16 13:33:36 +0100325 return -ENODEV;
326}
327static inline int vnc_display_pw_expire(DisplayState *ds, time_t expires)
328{
Jes Sorensen821601e2011-03-16 13:33:36 +0100329 return -ENODEV;
330};
Jes Sorensen821601e2011-03-16 13:33:36 +0100331#endif
pbrook87ecb682007-11-17 17:14:51 +0000332
balrog4d3b6f62008-02-10 16:33:14 +0000333/* curses.c */
334void curses_display_init(DisplayState *ds, int full_screen);
335
Amos Kong1048c882012-08-31 10:56:25 +0800336/* input.c */
Amos Kong1048c882012-08-31 10:56:25 +0800337int index_from_key(const char *key);
338int index_from_keycode(int code);
339
Anthony Liguoria4ccabc2013-02-20 07:43:20 -0600340/* gtk.c */
341void early_gtk_display_init(void);
342void gtk_display_init(DisplayState *ds);
343
pbrook87ecb682007-11-17 17:14:51 +0000344#endif