[Freeciv-Dev] Re: [Patch] Extended connect dialog (PR#977)
[Top] [All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
>
> 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);
+}
+
|
|