]> granicus.if.org Git - xconq/blobdiff - kernel/win32.c
commits for 7.5.0 pre-release tarball
[xconq] / kernel / win32.c
index 36b0371040fc8a31762da26dac5ecbcea19b7674..0ea1eeca0da69b4989ea27689d1b37a2e532776b 100644 (file)
@@ -19,21 +19,39 @@ any later version.  See the file COPYING.  */
 #include "module.h"
 #include "system.h"
 
-extern void close_displays(void);
+#ifdef __cplusplus
+extern "C" {
+#endif
 
-#include <signal.h>
-#include <unistd.h>
-#include <pwd.h>
-#include <sys/time.h>
 #include <errno.h>
 #include <fcntl.h>
+#include <signal.h>
+
+#if (defined (__CYGWIN32__) || defined (__MINGW32__)) 
+#include <unistd.h>
+#endif
 
-/* (should flush the following includes?) */
+#ifdef __CYGWIN32__
+#include <limits.h>
 #include <sys/file.h>
 #include <netinet/in.h>
 #include <sys/socket.h>
 #include <netdb.h>
 #include <sys/ioctl.h>
+#include <pwd.h>
+void cygwin_conv_to_full_win32_path(const char *path, char *win32_path);
+#endif
+
+#ifdef _MSC_VER
+#include <io.h>
+#include <windows.h>
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#define F_OK 0
 
 /* Default names for places. */
 
@@ -41,7 +59,8 @@ extern void close_displays(void);
 #undef XCONQDATA
 
 #ifndef XCONQDATA
-#define XCONQDATA ".."
+/* The Windows app should now live in the top directory. */
+#define XCONQDATA "."
 #endif
 
 #ifndef XCONQLIB
@@ -52,36 +71,51 @@ extern void close_displays(void);
 #define XCONQIMAGES "images"
 #endif
 
-#ifndef XCONQSCORES
-#define XCONQSCORES "scores"
+#ifdef __CYGWIN32__
+/* used in xconq.c and xtconq.c */
+uid_t games_uid;
 #endif
 
-static char *game_homedir(void);
-static char *game_filename(char *namevar, char *defaultname);
-static char *score_file_pathname(char *name);
+void extract_dirname (char **dirname, char *pathname);
 
-uid_t games_uid;
+static void stop_handler(int sig);
+static void crash_handler(int sig);
+static void hup_handler(int sig);
+
+char *xcq_program_name = NULL;
+FILE *xcq_fstdout = NULL;
 
 char *
 default_library_pathname(void)
 {
-    char *name;
-
-    name = xmalloc(strlen(XCONQDATA) + 1 + strlen(XCONQLIB) + 1);
-    strcpy(name, XCONQDATA);
-    strcat(name, "\\");
+    char *name = NULL;
+    char *tmpname = NULL;    
+
+    if (xcq_program_name) {
+        extract_dirname(&tmpname, xcq_program_name);
+        name = (char *)xmalloc(strlen(tmpname) + 1 + strlen(XCONQLIB) + 1);
+        strcpy(name, tmpname);
+        free(tmpname);
+    }
+    else {
+        name = (char *)xmalloc(strlen(XCONQDATA) + 1 + strlen(XCONQLIB) + 1);
+        strcpy(name, XCONQDATA);
+    }
+    strcat(name, "/");
     strcat(name, XCONQLIB);
     return name;
 }
 
 char *
-default_images_pathname(void)
+default_images_pathname(char *libpath)
 {
     char *name;
 
-    name = xmalloc(strlen(XCONQDATA) + 1 + strlen(XCONQIMAGES) + 1);
-    strcpy(name, XCONQDATA);
-    strcat(name, "\\");
+    if (libpath == NULL)
+      libpath = default_library_pathname();
+    name = (char *)xmalloc(strlen(libpath) + 4 + strlen(XCONQIMAGES) + 1);
+    strcpy(name, libpath);
+    strcat(name, "/../");
     strcat(name, XCONQIMAGES);
     return name;
 }
@@ -94,93 +128,86 @@ news_filename(void)
     return spbuf;
 }
 
-static char *savegamename;
-
-char *
-saved_game_filename(void)
-{
-    if (savegamename == NULL)
-      savegamename = game_filename("XCONQSAVEFILE", SAVEFILE);
-    return savegamename;
-}
-
-char *
-checkpoint_filename(int n)
-{
-    char *str, *home;
-
-    home = game_homedir();
-    str = xmalloc(strlen(home) + 40);
-    sprintf(str, "%s\\Check%d.Xconq", home, n);
-    return str;
-}
-
-static char *preferences_name;
-
-char *
-preferences_filename(void)
-{
-    if (preferences_name == NULL)
-      preferences_name = game_filename("XCONQPREFERENCES", PREFERENCESFILE);
-    return preferences_name;
-}
-
-char *
-error_save_filename(void)
+void
+save_game(char *fname)
 {
-    /* No need to cache name, will only get requested once. */
-    return game_filename("XCONQERRORFILE", ERRORFILE);
-}
+    char *name;
 
