Complete.Org: Mailing Lists: Archives: freeciv-dev: October 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: Sat, 6 Oct 2001 21:03:40 +0200

 > 
 > The real amount which can be extracted can only examined after a
 > second client is converted. Still missing are command line options
 > like "-f" and a "--skip-main-menu". The code for these would probably
 > in client/*.c.
 > 
Agreed. I have forgotten that issue. The functions in
client/include/connectdlg_g.h are written to be used also from
client/*.c.

Here is the patch for gui-win32/connectdlg.c. It is not ready yet, but
it should be enough to see what code should go into client/*.c.
The start_server stuff was derived from wincivgo.

Greetings
Andreas Kemnade

--- /usr/src/cvs/freeciv/client/gui-win32/connectdlg.c  Tue Sep  4 19:04:38 2001
+++ connectdlg.c        Sat Oct  6 20:24:41 2001
@@ -13,7 +13,10 @@
 #ifdef HAVE_CONFIG_H
 #include <config.h>
 #endif
+
+#include <assert.h>
 #include <windows.h>
+
 #include "fcintl.h"
 #include "game.h"
 #include "log.h"
@@ -35,6 +38,7 @@
 #include "graphics.h"
 #include "gui_stuff.h"
 #include "helpdata.h"           /* boot_help_texts() */
+#include "inputdlg.h"
 #include "mapctrl.h"
 #include "mapview.h"
 #include "menu.h"
@@ -51,10 +55,102 @@
 #include <windowsx.h>
 /* in civclient.c; FIXME hardcoded sizes */
 
+struct t_server_button {
+  HWND button;
+  char *button_string;
+  char *command;
+};
+
+static struct t_server_button server_buttons[]={{NULL,"Start Game","start"},
+                                               {NULL,"End Game","quit"}};
+
+
 extern HWND root_window;
 extern HINSTANCE freecivhinst;
 HWND connect_dlg;
 static int autoconnect_timer_id;
+static HANDLE server_process=INVALID_HANDLE_VALUE;
+static HANDLE stdin_pipe[2];
+static HANDLE stdout_pipe[2];
+static HANDLE stderr_pipe[2];
+static HWND server_window;
+static HWND server_output;
+static HWND server_commandline;
+static HWND main_menu;
+
+/**************************************************************************
+ Tests if the client has started the server.
+**************************************************************************/
+int is_server_running()
+{
+  return (server_process!=INVALID_HANDLE_VALUE);
+}
+
+/**************************************************************************
+ Kills the server if the client has started it (atexit handler)
+**************************************************************************/
+void kill_server()
+{
+  if (is_server_running()) {
+    TerminateProcess(server_process,0);
+    CloseHandle(server_process);
+    server_process=INVALID_HANDLE_VALUE;
+  }
+}
+
+/*************************************************************************
+ Exit without killing the server
+*************************************************************************/
+void quit_client_only()
+{
+  CloseHandle(server_process);
+  server_process=INVALID_HANDLE_VALUE;
+  exit(0);
+}
+
+/*************************************************************************
+
+*************************************************************************/
+void show_server_window()
+{
+  ShowWindow(server_window,SW_SHOWNORMAL);
+}
+
+/*************************************************************************
+ Updates the button row in the server window
+*************************************************************************/
+static void update_server_buttons()
+{
+  int i;
+  if (!server_window)
+    return;
+  if (is_server_running()) {
+    for(i=0;i<ARRAY_SIZE(server_buttons);i++)
+      EnableWindow(server_buttons[i].button,TRUE);
+    EnableWindow(server_commandline,TRUE);
+  } else {
+    for(i=0;i<ARRAY_SIZE(server_buttons);i++)
+      EnableWindow(server_buttons[i].button,FALSE);
+    EnableWindow(server_commandline,FALSE);
+  }  
+}
+
+
+/**************************************************************************
+  This should be used for MsgWaitForMultipleObjects
+**************************************************************************/
+int fillin_handles(HANDLE *handles, int maxnum)
+{
+  assert(maxnum>=3);
+  if (!server_window)
+    return 0;
+  handles[0]=stdout_pipe[0];
+  handles[1]=stderr_pipe[0];
+  if (!is_server_running())
+    return 2;
+  handles[2]=server_process;
+  return 3;
+}
 
 /**************************************************************************
 
@@ -185,14 +281,18 @@
                                    function again */
 #if 0
   case ECONNREFUSED:            /* Server not available (yet) */
