Re: Idle Function Not Getting Called




I tried G_PRIORITY_HIGH_IDLE with similar results ... the idle
function is called only with the following code:

     g_idle_add_full (G_PRIORITY_HIGH_IDLE, (GSourceFunc) idlefunc, NULL, NULL);
     while (gtk_events_pending ())
         gtk_main_iteration ();

If the while loop is not part of the coding then the idle function (idlefunc) is not called.

The difference with using G_PRIORITY_HIGH_IDLE is that some of the buttons inside the dialogs drawn in the idle function are not displayed. But they still react to user clicks if clicked in the right area. I expect this is linked to your "GDK drawing functions" statement above.

Then you must have some function blocking between your call to
g_idle_add_full() and control returning to the main loop.

Anything in a GTK+ signal or event handler must not block.  This means
in practice that nothing should block after your call to gtk_main().

After spending more time with my code I'm just not seeing it. Below is the pertinent code.

AddName() is called from a drop-down menu item.

Via debug code I've seen that the program flow is as it should be ... all functions are exited. The first idle function (PlayNetGame()) is added, executed, and exited as it should be. The second idle function (PlayTheGame()) is added but is never called.

Does anyone see what might be blocking the call of PlayTheGame() or have any other suggestions?




void
AddName (gpointer callback_data, guint callback_action, GtkWidget *widget) {
    /* listen on another socket for challenges */
    if (!g_thread_create (Wait4Challenge, NULL, FALSE, NULL))
        syslog (LOG_INFO, "error trying to create new thread");
}

char challenger[50];

/* wait for a gameplay challenge from another user */
void *
Wait4Challenge () {
    int x, port = 0, listensock, connected;
    char buffer[5000], *msg[5];

    listensock = -1;
    for (x = 0; x < 5; x++)
        msg[x] = NULL;

    wsock = get_connection_nofork (SOCK_STREAM, port, &listensock);

    connected = 1;
    while (connected) {
        /* get communication */
        if (sock_gets (wsock, &buffer[0], sizeof (buffer)) < 0) {
            msg[0] = "There is a problem with the server.\n\n";
            outMessage (msg);
            connected = 0;
        }

        if (buffer[0] == 'R')
            /* this user removed his ID from the waiting pool so end this thread and close the socket */
            connected = 0;

        if (buffer[0] != 'C')
            continue;

        strcpy (&challenger[0], &buffer[1]);

        /* add idle function to process requests to play from challengers */
        g_mutex_lock (data_mutex);
        FromThread = 0;
        g_idle_add ((GSourceFunc) PlayChallenger, NULL);

        /* wait for PlayChallenger() to finish */
        while (!FromThread)
            g_cond_wait (data_cond, data_mutex);
        g_mutex_unlock (data_mutex);

        if (!ShallWeContinue4Thread) {
            /* this challengee does not want to play this challenger */
            sock_puts (wsock, "NO\n");
            for (x = 0; x < 5; x++)
                msg[x] = NULL;
            continue;
        }
        else {
            /* this challengee wants to play */
            char work[50], cport[50], *blank;

            /* tell server to open a port for receiving communications from the challenger (the challengee 
server
               process will control gameplay) */
            sock_puts (sock, "O\n");
            sock_puts (wsock, "OK \n");

            g_idle_add ((GSourceFunc) PlayNetGame, NULL);

            /* no longer need this thread */
            connected = 0;
        }
    }

    shutdown (wsock, SHUT_RDWR);
    close (wsock);
    return (NULL);
}

GtkWidget *dlgFile;

/* display a dialog which calls for a user response */
gboolean
PlayChallenger () {
    gchar labeltext[500];
    GtkWidget *label = NULL, *hbox, *separator, *okbutton, *disbutton;

    dlgFile = gtk_dialog_new ();
    gtk_window_set_title (GTK_WINDOW (dlgFile), "Play Challenger?");
    gtk_signal_connect (GTK_OBJECT (dlgFile), "delete_event", GTK_SIGNAL_FUNC (donot_delete_event), 0);
    gtk_window_set_modal (GTK_WINDOW (dlgFile), TRUE);

    strcpy (&labeltext[0], &challenger[0]);
    strcat (&labeltext[0], " challenges you to a game.  Do you accept?\n\n");

    label = gtk_label_new (labeltext);
    gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
    gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlgFile)->vbox), label, TRUE, TRUE, 0);

    separator = gtk_hseparator_new ();
    gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlgFile)->vbox), separator, FALSE, TRUE, 0);

    hbox = gtk_hbutton_box_new ();
    gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlgFile)->vbox), hbox, FALSE, FALSE, 0);

    okbutton = gtk_button_new_with_label ("ACCEPT");
    g_signal_connect (G_OBJECT (okbutton), "clicked", G_CALLBACK (PlayOK), dlgFile);
    disbutton = gtk_button_new_with_label ("Decline");
    g_signal_connect (G_OBJECT (disbutton), "clicked", G_CALLBACK (PCscatDestroyDialog), NULL);
    gtk_box_pack_start (GTK_BOX (hbox), okbutton, TRUE, TRUE, 0);
    gtk_box_pack_start (GTK_BOX (hbox), disbutton, TRUE, TRUE, 0);

    gtk_widget_show_all (dlgFile);
    return FALSE;
}

void
PlayOK (GtkWidget *widget, gpointer *pdata) {
    g_mutex_lock (data_mutex);
    ShallWeContinue4Thread = 1;
    FromThread = 1;
    g_cond_signal (data_cond);
    g_mutex_unlock (data_mutex);
    DestroyDialog (dlgFile, dlgFile);
}