-char *
-statistics_filename(void)
-{
-    /* No need to cache name, will only get requested once. */
-    return game_filename("XCONQSTATSFILE", STATSFILE);
+    name = copy_string(game_filename("", fname));
+    write_entire_game_state(name);
 }
 
 static char *homedir;
 
-static char *
+char *
 game_homedir(void)
 {
     char *str;
+#ifdef __CYGWIN32__
     struct passwd *pwd;
+    char *homedirconv = NULL;
+    char *pc = NULL;
+#endif
 
     if (homedir != NULL)
       return homedir;
     if ((str = getenv("XCONQ_HOME")) != NULL) {
        homedir = copy_string(str);
     } else if ((str = getenv("HOME")) != NULL) {
-       homedir = xmalloc(strlen(str) + 20);
+       homedir = (char *) xmalloc(strlen(str) + 20);
        strcpy(homedir, str);
-       strcat(homedir, "/_xconq");
+       strcat(homedir, "/xconq");
+#ifdef __CYGWIN32__
     } else if ((pwd = getpwuid(getuid())) != NULL) {
-       homedir = xmalloc(strlen(pwd->pw_dir) + 20);
+       homedir = (char *) xmalloc(strlen(pwd->pw_dir) + 20);
        strcpy(homedir, pwd->pw_dir);
-       strcat(homedir, "/_xconq");
+       strcat(homedir, "/xconq");
+#endif
     } else {
-       homedir = ".";
+       homedir = "./save";
     }
+
+    /* Convert to something that can actually be used by native Win32 
+       Tcl/Tk and perhaps others as well.
+    */
+#ifdef __CYGWIN32__
+    homedirconv = (char *) xmalloc(PATH_MAX + 1);
+    cygwin_conv_to_full_win32_path(homedir, homedirconv);
+    /*
+    for (pc = homedirconv; *pc; pc++)
+      if (*pc == '\\')
+        *pc = '/';
+    */
+    free(homedir);
+    homedir = homedirconv;
+#endif
+
     /* Try to ensure that the directory exists. */
     if (access(homedir, F_OK) != 0) {
+#ifdef __CYGWIN32__
        mkdir(homedir, 0755);
+#elif defined (_MSC_VER) || defined (__MWERKS__)
+       CreateDirectory(homedir, NULL);
+#else
+       mkdir(homedir);
+#endif
        /* (should warn of problems) */
     }
     return homedir;
 }
-
-static char *
+char *
 game_filename(char *namevar, char *defaultname)
 {
     char *str, *home;
 
-    if ((str = getenv(namevar)) != NULL && *str)
-      return copy_string(str);
+    if (namevar && (str = getenv(namevar)) != NULL && *str) {
+       return copy_string(str);
+    }
     home = game_homedir();
-    str = xmalloc(strlen(home) + 1 + strlen(defaultname) + 1);
+    str = (char *)xmalloc(strlen(home) + 1 + strlen(defaultname) + 1);
     strcpy(str, home);
-    strcat(str, "\\");
+    strcat(str, "/");
     strcat(str, defaultname);
     return str;
 }
@@ -195,43 +222,10 @@ open_file(char *filename, char *mode)
        return fopen(filename, mode);
 }
 
