Skip to content

Commit

Permalink
gtk: stop using DisplayState
Browse files Browse the repository at this point in the history
Rework DisplayStateListener callbacks to not use the DisplayState
any more.  Factor out the window size handling to a separate function,
so the zoom callbacks can call that directly instead of abusing the
gd_switch DisplayStateListener callback for that.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
  • Loading branch information
kraxel committed Mar 18, 2013
1 parent 626e3b3 commit 9d9801c
Showing 1 changed file with 80 additions and 60 deletions.
140 changes: 80 additions & 60 deletions ui/gtk.c
Expand Up @@ -143,7 +143,7 @@ typedef struct GtkDisplayState
GtkWidget *drawing_area;
cairo_surface_t *surface;
DisplayChangeListener dcl;
DisplayState *ds;
DisplaySurface *ds;
int button_mask;
int last_x;
int last_y;
Expand Down Expand Up @@ -225,10 +225,48 @@ static void gd_update_caption(GtkDisplayState *s)
g_free(title);
}

static void gd_update_windowsize(GtkDisplayState *s)
{
if (!s->full_screen) {
GtkRequisition req;
double sx, sy;

if (s->free_scale) {
sx = s->scale_x;
sy = s->scale_y;

s->scale_y = 1.0;
s->scale_x = 1.0;
} else {
sx = 1.0;
sy = 1.0;
}

gtk_widget_set_size_request(s->drawing_area,
surface_width(s->ds) * s->scale_x,
surface_height(s->ds) * s->scale_y);
#if GTK_CHECK_VERSION(3, 0, 0)
gtk_widget_get_preferred_size(s->vbox, NULL, &req);
#else
gtk_widget_size_request(s->vbox, &req);
#endif

gtk_window_resize(GTK_WINDOW(s->window),
req.width * sx, req.height * sy);
}
}

static void gd_update_full_redraw(GtkDisplayState *s)
{
int ww, wh;
gdk_drawable_get_size(gtk_widget_get_window(s->drawing_area), &ww, &wh);
gtk_widget_queue_draw_area(s->drawing_area, 0, 0, ww, wh);
}

/** DisplayState Callbacks **/

