Re: pthreads + drawing area = expose event fails
- From: Ray Clouse <ray clouse boeing com>
- To: Paul Davis <paul linuxaudiosystems com>
- Cc: gtk-list gnome org, "Jones, Heiko" <heiko jones boeing com>
- Subject: Re: pthreads + drawing area = expose event fails
- Date: Fri, 20 Feb 2004 15:04:49 -0800
I tried putting gdk_threads_enter() & leave() in appropriate places to
no avail. So here's more code:
int
main (int argc, char *argv[])
{
GtkWidget *mainwindow;
gint major, minor;
sigset_t sig_to_block;
int i, j;
/* init glib threads stuff for gtk */
g_thread_init(NULL);
gdk_threads_init();
/* Setup the signals to block, threads will inherit this mask... */
sigemptyset(&sig_to_block);
/* Block SIGPIPE so the write to sockets will not get us when socket
closed */
sigaddset(&sig_to_block, SIGPIPE);
/* Block SIG INT,TERM,SEGV so we can catch to close down and exit... */
sigaddset(&sig_to_block, SIGINT);
sigaddset(&sig_to_block, SIGTERM);
sigaddset(&sig_to_block, SIGSEGV);
pthread_sigmask(SIG_BLOCK, &sig_to_block, NULL);
gtk_set_locale ();
gtk_init (&argc, &argv);
gtk_gl_init (&argc, &argv);
gdk_gl_query_version (&major, &minor);
g_print ("\nOpenGL extension version - %d.%d\n",
major, minor);
mainwindow = create_mainwindow ();
gtk_widget_show (mainwindow);
gdk_threads_enter();
gtk_main ();
gdk_threads_leave();
return 0;
}
GtkWidget*
create_viewwindow (void)
{
GtkWidget *viewwindow;
GtkWidget *vbox4;
GtkWidget *menubar3;
GtkWidget *menuitem9;
GtkWidget *menuitem9_menu;
GtkWidget *separatormenuitem3;
GtkWidget *exit2;
GtkWidget *drawing_area;
GtkAccelGroup *accel_group;
glargs *garg;
.
.
.
if ((garg = (glargs *) calloc(1, sizeof(glargs))) == NULL) {
printf("Cannot calloc gl args.\n");
return NULL;
}
/* Try double-buffered visual */
garg->glconfig = gdk_gl_config_new_by_mode (GDK_GL_MODE_RGB |
GDK_GL_MODE_DEPTH |
GDK_GL_MODE_DOUBLE);
garg->drawing_area = gtk_drawing_area_new();
gtk_widget_set_size_request(garg->drawing_area, 300, 300);
/* Set OpenGL-capability to the widget. */
gtk_widget_set_gl_capability(garg->drawing_area,
garg->glconfig,
NULL,
TRUE,
GDK_GL_RGBA_TYPE);
gtk_widget_add_events(garg->drawing_area,
GDK_BUTTON1_MOTION_MASK |
GDK_BUTTON2_MOTION_MASK |
GDK_BUTTON_PRESS_MASK |
GDK_VISIBILITY_NOTIFY_MASK);
g_signal_connect_after(G_OBJECT(garg->drawing_area), "realize",
G_CALLBACK(init), NULL);
g_signal_connect(G_OBJECT(garg->drawing_area), "configure_event",
G_CALLBACK(configure_event), NULL);
g_signal_connect(G_OBJECT(garg->drawing_area), "expose_event",
G_CALLBACK(expose_event), &garg);
gtk_box_pack_start(GTK_BOX(vbox4), garg->drawing_area, TRUE, TRUE, 0);
gtk_widget_show(garg->drawing_area);
gtk_window_add_accel_group (GTK_WINDOW(viewwindow), accel_group);
return viewwindow;
}
int
create_view_wrapper(viewthreadargs *vtargs)
{
vtargs->viewwindow = create_viewwindow();
gtk_container_set_reallocate_redraws(GTK_CONTAINER(vtargs->viewwindow),
TRUE);
gtk_widget_show(vtargs->viewwindow);
}
int
on_create_view_activate (GtkMenuItem *menuitem,
gpointer user_data)
{
pthread_t t1;
struct sched_param param1;
viewthreadargs *vtargs;
GError *error = NULL;
if ((vtargs = (viewthreadargs *) calloc(1, sizeof(viewthreadargs)))
== NULL) {
printf(" on_create_view_activate: Cannot calloc view window thread
info.\n");
return -1;
}
if ((pthread_create(&t1,
NULL,
(void *) create_view_wrapper,
vtargs)) != 0) {
printf(" Problem pthread_create\n");
return -1;
}
return 1;
}
void
init(GtkWidget *widget,
gpointer data)
{
GdkGLContext *glcontext = gtk_widget_get_gl_context(widget);
GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable(widget);
printf("init; values: %x %x %x\n", &widget, &glcontext, &gldrawable);
fflush(stdout);
static GLfloat pos[4] = {5.0, 5.0, 10.0, 0.0};
static GLfloat red[4] = {0.8, 0.1, 0.0, 1.0};
static GLfloat green[4] = {0.0, 0.8, 0.2, 1.0};
static GLfloat blue[4] = {0.2, 0.2, 1.0, 1.0};
/*** OpenGL BEGIN ***/
if (!gdk_gl_drawable_gl_begin (gldrawable, glcontext)) {
return;
}
glLightfv (GL_LIGHT0, GL_POSITION, pos);
glEnable (GL_CULL_FACE);
glEnable (GL_LIGHTING);
glEnable (GL_LIGHT0);
glEnable (GL_DEPTH_TEST);
glEnable (GL_NORMALIZE);
report_gl_version();
gdk_gl_drawable_gl_end (gldrawable);
}
gboolean
configure_event (GtkWidget *widget,
GdkEventConfigure *event,
gpointer data)
{
GdkGLContext *glcontext = gtk_widget_get_gl_context(widget);
GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable(widget);
printf("configure_event: values: %x %x %x\n",
&widget, &glcontext, &gldrawable);fflush(stdout);
GLfloat w = widget->allocation.width;
GLfloat h = widget->allocation.height;
GLfloat aspect;
/*** OpenGL BEGIN ***/
if (!gdk_gl_drawable_gl_begin (gldrawable, glcontext)) {
return FALSE;
}
glViewport (0, 0, w, h);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
if (w > h)
{
aspect = w / h;
glFrustum (-aspect, aspect, -1.0, 1.0, 2.0, 60.0);
}
else
{
aspect = h / w;
glFrustum (-1.0, 1.0, -aspect, aspect, 2.0, 60.0);
}
glMatrixMode (GL_MODELVIEW);
report_gl_version();
gdk_gl_drawable_gl_end (gldrawable);
/*** OpenGL END ***/
return TRUE;
}
gboolean
expose_event(GtkWidget *widget,
GdkEventExpose *event,
gpointer data)
{
glargs *g1 = (glargs *) data;
GdkGLContext *glcontext = gtk_widget_get_gl_context(widget);
GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable(widget);
GdkDrawable *drawable;
/*** OpenGL BEGIN ***/
printf("expose_event: values: %x %x %x\n", &widget,
&glcontext,
&gldrawable);fflush(stdout);
printf("expose_event: values: %x %x %x\n", &g1->drawing_area,
&g1->glcontext,
&g1->gldrawable);fflush(stdout);
drawable = g1->drawing_area->window;
gdk_draw_rectangle(drawable,
g1->drawing_area->style->white_gc,
TRUE,
0, 0,
g1->drawing_area->allocation.width,
g1->drawing_area->allocation.height);
/* if (!gdk_gl_drawable_gl_begin(g1->gldrawable, g1->glcontext)) {
printf("expose_event: didn't get it :P\n"); fflush(stdout);
report_gl_version();
return FALSE;
}
printf("expose_event: got it! continuing...\n"); fflush(stdout);
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
if (gdk_gl_drawable_is_double_buffered (g1->gldrawable))
gdk_gl_drawable_swap_buffers (g1->gldrawable);
else
glFlush ();
gdk_gl_drawable_gl_end (g1->gldrawable);
/*** OpenGL END ***/
return TRUE;
}
Paul Davis wrote:
I'm trying to write an app that lets me open multiple pthreaded windows
and do OpenGL in them using the GtkGLExt. Unfortunately I'm running
into a problem getting the drawable in my expose event.
you haven't posted much code.
the golden rule of X programming (with *any* toolkit) is:
use only 1 thread to make calls that resolve to Xlib calls
if you don't want to do this, then you have to use mutexes to protect
each and every call to any function that might ever make a call to
Xlib. g_threads_enter() and g_threads_leave() are your GTK-related
friends here. See the FAQ.
--p
_______________________________________________
gtk-list mailing list
gtk-list gnome org
http://mail.gnome.org/mailman/listinfo/gtk-list
--
------------------------------------------------------------------------
Ray Clouse
STICS Lab
ray.clouse AT boeing.com Don't fear the penguins.
clouse AT rayclouse.org
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]