XInitThreads causing problems to GTK windows.
- From: "Peter Wilson" <peter stubble force9 co uk>
- To: <gtk-list redhat com>
- Cc: <gtk-devel-list redhat com>
- Subject: XInitThreads causing problems to GTK windows.
- Date: Wed, 14 Jul 1999 23:52:57 +0100
/*
Hello there!
Can someone tell me if there's something I need to know before calling
Xlib code directly, within GTK programs? I'm trying to write a proggy that
will have one thread that does some graphics stuff, talking directly to XLib
(with it's own connection to the X server). Because that means that there
might
be two threads calling XLib concurrently I need to call XInitThreads() -
it's
man page states..:-
This function must be the first Xlib
function a multi-threaded program calls,
and it must complete before any other
Xlib call is made.
However - I've found that if I call XInitThreads BEFORE gtk_init, then
pressing a key with a fileselection on the screen causes the program to hang
somewhere inside gtk_main_iteration().
If I call XInitThreads after gtk_init then everything appears fine, but
I don't know what affects that'll have on XLib. I'm not really too bothered
about GTK / GDK or GLIB being thread safe - the second thread need not call
any of those functions. But I've tried inserting g_threads_init() here and
there, without any luck.
Anyone have any ideas?
Cheers...
Chris Wilson
cdw22@cam.ac.uk
----------------- Cut here ;] -------------------*/
// Little proggy to demonstrate GTK+ bug [?] ...
// ... I think... ;[
//
//
// Compile and run this, notice that the fileselector works fine with the
// mouse - but if you try to type something into the box - the progam hangs.
/*
Save as gtkbug.c and compile me:-
gcc -O2 -Wall gtkbug.c `gtk-config --cflags gthread` \
`gtk-config --libs gthread` -o gtkbug
*/
#include <X11/X.h>
#include <X11/Xlib.h>
#include <glib.h>
#include <gtk/gtk.h>
typedef struct
{
GtkWidget *fs;
gchar *filename;
gboolean cancelled;
gboolean done;
} fileselector;
// Prototypes [yawn]
fileselector *make_fileselector(gchar *title, gchar *dir, gchar *pattern);
void fileselector_wait(fileselector *fs);
int main(int argc, char *argv[]);
// Signal & event handlers
static void filesel_ok(GtkWidget *w, fileselector *fs);
static void filesel_canc(GtkWidget *w, fileselector *fs);
static gboolean filesel_deleteevent (GtkWidget *w, GdkEvent *e, fileselector
*fs);
// Code
int main(int argc, char *argv[])
{
fileselector *fs;
if(!XInitThreads())
{
g_print("XLib is not thread safe. Bailing...\n");
exit(-1);
}
gtk_init(&argc, &argv);
fs=make_fileselector("blah blah", "/home/chris", "*");
fileselector_wait(fs);
if(fs->cancelled)
{
g_print("Cancelled\n");
return 0;
}
g_print("Filename selected %s\n",fs->filename);
return 0;
}
fileselector *make_fileselector(gchar *title, gchar *dir, gchar *pattern)
{
fileselector *fs;
fs = g_malloc(sizeof(fileselector));
fs->fs=gtk_file_selection_new(title);
gtk_window_set_position(GTK_WINDOW(fs->fs), GTK_WIN_POS_MOUSE);
gtk_file_selection_set_filename(GTK_FILE_SELECTION (fs->fs), dir);
gtk_file_selection_complete(GTK_FILE_SELECTION (fs->fs), pattern);
fs->filename=NULL;
fs->cancelled=FALSE;
fs->done=FALSE;
gtk_signal_connect(GTK_OBJECT (GTK_FILE_SELECTION (fs->fs)->ok_button),
"clicked", GTK_SIGNAL_FUNC (filesel_ok), fs);
gtk_signal_connect(GTK_OBJECT (GTK_FILE_SELECTION (fs->fs)->cancel_button),
"clicked", GTK_SIGNAL_FUNC (filesel_canc), fs);
gtk_signal_connect(GTK_OBJECT (fs->fs), "delete_event", GTK_SIGNAL_FUNC
(filesel_deleteevent), fs);
gtk_widget_show(fs->fs);
return fs;
}
void fileselector_wait(fileselector *fs)
{
while(!fs->done)
gtk_main_iteration();
}
static void filesel_ok(GtkWidget *w, fileselector *fs)
{
gchar *filename;
filename = gtk_file_selection_get_filename(GTK_FILE_SELECTION (fs->fs));
fs->filename=g_malloc(strlen(filename)+1);
strcpy(fs->filename, filename);
fs->done=TRUE;
gtk_widget_hide(fs->fs);
gtk_widget_destroy(fs->fs);
}
static void filesel_canc(GtkWidget *w, fileselector *fs)
{
fs->cancelled=TRUE;
fs->done=TRUE;
gtk_widget_hide(fs->fs);
gtk_widget_destroy(fs->fs);
}
static gboolean filesel_deleteevent (GtkWidget *w, GdkEvent *e, fileselector
*fs)
{
fs->cancelled=TRUE;
fs->done=TRUE;
gtk_widget_hide(fs->fs);
gtk_widget_destroy(fs->fs);
return TRUE;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]