qemu/include/ui/console.h
<<
>>
Prefs
   1#ifndef CONSOLE_H
   2#define CONSOLE_H
   3
   4#include "ui/qemu-pixman.h"
   5#include "qom/object.h"
   6#include "qapi/qmp/qdict.h"
   7#include "qemu/notify.h"
   8#include "qemu/typedefs.h"
   9#include "qapi-types.h"
  10#include "qemu/error-report.h"
  11#include "qapi/error.h"
  12
  13#ifdef CONFIG_OPENGL
  14# include <epoxy/gl.h>
  15# include "ui/shader.h"
  16#endif
  17
  18/* keyboard/mouse support */
  19
  20#define MOUSE_EVENT_LBUTTON 0x01
  21#define MOUSE_EVENT_RBUTTON 0x02
  22#define MOUSE_EVENT_MBUTTON 0x04
  23#define MOUSE_EVENT_WHEELUP 0x08
  24#define MOUSE_EVENT_WHEELDN 0x10
  25
  26/* identical to the ps/2 keyboard bits */
  27#define QEMU_SCROLL_LOCK_LED (1 << 0)
  28#define QEMU_NUM_LOCK_LED    (1 << 1)
  29#define QEMU_CAPS_LOCK_LED   (1 << 2)
  30
  31/* in ms */
  32#define GUI_REFRESH_INTERVAL_DEFAULT    30
  33#define GUI_REFRESH_INTERVAL_IDLE     3000
  34
  35/* Color number is match to standard vga palette */
  36enum qemu_color_names {
  37    QEMU_COLOR_BLACK   = 0,
  38    QEMU_COLOR_BLUE    = 1,
  39    QEMU_COLOR_GREEN   = 2,
  40    QEMU_COLOR_CYAN    = 3,
  41    QEMU_COLOR_RED     = 4,
  42    QEMU_COLOR_MAGENTA = 5,
  43    QEMU_COLOR_YELLOW  = 6,
  44    QEMU_COLOR_WHITE   = 7
  45};
  46/* Convert to curses char attributes */
  47#define ATTR2CHTYPE(c, fg, bg, bold) \
  48    ((bold) << 21 | (bg) << 11 | (fg) << 8 | (c))
  49
  50typedef void QEMUPutKBDEvent(void *opaque, int keycode);
  51typedef void QEMUPutLEDEvent(void *opaque, int ledstate);
  52typedef void QEMUPutMouseEvent(void *opaque, int dx, int dy, int dz, int buttons_state);
  53
  54typedef struct QEMUPutMouseEntry QEMUPutMouseEntry;
  55typedef struct QEMUPutKbdEntry QEMUPutKbdEntry;
  56typedef struct QEMUPutLEDEntry QEMUPutLEDEntry;
  57
  58QEMUPutKbdEntry *qemu_add_kbd_event_handler(QEMUPutKBDEvent *func,
  59                                            void *opaque);
  60QEMUPutMouseEntry *qemu_add_mouse_event_handler(QEMUPutMouseEvent *func,
  61                                                void *opaque, int absolute,
  62                                                const char *name);
  63void qemu_remove_mouse_event_handler(QEMUPutMouseEntry *entry);
  64void qemu_activate_mouse_event_handler(QEMUPutMouseEntry *entry);
  65
  66QEMUPutLEDEntry *qemu_add_led_event_handler(QEMUPutLEDEvent *func, void *opaque);
  67void qemu_remove_led_event_handler(QEMUPutLEDEntry *entry);
  68
  69void kbd_put_ledstate(int ledstate);
  70
  71struct MouseTransformInfo {
  72    /* Touchscreen resolution */
  73    int x;
  74    int y;
  75    /* Calibration values as used/generated by tslib */
  76    int a[7];
  77};
  78
  79void hmp_mouse_set(Monitor *mon, const QDict *qdict);
  80
  81/* keysym is a unicode code except for special keys (see QEMU_KEY_xxx
  82   constants) */
  83#define QEMU_KEY_ESC1(c) ((c) | 0xe100)
  84#define QEMU_KEY_BACKSPACE  0x007f
  85#define QEMU_KEY_UP         QEMU_KEY_ESC1('A')
  86#define QEMU_KEY_DOWN       QEMU_KEY_ESC1('B')
  87#define QEMU_KEY_RIGHT      QEMU_KEY_ESC1('C')
  88#define QEMU_KEY_LEFT       QEMU_KEY_ESC1('D')
  89#define QEMU_KEY_HOME       QEMU_KEY_ESC1(1)
  90#define QEMU_KEY_END        QEMU_KEY_ESC1(4)
  91#define QEMU_KEY_PAGEUP     QEMU_KEY_ESC1(5)
  92#define QEMU_KEY_PAGEDOWN   QEMU_KEY_ESC1(6)
  93#define QEMU_KEY_DELETE     QEMU_KEY_ESC1(3)
  94
  95#define QEMU_KEY_CTRL_UP         0xe400
  96#define QEMU_KEY_CTRL_DOWN       0xe401
  97#define QEMU_KEY_CTRL_LEFT       0xe402
  98#define QEMU_KEY_CTRL_RIGHT      0xe403
  99#define QEMU_KEY_CTRL_HOME       0xe404
 100#define QEMU_KEY_CTRL_END        0xe405
 101#define QEMU_KEY_CTRL_PAGEUP     0xe406
 102#define QEMU_KEY_CTRL_PAGEDOWN   0xe407
 103
 104void kbd_put_keysym_console(QemuConsole *s, int keysym);
 105bool kbd_put_qcode_console(QemuConsole *s, int qcode);
 106void kbd_put_string_console(QemuConsole *s, const char *str, int len);
 107void kbd_put_keysym(int keysym);
 108
 109/* consoles */
 110
 111#define TYPE_QEMU_CONSOLE "qemu-console"
 112#define QEMU_CONSOLE(obj) \
 113    OBJECT_CHECK(QemuConsole, (obj), TYPE_QEMU_CONSOLE)
 114#define QEMU_CONSOLE_GET_CLASS(obj) \
 115    OBJECT_GET_CLASS(QemuConsoleClass, (obj), TYPE_QEMU_CONSOLE)
 116#define QEMU_CONSOLE_CLASS(klass) \
 117    OBJECT_CLASS_CHECK(QemuConsoleClass, (klass), TYPE_QEMU_CONSOLE)
 118
 119typedef struct QemuConsoleClass QemuConsoleClass;
 120
 121struct QemuConsoleClass {
 122    ObjectClass parent_class;
 123};
 124
 125#define QEMU_ALLOCATED_FLAG     0x01
 126
 127struct PixelFormat {
 128    uint8_t bits_per_pixel;
 129    uint8_t bytes_per_pixel;
 130    uint8_t depth; /* color depth in bits */
 131    uint32_t rmask, gmask, bmask, amask;
 132    uint8_t rshift, gshift, bshift, ashift;
 133    uint8_t rmax, gmax, bmax, amax;
 134    uint8_t rbits, gbits, bbits, abits;
 135};
 136
 137struct DisplaySurface {
 138    pixman_format_code_t format;
 139    pixman_image_t *image;
 140    uint8_t flags;
 141#ifdef CONFIG_OPENGL
 142    GLenum glformat;
 143    GLenum gltype;
 144    GLuint texture;
 145#endif
 146};
 147
 148typedef struct QemuUIInfo {
 149    /* geometry */
 150    int       xoff;
 151    int       yoff;
 152    uint32_t  width;
 153    uint32_t  height;
 154} QemuUIInfo;
 155
 156/* cursor data format is 32bit RGBA */
 157typedef struct QEMUCursor {
 158    int                 width, height;
 159    int                 hot_x, hot_y;
 160    int                 refcount;
 161    uint32_t            data[];
 162} QEMUCursor;
 163
 164QEMUCursor *cursor_alloc(int width, int height);
 165void cursor_get(QEMUCursor *c);
 166void cursor_put(QEMUCursor *c);
 167QEMUCursor *cursor_builtin_hidden(void);
 168QEMUCursor *cursor_builtin_left_ptr(void);
 169void cursor_print_ascii_art(QEMUCursor *c, const char *prefix);
 170int cursor_get_mono_bpl(QEMUCursor *c);
 171void cursor_set_mono(QEMUCursor *c,
 172                     uint32_t foreground, uint32_t background, uint8_t *image,
 173                     int transparent, uint8_t *mask);
 174void cursor_get_mono_image(QEMUCursor *c, int foreground, uint8_t *mask);
 175void cursor_get_mono_mask(QEMUCursor *c, int transparent, uint8_t *mask);
 176
 177typedef void *QEMUGLContext;
 178typedef struct QEMUGLParams QEMUGLParams;
 179
 180struct QEMUGLParams {
 181    int major_ver;
 182    int minor_ver;
 183};
 184
 185struct QemuDmaBuf {
 186    int       fd;
 187    uint32_t  width;
 188    uint32_t  height;
 189    uint32_t  stride;
 190    uint32_t  fourcc;
 191    uint32_t  texture;
 192};
 193
 194typedef struct DisplayChangeListenerOps {
 195    const char *dpy_name;
 196
 197    void (*dpy_refresh)(DisplayChangeListener *dcl);
 198
 199    void (*dpy_gfx_update)(DisplayChangeListener *dcl,
 200                           int x, int y, int w, int h);
 201    void (*dpy_gfx_switch)(DisplayChangeListener *dcl,
 202                           struct DisplaySurface *new_surface);
 203    bool (*dpy_gfx_check_format)(DisplayChangeListener *dcl,
 204                                 pixman_format_code_t format);
 205
 206    void (*dpy_text_cursor)(DisplayChangeListener *dcl,
 207                            int x, int y);
 208    void (*dpy_text_resize)(DisplayChangeListener *dcl,
 209                            int w, int h);
 210    void (*dpy_text_update)(DisplayChangeListener *dcl,
 211                            int x, int y, int w, int h);
 212
 213    void (*dpy_mouse_set)(DisplayChangeListener *dcl,
 214                          int x, int y, int on);
 215    void (*dpy_cursor_define)(DisplayChangeListener *dcl,
 216                              QEMUCursor *cursor);
 217
 218    QEMUGLContext (*dpy_gl_ctx_create)(DisplayChangeListener *dcl,
 219                                       QEMUGLParams *params);
 220    void (*dpy_gl_ctx_destroy)(DisplayChangeListener *dcl,
 221                               QEMUGLContext ctx);
 222    int (*dpy_gl_ctx_make_current)(DisplayChangeListener *dcl,
 223                                   QEMUGLContext ctx);
 224    QEMUGLContext (*dpy_gl_ctx_get_current)(DisplayChangeListener *dcl);
 225
 226    void (*dpy_gl_scanout_disable)(DisplayChangeListener *dcl);
 227    void (*dpy_gl_scanout_texture)(DisplayChangeListener *dcl,
 228                                   uint32_t backing_id,
 229                                   bool backing_y_0_top,
 230                                   uint32_t backing_width,
 231                                   uint32_t backing_height,
 232                                   uint32_t x, uint32_t y,
 233                                   uint32_t w, uint32_t h);
 234    void (*dpy_gl_scanout_dmabuf)(DisplayChangeListener *dcl,
 235                                  QemuDmaBuf *dmabuf);
 236    void (*dpy_gl_cursor_dmabuf)(DisplayChangeListener *dcl,
 237                                 QemuDmaBuf *dmabuf,
 238                                 uint32_t pos_x, uint32_t pos_y);
 239    void (*dpy_gl_release_dmabuf)(DisplayChangeListener *dcl,
 240                                  QemuDmaBuf *dmabuf);
 241    void (*dpy_gl_update)(DisplayChangeListener *dcl,
 242                          uint32_t x, uint32_t y, uint32_t w, uint32_t h);
 243
 244} DisplayChangeListenerOps;
 245
 246struct DisplayChangeListener {
 247    uint64_t update_interval;
 248    const DisplayChangeListenerOps *ops;
 249    DisplayState *ds;
 250    QemuConsole *con;
 251
 252    QLIST_ENTRY(DisplayChangeListener) next;
 253};
 254
 255DisplayState *init_displaystate(void);
 256DisplaySurface *qemu_create_displaysurface_from(int width, int height,
 257                                                pixman_format_code_t format,
 258                                                int linesize, uint8_t *data);
 259DisplaySurface *qemu_create_displaysurface_pixman(pixman_image_t *image);
 260DisplaySurface *qemu_create_displaysurface_guestmem(int width, int height,
 261                                                    pixman_format_code_t format,
 262                                                    int linesize,
 263                                                    uint64_t addr);
 264PixelFormat qemu_default_pixelformat(int bpp);
 265
 266DisplaySurface *qemu_create_displaysurface(int width, int height);
 267void qemu_free_displaysurface(DisplaySurface *surface);
 268
 269static inline int is_surface_bgr(DisplaySurface *surface)
 270{
 271    if (PIXMAN_FORMAT_BPP(surface->format) == 32 &&
 272        PIXMAN_FORMAT_TYPE(surface->format) == PIXMAN_TYPE_ABGR) {
 273        return 1;
 274    } else {
 275        return 0;
 276    }
 277}
 278
 279static inline int is_buffer_shared(DisplaySurface *surface)
 280{
 281    return !(surface->flags & QEMU_ALLOCATED_FLAG);
 282}
 283
 284void register_displaychangelistener(DisplayChangeListener *dcl);
 285void update_displaychangelistener(DisplayChangeListener *dcl,
 286                                  uint64_t interval);
 287void unregister_displaychangelistener(DisplayChangeListener *dcl);
 288
 289bool dpy_ui_info_supported(QemuConsole *con);
 290int dpy_set_ui_info(QemuConsole *con, QemuUIInfo *info);
 291
 292void dpy_gfx_update(QemuConsole *con, int x, int y, int w, int h);
 293void dpy_gfx_replace_surface(QemuConsole *con,
 294                             DisplaySurface *surface);
 295void dpy_text_cursor(QemuConsole *con, int x, int y);
 296void dpy_text_update(QemuConsole *con, int x, int y, int w, int h);
 297void dpy_text_resize(QemuConsole *con, int w, int h);
 298void dpy_mouse_set(QemuConsole *con, int x, int y, int on);
 299void dpy_cursor_define(QemuConsole *con, QEMUCursor *cursor);
 300bool dpy_cursor_define_supported(QemuConsole *con);
 301bool dpy_gfx_check_format(QemuConsole *con,
 302                          pixman_format_code_t format);
 303
 304void dpy_gl_scanout_disable(QemuConsole *con);
 305void dpy_gl_scanout_texture(QemuConsole *con,
 306                            uint32_t backing_id, bool backing_y_0_top,
 307                            uint32_t backing_width, uint32_t backing_height,
 308                            uint32_t x, uint32_t y, uint32_t w, uint32_t h);
 309void dpy_gl_scanout_dmabuf(QemuConsole *con,
 310                           QemuDmaBuf *dmabuf);
 311void dpy_gl_cursor_dmabuf(QemuConsole *con,
 312                          QemuDmaBuf *dmabuf,
 313                          uint32_t pos_x, uint32_t pos_y);
 314void dpy_gl_release_dmabuf(QemuConsole *con,
 315                           QemuDmaBuf *dmabuf);
 316void dpy_gl_update(QemuConsole *con,
 317                   uint32_t x, uint32_t y, uint32_t w, uint32_t h);
 318
 319QEMUGLContext dpy_gl_ctx_create(QemuConsole *con,
 320                                QEMUGLParams *params);
 321void dpy_gl_ctx_destroy(QemuConsole *con, QEMUGLContext ctx);
 322int dpy_gl_ctx_make_current(QemuConsole *con, QEMUGLContext ctx);
 323QEMUGLContext dpy_gl_ctx_get_current(QemuConsole *con);
 324
 325bool console_has_gl(QemuConsole *con);
 326bool console_has_gl_dmabuf(QemuConsole *con);
 327
 328static inline int surface_stride(DisplaySurface *s)
 329{
 330    return pixman_image_get_stride(s->image);
 331}
 332
 333static inline void *surface_data(DisplaySurface *s)
 334{
 335    return pixman_image_get_data(s->image);
 336}
 337
 338static inline int surface_width(DisplaySurface *s)
 339{
 340    return pixman_image_get_width(s->image);
 341}
 342
 343static inline int surface_height(DisplaySurface *s)
 344{
 345    return pixman_image_get_height(s->image);
 346}
 347
 348static inline int surface_bits_per_pixel(DisplaySurface *s)
 349{
 350    int bits = PIXMAN_FORMAT_BPP(s->format);
 351    return bits;
 352}
 353
 354static inline int surface_bytes_per_pixel(DisplaySurface *s)
 355{
 356    int bits = PIXMAN_FORMAT_BPP(s->format);
 357    return DIV_ROUND_UP(bits, 8);
 358}
 359
 360static inline pixman_format_code_t surface_format(DisplaySurface *s)
 361{
 362    return s->format;
 363}
 364
 365typedef uint32_t console_ch_t;
 366
 367static inline void console_write_ch(console_ch_t *dest, uint32_t ch)
 368{
 369    *dest = ch;
 370}
 371
 372typedef struct GraphicHwOps {
 373    void (*invalidate)(void *opaque);
 374    void (*gfx_update)(void *opaque);
 375    void (*text_update)(void *opaque, console_ch_t *text);
 376    void (*update_interval)(void *opaque, uint64_t interval);
 377    int (*ui_info)(void *opaque, uint32_t head, QemuUIInfo *info);
 378    void (*gl_block)(void *opaque, bool block);
 379} GraphicHwOps;
 380
 381QemuConsole *graphic_console_init(DeviceState *dev, uint32_t head,
 382                                  const GraphicHwOps *ops,
 383                                  void *opaque);
 384void graphic_console_set_hwops(QemuConsole *con,
 385                               const GraphicHwOps *hw_ops,
 386                               void *opaque);
 387
 388void graphic_hw_update(QemuConsole *con);
 389void graphic_hw_invalidate(QemuConsole *con);
 390void graphic_hw_text_update(QemuConsole *con, console_ch_t *chardata);
 391void graphic_hw_gl_block(QemuConsole *con, bool block);
 392
 393void qemu_console_early_init(void);
 394
 395QemuConsole *qemu_console_lookup_by_index(unsigned int index);
 396QemuConsole *qemu_console_lookup_by_device(DeviceState *dev, uint32_t head);
 397QemuConsole *qemu_console_lookup_by_device_name(const char *device_id,
 398                                                uint32_t head, Error **errp);
 399bool qemu_console_is_visible(QemuConsole *con);
 400bool qemu_console_is_graphic(QemuConsole *con);
 401bool qemu_console_is_fixedsize(QemuConsole *con);
 402bool qemu_console_is_gl_blocked(QemuConsole *con);
 403char *qemu_console_get_label(QemuConsole *con);
 404int qemu_console_get_index(QemuConsole *con);
 405uint32_t qemu_console_get_head(QemuConsole *con);
 406QemuUIInfo *qemu_console_get_ui_info(QemuConsole *con);
 407int qemu_console_get_width(QemuConsole *con, int fallback);
 408int qemu_console_get_height(QemuConsole *con, int fallback);
 409/* Return the low-level window id for the console */
 410int qemu_console_get_window_id(QemuConsole *con);
 411/* Set the low-level window id for the console */
 412void qemu_console_set_window_id(QemuConsole *con, int window_id);
 413
 414void console_select(unsigned int index);
 415void qemu_console_resize(QemuConsole *con, int width, int height);
 416DisplaySurface *qemu_console_surface(QemuConsole *con);
 417
 418/* console-gl.c */
 419#ifdef CONFIG_OPENGL
 420bool console_gl_check_format(DisplayChangeListener *dcl,
 421                             pixman_format_code_t format);
 422void surface_gl_create_texture(QemuGLShader *gls,
 423                               DisplaySurface *surface);
 424void surface_gl_update_texture(QemuGLShader *gls,
 425                               DisplaySurface *surface,
 426                               int x, int y, int w, int h);
 427void surface_gl_render_texture(QemuGLShader *gls,
 428                               DisplaySurface *surface);
 429void surface_gl_destroy_texture(QemuGLShader *gls,
 430                               DisplaySurface *surface);
 431void surface_gl_setup_viewport(QemuGLShader *gls,
 432                               DisplaySurface *surface,
 433                               int ww, int wh);
 434#endif
 435
 436/* sdl.c */
 437#ifdef CONFIG_SDL
 438void sdl_display_early_init(int opengl);
 439void sdl_display_init(DisplayState *ds, int full_screen, int no_frame);
 440#else
 441static inline void sdl_display_early_init(int opengl)
 442{
 443    /* This must never be called if CONFIG_SDL is disabled */
 444    error_report("SDL support is disabled");
 445    abort();
 446}
 447static inline void sdl_display_init(DisplayState *ds, int full_screen,
 448                                    int no_frame)
 449{
 450    /* This must never be called if CONFIG_SDL is disabled */
 451    error_report("SDL support is disabled");
 452    abort();
 453}
 454#endif
 455
 456/* cocoa.m */
 457#ifdef CONFIG_COCOA
 458void cocoa_display_init(DisplayState *ds, int full_screen);
 459#else
 460static inline void cocoa_display_init(DisplayState *ds, int full_screen)
 461{
 462    /* This must never be called if CONFIG_COCOA is disabled */
 463    error_report("Cocoa support is disabled");
 464    abort();
 465}
 466#endif
 467
 468/* vnc.c */
 469void vnc_display_init(const char *id);
 470void vnc_display_open(const char *id, Error **errp);
 471void vnc_display_add_client(const char *id, int csock, bool skipauth);
 472#ifdef CONFIG_VNC
 473int vnc_display_password(const char *id, const char *password);
 474int vnc_display_pw_expire(const char *id, time_t expires);
 475QemuOpts *vnc_parse(const char *str, Error **errp);
 476int vnc_init_func(void *opaque, QemuOpts *opts, Error **errp);
 477#else
 478static inline int vnc_display_password(const char *id, const char *password)
 479{
 480    return -ENODEV;
 481}
 482static inline int vnc_display_pw_expire(const char *id, time_t expires)
 483{
 484    return -ENODEV;
 485};
 486static inline QemuOpts *vnc_parse(const char *str, Error **errp)
 487{
 488    error_setg(errp, "VNC support is disabled");
 489    return NULL;
 490}
 491static inline int vnc_init_func(void *opaque, QemuOpts *opts, Error **errp)
 492{
 493    error_setg(errp, "VNC support is disabled");
 494    return -1;
 495}
 496#endif
 497
 498/* curses.c */
 499#ifdef CONFIG_CURSES
 500void curses_display_init(DisplayState *ds, int full_screen);
 501#else
 502static inline void curses_display_init(DisplayState *ds, int full_screen)
 503{
 504    /* This must never be called if CONFIG_CURSES is disabled */
 505    error_report("curses support is disabled");
 506    abort();
 507}
 508#endif
 509
 510/* input.c */
 511int index_from_key(const char *key, size_t key_length);
 512
 513/* gtk.c */
 514#ifdef CONFIG_GTK
 515void early_gtk_display_init(int opengl);
 516void gtk_display_init(DisplayState *ds, bool full_screen, bool grab_on_hover);
 517#else
 518static inline void gtk_display_init(DisplayState *ds, bool full_screen,
 519                                    bool grab_on_hover)
 520{
 521    /* This must never be called if CONFIG_GTK is disabled */
 522    error_report("GTK support is disabled");
 523    abort();
 524}
 525
 526static inline void early_gtk_display_init(int opengl)
 527{
 528    /* This must never be called if CONFIG_GTK is disabled */
 529    error_report("GTK support is disabled");
 530    abort();
 531}
 532#endif
 533
 534/* egl-headless.c */
 535void egl_headless_init(void);
 536
 537#endif
 538