GTK+ Forums

Discussion forum for GTK+ and Programming. Ask questions, troubleshoot problems, view and post example code, or express your opinions.
It is currently Mon Jul 28, 2014 6:15 am

All times are UTC




Post new topic Reply to topic  [ 1 post ] 
Author Message
 Post subject: Threading Question
PostPosted: Sun Apr 27, 2008 10:31 pm 
Offline

Joined: Fri Apr 25, 2008 4:31 am
Posts: 4
Hi, I'm having some problems with threads. I think that my problem is with the global lock. I'm trying to update a progress bar by continually pulsing it in a thread while another thread waits for an incoming network connection. Both of these are separate from the main thread. However, I don't see any of the GTK output until the function gui_get_opponent returns. I do see printf statements if I put them in there. Am I missing something obvious here?

Code:
#include "checkers.h"
#include "check_net.h"
#include "check_gui.h"
#include <gtk/gtk.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

int
main( int argc, char ** argv )
{
    /* The checkers game */
    struct checkers_game * game = new_checkers_game();

    /* Initialize Threading */
    g_thread_init( NULL );
    gdk_threads_init( );

    /* Initialize GTK+ */
    gtk_init( &argc, &argv );

    /* Setup the game, which sets the name
     * and finds an opponent */
    if( gui_game_setup( game ) == -1 ) { return 0; }

    /* Get an opponent in a new thread */

    /* Send control off to GTK+ */
    gtk_main();

    return 0;
}


int
gui_game_setup( struct checkers_game * game )
{
    /* create the game */
    game = new_checkers_game();

    /* Get the username.  This doesn't need to be in
     * another thread */
    gdk_threads_enter();
    if( gui_get_username( game ) == -1 ) { return -1; }
    gdk_threads_leave();

    g_thread_join( g_thread_create( gui_get_opponent, game, TRUE, NULL ) );
    return 0;
}

int
gui_get_username( struct checkers_game * game )
{
    /* We'll need to create a dialog box for getting
     * the information */
    GtkWidget* dialog;
    GtkWidget* text;
    GtkWidget* label;

    /* result holds the status of the box */
    gint result = GTK_RESPONSE_ACCEPT;

    /* Pointer to hold the location of the text from the dialog */
    const gchar * response = NULL;

    /* Create the widgets */
    dialog = gtk_dialog_new_with_buttons( "Name?",
                                          NULL,
                                          GTK_DIALOG_MODAL,
                                          GTK_STOCK_CANCEL,
                                          GTK_RESPONSE_CANCEL,
                                          GTK_STOCK_OK,
                                          GTK_RESPONSE_ACCEPT,
                                          NULL );

    text  = gtk_entry_new( );
    label = gtk_label_new( "Please enter your name:  " );

    /* Ensure that the user can only enter so many characters */
    gtk_entry_set_max_length( GTK_ENTRY( text ), MAX_NAME_LENGTH );

    /* Add the label and text entry field to the dialog's vbox */
    gtk_container_add( GTK_CONTAINER( GTK_DIALOG( dialog )->vbox ), label );
    gtk_container_add( GTK_CONTAINER( GTK_DIALOG( dialog )->vbox ), text );

    /* Ensure that any activity on text field will activate the dialog */
    gtk_dialog_set_default_response( GTK_DIALOG( dialog ),
                                     GTK_RESPONSE_ACCEPT );
    gtk_entry_set_activates_default( GTK_ENTRY( text ), TRUE );

    /* Ensure that the window is centered on screen */
    gtk_window_set_position( GTK_WINDOW( dialog ), GTK_WIN_POS_CENTER );

    /* Show the text field inside the box */
    gtk_widget_show( GTK_WIDGET( label ) );
    gtk_widget_show( GTK_WIDGET( text ) );

    /* Show the dialog */
    do
    {
        result   = gtk_dialog_run( GTK_DIALOG( dialog ) );

        if( result == GTK_RESPONSE_CANCEL )
        {
            return -1;
        }

        response = gtk_entry_get_text( GTK_ENTRY( text ) );
    } while( result != GTK_RESPONSE_ACCEPT || strlen( response ) <= 0 );

    /* Copy the name to the struct */
    strncpy( game->player_name, response, MAX_NAME_LENGTH + 1 );

    /* clean up */
    gtk_widget_hide( GTK_WIDGET( dialog ) );
    gtk_widget_destroy( GTK_WIDGET( label ) );
    gtk_widget_destroy( GTK_WIDGET( text ) );
    gtk_widget_destroy( GTK_WIDGET( dialog ) );

    return 0;
}

gpointer
gui_get_opponent( gpointer data )
{
    /* The widgets we'll need to make the window */
    GtkWidget* window;
    GtkWidget* box;
    GtkWidget* progress;
    GtkWidget* cancel;
    GtkWidget* label;
    GThread*   thread;

    /* The checkers game */
    struct checkers_game * game = ( struct checkers_game * ) data;

    /* The info for telling us when the thread is done */
    struct gui_pulse_struct * info = malloc(
        sizeof( struct gui_pulse_struct ) );

    gdk_threads_enter();

    /* Create the widgets */
    window   = gtk_window_new( GTK_WINDOW_POPUP );
    box      = gtk_vbox_new( FALSE, 10 );
    progress = gtk_progress_bar_new( );
    cancel   = gtk_button_new_from_stock( GTK_STOCK_CANCEL );
    label    = gtk_label_new( "Please wait while we find you an opponent" );

    /* Pack up the box and add the box to the window */
    gtk_container_add( GTK_CONTAINER( box ), label );
    gtk_container_add( GTK_CONTAINER( box ), progress );
    gtk_container_add( GTK_CONTAINER( box ), cancel );
    gtk_container_add( GTK_CONTAINER( window ), box );

    /* Center the window */
    gtk_window_set_position( GTK_WINDOW( window ), GTK_WIN_POS_CENTER );

    /* show the window on the screen */
    gtk_widget_show_all( GTK_WIDGET( window ) );
    gdk_threads_leave();

    /* Set up our struct and create the thread */
    info->widget = progress;
    info->again  = TRUE;

    thread = g_thread_create( gui_pulse_thread, info, TRUE, NULL );

    sleep( 3 );
    get_opponent( game );
    info->again = FALSE;

    g_thread_join( thread );

    free( info );
    return NULL;
}

gpointer
gui_pulse_thread( gpointer data )
{
    struct gui_pulse_struct * info = ( struct gui_pulse_struct * ) data;

    gdk_threads_enter();
    while( info->again == TRUE )
    {
        gtk_progress_bar_pulse( GTK_PROGRESS_BAR( info->widget ) );
        gdk_flush();
        usleep( 1500000 );
    }
    gdk_threads_leave();
}


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 1 post ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 6 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group