void
PCscatDestroyDialog (GtkWidget *widget, gpointer *pdata) {
    g_mutex_lock (data_mutex);
    ShallWeContinue4Thread = 0;
    FromThread = 1;
    g_cond_signal (data_cond);
    g_mutex_unlock (data_mutex);
    DestroyDialog (dlgFile, dlgFile);
}

/* this is the challengee */
gboolean
PlayNetGame () {
    challenger_ind = 0;
    PlayNSB1GameOverNetwork ();

    return FALSE;
}

/* play 1 game against another human over a network */
void
PlayNSB1GameOverNetwork () {
    netgame = 1;
    watchsw = 0;
    Play1Game ('n');
}

/* play 1 game */
void
Play1Game (char which) {
    gint seldh, selrand;

    seldh = selrand = 0;

    if (!netgame || (netgame && !challenger_ind))
        /* if it's a game over a network then only the challengee gets to select the teams and whether or not 
to use a DH */
        if (!SelRandomTeams ()) {
            selrand = 1;
            if (!SelDesignatedHitter ()) {
                seldh = 1;
                dh = 1;
            }
            else
                dh = 0;
        }

    if (watchsw)
        if (!selrand)
            sock_puts (sock, "w\n");  /* tell server we want to watch a non-league game */
        else
            if (seldh)
                sock_puts (sock, "wR1\n");  /* tell server we want to watch a non-league game with randomly 
selected teams using a DH */
            else
                sock_puts (sock, "wR0\n");  /* tell server we want to watch a non-league game with randomly
                                               selected teams NOT using a DH */
    else
        if (which == 'c') {
            if (!selrand)
                sock_puts (sock, "p\n");  /* tell server we want to play a non-league game against the 
computer */
            else
                if (seldh)
                    sock_puts (sock, "pR1\n");  /* tell server we want to play a non-league game against the
                                                   computer with randomly selected teams using a DH */
                else
                    sock_puts (sock, "pR0\n");  /* tell server we want to play a non-league game against the
                                                   computer with randomly selected teams NOT using a DH */
        }
        else {
            if (!netgame || (netgame && !challenger_ind)) {
                /* if it's a game over a network then only the challengee will tell its child server process 
*/
                if (!selrand)
                    sock_puts (sock, "h\n");  /* tell server we want to play a non-league game against 
another human */
                else
                    if (seldh)
                        sock_puts (sock, "hR1\n");  /* tell server we want to play a non-league game against 
another
                                                       human with randomly selected teams using a DH */
                    else
                        sock_puts (sock, "hR0\n");  /* tell server we want to play a non-league game against 
another
                                                       human with randomly selected teams NOT using a DH */
            }
            ManageV = ManageH = 1;
        }
    if ((!netgame || (netgame && !challenger_ind)) && !selrand) {
        /* get all available teams from server (for a non-league game) */
        if (sock_gets (sock, &buffer[0], sizeof (buffer)) < 0) {
            GotError ();
            return;
        }
        if (!strncmp (&buffer[0], "-2", 2)) {
            gchar NoDir[256] = "There's a problem with the server.", *msg[5];
            gint x;

            for (x = 0; x < 5; x++)
                msg[x] = NULL;

            msg[0] = &NoDir[0];
            outMessage (msg);

            return;
        }
        if (!strlen (&buffer[0])) {
            gchar NoTeams[256] = "No teams available.", *msg[5];
            gint x;

            for (x = 0; x < 5; x++)
                msg[x] = NULL;

            msg[0] = &NoTeams[0];
            outMessage (msg);

            return;
        }
    }

    currenttype = which;
    offdialsw = defdialsw = lineupsw = clineupsw = EOSsw = EOPSsw = 0;

    g_idle_add ((GSourceFunc) PlayTheGame, NULL);
}

/* select 2 teams at random? */
int
SelRandomTeams () {
    gint x;
    GtkWidget *dlgFile, *label;

    dlgFile = gtk_dialog_new ();
    gtk_window_set_title (GTK_WINDOW (dlgFile), "Select Teams at Random?");
    gtk_signal_connect (GTK_OBJECT (dlgFile), "delete_event", GTK_SIGNAL_FUNC (donot_delete_event), 0);

    label = gtk_label_new ("Select One:");
    gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlgFile)->vbox), label, TRUE, TRUE, 0);

    gtk_dialog_add_button (GTK_DIALOG (dlgFile), "Randomly Select Two Teams", 0);
    gtk_dialog_add_button (GTK_DIALOG (dlgFile), "I'll Select the Teams", 1);

    gtk_widget_show (label);

    gtk_dialog_set_default_response (GTK_DIALOG (dlgFile), 2);

    x = gtk_dialog_run (GTK_DIALOG (dlgFile));
    gtk_widget_destroy (dlgFile);

    return (x);
}

/* use a designated hitter? */
int
SelDesignatedHitter () {
    gint x;
    GtkWidget *dlgFile, *label;

    dlgFile = gtk_dialog_new ();
    gtk_window_set_title (GTK_WINDOW (dlgFile), "Use Designated Hitter?");
    gtk_signal_connect (GTK_OBJECT (dlgFile), "delete_event", GTK_SIGNAL_FUNC (donot_delete_event), 0);

    label = gtk_label_new ("Select One:");
    gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlgFile)->vbox), label, TRUE, TRUE, 0);

    gtk_dialog_add_button (GTK_DIALOG (dlgFile), "Use a Designated Hitter", 0);
    gtk_dialog_add_button (GTK_DIALOG (dlgFile), "Do NOT Use a Designated Hitter", 1);

    gtk_widget_show (label);

    gtk_dialog_set_default_response (GTK_DIALOG (dlgFile), 2);

    x = gtk_dialog_run (GTK_DIALOG (dlgFile));
    gtk_widget_destroy (dlgFile);

    return (x);
}



--
Marshall Lake -- mlake mlake net -- http://mlake.net



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