-/* Attempt to open a library file. */
-
-FILE *
-open_module_library_file(Module *module)
-{
-    LibraryPath *p;
-    FILE *fp;
-
-    /* Don't try to do on anon modules? */
-    if (module->name == NULL)
-      return NULL;
-    for_all_library_paths(p) {
-       /* Generate library pathname. */
-       make_pathname(p->path, module->name, "g", spbuf);
-       /* Now try to open the file. */
-       fp = open_file(spbuf, "r");
-       if (fp != NULL) {
-           /* Remember the filename where we found it. */
-           module->filename = copy_string(spbuf);
-           return fp;
-       }
-    }
-    return NULL;
-}
-
-FILE *
-open_module_explicit_file(Module *module)
-{
-    if (module->filename == NULL)
-      return NULL;
-    return (open_file(module->filename, "r"));
-}
-
 FILE *
 open_library_file(char *filename)
 {
-    char fullnamebuf[1024];
+    char fullnamebuf[BUFSIZE];
     LibraryPath *p;
     FILE *fp = NULL;
 
@@ -253,32 +247,18 @@ open_library_file(char *filename)
 FILE *
 open_scorefile_for_reading(char *name)
 {
-    char *fname;
     FILE *fp;
 
-    fname = score_file_pathname(name);
-    fp = open_file(fname, "r");
-    if (fp == NULL) {
-       run_warning("Unable to open \"%s\" for reading;
-will retry once if you continue", fname);
-       fp = open_file(fname, "r");
-    }
+    fp = open_file(game_filename(NULL, name), "r");
     return fp;
 }
 
 FILE *
 open_scorefile_for_writing(char *name)
 {
-    char *fname;
     FILE *fp;
 
-    fname = score_file_pathname(name);
-    fp = open_file(fname, "a");
-    if (fp == NULL) {
-       run_warning("Unable to open \"%s\" for writing;
-will retry once if you continue", fname);
-       fp = open_file(fname, "a");
-    }
+    fp = open_file(game_filename(NULL, name), "a");
     return fp;
 }
 
@@ -288,30 +268,6 @@ close_scorefile_for_writing(FILE *fp)
     fclose(fp);
 }
 
-static char *scorenamebuf;
-
-static char *
-score_file_pathname(char *name)
-{
-    char *scorepath, extrabuf[BUFSIZE];
-
-    /* (Note that this wires in the name on the first call, so cannot
-       be called with different names.  We could make this smarter, but
-       no point to it right now.) */
-    if (scorenamebuf == NULL) {
-       scorepath = getenv("XCONQ_SCORES");
-       if (empty_string(scorepath)) {
-           strcpy(extrabuf, XCONQDATA);
-           strcat(extrabuf, "\\");
-           strcat(extrabuf, XCONQSCORES);
-           scorepath = extrabuf;
-       }
-       scorenamebuf = xmalloc(strlen(scorepath) + 1 + strlen(name) + 10);
-       make_pathname(scorepath, name, NULL, scorenamebuf);
-    }
-    return scorenamebuf;
-}
-
 void
 make_pathname(char *path, char *name, char *extn, char *pathbuf)
 {
@@ -333,6 +289,25 @@ make_pathname(char *path, char *name, char *extn, char *pathbuf)
     }
 }
 
+/* Get dirname of a given file. */
+
+void
+extract_dirname (char **dirname, char *pathname)
+{
+    char *pdelim = NULL;
+
+    *dirname = copy_string(pathname);
+    pdelim = strrchr(*dirname, '/');
+    if (!pdelim)
+        pdelim = strrchr(*dirname, '\\');
+    else
+        *pdelim = 0;
+    if (!pdelim)
+        **dirname = 0;
+    else
+        *pdelim = 0;  
+}
+
 /* Remove a given file. */
 
 int
@@ -345,11 +320,7 @@ remove_file(char *fname)
 
 /* Default behavior on explicit kill. */
 
-void stop_handler(int sig);
-void crash_handler(int sig);
-void hup_handler(int sig);
-
-void
+static void
 stop_handler(int sig)
 {
     close_displays();
@@ -358,7 +329,7 @@ stop_handler(int sig)
 
 /* This routine attempts to save the state before dying. */
 
-void
+static void
 crash_handler(int sig)
 {
     static int already_been_here = FALSE;
@@ -369,12 +340,16 @@ crash_handler(int sig)
        printf("Fatal error encountered. Signal %d\n", sig);
        write_entire_game_state(error_save_filename());
     }
+#ifdef __cplusplus
+    throw "snafu";
+#else
     abort();
+#endif
 }
 
 /* Accidental disconnection saves state. */
 
-void
+static void
 hup_handler(int sig)
 {
     static int already_been_here = FALSE;
@@ -385,7 +360,11 @@ hup_handler(int sig)
        printf("Somebody was disconnected, saving the game.\n");
        write_entire_game_state(error_save_filename());
     }
+#ifdef __cplusplus
+    throw "snafu";
+#else
     abort();
+#endif
 }
 
 void
@@ -398,20 +377,31 @@ init_signal_handlers(void)
        signal(SIGINT, SIG_DFL);
 /*     signal(SIGINT, crash_handler);  */
     }
-    signal(SIGHUP, hup_handler);
     signal(SIGSEGV, crash_handler);
     signal(SIGFPE, crash_handler);
     signal(SIGILL, crash_handler);
     signal(SIGINT, crash_handler);
-    signal(SIGQUIT, crash_handler);
     signal(SIGTERM, crash_handler);
     /* The following signals may not be available everywhere. */
+#ifdef SIGHUP
+    signal(SIGHUP, hup_handler);
+#endif
+#ifdef SIGQUIT
+    signal(SIGQUIT, crash_handler);
+#endif
 #ifdef SIGBUS
     signal(SIGBUS, crash_handler);
-#endif /* SIGBUS */
+#endif
 #ifdef SIGSYS
     signal(SIGSYS, crash_handler);
-#endif /* SIGSYS */
+#endif
+}
+
+char *
+error_save_filename(void)
+{
+    /* No need to cache name, will only get requested once. */
+    return game_filename("XCONQERRORFILE", ERRORFILE);
 }
 
 struct timeval reallasttime = { 0, 0 };