~netrek-developers/netrek-client-cow/trunk

« back to all changes in this revision

Viewing changes to _darcs/pristine/win32/winmain.c

  • Committer: Collin Pruitt
  • Date: 2009-05-12 04:30:09 UTC
  • Revision ID: collinp111@gmail.com-20090512043009-3jsjojoyrk16oass
Initial upload - updated from http://james.tooraweenah.com/darcs/netrek-client-cow/ using darcs (hince the existnace of _darcs), fully patched.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * winmain.c
 
3
 * Main file for the MS-Windows port of Netrek. Contains the "main" function,
 
4
 * as well as Windows implemenations of major Unix functions. Handles differences
 
5
 * between NT and Win32s, specifically the lack of consoles on Win32s.
 
6
 *
 
7
 * Copyright (C) 1993-1995 Jonathan Shekter
 
8
 */
 
9
 
 
10
#define NO_BOOLEAN
 
11
 
 
12
#include <windows.h>
 
13
#include <windowsx.h>
 
14
#include <winsock.h>
 
15
#include <stdio.h>
 
16
#include <stdarg.h>
 
17
#include <stdlib.h>
 
18
#include "win32/string.h"
 
19
#include <pwd.h>
 
20
 
 
21
#include "config.h"
 
22
#include "Wlib.h"
 
23
#include "defs.h"
 
24
#include "struct.h"
 
25
#include "data.h"
 
26
 
 
27
#ifdef __BORLANDC__
 
28
   #pragma warn -par  //so we don't get a zillion parameter never used messages
 
29
#endif
 
30
#ifdef _MSC_VER
 
31
#define putenv _putenv
 
32
#endif
 
33
 
 
34
//Global data
 
35
HINSTANCE MyInstance;
 
36
char ExeDir[100];
 
37
char HomeDir[100];
 
38
#ifdef SUPPORT_WIN32S
 
39
BOOL fWin32s;
 
40
W_Window console;
 
41
int PrintfSafe = 0;     //Turns off printf during critical operations
 
42
 
 
43
void Wprintf(char *format,...);
 
44
void Wfprintfstderr(char *format, ...);
 
45
#endif
 
46
 
 
47
void WinMainCleanup();
 
48
 
 
49
char *GetExeDir()
 
50
   {
 
51
   return ExeDir;
 
52
   }
 
53
 
 
54
#ifdef _MSC_VER_ACK
 
55
/* Micro$oft, in their infinite wisdom, no longer support main(int, char**)
 
56
 * in Win32! (or at least in the version I got). So write a WinMain that is
 
57
 * compatable with the rest of the code. -SAC */
 
58
/* Well, not quite - you have to remember to set the linker to console :/
 
59
 * At any rate, I'm leaving this here, 'cause I bet it's gonna be need
 
60
 * before to oft long -SAC 01 Aug 1996 */
 
61
/* int
 
62
WINAPI
 
63
WinMain(
 
64
    HINSTANCE hInstance,
 
65
    HINSTANCE hPrevInstance,
 
66
    LPSTR lpCmdLine,
 
67
    int nShowCmd
 
68
    ); */
 
69
 
 
70
int WINAPI wWinMain(HINSTANCE MyInstance, 
 
71
                                    HINSTANCE hPrevInstance, 
 
72
                                        LPSTR lpCmdLine, 
 
73
                                        int showCmd)
 
