[Date Prev][Date Next] [Thread Prev][Thread Next]
[Thread Index]
[Date Index]
[Author Index]
problem with delayed update after gtk_widget_draw()
- From: David Arnold <arnold dstc edu au>
- To: gtk-app-devel-list redhat com
- Subject: problem with delayed update after gtk_widget_draw()
- Date: Sat, 16 Oct 1999 17:38:57 +1000
hi all,
i'm having a problem with a a small application, where the
expose_event handler used to copy a backing pixmap onto the
drawing_area widget appears to have an odd delayed effect.
the application is multi-threaded, and in one thread gets a network
packet which has data used to update the backing pixmap. before
calling any of the gdk_* functions to write to the pixmap, i call
gdk_threads_enter(), do my drawing, call gtk_widget_draw() and finally
gdk_threads_leave() after i'm done.
i've also got the threads_enter/leave around the gtk_main().
problem is, the update doesn't seem to happen. the expose_event
handler runs ok, but the drawing_area does not change until either 3
or 4 expose_events have been processed, or, until i move the mouse
over the application window. if i do just one update/expose, the
drawing_area does not get updated (well, i've only waiting for like 10
minutes).
after sending 3 or 4 updates (and thus gtk_widget_draw() is called 3
or 4 times), the drawing_area is updated, but the data might from
either the last or the second last update.
it feels like the X event queue is not being processed in reasonable
time for some reason. i fear thread problems, but wondered if anyone
had suggestions for stupid error i might have made?
for further oddness, under gdb on Linux (debian 2.1) the problem does
not occur. under gdb on solaris i get the same broken-ness as normal
execution.
thanks in advance for any ideas,
d
code below has been cut&pasted out of order ... the Elvin stuff is a
notification service which does callbacks in a separate thread (which
calls deliver()).
int main(int argc, char *argv[])
{
GtkWidget *window, *vbox, *drawing_area;
/* initialise Gtk */
if (! g_thread_supported()) {
g_thread_init(NULL);
}
gtk_init(&argc, &argv);
/* create application window */
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window), "Brisbane");
gtk_signal_connect(GTK_OBJECT(window),
"destroy",
GTK_SIGNAL_FUNC (quit),
NULL);
vbox = gtk_vbox_new(FALSE, 0);
gtk_container_add(GTK_CONTAINER(window), vbox);
gtk_widget_show(vbox);
/* create the drawing area */
drawing_area = gtk_drawing_area_new();
gtk_drawing_area_size(GTK_DRAWING_AREA(drawing_area), 370, 220);
gtk_box_pack_start(GTK_BOX(vbox), drawing_area, TRUE, TRUE, 0);
gtk_widget_show(drawing_area);
/* connect to Elvin */
elvin = elvin_connect(EC_NAMEDHOST, "localhost", 5678,
NULL, NULL,
NULL, NULL,
0);
/* create weather model */
w = weather_alloc();
/* create weather view */
wv = weather_view_alloc(drawing_area);
/* paint initial view contents */
gtk_widget_show(window);
weather_view_update(wv, w);
/* subscribe to weather updates */
weather_sub = elvin_add_subscription(elvin,
"exists(org.elvin.weather)",
deliver,
NULL,
1);
/* ok, go! */
gdk_threads_enter();
gtk_main();
gdk_threads_leave();
exit(0);
}
void deliver(elvin_t elvin, void *arg, uint32 sub_id, en_notify_t nfn)
{
en_type_t type;
void *value;
g_print("deliver\n");
if (! en_search(nfn, "temp", &type, &value)) {
weather_set_temp(w, *(float *)value);
}
en_free(nfn);
/* update GUI */
weather_view_update(wv, w);
return;
}
void weather_view_update(weather_view_t wv, weather_t w)
{
GdkRectangle update_rect;
char buf[100];
gdk_threads_enter();
/* clear background */
gdk_draw_rectangle(pixmap,
wv->drawing_area->style->white_gc,
TRUE,
0, 0,
wv->drawing_area->allocation.width,
wv->drawing_area->allocation.height);
/* temperature */
snprintf(buf, 4, "%2.0f\260", weather_get_temp(w));
gdk_draw_string(pixmap,
wv->temp->font,
wv->drawing_area->style->black_gc,
15, 74, buf);
snprintf(buf, 10, "min %2.1f", weather_get_temp_min(w));
gdk_draw_string(pixmap,
wv->detail->font,
wv->drawing_area->style->black_gc,
110, 62, buf);
snprintf(buf, 10, "max %2.1f", weather_get_temp_max(w));
gdk_draw_string(pixmap,
wv->detail->font,
wv->drawing_area->style->black_gc,
110, 74, buf);
/* force redraw onto window */
update_rect.x = 0;
update_rect.y = 0;
update_rect.width = wv->drawing_area->allocation.width;
update_rect.height = wv->drawing_area->allocation.height;
gtk_widget_draw(wv->drawing_area, &update_rect);
gdk_threads_leave();
return;
}
static gint expose_event(GtkWidget *widget, GdkEventExpose *event)
{
/* copy the backing pixmap into the drawing area */
gdk_draw_pixmap(widget->window,
widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
pixmap,
event->area.x, event->area.y,
event->area.x, event->area.y,
event->area.width, event->area.height);
g_print("expose (copied pixmap to widget->window)\n");
return FALSE;
}
[Date Prev][Date Next] [Thread Prev][Thread Next]
[Thread Index]
[Date Index]
[Author Index]