[Freeciv-Dev] [Patch] Extended connect dialog (PR#977)
[Top] [All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
This patch pops up a new dialog after starting civclient.
It has three buttons:
New Game
Load Game
Join Game
The last button pops up the normal connect dialog. The other buttons
start the server and pipe its stdout and stderr to a window.
You can load games without using the keyboard.
Todo:
- Menu item for server window.
- Chatline should send server commands through stdin pipe, if
possible.
- What should happen if you select "Disconnect from server" if civclient
has started the server?
- Kill server when civclient exits (How to do this?)
- More error checking
Comments?
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 14:32:49 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)
+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,183 @@
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();
+}
+
+/**************************************************************************
+
+**************************************************************************/
+void filesel_callback(GtkWidget *w,gpointer data)
+{
+ char *filename;
+ filename=gtk_file_selection_get_filename(GTK_FILE_SELECTION(data));
+ start_server_callback(NULL,filename);
+}
+
+
+/**************************************************************************
+
+**************************************************************************/
+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);
}
- [Freeciv-Dev] [Patch] Extended connect dialog (PR#977),
Andreas Kemnade <=
- [Freeciv-Dev] Re: [Patch] Extended connect dialog (PR#977), Raimar Falke, 2001/09/24
- [Freeciv-Dev] Re: [Patch] Extended connect dialog (PR#977), Andreas Kemnade, 2001/09/24
- [Freeciv-Dev] Re: [Patch] Extended connect dialog (PR#977), Raimar Falke, 2001/09/24
- [Freeciv-Dev] Re: [Patch] Extended connect dialog (PR#977), Andreas Kemnade, 2001/09/25
- [Freeciv-Dev] Re: [Patch] Extended connect dialog (PR#977), Raimar Falke, 2001/09/25
- [Freeciv-Dev] Re: [Patch] Extended connect dialog (PR#977), Andreas Kemnade, 2001/09/25
- [Freeciv-Dev] Re: [Patch] Extended connect dialog (PR#977), Raimar Falke, 2001/09/25
- [Freeciv-Dev] Re: [Patch] Extended connect dialog (PR#977), Andreas Kemnade, 2001/09/25
|
|