Complete.Org: Mailing Lists: Archives: freeciv-dev: September 2001:
[Freeciv-Dev] Re: [Patch] Extended connect dialog (PR#977)
Home

[Freeciv-Dev] Re: [Patch] Extended connect dialog (PR#977)

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: rf13@xxxxxxxxxxxxxxxxxxxxxx
Cc: freeciv-dev@xxxxxxxxxxx, bugs@xxxxxxxxxxxxxxxxxxx
Subject: [Freeciv-Dev] Re: [Patch] Extended connect dialog (PR#977)
From: Andreas Kemnade <akemnade@xxxxxxxxxxx>
Date: Mon, 24 Sep 2001 21:27:16 +0200

Raimar Falke writes:
 > On Mon, Sep 24, 2001 at 05:52:57AM -0700, Andreas Kemnade wrote:
 > 
 > It produces compiler warnings:
 > 
Fixed. The core dump is also fixed. But you can crash the client if you
close the dialog and select the "Disconnect" menu item. But what
should happen if you close the dialog:
Quit the client?
Popup the normal connect dialog?

The things on the todo list have still to be done.

The updated patch is attached.
Of course, it is not ready for cvs.

Are the label texts good or could there be more meaningful text?
What about the server window? More buttons? 

Greetings
Andreas Kemnade

diff --exclude-from freeciv/diff_ignore -Nur 
/usr/src/cvs/freeciv/client/gui-gtk/connectdlg.c 
freeciv/client/gui-gtk/connectdlg.c
--- /usr/src/cvs/freeciv/client/gui-gtk/connectdlg.c    Sun Sep  9 15:35:39 2001
+++ freeciv/client/gui-gtk/connectdlg.c Mon Sep 24 21:07:39 2001
@@ -17,6 +17,9 @@
 #include <errno.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <sys/types.h>
+#include <unistd.h>
+
 
 #include <gtk/gtk.h>
 
@@ -40,6 +43,14 @@
 
 static GtkWidget *dialog;
 
+static GtkWidget *server_window=NULL;
+static GtkWidget *server_output;
+static GtkWidget *server_output_scrollbar;
+
+static int stdin_pipe[2];
+static int stderr_pipe[2];
+static int stdout_pipe[2];
+
 /* meta Server */
 static int update_meta_dialog(GtkWidget *meta_list);
 static void meta_list_callback(GtkWidget *w, gint row, gint column);
@@ -120,10 +131,11 @@
   return FALSE;
 }
 
+
 /**************************************************************************
 ...
 **************************************************************************/
-void gui_server_connect(void)
+static void join_game_callback(GtkWidget *w,gpointer data)
 {
   GtkWidget *label, *table, *book, *scrolled, *list, *vbox, *update;
   static char *titles_[6]= {N_("Server Name"), N_("Port"), N_("Version"),
@@ -132,6 +144,8 @@
   char buf [256];
   int i;
 
+  if (w)
+    destroy_message_dialog(w);
   if (!titles) titles = intl_slist(6, titles_);
 
   gtk_widget_set_sensitive(turn_done_button, FALSE);
@@ -365,4 +379,184 @@
   if (try_to_autoconnect()) {
     gtk_timeout_add(AUTOCONNECT_INTERVAL, try_to_autoconnect, NULL);
   }
+}
+
+/**************************************************************************
+  Sends a server command to the stdin pipe
+**************************************************************************/
+static void server_command_callback(GtkWidget *w,gpointer data)
+{
+  char *s;
+  if (data) {
+    s=(char *)data;
+  } else {
+    s=gtk_editable_get_chars(GTK_EDITABLE(w),0,-1);
+  }
+  write(stdin_pipe[1],s,strlen(s));
+  write(stdin_pipe[1],"\n",1);
+  if (!data)
+    g_free(s);
+}
+
+/**************************************************************************
+ Reads input from the server (pipe)
+**************************************************************************/
+static void get_pipe_input(gpointer data,
+                          gint fid,
+                          GdkInputCondition condition)
+{
+  char buf[1024];
+  int len;
+  len=read(fid,buf,sizeof(buf)-1);
+  if (len>0) { 
+    buf[len]=0;
+    gtk_text_freeze(GTK_TEXT(server_output));
+    gtk_text_insert(GTK_TEXT(server_output),NULL,NULL,NULL,buf,-1);
+    gtk_text_thaw(GTK_TEXT(server_output));
+  }
+
+  /* move the scrollbar forward by a ridiculous amount */
+  gtk_range_default_vmotion(GTK_RANGE(server_output_scrollbar), 0, 10000);
+  
+}
+
+/**************************************************************************
+ Creates the server window (which shows stdout and stderr of the server)
+**************************************************************************/
+static void create_server_window()
+{
+  GtkWidget *entry;
+  GtkWidget *button;
+  GtkWidget *vbox;
+  GtkWidget *hbox;
+  server_window=gtk_window_new(GTK_WINDOW_TOPLEVEL);
+  gtk_window_set_title(GTK_WINDOW(server_window),_("Game control"));
+  gtk_signal_connect(GTK_OBJECT(server_window),"delete_event",
+                    GTK_SIGNAL_FUNC(gtk_widget_hide),server_window);
+  vbox=gtk_vbox_new(FALSE,5);
+  gtk_container_add(GTK_CONTAINER(server_window),vbox);
+  server_output=gtk_text_new(NULL,NULL);
+  gtk_text_set_editable(GTK_TEXT(server_output),FALSE);
+  server_output_scrollbar=gtk_vscrollbar_new(GTK_TEXT(server_output)->vadj);
+  hbox=gtk_hbox_new(FALSE,0);
+  gtk_box_pack_start(GTK_BOX(hbox),server_output,TRUE,TRUE,0);
+  gtk_box_pack_start(GTK_BOX(hbox),server_output_scrollbar,FALSE,FALSE,0);
+  gtk_box_pack_start(GTK_BOX(vbox),hbox,FALSE,FALSE,0);
+  gtk_widget_set_usize(server_output,600,100);
+  
+  hbox=gtk_hbox_new(FALSE,5);
+  gtk_box_pack_start(GTK_BOX(vbox),hbox,FALSE,FALSE,0);
+  
+  button=gtk_button_new_with_label(_("Start game"));
+  gtk_box_pack_start(GTK_BOX(hbox),button,FALSE,FALSE,0);
+  gtk_signal_connect(GTK_OBJECT(button),"clicked",
+                    GTK_SIGNAL_FUNC(server_command_callback),"start");
+  
+  button=gtk_button_new_with_label(_("End game"));
+  gtk_signal_connect(GTK_OBJECT(button),"clicked",
+                    GTK_SIGNAL_FUNC(server_command_callback),"quit");
+  gtk_box_pack_start(GTK_BOX(hbox),button,FALSE,FALSE,0);
+  
+  entry=gtk_entry_new();
+  gtk_box_pack_start(GTK_BOX(hbox),entry,TRUE,TRUE,0);
+  gtk_signal_connect(GTK_OBJECT(entry),"activate",
+                    GTK_SIGNAL_FUNC(server_command_callback),
+                    NULL);
+  gtk_widget_show_all(vbox);
+
+  if (pipe(stdin_pipe)) {
+    freelog(LOG_FATAL,_("Cannot create pipe"));
+    exit(1);
+  }
+  if (pipe(stdout_pipe)) {
+    freelog(LOG_FATAL,_("Cannot create pipe"));
+    exit(1);
+  }
+  if (pipe(stderr_pipe)) {
+    freelog(LOG_FATAL,_("Cannot create pipe"));
+    exit(1);
+  }
+  gdk_input_add(stdout_pipe[0],GDK_INPUT_READ,
+               get_pipe_input,NULL);
+  gdk_input_add(stderr_pipe[0],GDK_INPUT_READ,
+               get_pipe_input,NULL);
+}
+
+/**************************************************************************
+ Starts the server. data can contain the filename of a game. 
+**************************************************************************/
+static void start_server_callback(GtkWidget *w,gpointer data)
+{
+  pid_t pid;
+  if (w)
+    destroy_message_dialog(w);
+  if (!server_window)        /* will also create pipes */
+    create_server_window();
+  pid=fork();
+  if (pid==0) {
+    char *argv[4];
+    /* redirecting stdio */
+    dup2(stdout_pipe[1],1);
+    dup2(stderr_pipe[1],2);
+    dup2(stdin_pipe[0],0);
+    argv[0]="civserver";
+    argv[1]=NULL;
+    if (data) {
+      argv[1]="-f";
+      argv[2]=data;
+      argv[3]=NULL;
+    }
+    execvp("civserver",argv);
+    /* This line is only reached if civserver cannot be started. 
+       Calling exit here is dangerous due to X11 problems
+       (async replies) */
+    _exit(1);
+  }
+
+  gtk_widget_show(server_window);
+  server_autoconnect();
+}
+
+/**************************************************************************
+
+**************************************************************************/
+static void filesel_callback(GtkWidget *w,gpointer data)
+{
+  char *filename;
+  filename=gtk_file_selection_get_filename(GTK_FILE_SELECTION(data));
+  start_server_callback(NULL,filename);
+}
+
+
+/**************************************************************************
+
+**************************************************************************/
+static void load_game_callback(GtkWidget *w,gpointer data)
+{
+  GtkWidget *filesel;
+  destroy_message_dialog(w);
+  filesel=gtk_file_selection_new(_("Please select a game file to load"));
+  gtk_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(filesel)->ok_button),
+                    "clicked",GTK_SIGNAL_FUNC(filesel_callback),filesel);
+  gtk_signal_connect_object(GTK_OBJECT(GTK_FILE_SELECTION(filesel)
+                                      ->ok_button),"clicked",
+                           GTK_SIGNAL_FUNC(gtk_widget_destroy),
+                           (gpointer)filesel);
+  gtk_signal_connect_object(GTK_OBJECT(GTK_FILE_SELECTION(filesel)
+                                      ->cancel_button),"clicked",
+                           GTK_SIGNAL_FUNC(gtk_widget_destroy),
+                           (gpointer)filesel);
+  gtk_widget_show(filesel);
+}
+/**************************************************************************
+
+**************************************************************************/
+void gui_server_connect(void)
+{
+  popup_message_dialog(top_vbox,
+                      _("Start a game"),_("What do you wish to to?"),
+                      _("New Game"),start_server_callback,NULL,
+                      _("Load Game"),load_game_callback,NULL,
+                      _("Join Game"),join_game_callback,NULL,
+                      NULL);
 }

[Prev in Thread] Current Thread [Next in Thread]