}
window = gtk_widget_get_window(GTK_WIDGET(vc->gfx.drawing_area));
- if (s->full_screen || qemu_input_is_absolute() || s->ptr_owner == vc) {
+ if (s->full_screen || qemu_input_is_absolute(vc->gfx.dcl.con) || s->ptr_owner == vc) {
gdk_window_set_cursor(window, s->null_cursor);
} else {
gdk_window_set_cursor(window, NULL);
gint x_root, y_root;
if (!gtk_widget_get_realized(vc->gfx.drawing_area) ||
- qemu_input_is_absolute()) {
+ qemu_input_is_absolute(dcl->con)) {
return;
}
}
vc->gfx.ds = surface;
- if (surface->format == PIXMAN_x8r8g8b8) {
+ if (surface_format(surface) == PIXMAN_x8r8g8b8) {
/*
* PIXMAN_x8r8g8b8 == CAIRO_FORMAT_RGB24
*
{
VirtualConsole *vc = vcon;
QemuDmaBuf *dmabuf = vc->gfx.guest_fb.dmabuf;
+ int fence_fd;
- qemu_set_fd_handler(dmabuf->fence_fd, NULL, NULL, NULL);
- close(dmabuf->fence_fd);
- dmabuf->fence_fd = -1;
- graphic_hw_gl_block(vc->gfx.dcl.con, false);
+ fence_fd = qemu_dmabuf_get_fence_fd(dmabuf);
+ if (fence_fd >= 0) {
+ qemu_set_fd_handler(fence_fd, NULL, NULL, NULL);
+ close(fence_fd);
+ qemu_dmabuf_set_fence_fd(dmabuf, -1);
+ graphic_hw_gl_block(vc->gfx.dcl.con, false);
+ }
}
/** DisplayState Callbacks (opengl version) **/
s = container_of(notify, GtkDisplayState, mouse_mode_notifier);
/* release the grab at switching to absolute mode */
- if (qemu_input_is_absolute() && s->ptr_owner) {
+ if (s->ptr_owner && qemu_input_is_absolute(s->ptr_owner->gfx.dcl.con)) {
if (!s->ptr_owner->window) {
gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(s->grab_item),
FALSE);
{
QemuUIInfo info;
+ if (!dpy_ui_info_supported(vc->gfx.dcl.con)) {
+ return;
+ }
+
info = *dpy_get_ui_info(vc->gfx.dcl.con);
info.refresh_rate = refresh_rate;
dpy_set_ui_info(vc->gfx.dcl.con, &info, true);
{
QemuUIInfo info;
+ if (!dpy_ui_info_supported(vc->gfx.dcl.con)) {
+ return;
+ }
+
info = *dpy_get_ui_info(vc->gfx.dcl.con);
info.width = width;
info.height = height;
int x, y;
int mx, my;
int fbh, fbw;
- int ww, wh, ws;
+ int ww, wh;
if (!vc->gfx.ds) {
return TRUE;
fbw = surface_width(vc->gfx.ds) * vc->gfx.scale_x;
fbh = surface_height(vc->gfx.ds) * vc->gfx.scale_y;
-
ww = gtk_widget_get_allocated_width(widget);
wh = gtk_widget_get_allocated_height(widget);
- ws = gtk_widget_get_scale_factor(widget);
+ /*
+ * `widget` may not have the same size with the frame buffer.
+ * In such cases, some paddings are needed around the `vc`.
+ * To achieve that, `vc` will be displayed at (mx, my)
+ * so that it is displayed at the center of the widget.
+ */
mx = my = 0;
if (ww > fbw) {
mx = (ww - fbw) / 2;
my = (wh - fbh) / 2;
}
- x = (motion->x - mx) / vc->gfx.scale_x * ws;
- y = (motion->y - my) / vc->gfx.scale_y * ws;
+ /*
+ * `motion` is reported in `widget` coordinates
+ * so translating it to the coordinates in `vc`.
+ */
+ x = (motion->x - mx) / vc->gfx.scale_x;
+ y = (motion->y - my) / vc->gfx.scale_y;
+
+ trace_gd_motion_event(ww, wh, gtk_widget_get_scale_factor(widget), x, y);
- if (qemu_input_is_absolute()) {
+ if (qemu_input_is_absolute(vc->gfx.dcl.con)) {
if (x < 0 || y < 0 ||
x >= surface_width(vc->gfx.ds) ||
y >= surface_height(vc->gfx.ds)) {
s->last_y = y;
s->last_set = TRUE;
- if (!qemu_input_is_absolute() && s->ptr_owner == vc) {
+ if (!qemu_input_is_absolute(vc->gfx.dcl.con) && s->ptr_owner == vc) {
GdkScreen *screen = gtk_widget_get_screen(vc->gfx.drawing_area);
GdkDisplay *dpy = gtk_widget_get_display(widget);
GdkWindow *win = gtk_widget_get_window(widget);
GdkMonitor *monitor = gdk_display_get_monitor_at_window(dpy, win);
GdkRectangle geometry;
- int x = (int)motion->x_root;
- int y = (int)motion->y_root;
+ int xr = (int)motion->x_root;
+ int yr = (int)motion->y_root;
gdk_monitor_get_geometry(monitor, &geometry);
* may still be only half way across the screen. Without
* this warp, the server pointer would thus appear to hit
* an invisible wall */
- if (x <= geometry.x || x - geometry.x >= geometry.width - 1 ||
- y <= geometry.y || y - geometry.y >= geometry.height - 1) {
+ if (xr <= geometry.x || xr - geometry.x >= geometry.width - 1 ||
+ yr <= geometry.y || yr - geometry.y >= geometry.height - 1) {
GdkDevice *dev = gdk_event_get_device((GdkEvent *)motion);
- x = geometry.x + geometry.width / 2;
- y = geometry.y + geometry.height / 2;
+ xr = geometry.x + geometry.width / 2;
+ yr = geometry.y + geometry.height / 2;
- gdk_device_warp(dev, screen, x, y);
+ gdk_device_warp(dev, screen, xr, yr);
s->last_set = FALSE;
return FALSE;
}
/* implicitly grab the input at the first click in the relative mode */
if (button->button == 1 && button->type == GDK_BUTTON_PRESS &&
- !qemu_input_is_absolute() && s->ptr_owner != vc) {
+ !qemu_input_is_absolute(vc->gfx.dcl.con) && s->ptr_owner != vc) {
if (!vc->window) {
gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(s->grab_item),
TRUE);
GdkEventKey *key, void *opaque)
{
VirtualConsole *vc = opaque;
- QemuConsole *con = vc->gfx.dcl.con;
+ QemuTextConsole *con = QEMU_TEXT_CONSOLE(vc->gfx.dcl.con);
if (key->keyval == GDK_KEY_Delete) {
- kbd_put_qcode_console(con, Q_KEY_CODE_DELETE, false);
+ qemu_text_console_put_qcode(con, Q_KEY_CODE_DELETE, false);
} else if (key->length) {
- kbd_put_string_console(con, key->string, key->length);
+ qemu_text_console_put_string(con, key->string, key->length);
} else {
int qcode = gd_map_keycode(gd_get_keycode(key));
- kbd_put_qcode_console(con, qcode, false);
+ qemu_text_console_put_qcode(con, qcode, false);
}
return TRUE;
}
eglDestroySurface(qemu_egl_display, vc->gfx.esurface);
vc->gfx.esurface = NULL;
}
- if (vc->gfx.esurface) {
+ if (vc->gfx.ectx) {
eglDestroyContext(qemu_egl_display, vc->gfx.ectx);
vc->gfx.ectx = NULL;
}
{
ChardevClass *cc = CHARDEV_CLASS(oc);
- cc->parse = qemu_chr_parse_vc;
cc->open = gd_vc_open;
cc->chr_write = gd_vc_chr_write;
cc->chr_accept_input = gd_vc_chr_accept_input;
{
VirtualConsole *vc;
- GtkDisplayState *s = g_malloc0(sizeof(*s));
+ GtkDisplayState *s;
GdkDisplay *window_display;
GtkIconTheme *theme;
char *dir;
+ int idx;
if (!gtkinit) {
fprintf(stderr, "gtk initialization failed\n");
exit(1);
}
assert(opts->type == DISPLAY_TYPE_GTK);
+ s = g_malloc0(sizeof(*s));
s->opts = opts;
theme = gtk_icon_theme_get_default();
gtk_container_add(GTK_CONTAINER(s->window), s->vbox);
gtk_widget_show_all(s->window);
+
+ for (idx = 0;; idx++) {
+ QemuConsole *con = qemu_console_lookup_by_index(idx);
+ if (!con) {
+ break;
+ }
+ gtk_widget_realize(s->vc[idx].gfx.drawing_area);
+ }
+
if (opts->u.gtk.has_show_menubar &&
!opts->u.gtk.show_menubar) {
gtk_widget_hide(s->menu_bar);
.type = DISPLAY_TYPE_GTK,
.early_init = early_gtk_display_init,
.init = gtk_display_init,
+ .vc = "vc",
};
static void register_gtk(void)