+static gboolean
+expose_event_callback (GtkWidget *widget, GdkEventExpose *event, gpointer data)
+{
+ struct som_entity *entity = g_object_get_data (G_OBJECT (widget), "entity");
+ GdkWindow *window = widget->window;
+ cairo_t *cairo = gdk_cairo_create (GDK_DRAWABLE (window));
+ struct outp_driver *driver = xr_create_driver (cairo); /* XXX can fail */
+ struct tab_table *t = entity->ext;
+ void *rendering;
+
+ rendering = entity->class->render_init (entity, driver, tab_l (t),
+ tab_r (t), tab_t (t), tab_b (t));
+
+ entity->class->title (rendering, 0, 0,
+ entity->table_num, entity->subtable_num);
+ entity->class->render (rendering, tab_l (t), tab_t (t),
+ tab_nc (t) - tab_r (t),
+ tab_nr (t) - tab_b (t));
+
+ entity->class->render_free (rendering);
+ driver->class->close_driver (driver);
+ outp_free_driver (driver);
+ return TRUE;
+}
+
+static void
+psppire_output_submit (struct outp_driver *this, struct som_entity *entity)
+{
+ if (the_output_viewer == NULL)
+ {
+ the_output_viewer = PSPPIRE_OUTPUT_WINDOW (psppire_output_window_new ());
+ gtk_widget_show_now (GTK_WIDGET (the_output_viewer));
+ }
+
+ if (entity->type == SOM_TABLE)
+ {
+ GdkWindow *window = GTK_WIDGET (the_output_viewer)->window;
+ cairo_t *cairo = gdk_cairo_create (GDK_DRAWABLE (window));
+ struct outp_driver *driver = xr_create_driver (cairo); /* XXX can fail */
+ struct tab_table *t = entity->ext;
+ GtkWidget *drawing_area;
+ void *rendering;
+ int tw, th;
+
+ tab_ref (t);
+ rendering = entity->class->render_init (entity, driver, tab_l (t),
+ tab_r (t), tab_t (t), tab_b (t));
+ entity->class->area (rendering, &tw, &th);
+
+ drawing_area = gtk_drawing_area_new ();
+ g_object_set_data (G_OBJECT (drawing_area),
+ "entity", xmemdup (entity, sizeof *entity));
+ gtk_widget_set_size_request (drawing_area, tw / 1024, th / 1024);
+ gtk_layout_put (the_output_viewer->output, drawing_area,
+ 0, the_output_viewer->y);
+ gtk_widget_show (drawing_area);
+ g_signal_connect (G_OBJECT (drawing_area), "expose_event",
+ G_CALLBACK (expose_event_callback), NULL);
+
+ entity->class->render_free (rendering);
+ driver->class->close_driver (driver);
+ outp_free_driver (driver);
+
+ the_output_viewer->y += th / 1024;
+ }
+
+ gtk_window_set_urgency_hint (GTK_WINDOW (the_output_viewer), TRUE);
+}
+
+static struct outp_class psppire_output_class =
+ {
+ "PSPPIRE", /* name */
+ true, /* special */
+ NULL, /* open_driver */
+ NULL, /* close_driver */
+ NULL, /* open_page */
+ NULL, /* close_page */
+ NULL, /* flush */
+ psppire_output_submit, /* submit */
+ NULL, /* line */
+ NULL, /* text_metrics */
+ NULL, /* text_draw */
+ NULL, /* initialise_chart */
+ NULL, /* finalise_chart */
+ };