I am developing a simple interface which simulates a led using GTK3 and C. When I receive a command the "led" turn on or turn off according to command. I am using Cairo in drawing area to draw a circle representing my led and I am using gtk_widget_queue_draw_area to update screen in my timeout function. After a while my CPU usage increase to 100% in my application.
When I receive a command I call the function below
void update_status_led(int led, int status_led)
{
g_signal_connect(G_OBJECT(darea[led]), "draw", G_CALLBACK(on_draw_event_leds), GINT_TO_POINTER(status_led));
}
so the callback function "on_draw_event_leds" is called
gboolean on_draw_event_leds(GtkWidget *widget, cairo_t *cr,
gpointer user_data)
{
set_status_led(cr, GPOINTER_TO_INT(user_data));
return FALSE;
}
So it calls the function "set_status_led"
void set_status_led(cairo_t *cr, int status)
{
printf("update status led: %d\n", countref++);
cairo_reference(cr);
cairo_set_line_width(cr, 2);
cairo_set_source_rgb(cr, 0, 0, 0);
cairo_arc(cr, 9, 9, 7, 0, 2 * M_PI);
if (status>0)
{
cairo_set_source_rgb(cr, 1, 0, 0); //red
}
else
{
cairo_set_source_rgb(cr, 0, 0, 0); //black
}
cairo_fill(cr);
cairo_stroke(cr);
cairo_destroy(cr);
}
I am using "printf("update status led: %d\n", countref++);" to know how many times my function is called and my log is printed below
New Connection from 127.0.0.1:34589
1 Command Received
update status led: 6
update status led: 7
1 Command Received
update status led: 8
update status led: 9
update status led: 10
1 Command Received
update status led: 11
update status led: 12
update status led: 13
update status led: 14
1 Command Received
update status led: 15
update status led: 16
update status led: 17
update status led: 18
update status led: 19
1 Command Received
update status led: 20
update status led: 21
update status led: 22
update status led: 23
update status led: 24
update status led: 25
1 Command Received
...
As can be seen, I receive only one command and my callback function on_draw_event_leds is called many times and always increase 1 more call each received command as previous cairo was not deleted and gtk_widget_queue_draw_area render them all again.
Can someone help me?
Thanks,
cairo_reference()
andcairo_destroy()
; you do not own thecairo_t
that you get from thedraw
callback. Second,cairo_fill()
clears the current path, so yourcairo_stroke()
draws nothing. Useciaro_fill_preserve()
instead. I'll take a closer look later today. – andlabsupdate_status_led()
on every change.g_signal_connect()
does NOT replace any existing connection with a new one; rather, it adds a new connection to the list of existing connections. So all the signal handlers you connected before are still there. You will need to change your code to only callg_signal_connect()
once. Perhaps store the current state in a global variable or a shared variable passed around through the lastgpointer
parameter to the signal function and usegtk_widget_queue_draw()
to schedule a redraw. – andlabswinapi
tag. Admittedly this question should be answered by what I said; I can write up a more thorough answer too, but right now I'm busy with IRL stuff. – andlabs