74
{
 
75
        char *c;
 
76
        WSADATA data;
 
77
        char *lpCmdLineCopy; // Gotta free it later :/
 
78
        int argc;
 
79
        char **argv;
 
80
 
 
81
        lpCmdLineCopy = calloc(1,strlen(lpCmdLine)+10);
 
82
 
 
83
        strcpy(lpCmdLineCopy, "netrek.exe");
 
84
 
 
85
        if (*lpCmdLine)
 
86
        {
 
87
                lpCmdLineCopy[10] = ' ';
 
88
                strcpy(lpCmdLineCopy+11,lpCmdLine);
 
89
        }
 
90
 
 
91
        for(argc=0, c=lpCmdLineCopy; c != NULL; c++)
 
92
                if (*c==' ')
 
93
                  argc++;
 
94
 
 
95
        argv = calloc(argc+1, sizeof(c));
 
96
        argv[0] = lpCmdLineCopy;
 
97
 
 
98
        if (argc)
 
99
        {
 
100
                int t; //MSCV can do it :)
 
101
 
 
102
                c = strtok(lpCmdLineCopy," ");
 
103
                for(t=1; c; c = strtok(" ",lpCmdLineCopy),t++)
 
104
                        argv[t] = c;
 
105
 
 
106
        }
 
107
#else /* Non-Visual C */
 
108
 
 
109
//Our main. Does some init before calling the actual Netrek code, which
 
110
//now has main2() instead of main().
 
111
int main(int argc, char **argv)
 
112
   {
 
113
   char *c;
 
114
   WSADATA data;                                   //Using sockets - perform WinSock startup
 
115
 
 
116
   MyInstance = GetModuleHandle(NULL);
 
117
 
 
118
#ifdef SUPPORT_WIN32S
 
119
   fWin32s = (getenv("FORCECONSOLE") ? 1 : GetVersion() & 0x80000000);
 
120
#endif
 
121
 
 
122
#endif /* Visual C */
 
123
 
 
124
   //Get home path (screwny NT environ vars), and set HOME var
 
125
   if (c=getenv("HOMEDRIVE"))
 
126
      {
 
127
      strcpy(HomeDir, "HOME=");
 
128
      strcat(HomeDir, c);
 
129
      if (c=getenv("HOMEPATH"))
 
130
         strcat(HomeDir, c);
 
131
      if (HomeDir[strlen(HomeDir)-1] != '\\')
 
132
        strcat(HomeDir, "\\");
 
133
      putenv(HomeDir);
 
134
      }
 
135
 
 
136
   //Get the executable file directory
 
137
   c = ExeDir + GetModuleFileName(MyInstance, ExeDir, sizeof(ExeDir)) -1;
 
138
   while (*c != '\\')   //remove filename
 
139
      *(c--) = 0;
 
140
   *c = 0;  //remove last backslash
 
141
 
 
142
 
 
143
   //Kick winsock into gear
 
144
   if (WSAStartup(MAKEWORD(1,1), &data) != 0)
 
145
      {
 
146
      fprintf(stderr,"Could not find WINSOCK.DLL / WINSOCK initializtion failed\n");
 
147
      return -1;
 
148
      }
 
149
   if ( data.wVersion<MAKEWORD(1,1) )
 
150
      {
 
151
      fprintf(stderr,"Bad WINSOCK.DLL version (need at least v1.1).\n");
 
152
      WSACleanup();
 
153
      return -1;
 
154
      }
 
155
 
 
156
#ifdef SUPPORT_WIN32S
 
157
   //Create the "Console" window if running on Win32s
 
158
   W_Initialize(NULL);   /* NULL == don't need a display name as not on X */
 
159
   if (fWin32s)
 
160
      {
 
161
      console = W_MakeScrollingWindow("Console", 0, 0, 80, 10, NULL, 2);
 
162
      PrintfSafe = 1;                                 //Now OK to printf
 
163
      }
 
164
#endif
 
165
 
 
166
   atexit(WinMainCleanup);
 
167
 
 
168
   main2(argc, argv);                                 //Call BRM main!
 
169
 
 
170
   return 0;
 
171
   }
 
172
 
 
173
 
 
174
void WinMainCleanup()
 
175
   {
 
176
#ifdef SUPPORT_WIN32S      
 
177
   if (fWin32s)
 
178
      {
 
179
      //If we're using our own special console window,
 
180
      //pause before closing so the user can read
 
181
      Wprintf("Netrek/Win32 terminating...");
 
182
      W_DestroyWindow(console);
 
183
      PrintfSafe=0;        //Console is dead
 
184
      }
 
185
#endif
 
186
   WSACleanup();        //Shut down our sockets
 
187
   }
 
188
 
 
189
 
 
190
//***************************************************************************//
 
191
// Various UNIX functions that will enable the code to compile as-is without //
 
192
// changes - only this file added.                                           //
 
193
//***************************************************************************//
 
194
 
 
195
//Get process ID
 
196
int getpid()
 
197
   {
 
198
   return (int) GetCurrentProcessId();
 
199
   }
 
200
 
 
201
 
 
202
//Get user ID - fugde!
 
203
char *getuid()
 
204
   {
 
205
   return (char *)1;
 
206
   }
 
207
 
 
208
//getpwuid() function - does it for real under NT. Just copies the given string...
 
209
struct passwd *getpwuid(char *getuidstuff)
 
210
   {
 
211
   static struct passwd pw;
 
212
   static char name[100];
 
213
   char *p;
 
214
   int i= sizeof(name);
 
215
 
 
216
   memset(name,0,sizeof(name));
 
217
 
 
218
   /* Try to get user w/ WNetGetUser instead of GetUserName in the
 
219
      hope that it will retrieve the user name on WFWG */
 
220
   if ((WNetGetUser(NULL, name, &i)!=NO_ERROR ) ||
 
221
       !stricmp(name,"Administrator") ||
 
222
       !stricmp(name,"admin")         ||
 
223
       !stricmp(name,"root"))
 
224
   {
 
225
       /* Pretty lame ids - use the one given in the rc file */
 
226
       p = NULL;
 
227
       p = getdefault("login");
 
228
       if (!p || !name[0])
 
229
        return NULL;
 
230
       pw.pw_name = p;
 
231
       return &pw;
 
232
   }
 
233
 
 
234
   pw.pw_name = name;
 
235
   return &pw;
 
236
   }
 
237
 
 
238
//Sleep...
 
239
void sleep(int seconds)
 
240
   {
 
241
   Sleep(seconds * 1000);
 
242
   }
 
243
 
 
244
 
 
245
// rint
 
246
double rint(double r)
 
247
{
 
248
   return floor(r+0.5);
 
249
}
 
250
 
 
251
 
 
252
//A more useful perror(), reports last winsock error as well
 
253
void perror(const char *str)
 
254
   {
 
255
   printf("%s: errno = %d, WSALast = %d\n", str, errno, WSAGetLastError());
 
256
   }
 
257
 
 
258
 
 
259
#ifdef NEW_SELECT
 
260
// ********************************* select ********************************
 
261
// This is our implementation of select, using WaitForMultipleObjects()
 
262
// We support W_Socket() here too. Note that we only handle readfds
 
263
#define W_SOCKET 0x0CABBABE // can be anything but must match mswindow.c
 
264
int PASCAL select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout)
 