-    return TRUE;                /* Keep calling this function */
+    return TRUE;                /* Keep calling this function
+                                   ECONNREFUSED does not exits on windows */
 #endif
-  default:                      /* All other errors are fatal */
+  default:
+    return TRUE; /* All other errors are fatal */
+#if 0
     freelog(LOG_FATAL,
             _("Error contacting server \"%s\" at port %d "
               "as \"%s\":\n %s\n"),
             server_host, server_port, player_name, errbuf);
     exit(1);     
+#endif
   }
 }
 
@@ -202,6 +302,7 @@
 static void CALLBACK autoconnect_timer(HWND  hwnd,UINT uMsg,
                                       UINT idEvent,DWORD  dwTime)  
 {
+  printf("Timer\n");
   if (!try_to_autoconnect())
     KillTimer(NULL,autoconnect_timer_id);
 }
@@ -233,8 +334,349 @@
   }
   printf("server_autoconnect\n");
   if (try_to_autoconnect()) {
+    printf("T2\n");
     autoconnect_timer_id=SetTimer(root_window,3,AUTOCONNECT_INTERVAL,
                                  autoconnect_timer);
   }
 
 }
+
+/**************************************************************************
+  Sends a server command to the stdin pipe
+**************************************************************************/
+void send_server_commandline(char *s)
+{
+  DWORD wlen;
+  WriteFile(stdin_pipe[1],s,strlen(s),&wlen,NULL);
+  WriteFile(stdin_pipe[1],"\n",1,&wlen,NULL);
+}
+
+/**************************************************************************
+
+**************************************************************************/
+static void append_server_output(HANDLE pipe)
+{
+  int len;
+  char buf[1024];
+  DWORD rlen;
+  if (WaitForSingleObject(pipe,0)==WAIT_OBJECT_0) {
+    if (ReadFile(pipe,buf,1023,&rlen,NULL)) {
+      buf[rlen]=0;
+      
+      len=Edit_GetTextLength(server_output);
+      if (len>(32767-strlen(buf))) {
+       Edit_SetSel(server_output,0,len);
+      } else {
+       Edit_SetSel(server_output,len,len);
+      }
+      Edit_ReplaceSel(server_output,buf);
+      if (len==Edit_GetTextLength(server_output)) {
+       SetWindowText(server_output,buf);   
+       /* Skip some code part */
+      }
+    }
+  }
+}
+
+/**************************************************************************
+
+**************************************************************************/
+void handle_pipe_and_process(void)
+{
+  if (!server_window)
+    return;
+  append_server_output(stdout_pipe[0]);
+  append_server_output(stderr_pipe[0]);
+  if (is_server_running()&&WaitForSingleObject(server_process,0)) {
+    CloseHandle(server_process);
+    server_process=INVALID_HANDLE_VALUE;
+    update_server_buttons();
+  }
+}
+
+/**************************************************************************
+
+**************************************************************************/
+static LONG CALLBACK server_window_proc(HWND dlg,UINT message,
+                                       WPARAM wParam,LPARAM lParam)
+{
+  int i;
+  HWND controlwnd;
+  switch(message) {
+  case WM_CLOSE:
+    ShowWindow(dlg,SW_HIDE);
+    break;
+  case WM_DESTROY:
+  case WM_SIZE:
+  case WM_GETMINMAXINFO:
+    break;
+  case WM_COMMAND:
+    controlwnd=(HWND)lParam;
+    if (controlwnd==server_commandline) {
+      char *crpos;
+      char buf[512];
+      GetWindowText(controlwnd,buf,sizeof(buf));
+      if (strchr(buf,'\n')) {
+       if ((crpos=strchr(buf,'\r')))
+         crpos[0]=0;
+       if ((crpos=strchr(buf,'\n')))
+         crpos[0]=0;
+       send_server_commandline(buf);
+      }
+    } else {
+      for(i=0;i<ARRAY_SIZE(server_buttons);i++) {
+       if (server_buttons[i].button==controlwnd) {
+         send_server_commandline(server_buttons[i].command);
+         break;
+       }
+      }
+    }
+    
+    break;
+  default:
+    return DefWindowProc(dlg,message,wParam,lParam);
+  }
+  return 0;
+}
+
+
+/**************************************************************************
+
+**************************************************************************/
+static void output_minsize(POINT *minsize, void *data)
+{
+  minsize->x=500;
+  minsize->y=100;
+}
+
+/**************************************************************************
+
+**************************************************************************/
+static void output_setsize(RECT *rc, void *data)
+{
+  MoveWindow((HWND)data,rc->left,rc->top,rc->right-rc->left,
+            rc->bottom-rc->top,TRUE);
+}
+
+/**************************************************************************
+
+**************************************************************************/
+static void output_del(void *data)
+{
+  DestroyWindow((HWND)data);
+}
+
+/**************************************************************************
+ Creates the server window (which shows stdout and stderr of the server)
+**************************************************************************/
+static void create_server_window()
+{
+  int i;
+  SECURITY_ATTRIBUTES sa;
+  struct fcwin_box *hbox;
+  struct fcwin_box *vbox;
+  memset(&sa,0,sizeof(sa));
+  sa.nLength=sizeof(sa);
+  sa.bInheritHandle=TRUE;
+  
+  if (!CreatePipe(&stdout_pipe[0],&stdout_pipe[1],&sa,1024)) {
+    freelog(LOG_FATAL,_("Cannot create pipe"));
+    exit(1);
+  }
+  if (!CreatePipe(&stderr_pipe[0],&stderr_pipe[1],&sa,1024)) {
+    freelog(LOG_FATAL,_("Cannot create pipe"));
+    exit(1);
+  }
+  if (!CreatePipe(&stdin_pipe[0],&stdin_pipe[1],&sa,1024)) {
+    freelog(LOG_FATAL,_("Cannot create pipe"));
+    exit(1);
+  }
+  
+  server_window=fcwin_create_layouted_window(server_window_proc,
+                                            _("Game Control"),
+                                            WS_OVERLAPPEDWINDOW,
+                                            CW_USEDEFAULT,CW_USEDEFAULT,
+                                            root_window,NULL,NULL);
+  vbox=fcwin_vbox_new(server_window,FALSE);
+  server_output=CreateWindowEx(WS_EX_CLIENTEDGE,
+                              "EDIT",
+                              "",
+                              WS_CHILD | ES_READONLY | WS_VISIBLE | 
+                              WS_VSCROLL | ES_LEFT | ES_WANTRETURN |
+                              ES_MULTILINE | ES_AUTOVSCROLL,
+                              0, 0, 0, 0,
+                              server_window,
+                              NULL,
+                              freecivhinst,
+                              NULL);      
+  fcwin_box_add_generic(vbox,output_minsize,output_setsize,output_del,
+                       server_output,
+                       TRUE,TRUE,5);
+  hbox=fcwin_hbox_new(server_window,FALSE);
+  for (i=0;i<ARRAY_SIZE(server_buttons);i++) {
+    server_buttons[i].button=
+      fcwin_box_add_button(hbox,server_buttons[i].button_string,
+                          0,0,FALSE,FALSE,10);
+  }
+  server_commandline=fcwin_box_add_edit(hbox,"",50,0,
+                                       ES_WANTRETURN | ES_MULTILINE,
+                                       TRUE,TRUE,10);
+  fcwin_box_add_box(vbox,hbox,FALSE,FALSE,5);
+  fcwin_set_box(server_window,vbox);
+  atexit(kill_server);
+  update_server_buttons();
+}
+
+/*****************************************************************************
+
+*****************************************************************************/
+static void start_server(char *cmdline)
+{
+  STARTUPINFO si;
+  PROCESS_INFORMATION pi;
+  if (!server_window)
+    create_server_window();
+  ZeroMemory(&si,sizeof(si));
+  si.cb=sizeof(si);
+  si.hStdOutput=stdout_pipe[1];
+  si.hStdInput=stdin_pipe[0];
+  si.hStdError=stderr_pipe[1];
+  si.dwFlags=STARTF_USESTDHANDLES;
+  
+  if (!CreateProcess(NULL,cmdline,NULL,NULL,TRUE,NORMAL_PRIORITY_CLASS,
+                    NULL,NULL,&si,&pi))
+    {
+      MessageBox(NULL,"Cannot start the 
server","Freeciv",MB_OK|MB_ICONEXCLAMATION);
+      exit(1);
+    }
+  CloseHandle(pi.hThread);
+  server_process=pi.hProcess;
+  update_server_buttons();
+  show_server_window();
+}
+
+/**************************************************************************
+ Starts the server without arguments.
+**************************************************************************/
+void start_server_for_new_game()
+{
+  start_server("civserver");
+}
+
+/*************************************************************************
+ Starts the server with -f option to load a game
+*************************************************************************/
+void start_server_load_game(char *filename)
+{
+  char cmdline[512];
+  my_snprintf(cmdline,sizeof(cmdline),"civserver -f \"%s\"",filename);
+  start_server(cmdline);
+}
+
+/**************************************************************************
+
+**************************************************************************/
+static void load_game_name_ok_callback(HWND w,void * data)
+{
+  char dirname[MAX_PATH+1];
+  OPENFILENAME ofn;
+  char filename[MAX_PATH+1];
+  filename[0]='\0';
+  sz_strlcpy(player_name,input_dialog_get_input(w));
+  input_dialog_destroy(w);
+  
+  ZeroMemory(&ofn,sizeof(ofn));
+  ofn.lStructSize=sizeof(OPENFILENAME);
+  ofn.hwndOwner=root_window;
+  ofn.hInstance=(HINSTANCE)GetWindowLong(root_window,GWL_HINSTANCE);
+  ofn.lpstrTitle="Load Game"; 
+  ofn.lpstrFile=filename;
+  ofn.nMaxFile=sizeof(filename);
+  ofn.Flags=OFN_EXPLORER;
+
+  GetCurrentDirectory(MAX_PATH,dirname);
+  if (GetOpenFileName(&ofn)) {
+    SetCurrentDirectory(dirname);
+    start_server_load_game(ofn.lpstrFile);
+  } else {
+    SetCurrentDirectory(dirname);
+  }
+}
+
+/**************************************************************************
+ Callback for the new game button 
+**************************************************************************/
+static void new_game_name_ok_callback(HWND w,void * data)
+{
+  sz_strlcpy(player_name,input_dialog_get_input(w));
+  input_dialog_destroy(w);
+  DestroyWindow(main_menu);
+  start_server_for_new_game();
+}
+
+/**************************************************************************
+
+**************************************************************************/
+static void name_input_destroy_callback(HWND w, void * data)
+{
+  input_dialog_destroy(w);
+}
+
+
+/**************************************************************************
+
+**************************************************************************/
+static void new_game_callback(HWND w,void * data)
+{
+  input_dialog_create(root_window,
+                      _("New Game"),_("Enter your name:"),player_name,
+                      new_game_name_ok_callback,NULL,
+                      name_input_destroy_callback,NULL);
+}
+
+/**************************************************************************
+
+**************************************************************************/
+static void load_game_callback(HWND w,void * data)
+{
+  input_dialog_create(root_window,
+                      _("Load Game"),_("Enter your name:"),player_name,
+                      load_game_name_ok_callback,NULL,
+                      name_input_destroy_callback,NULL);
+}
+
+/**************************************************************************
+
+**************************************************************************/
+static void quit_game_callback(HWND w,void *data)
+{
+  exit(0);
+}
+
+/**************************************************************************
+...
+**************************************************************************/
+static void join_game_callback(HWND w,void *data)
+{ 
+  if (w)
+    destroy_message_dialog(w);
+  gui_server_connect();
+}
+
+/**************************************************************************
+
+**************************************************************************/
+void popup_main_menu()
+{
+  if (server_window)
+    ShowWindow(server_window,SW_HIDE);
+  main_menu=popup_message_dialog(root_window,
+                                 _("Start a game"),
+                                 _("What do you wish to to?"),
+                                 _("New Game"),new_game_callback,NULL,
+                                 _("Load Game"),load_game_callback,NULL,
+                                 _("Join Game"),join_game_callback,NULL,
+                                 _("Quit Game"),quit_game_callback,NULL,
+                                 NULL);
+}
+

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