This should be used by threads when they finish loading something. Any
additional loading which must be done by the main thread will ideally be
done during the next draw.
static gboolean on_motion_notify(GritsOpenGL *opengl, GdkEventMotion *event, gpointer _)
{
opengl->mouse_queue = *event;
static gboolean on_motion_notify(GritsOpenGL *opengl, GdkEventMotion *event, gpointer _)
{
opengl->mouse_queue = *event;
- gtk_widget_queue_draw(GTK_WIDGET(opengl));
+ grits_viewer_queue_draw(GRITS_VIEWER(opengl));
/* Testing */
if (kv == GDK_w) {
opengl->wireframe = !opengl->wireframe;
/* Testing */
if (kv == GDK_w) {
opengl->wireframe = !opengl->wireframe;
- gtk_widget_queue_draw(GTK_WIDGET(opengl));
+ grits_viewer_queue_draw(GRITS_VIEWER(opengl));
}
if (kv == GDK_p) {
opengl->pickmode = !opengl->pickmode;
}
if (kv == GDK_p) {
opengl->pickmode = !opengl->pickmode;
- gtk_widget_queue_draw(GTK_WIDGET(opengl));
+ grits_viewer_queue_draw(GRITS_VIEWER(opengl));
}
#ifdef ROAM_DEBUG
else if (kv == GDK_n) roam_sphere_split_one(opengl->sphere);
else if (kv == GDK_p) roam_sphere_merge_one(opengl->sphere);
else if (kv == GDK_r) roam_sphere_split_merge(opengl->sphere);
else if (kv == GDK_u) roam_sphere_update_errors(opengl->sphere);
}
#ifdef ROAM_DEBUG
else if (kv == GDK_n) roam_sphere_split_one(opengl->sphere);
else if (kv == GDK_p) roam_sphere_merge_one(opengl->sphere);
else if (kv == GDK_r) roam_sphere_split_merge(opengl->sphere);
else if (kv == GDK_u) roam_sphere_update_errors(opengl->sphere);
- gtk_widget_queue_draw(GTK_WIDGET(opengl));
+ grits_viewer_queue_draw(GRITS_VIEWER(opengl));
while (viewer->rotation[2] > 180) viewer->rotation[2] -= 360;
}
while (viewer->rotation[2] > 180) viewer->rotation[2] -= 360;
}
+static gboolean _grits_viewer_queue_draw_cb(gpointer _viewer)
+{
+ GritsViewer *viewer = _viewer;
+ gtk_widget_queue_draw(GTK_WIDGET(viewer));
+ viewer->draw_source = 0;
+ return FALSE;
+}
+
/* Signal helpers */
static void _grits_viewer_emit_location_changed(GritsViewer *viewer)
{
/* Signal helpers */
static void _grits_viewer_emit_location_changed(GritsViewer *viewer)
{
static void on_view_changed(GritsViewer *viewer,
gdouble _1, gdouble _2, gdouble _3)
{
static void on_view_changed(GritsViewer *viewer,
gdouble _1, gdouble _2, gdouble _3)
{
- gtk_widget_queue_draw(GTK_WIDGET(viewer));
+ grits_viewer_queue_draw(viewer);
return viewer->offline;
}
return viewer->offline;
}
+/**
+ * grits_viewer_queue_draw:
+ * @viewer: the viewer
+ *
+ * Causes the viewer to redraw the screen. This has the safe effect as
+ * gtk_widget_queue_draw, but is thread safe, and probably faster.
+ */
+void grits_viewer_queue_draw(GritsViewer *viewer)
+{
+ if (!viewer->draw_source)
+ viewer->draw_source = g_idle_add_full(G_PRIORITY_HIGH,
+ _grits_viewer_queue_draw_cb, viewer, NULL);
+}
+
/***********************************
* To be implemented by subclasses *
***********************************/
/***********************************
* To be implemented by subclasses *
***********************************/
g_signal_connect(viewer, "location-changed", G_CALLBACK(on_view_changed), NULL);
g_signal_connect(viewer, "rotation-changed", G_CALLBACK(on_view_changed), NULL);
}
g_signal_connect(viewer, "location-changed", G_CALLBACK(on_view_changed), NULL);
g_signal_connect(viewer, "rotation-changed", G_CALLBACK(on_view_changed), NULL);
}
+static void grits_viewer_dispose(GObject *gobject)
+{
+ g_debug("GritsViewer: dispose");
+ GritsViewer *viewer = GRITS_VIEWER(gobject);
+ if (viewer->draw_source)
+ g_source_remove(viewer->draw_source);
+ G_OBJECT_CLASS(grits_viewer_parent_class)->dispose(gobject);
+}
static void grits_viewer_finalize(GObject *gobject)
{
g_debug("GritsViewer: finalize");
static void grits_viewer_finalize(GObject *gobject)
{
g_debug("GritsViewer: finalize");
{
g_debug("GritsViewer: class_init");
GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
{
g_debug("GritsViewer: class_init");
GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
+ gobject_class->dispose = grits_viewer_dispose;
gobject_class->finalize = grits_viewer_finalize;
/**
gobject_class->finalize = grits_viewer_finalize;
/**
/* For dragging */
gint drag_mode;
gdouble drag_x, drag_y;
/* For dragging */
gint drag_mode;
gdouble drag_x, drag_y;
+
+ /* For queue_draw */
+ guint draw_source;
};
struct _GritsViewerClass {
};
struct _GritsViewerClass {
gint level, gboolean sort);
void grits_viewer_remove(GritsViewer *viewer, GritsObject *object);
gint level, gboolean sort);
void grits_viewer_remove(GritsViewer *viewer, GritsObject *object);
+void grits_viewer_queue_draw(GritsViewer *viewer);
+
void grits_object_queue_draw(GritsObject *object)
{
if (object->viewer)
void grits_object_queue_draw(GritsObject *object)
{
if (object->viewer)
- gtk_widget_queue_draw(GTK_WIDGET(object->viewer));
+ grits_viewer_queue_draw(object->viewer);
}
void grits_object_set_cursor(GritsObject *object, GdkCursorType cursor)
}
void grits_object_set_cursor(GritsObject *object, GdkCursorType cursor)