265
{
 
266
   HANDLE handles[FD_SETSIZE];
 
267
   DWORD got;
 
268
   int i,j,ms;
 
269
   int wsocket_present = 0;
 
270
 
 
271
   // Set timeout
 
272
   if (timeout)
 
273
      {
 
274
      ms = (timeout->tv_sec<<10) + (timeout->tv_usec>>10);
 
275
      printf("sec = %d, usec = %d\n", timeout->tv_sec, timeout->tv_usec);
 
276
      }
 
277
   else
 
278
      ms = INFINITE;
 
279
 
 
280
   printf("ms=%d, ", ms);
 
281
   
 
282
   /* Scan through the array, copying and looking for W_Socket */
 
283
   for (i=j=0; i<readfds->fd_count; i++)
 
284
      {
 
285
      if (readfds->fd_array[i] != W_SOCKET)
 
286
      {
 
287
         printf("handle %d, sock=%d\n", readfds->fd_array[i], sock);
 
288
         handles[j++] = readfds->fd_array[i];
 
289
      }
 
290
      else
 
291
         wsocket_present = 1;
 
292
      }
 
293
 
 
294
   printf("handles=%d, handle[0]=%d, wsocket=%d\n", j, handles[0], wsocket_present);
 
295
 
 
296
   readfds->fd_count=1;
 
297
   
 
298
/*   if (wsocket_present)
 
299
      {
 
300
      if (W_EventsPending())   //MsgWait... does not return if there is input ready, only
 
301
         {                     //if it _arrives_ 
 
302
         readfds->fd_count=2;
 
303
         readfds->fd_array[1] = W_SOCKET;
 
304
         } 
 
305
      else 
 
306
         got = MsgWaitForMultipleObjects(j, handles, FALSE, // false == wait for only one object
 
307
                                         ms,  QS_ALLINPUT);
 
308
      if (got == WAIT_OBJECT_0+j) // == windowing event arrived
 
309
         {
 
310
         readfds->fd_array[0] = W_SOCKET;
 
311
         return 1;
 
312
         }
 
313
      }
 
314
   else*/
 
315
//      got = WaitForMultipleObjects(j, handles, FALSE /* wait for one only */,ms)  ;
 
316
        got = WaitForSingleObject(handles[0], ms);
 
317
   
 
318
   if (got == WAIT_TIMEOUT)
 
319
      {
 
320
      printf("Timeout\n");
 
321
      readfds->fd_count = 0;  // clear
 
322
      return 0;
 
323
      }
 
324
 
 
325
   readfds->fd_array[0] = handles[got-WAIT_OBJECT_0];
 
326
   return 1;
 
327
 
 
328
   printf("Success! Returned %d\n", got);
 
329
}
 
330
#endif
 
331
 
 
332
#ifdef SUPPORT_WIN32S      
 
333
 
 
334
//******************************** STDIO HANDLING *****************************//
 
335
// Under Win32s we have to do our own stdio. Yeesh!
 
336
 
 
337
//A useful function to replace printf().
 
338
void Wprintf(char *format,...)
 
339
   {
 
340
   char buf[300];
 
341
   va_list args;
 
342
   va_start(args, format);
 
343
   vsprintf(buf,format,args);
 
344
   va_end(args);
 
345
   vsprintf(buf,format,args);
 
346
   MessageBox(NULL,buf,"Netrek/Win32",MB_OK);
 
347
   }
 
348
 
 
349
//Another function, this one to replace fprintf(stderr,...)
 
350
void Wfprintfstderr(char *format, ...)
 
