From a0fee0a66128078238d957333c1c3973622f3a7c Mon Sep 17 00:00:00 2001 From: Daniel Carbonell Fraj Date: Sun, 9 Feb 2003 19:29:37 +0000 Subject: [PATCH] ported to g_io_channel, now gtetrinet is only one process --- ChangeLog | 40 +++++++ src/client.c | 281 ++++++++++++++++++++---------------------------- src/client.h | 9 +- src/commands.c | 2 +- src/config.c | 2 + src/dialogs.c | 2 +- src/fields.c | 4 +- src/gtetrinet.c | 58 +--------- 8 files changed, 162 insertions(+), 236 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6a7adb5..a0df8ad 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,43 @@ +2003-02-09 Dani Carbonell + + * client.c: added gnome.h so some strings can be localized. Removed + most of the cruft, now gtetrinet works with only one process. + (client_inputfunc): removed. + (client_cleanpipe): removed. + (client_mainloop): removed. + (client_initpipes): removed. + (client_destroypipes): removed. + (client_init): it's no longer needed to check for the child. + (client_connectcancel): removed. + (client_destroy): removed. + (client_outmessage): directly send it to the socket. + (client_inmessage): directly parse it in tetrinet.c. + (client_process): string marked for translating. Now, the client + process just sets up the connection and connects. + (client_connect): sets up the g_io_channel. + (client_disconnect): shutdowns the g_io_channel, closing the GSource + event and shutting down also the socket. + (io_channel_cb): callback to handle the event of new data coming + into the socket. + (client_sendmsg): sends the data using g_io_channel_write functions. + (client_readmsg): reads the data using g_io_channel_read functions. + + * client.h: removed functions. + + * commands.c (disconnect_command): call client_disconnect instead of + client_destroy. + + * config.c (sound_enable_sound_changed): re-cache the sounds if the + sound option is enabled, fixes #105651. + + * dialogs.c (connectingdialog_button): call client_disconnect + instead of client_connectcancel. + + * fields.c (fields_page_contents): few improvements to the gui. + + * gtetrinet.c (main): removed some useless assertions. Also, removed + some useless function calls. + 2003-02-07 Jordi Mallach * NEWS, configure.in: release 0.6.2. It compiles, promise. diff --git a/src/client.c b/src/client.c index 78ea86b..7f9a132 100644 --- a/src/client.c +++ b/src/client.c @@ -33,6 +33,7 @@ #include #include #include +#include #include "client.h" #include "tetrinet.h" @@ -44,15 +45,12 @@ #define PORT 31457 #define SPECPORT 31458 -int fdin[2], fdout[2]; /* two pipes, in and out */ - -int inputcbid; - int connected; char server[128]; -int clientpid; -static int sock, connecterror; +static int sock; +static GIOChannel *io_channel; +static guint source; /* structures and arrays for message translation */ @@ -140,37 +138,21 @@ struct outmsgt outmsgtable[] = { {0, 0} }; -static void client_inputfunc (void); - /* functions which set up the connection */ static void client_process (void); -static void client_cleanpipe (void); -static int client_mainloop (void); static int client_connect (void); static void client_connected (void); -static int client_disconnect (void); /* some other useful functions */ +static gboolean +io_channel_cb (GIOChannel *source, GIOCondition condition, gpointer data); static int client_sendmsg (char *str); -static int client_readmsg (char *str, int len); +static int client_readmsg (gchar **str); static void server_ip (unsigned char buf[4]); enum inmsg_type inmsg_translate (char *str); char *outmsg_translate (enum outmsg_type); -void client_initpipes (void) -{ - pipe (fdin); - pipe (fdout); - - inputcbid = gdk_input_add (fdin[0], GDK_INPUT_READ, - (GdkInputFunction)client_inputfunc, NULL); -} - -void client_destroypipes (void) -{ -} - void client_init (const char *s, const char *n) { int i; @@ -181,54 +163,12 @@ void client_init (const char *s, const char *n) for (i = 0; nick[i]; i ++) if (isspace (nick[i])) nick[i] = 0; - if (clientpid) { - if (connected) client_destroy (); - else client_connectcancel (); - } - connectingdialog_new (); /* set the game mode */ inmsg_change(); - if ((clientpid = fork()) == 0) { - client_process (); - _exit (0); - } -} - -void client_connectcancel (void) -{ - /* just kill the process */ - if (clientpid) kill (clientpid, SIGTERM); - clientpid = 0; -} - -void client_destroy (void) -{ - /* tell it to disconnect, then wait for it to die */ - client_outmessage (OUT_DISCONNECT, NULL); - waitpid (clientpid, NULL, 0); - clientpid = 0; -} - -/* a function that reads stuff from the pipe */ -static void client_inputfunc (void) -{ - char buf[1024]; - char *token; - enum inmsg_type msgtype; - - fdreadline (fdin[0], buf); - - /* split the message */ - token = strtok (buf, " "); - if (token == NULL) return; - msgtype = inmsg_translate (token); - token = strtok (NULL, ""); - - /* process it */ - tetrinet_inmessage (msgtype, token); + client_process (); } void client_outmessage (enum outmsg_type msgtype, char *str) @@ -239,14 +179,28 @@ void client_outmessage (enum outmsg_type msgtype, char *str) GTET_O_STRCAT(buf, " "); GTET_O_STRCAT(buf, str); } - write (fdout[1], buf, strlen(buf)); - write (fdout[1], "\n", 1); + switch (msgtype) + { + case OUT_DISCONNECT : client_disconnect (); break; + case OUT_CONNECTED : client_connected (); break; + default : client_sendmsg (buf); + } } void client_inmessage (char *str) { - write (fdin[1], str, strlen(str)); - write (fdin[1], "\n", 1); + enum inmsg_type msgtype; + gchar **tokens, *final; + + /* split the message */ + tokens = g_strsplit (str, " ", 256); + msgtype = inmsg_translate (tokens[0]); + + /* process it */ + final = g_strjoinv (" ", &tokens[1]); + tetrinet_inmessage (msgtype, final); + g_strfreev (tokens); + g_free (final); } /* these functions set up the connection */ @@ -260,83 +214,10 @@ void client_process (void) GTET_O_STRCPY(errmsg, "noconnecting "); if (errno) GTET_O_STRCAT(errmsg, strerror (errno)); - else if (h_errno) GTET_O_STRCAT(errmsg, "Unknown host"); + else if (h_errno) GTET_O_STRCAT(errmsg, _("Could not resolve host.")); client_inmessage (errmsg); - - return; - } - connecterror = 0; - client_cleanpipe (); - client_mainloop (); - client_disconnect (); - return; -} - -void client_cleanpipe () -{ - fd_set rfds; - struct timeval tv; - char buf[1024]; - - while (1) { - FD_ZERO (&rfds); - FD_SET (fdout[0], &rfds); - tv.tv_sec = 0; tv.tv_usec = 0; - if (select (fdout[0]+1, &rfds, NULL, NULL, &tv)) fdreadline (fdout[0], buf); - else return; - } -} - -int client_mainloop (void) -{ - fd_set rfds; - struct timeval tv; - int m; - - /* read in stuff from the socket and the pipe */ - while (1) { - FD_ZERO (&rfds); - FD_SET (sock, &rfds); - FD_SET (fdout[0], &rfds); - m = sock > fdout[0] ? sock : fdout[0]; - tv.tv_sec = 0; - tv.tv_usec = 50000; /* wait a little while */ - if (select (m+1, &rfds, NULL, NULL, &tv)) - { - char buf[1024]; /* a big buffer */ - - /* we have something to read */ - - /* is it the socket?? */ - FD_ZERO (&rfds); FD_SET (sock, &rfds); - tv.tv_sec = 0; tv.tv_usec = 0; - if (select (sock+1, &rfds, NULL, NULL, &tv)) { - if (client_readmsg (buf, sizeof(buf)) < 0) - return -1; - client_inmessage (buf); /* send to parent process */ - if (strncmp ("noconnecting", buf, 12) == 0) { - connecterror = 1; - goto clientend; - } - } - - /* or it the pipe?? */ - FD_ZERO (&rfds); FD_SET (fdout[0], &rfds); - tv.tv_sec = 0; tv.tv_usec = 0; - if (select (fdout[0]+1, &rfds, NULL, NULL, &tv)) { - fdreadline (fdout[0], buf); - if (strcmp (buf, outmsg_translate(OUT_DISCONNECT)) == 0) - goto clientend; - else if (strcmp (buf, outmsg_translate(OUT_CONNECTED)) == 0) - client_connected (); - else - client_sendmsg (buf); - } - } } -clientend: - return 0; } int client_connect (void) @@ -406,6 +287,14 @@ int client_connect (void) return -1; #endif + /** + * Set up the g_io_channel + * We should set it with no encoding and no buffering, just to simplify things */ + io_channel = g_io_channel_unix_new (sock); + g_io_channel_set_encoding (io_channel, NULL, NULL); + g_io_channel_set_buffered (io_channel, FALSE); + source = g_io_add_watch (io_channel, G_IO_IN, io_channel_cb, NULL); + /* say hello to the server */ { GString *s1 = g_string_sized_new(80); @@ -456,50 +345,108 @@ void client_connected (void) client_inmessage ("connect"); } -int client_disconnect (void) +void client_disconnect (void) { - shutdown (sock, 2); - close (sock); - - if (!connecterror || connected) client_inmessage ("disconnect"); - - return 0; + if (connected) + { + client_inmessage ("disconnect"); + g_source_destroy (g_main_context_find_source_by_id (NULL, source)); + g_io_channel_shutdown (io_channel, TRUE, NULL); + g_io_channel_unref (io_channel); + shutdown (sock, 2); + close (sock); + connected = 0; + } } /* some other useful functions */ +static gboolean +io_channel_cb (GIOChannel *source, GIOCondition condition, gpointer data) +{ + gchar *buf; + gint i = 0; + + switch (condition) + { + case G_IO_IN : + { + if (client_readmsg (&buf) < 0) + g_warning ("client_readmsg returned -1\n"); + + if (strlen (buf)) client_inmessage (buf); + + if (strncmp ("noconnecting", buf, 12) == 0) + { + connected = 1; /* so we can disconnect :) */ + client_disconnect (); + } + + g_free (buf); + }; break; + default : break; + } + + return TRUE; +} + int client_sendmsg (char *str) { char c = 0xFF; + GError *error = NULL; + g_io_channel_write_chars (io_channel, str, -1, NULL, &error); + g_io_channel_write_chars (io_channel, &c, 1, NULL, &error); + g_io_channel_flush (io_channel, &error); + #ifdef DEBUG printf ("> %s\n", str); #endif - if (write (sock, str, strlen (str))==-1) return -1; - if (write (sock, &c, 1)==-1) return -1; - return 0; } -int client_readmsg (char *str, int len) +int client_readmsg (gchar **str) { - int i = 0; - /* read it in one char at a time */ - for (;i < len-1; i++) { - if (read (sock, &str[i], 1) != 1) - /* we have an error */ + gint bytes = 0; + gchar buf[1024]; + GError *error = NULL; + GIOStatus status; + gint i = 0; + + do + { + switch (g_io_channel_read_chars (io_channel, &buf[i], 1, &bytes, &error)) + { + case G_IO_STATUS_EOF : + g_warning ("End of file."); break; + + case G_IO_STATUS_AGAIN : + g_warning ("Resource temporarily unavailable."); break; + + case G_IO_STATUS_ERROR : + g_warning ("Error"); break; + + case G_IO_STATUS_NORMAL : + if (error != NULL) + { + g_warning ("ERROR READING: %s\n", error->message); + g_error_free (error); return -1; - if (str[i]==(char)0xFF) break; - } - str[i] = 0; + }; break; + } + i++; + } while ((bytes == 1) && (buf[i-1] != (gchar)0xFF) && (i<1024)); + buf[i-1] = 0; #ifdef DEBUG - printf ("< %s\n", str); + printf ("< %s\n", buf); #endif + + *str = g_strdup (buf); - return i; + return 0; } void server_ip (unsigned char buf[4]) diff --git a/src/client.h b/src/client.h index 8504171..28f99af 100644 --- a/src/client.h +++ b/src/client.h @@ -1,5 +1,3 @@ -extern int fdin[2], fdout[2]; /* two pipes, in and out */ - extern int connected; extern char server[128]; @@ -30,14 +28,9 @@ enum outmsg_type { OUT_VERSION }; -/* initalisation functions */ -extern void client_initpipes (void); -extern void client_destroypipes (void); - /* functions for connecting and disconnecting */ extern void client_init (const char *server, const char *nick); -extern void client_connectcancel (void); -extern void client_destroy (void); +extern void client_disconnect (void); /* for sending stuff back and forth */ extern void client_outmessage (enum outmsg_type msgtype, char *str); diff --git a/src/commands.c b/src/commands.c index 15eee05..35f23fc 100644 --- a/src/commands.c +++ b/src/commands.c @@ -102,7 +102,7 @@ void connect_command (void) void disconnect_command (void) { - client_destroy (); + client_disconnect (); } void team_command (void) diff --git a/src/config.c b/src/config.c index 2940df4..66ec36d 100644 --- a/src/config.c +++ b/src/config.c @@ -353,6 +353,8 @@ sound_enable_sound_changed (GConfClient *client, soundenable = gconf_value_get_bool (gconf_entry_get_value (entry)); if (!soundenable) gconf_client_set_bool (gconf_client, "/apps/gtetrinet/sound/enable_midi", FALSE, NULL); + else + sound_cache (); } void diff --git a/src/dialogs.c b/src/dialogs.c index 4caeae3..cc73de7 100644 --- a/src/dialogs.c +++ b/src/dialogs.c @@ -56,7 +56,7 @@ void connectingdialog_button (GtkWidget *dialog, gint button) gtk_timeout_remove (timeouttag); timeouttag = 0; if (connectingdialog == 0) return; - client_connectcancel (); + client_disconnect (); gtk_widget_destroy (connectingdialog); connectingdialog = 0; break; diff --git a/src/fields.c b/src/fields.c index ca3c82f..6517988 100644 --- a/src/fields.c +++ b/src/fields.c @@ -99,7 +99,7 @@ GtkWidget *fields_page_new (void) pagecontents = fields_page_contents (); if (fieldspage == NULL) { - fieldspage = gtk_alignment_new (0.5, 0.5, 0.0, 0.0); + fieldspage = gtk_alignment_new (0.5, 0.5, 1.0, 1.0); gtk_container_set_border_width (GTK_CONTAINER(fieldspage), 2); } gtk_container_add (GTK_CONTAINER(fieldspage), pagecontents); @@ -305,7 +305,7 @@ GtkWidget *fields_page_contents (void) align = gtk_alignment_new (0.5, 0.5, 0.0, 0.0); gtk_container_add (GTK_CONTAINER (align), table); - gtk_box_pack_start (GTK_BOX (vbox), align, TRUE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (vbox), align, FALSE, FALSE, 0); align = gtk_alignment_new (0.5, 0.5, 1.0, 1.0); gtk_container_add (GTK_CONTAINER (align), table2); gtk_box_pack_start (GTK_BOX (vbox), align, TRUE, TRUE, 0); diff --git a/src/gtetrinet.c b/src/gtetrinet.c index c23dc51..128469d 100644 --- a/src/gtetrinet.c +++ b/src/gtetrinet.c @@ -102,59 +102,6 @@ int main (int argc, char *argv[]) char buf[1024]; GdkPixbuf *icon_pixbuf; GError *err = NULL; - - GTET_STRCPY(buf, "", 4); - g_assert(strlen(buf) == 0); - g_assert(buf[0] == 0); - - GTET_STRCAT(buf, "", 4); - g_assert(strlen(buf) == 0); - g_assert(buf[0] == 0); - - GTET_STRCPY(buf, "a", 1); - g_assert(strlen(buf) == 0); - g_assert(buf[0] == 0); - - GTET_STRCAT(buf, "a", 1); - g_assert(strlen(buf) == 0); - g_assert(buf[0] == 0); - - GTET_STRCPY(buf, "abcd", 4); - g_assert(strlen(buf) == 3); - g_assert(buf[3] == 0); - g_assert(buf[2] == 'c'); - g_assert(buf[1] == 'b'); - g_assert(buf[0] == 'a'); - - GTET_STRCAT(buf, "xyz", 4); - g_assert(strlen(buf) == 3); - g_assert(buf[3] == 0); - g_assert(buf[2] == 'c'); - g_assert(buf[1] == 'b'); - g_assert(buf[0] == 'a'); - - GTET_STRCAT(buf, "abcd", 7); - g_assert(strlen(buf) == 6); - g_assert(buf[6] == 0); - g_assert(buf[5] == 'c'); - g_assert(buf[4] == 'b'); - g_assert(buf[3] == 'a'); - g_assert(buf[2] == 'c'); - g_assert(buf[1] == 'b'); - g_assert(buf[0] == 'a'); - - GTET_O_STRCPY(buf, "abcd"); - GTET_O_STRCAT(buf, "abcd"); - g_assert(strlen(buf) == 8); - g_assert(buf[8] == 0); - g_assert(buf[7] == 'd'); - g_assert(buf[6] == 'c'); - g_assert(buf[5] == 'b'); - g_assert(buf[4] == 'a'); - g_assert(buf[3] == 'd'); - g_assert(buf[2] == 'c'); - g_assert(buf[1] == 'b'); - g_assert(buf[0] == 'a'); bindtextdomain(PACKAGE, LOCALEDIR); bind_textdomain_codeset(PACKAGE, "UTF-8"); @@ -162,7 +109,6 @@ int main (int argc, char *argv[]) srand (time(NULL)); - //gnome_init_with_popt_table (APPID, APPVERSION, argc, argv, options, 0 , NULL); gnome_program_init (APPID, APPVERSION, LIBGNOMEUI_MODULE, argc, argv, GNOME_PARAM_POPT_TABLE, options, GNOME_PARAM_NONE); @@ -242,7 +188,6 @@ int main (int argc, char *argv[]) config_loadconfig (); /* initialise some stuff */ - client_initpipes (); fields_init (); /* first set up the display */ @@ -354,9 +299,8 @@ int main (int argc, char *argv[]) gtk_main (); /* cleanup */ - client_destroypipes (); fields_cleanup (); - client_connectcancel (); /* kills the client process */ + client_disconnect (); /* kills the client process */ sound_stopmidi (); return 0; -- 2.50.1