RFC: gtk-thread.c



Hi all,

In addition to my gtk-fork example I posted to this list a month ago,
I now made a GTK + threads example. This is also my first multi-threaded
program, so please tell me about errors. I tested this on Linux only,
so maybe it is not completely portable.


Erik

---- 8< ---- 8< ---- begin gtk-thread.c ---- 8< ---- 8< ----
/*-------------------------------------------------------------------------
 * Filename:      gtk-thread.c
 * Version:       0.99.1
 * Copyright:     Copyright (C) 1999, Erik Mouw
 * Author:        Erik Mouw <J.A.K.Mouw@its.tudelft.nl>
 * Description:   GTK threads example
 * Created at:    Sun Oct 17 21:27:09 1999
 * Modified by:   Erik Mouw <J.A.K.Mouw@its.tudelft.nl>
 * Modified at:   Sun Oct 24 17:28:50 1999
 *-----------------------------------------------------------------------*/
/*
 * Compile with:
 *
 * cc -o gtk-thread gtk-thread.c `gtk-config --cflags --libs gthread`
 *
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <gtk/gtk.h>
#include <glib.h>
#include <pthread.h>




#define YES_IT_IS    (1)
#define NO_IT_IS_NOT (0)




typedef struct 
{
  GtkWidget *label;
  int what;
} yes_or_no_args;




static volatile int yes_or_no = YES_IT_IS;




gint delete_event(GtkWidget *widget, GdkEvent *event, gpointer data)
{
  return(FALSE);
}




void destroy(GtkWidget *widget, gpointer data)
{
  gtk_main_quit();
}




void *argument_thread(void *args)
{
  yes_or_no_args *data = (yes_or_no_args *)args;

  for(;;)
    {
      /* sleep a while */
      sleep(rand() / (RAND_MAX / 3) + 1);

      /* do we have to say something? */
      if(yes_or_no != data->what)
	{
	  /* set the variable */
	  yes_or_no = data->what;

	  /* get GTK thread lock */
	  gdk_threads_enter();

	  /* set label text */
	  if(data->what == YES_IT_IS)
	    gtk_label_set_text(GTK_LABEL(data->label), "O yes, it is!");
	  else
	    gtk_label_set_text(GTK_LABEL(data->label), "O no, it isn't!");

	  /* release GTK thread lock */
	  gdk_threads_leave();
	}
    }

  return(NULL);
}




int main(int argc, char *argv[])
{
  GtkWidget *window;
  GtkWidget *label;
  yes_or_no_args yes_args, no_args;
  pthread_t no_tid, yes_tid;

  /* init threads */
  g_thread_init(NULL);

  /* init gtk */
  gtk_init(&argc, &argv);

  /* init random number generator */
  srand((unsigned int)time(NULL));

  /* create a window */
  window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  
  gtk_signal_connect(GTK_OBJECT (window), "delete_event",
		     GTK_SIGNAL_FUNC(delete_event), NULL);
          
  gtk_signal_connect(GTK_OBJECT (window), "destroy",
		     GTK_SIGNAL_FUNC(destroy), NULL);

#if (GTK_MAJOR_VERSION == 1) && (GTK_MINOR_VERSION == 0)
  gtk_container_border_width(GTK_CONTAINER (window), 10);
#else  
  gtk_container_set_border_width(GTK_CONTAINER (window), 10);
#endif

  /* create a label */
  label = gtk_label_new("And now for something completely different ...");
  gtk_container_add(GTK_CONTAINER(window), label);
  
  /* show everything */
  gtk_widget_show(label);
  gtk_widget_show (window);

  /* create the threads */
  yes_args.label = label;
  yes_args.what = YES_IT_IS;
  pthread_create(&yes_tid, NULL, argument_thread, &yes_args);

  no_args.label = label;
  no_args.what = NO_IT_IS_NOT;
  pthread_create(&no_tid, NULL, argument_thread, &no_args);

  /* enter the GTK main loop */
  gdk_threads_enter();
  gtk_main();
  gdk_threads_leave();

  return(0);
}
---- 8< ---- 8< ---- end gtk-thread.c ---- 8< ---- 8< ----

-- 
J.A.K. (Erik) Mouw, Information and Communication Theory Group, Department
of Electrical Engineering, Faculty of Information Technology and Systems,
Delft University of Technology, PO BOX 5031,  2600 GA Delft, The Netherlands
Phone: +31-15-2785859  Fax: +31-15-2781843  Email J.A.K.Mouw@its.tudelft.nl
WWW: http://www-ict.its.tudelft.nl/~erik/



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]