Here's what I tried:
#include <gtk/gtk.h>
static GtkWidget *window, *drawing_area;
static gboolean drawCallback(GtkWidget *widget, cairo_t *cr, gpointer arg) {
cairo_set_source_rgb(cr, 1.0, 0, 0);
cairo_arc(cr, 200.0, 150.0, 50.0, 0, 2*G_PI);
cairo_fill(cr);
}
static gboolean savePNG(gpointer arg) {
cairo_surface_t *surface = cairo_image_surface_create(
CAIRO_FORMAT_RGB24, 400, 300
);
cairo_t *cr = cairo_create(surface);
gdk_cairo_set_source_window(
cr,
gtk_widget_get_window(GTK_WIDGET(window)),
0, 0
);
printf("cairo_status(cr): %s\ncairo_surface_status(surface): %s\n",
cairo_status_to_string(cairo_status(cr)),
cairo_status_to_string(cairo_surface_status(surface)));
cairo_surface_write_to_png(surface, "test.png");
}
static void app_activate(GtkApplication *app, gpointer user_data) {
window = gtk_application_window_new(app);
gtk_window_set_title(GTK_WINDOW(window), "Sandbox");
gtk_widget_set_size_request(GTK_WIDGET(window), 400, 300);
gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
drawing_area = gtk_drawing_area_new();
gtk_container_add(GTK_CONTAINER(window), drawing_area);
g_signal_connect(G_OBJECT(drawing_area), "draw", G_CALLBACK(drawCallback), NULL);
gtk_widget_show_all(window);
gtk_window_move(GTK_WINDOW(window), 10, 10);
}
int main(int argc, char **argv) {
GtkApplication *app;
int status;
app = gtk_application_new("the.application.id", G_APPLICATION_FLAGS_NONE);
g_signal_connect(app, "activate", G_CALLBACK(app_activate), NULL);
g_timeout_add(1000, savePNG, NULL);
status = g_application_run(G_APPLICATION(app), argc, argv);
g_object_unref(app);
return status;
}
The window shows a red circle, but the test.png file that is created contains an all black image.
Here's the output:
cairo_status(cr): no error has occurred
cairo_surface_status(surface): no error has occurred
This answer suggested the pattern that I used.