I am attempting to create a circular shape on a Gtk4 GtkDrawingarea using CSS. The goal is to then save the circle as a PNG file upon clicking on it. However, I am encountering difficulties in transferring the drawing (gradient) from the drawing area to a cairo surface (cairo_surface_t). Is there a way to save the drawing created through CSS? Below is the code snippet:
#include <gtk/gtk.h>
//draw function
static void
draw_function (GtkDrawingArea *darea,
cairo_t *cr,
int width,
int height,
gpointer user_data)
{
GdkDisplay *display = gdk_display_get_default ();
GtkCssProvider* provider = gtk_css_provider_new ();
gtk_css_provider_load_from_data (provider,
"#darea { border-radius: 50%;"
" background: radial-gradient(#FFFFFF, #000000); "
"}",-1);
gtk_style_context_add_provider (gtk_widget_get_style_context (GTK_WIDGET (darea)),
GTK_STYLE_PROVIDER (provider),GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
g_object_unref(provider);
}
/*save as png on click*/
void click_event (GtkEventController *gesture,
gdouble x,
gdouble y,
gpointer user_data)
{
//user_data = darea (widget)
int w1 = gtk_widget_get_allocated_width(user_data);
int h1 = gtk_widget_get_allocated_height(user_data);
/*paintable from the darea widget*/
GdkPaintable* paintable = gtk_widget_paintable_new (user_data);
/*take snapshot*/
GdkSnapshot* snapshot = gtk_snapshot_new();
gdk_paintable_snapshot (paintable, snapshot, w1, h1);
graphene_rect_t *rec = graphene_rect_alloc ();
GskRenderNode* ren = gsk_cairo_node_new (rec);
cairo_t* cr = gtk_snapshot_append_cairo (snapshot, rec);
cairo_surface_t* srf = gsk_cairo_node_get_surface ((GskRenderNode *)ren);
cairo_surface_write_to_png (srf, "blur.png"); //use it -error Segmentation fault
}
static void
activate (GtkApplication* app,
gpointer user_data)
{
GtkWidget *window;
window = gtk_application_window_new (app);
gtk_window_set_title (GTK_WINDOW (window), "Window");
gtk_window_set_default_size (GTK_WINDOW (window), 200, 200);
gtk_window_present (GTK_WINDOW (window));
GtkWidget *darea = gtk_drawing_area_new();
gtk_widget_set_name (darea, "darea");
gtk_drawing_area_set_content_width (GTK_DRAWING_AREA (darea), 350);
gtk_drawing_area_set_content_height (GTK_DRAWING_AREA (darea), 350);
gtk_drawing_area_set_draw_func (GTK_DRAWING_AREA (darea),
draw_function,
NULL, NULL);
gtk_window_set_child (GTK_WINDOW (window), darea);
//create gesture for mouse click event
GtkGesture * = gtk_gesture_click_new();
gtk_gesture_single_set_button(GTK_GESTURE_SINGLE(gesture), 0);
gtk_widget_add_controller(darea,(GTK_EVENT_CONTROLLER(gesture)));
g_signal_connect (gesture, "pressed", G_CALLBACK (click_event), darea);
gtk_window_present (GTK_WINDOW(window));
}
int
main (int argc,
char **argv)
{
GtkApplication *app;
int status;
app = gtk_application_new ("org.gtk.example", G_APPLICATION_DEFAULT_FLAGS);
g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
status = g_application_run (G_APPLICATION (app), argc, argv);
g_object_unref (app);
return status;
}
Unfortunately, the code is not functioning properly and results in a crash!