static void gd_update(DisplayChangeListener *dcl,
DisplayState *ds, int x, int y, int w, int h)
DisplayState *dontuse, int x, int y, int w, int h)
{
GtkDisplayState *s = container_of(dcl, GtkDisplayState, dcl);
int x1, x2, y1, y2;
Expand All @@ -244,8 +282,8 @@ static void gd_update(DisplayChangeListener *dcl,
x2 = ceil(x * s->scale_x + w * s->scale_x);
y2 = ceil(y * s->scale_y + h * s->scale_y);

fbw = ds_get_width(s->ds) * s->scale_x;
fbh = ds_get_height(s->ds) * s->scale_y;
fbw = surface_width(s->ds) * s->scale_x;
fbh = surface_height(s->ds) * s->scale_y;

gdk_drawable_get_size(gtk_widget_get_window(s->drawing_area), &ww, &wh);

Expand All @@ -261,27 +299,34 @@ static void gd_update(DisplayChangeListener *dcl,
}

static void gd_refresh(DisplayChangeListener *dcl,
DisplayState *ds)
DisplayState *dontuse)
{
vga_hw_update();
}

static void gd_switch(DisplayChangeListener *dcl,
DisplayState *ds,
DisplayState *dontuse,
DisplaySurface *surface)
{
GtkDisplayState *s = container_of(dcl, GtkDisplayState, dcl);
cairo_format_t kind;
bool resized = true;
int stride;

DPRINTF("resize(width=%d, height=%d)\n",
ds_get_width(ds), ds_get_height(ds));
surface_width(surface), surface_height(surface));

if (s->surface) {
cairo_surface_destroy(s->surface);
}

switch (ds->surface->pf.bits_per_pixel) {
if (s->ds &&
surface_width(s->ds) == surface_width(surface) &&
surface_height(s->ds) == surface_height(surface)) {
resized = false;
}
s->ds = surface;
switch (surface_bits_per_pixel(surface)) {
case 8:
kind = CAIRO_FORMAT_A8;
break;
Expand All @@ -296,41 +341,19 @@ static void gd_switch(DisplayChangeListener *dcl,
break;
}

stride = cairo_format_stride_for_width(kind, ds_get_width(ds));
g_assert(ds_get_linesize(ds) == stride);
stride = cairo_format_stride_for_width(kind, surface_width(surface));
g_assert(surface_stride(surface) == stride);

s->surface = cairo_image_surface_create_for_data(ds_get_data(ds),
s->surface = cairo_image_surface_create_for_data(surface_data(surface),
kind,
ds_get_width(ds),
ds_get_height(ds),
ds_get_linesize(ds));

if (!s->full_screen) {
GtkRequisition req;
double sx, sy;

if (s->free_scale) {
sx = s->scale_x;
sy = s->scale_y;

s->scale_y = 1.0;
s->scale_x = 1.0;
} else {
sx = 1.0;
sy = 1.0;
}

gtk_widget_set_size_request(s->drawing_area,
ds_get_width(ds) * s->scale_x,
ds_get_height(ds) * s->scale_y);
#if GTK_CHECK_VERSION(3, 0, 0)
gtk_widget_get_preferred_size(s->vbox, NULL, &req);
#else
gtk_widget_size_request(s->vbox, &req);
#endif
surface_width(surface),
surface_height(surface),
surface_stride(surface));

gtk_window_resize(GTK_WINDOW(s->window),
req.width * sx, req.height * sy);
if (resized) {
gd_update_windowsize(s);
} else {
gd_update_full_redraw(s);
}
}

Expand Down Expand Up @@ -405,8 +428,8 @@ static gboolean gd_draw_event(GtkWidget *widget, cairo_t *cr, void *opaque)
return FALSE;
}

fbw = ds_get_width(s->ds);
fbh = ds_get_height(s->ds);
fbw = surface_width(s->ds);
fbh = surface_height(s->ds);

gdk_drawable_get_size(gtk_widget_get_window(widget), &ww, &wh);

Expand Down Expand Up @@ -484,8 +507,8 @@ static gboolean gd_motion_event(GtkWidget *widget, GdkEventMotion *motion,
int fbh, fbw;
int ww, wh;

fbw = ds_get_width(s->ds) * s->scale_x;
fbh = ds_get_height(s->ds) * s->scale_y;
fbw = surface_width(s->ds) * s->scale_x;
fbh = surface_height(s->ds) * s->scale_y;

gdk_drawable_get_size(gtk_widget_get_window(s->drawing_area), &ww, &wh);

Expand All @@ -501,14 +524,14 @@ static gboolean gd_motion_event(GtkWidget *widget, GdkEventMotion *motion,
y = (motion->y - my) / s->scale_y;

if (x < 0 || y < 0 ||
x >= ds_get_width(s->ds) ||
y >= ds_get_height(s->ds)) {
x >= surface_width(s->ds) ||
y >= surface_height(s->ds)) {
return TRUE;
}

if (kbd_mouse_is_absolute()) {
dx = x * 0x7FFF / (ds_get_width(s->ds) - 1);
dy = y * 0x7FFF / (ds_get_height(s->ds) - 1);
dx = x * 0x7FFF / (surface_width(s->ds) - 1);
dy = y * 0x7FFF / (surface_height(s->ds) - 1);
} else if (s->last_x == -1 || s->last_y == -1) {
dx = 0;
dy = 0;
Expand Down Expand Up @@ -589,8 +612,8 @@ static gboolean gd_button_event(GtkWidget *widget, GdkEventButton *button,
}

if (kbd_mouse_is_absolute()) {
dx = s->last_x * 0x7FFF / (ds_get_width(s->ds) - 1);
dy = s->last_y * 0x7FFF / (ds_get_height(s->ds) - 1);
dx = s->last_x * 0x7FFF / (surface_width(s->ds) - 1);
dy = s->last_y * 0x7FFF / (surface_height(s->ds) - 1);
} else {
dx = 0;
dy = 0;
Expand Down Expand Up @@ -719,7 +742,8 @@ static void gd_menu_full_screen(GtkMenuItem *item, void *opaque)
gd_menu_show_tabs(GTK_MENU_ITEM(s->show_tabs_item), s);
gtk_widget_set_size_request(s->menu_bar, -1, -1);
gtk_widget_set_size_request(s->drawing_area,
ds_get_width(s->ds), ds_get_height(s->ds));
surface_width(s->ds),
surface_height(s->ds));
gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(s->grab_item), FALSE);
s->full_screen = FALSE;
s->scale_x = 1.0;
Expand All @@ -739,7 +763,7 @@ static void gd_menu_zoom_in(GtkMenuItem *item, void *opaque)
s->scale_x += .25;
s->scale_y += .25;

gd_switch(&s->dcl, s->ds, s->ds->surface);
gd_update_windowsize(s);
}

static void gd_menu_zoom_out(GtkMenuItem *item, void *opaque)
Expand All @@ -755,7 +779,7 @@ static void gd_menu_zoom_out(GtkMenuItem *item, void *opaque)
s->scale_x = MAX(s->scale_x, .25);
s->scale_y = MAX(s->scale_y, .25);

gd_switch(&s->dcl, s->ds, s->ds->surface);
gd_update_windowsize(s);
}

static void gd_menu_zoom_fixed(GtkMenuItem *item, void *opaque)
Expand All @@ -765,24 +789,21 @@ static void gd_menu_zoom_fixed(GtkMenuItem *item, void *opaque)
s->scale_x = 1.0;
s->scale_y = 1.0;

gd_switch(&s->dcl, s->ds, s->ds->surface);
gd_update_windowsize(s);
}

static void gd_menu_zoom_fit(GtkMenuItem *item, void *opaque)
{
GtkDisplayState *s = opaque;
int ww, wh;

if (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(s->zoom_fit_item))) {
s->free_scale = TRUE;
} else {
s->free_scale = FALSE;
}

gd_switch(&s->dcl, s->ds, s->ds->surface);

gdk_drawable_get_size(gtk_widget_get_window(s->drawing_area), &ww, &wh);
gtk_widget_queue_draw_area(s->drawing_area, 0, 0, ww, wh);
gd_update_windowsize(s);
gd_update_full_redraw(s);
}

static void gd_grab_keyboard(GtkDisplayState *s)
Expand Down Expand Up @@ -1298,7 +1319,6 @@ void gtk_display_init(DisplayState *ds)

gtk_init(NULL, NULL);

s->ds = ds;
s->dcl.ops = &dcl_ops;

s->window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
Expand Down

0 comments on commit 9d9801c

Please sign in to comment.