351
   {
 
352
   char buf[300];
 
353
   va_list args;
 
354
   va_start(args, format);
 
355
   vsprintf(buf,format,args);
 
356
   va_end(args);
 
357
   MessageBeep(MB_ICONEXCLAMATION);
 
358
   MessageBox(NULL,buf,"Netrek/Win32: Error",MB_OK|MB_ICONEXCLAMATION);
 
359
   }
 
360
 
 
361
 
 
362
/* - The following fns not needed in Win32, as we actually have a real, live console of our own
 
363
   - But, under Win32s we don't... so... arrgh */
 
364
 
 
365
 
 
366
//Yet another function, this one actually IS printf() - overrides the default
 
367
//definition, sends it to the console window -
 
368
int printf(const char *format,...)
 
369
   {
 
370
   char buf[300];
 
371
   int len, junk;
 
372
   va_list args;
 
373
 
 
374
   va_start(args, format);
 
375
   len = vsprintf(buf,format,args);
 
376
   va_end(args);
 
377
 
 
378
   if (fWin32s)
 
379
     {
 
380
     if (!PrintfSafe)  //Flag that helps us avoid infinite recursions and other nasties
 
381
        {
 
382
        MessageBox(NULL, buf, "This is a printf", MB_OK);
 
383
        return 0; 
 
384
        }
 
385
      PrintfSafe = 0;
 
386
      if (!W_IsMapped(console))
 
387
         W_MapWindow(console);
 
388
      W_WriteText(console, 0, 0, W_White, buf, len, W_RegularFont);
 
389
      W_FlushScrollingWindow(console);
 
390
      PrintfSafe = 1;
 
391
      }
 
392
   else
 
393
     WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), buf, len, &junk, NULL);
 
394
 
 
395
   return len;
 
396
   }
 
397
 
 
398
//Arrghh our version of fwrite...
 
399
int myfwrite(char *buf, int count1, FILE *file)
 
400
   {
 
401
   register int count = count1;
 
402
   while (count--)
 
403
      {
 
404
      if (fputc(*buf, file) == EOF)
 
405
         return ((count1 - count)-1);
 
406
      buf++;
 
407
      }
 
408
   return count1;
 
409
   }
 
410
 
 
411
 
 
412
//Redriect fprintf() to stdout and stderr to our console window under Win32s
 
413
int fprintf(FILE *handle, const char *format,...)
 
414
   {
 
415
   char buf[300];
 
416
   int len, junk;
 
417
   va_list args;
 
418
 
 
419
   va_start(args, format);
 
420
   len = vsprintf(buf,format,args);
 
421
   va_end(args);
 
422
 
 
423
   if (handle == stdout || handle == stderr)
 
424
         {
 
425
         if (fWin32s)
 
426
            {
 
427
            if (!PrintfSafe)
 
428
                {
 
429
                MessageBox(NULL, buf, "This is an fprintf to stderr/stdout", MB_OK);
 
430
                return 0;
 
431
                }
 
432
            PrintfSafe = 0;
 
433
            if (!W_IsMapped(console))
 
434
               W_MapWindow(console);
 
435
            W_WriteText(console, 0, 0, W_White, buf, len, W_RegularFont);
 
436
            W_FlushScrollingWindow(console);
 
437
            PrintfSafe = 1;
 
438
            }
 
439
         else
 
440
            WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), buf, len, &junk, NULL);
 
441
         }
 
442
   else
 
443
      return myfwrite(buf, len, handle);
 
444
 
 
445
   return len;
 
446
   }
 
447
 
 
448
 
 
449
//More nastyness: this time for fwrite. I hate Win32s. No consoles!
 
450
size_t fwrite(char *buf, int blksz, int count, FILE *handle)
 
451
   {
 
452
   int junk;
 
453
 
 
454
   if (handle == stdout || handle == stderr)
 
455
         {
 
456
         if (fWin32s)
 
457
            {
 
458
            if (!PrintfSafe)
 
459
                {
 
460
                MessageBox(NULL, buf, "This is an fwrite to stderr/stdout", MB_OK);
 
461
                return 0;
 
462
                }
 
463
            PrintfSafe = 0;
 
464
            if (!W_IsMapped(console))
 
465
               W_MapWindow(console);
 
466
            W_WriteText(console, 0, 0, W_White, buf, blksz*count, W_RegularFont);
 
467
            W_FlushScrollingWindow(console);
 
468
            PrintfSafe = 1;
 
469
            }
 
470
         else
 
471
            WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), buf, blksz*count, &junk, NULL);
 
472
         }
 
473
   else
 
474
      return myfwrite(buf, count*blksz, handle);
 
475
 
 
476
   return blksz*count;
 
477
   }
 
478
 
 
479
#endif  /* WIN32S */
 
480
 
 
481