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 <kra...@redhat.com>
---
 ui/gtk.c |  140 +++++++++++++++++++++++++++++++++++---------------------------
 1 file changed, 80 insertions(+), 60 deletions(-)

diff --git a/ui/gtk.c b/ui/gtk.c
index abef1ca..f06f18e 100644
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -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;
@@ -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;
@@ -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);
 
@@ -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;
@@ -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);
     }
 }
 
@@ -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);
 
@@ -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);
 
@@ -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;
@@ -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;
@@ -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;
@@ -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)
@@ -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)
@@ -765,13 +789,12 @@ 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;
@@ -779,10 +802,8 @@ static void gd_menu_zoom_fit(GtkMenuItem *item, void 
*opaque)
         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)
@@ -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);
-- 
1.7.9.7


Reply via email to