/[dtapublic]/projs/ets/trunk/src/c_tk_base_7_5_w_mods/winmain.c
ViewVC logotype

Diff of /projs/ets/trunk/src/c_tk_base_7_5_w_mods/winmain.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 70 by dashley, Sat Nov 5 10:54:17 2016 UTC revision 71 by dashley, Sat Nov 5 11:07:06 2016 UTC
# Line 1  Line 1 
1  /* $Header$ */  /* $Header$ */
2    
3  /*  /*
4   * winMain.c --   * winMain.c --
5   *   *
6   *      Main entry point for wish and other Tk-based applications.   *      Main entry point for wish and other Tk-based applications.
7   *   *
8   * Copyright (c) 1995-1997 Sun Microsystems, Inc.   * Copyright (c) 1995-1997 Sun Microsystems, Inc.
9   * Copyright (c) 1998-1999 by Scriptics Corporation.   * Copyright (c) 1998-1999 by Scriptics Corporation.
10   *   *
11   * See the file "license.terms" for information on usage and redistribution   * See the file "license.terms" for information on usage and redistribution
12   * of this file, and for a DISCLAIMER OF ALL WARRANTIES.   * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
13   *   *
14   * RCS: @(#) $Id: winmain.c,v 1.1.1.1 2001/06/13 05:15:23 dtashley Exp $   * RCS: @(#) $Id: winmain.c,v 1.1.1.1 2001/06/13 05:15:23 dtashley Exp $
15   */   */
16    
17  #include "tk.h"  #include "tk.h"
18  #define WIN32_LEAN_AND_MEAN  #define WIN32_LEAN_AND_MEAN
19  #include <windows.h>  #include <windows.h>
20  #undef WIN32_LEAN_AND_MEAN  #undef WIN32_LEAN_AND_MEAN
21  #include <malloc.h>  #include <malloc.h>
22  #include <locale.h>  #include <locale.h>
23    
24  #include "tkInt.h"  #include "tkInt.h"
25    
26  /*  /*
27   * The following declarations refer to internal Tk routines.  These   * The following declarations refer to internal Tk routines.  These
28   * interfaces are available for use, but are not supported.   * interfaces are available for use, but are not supported.
29   */   */
30    
31    
32  /*  /*
33   * Forward declarations for procedures defined later in this file:   * Forward declarations for procedures defined later in this file:
34   */   */
35    
36  static void             setargv _ANSI_ARGS_((int *argcPtr, char ***argvPtr));  static void             setargv _ANSI_ARGS_((int *argcPtr, char ***argvPtr));
37  static void             WishPanic _ANSI_ARGS_(TCL_VARARGS(char *,format));  static void             WishPanic _ANSI_ARGS_(TCL_VARARGS(char *,format));
38    
39  #ifdef TK_TEST  #ifdef TK_TEST
40  extern int              Tktest_Init(Tcl_Interp *interp);  extern int              Tktest_Init(Tcl_Interp *interp);
41  #endif /* TK_TEST */  #endif /* TK_TEST */
42    
43  #ifdef TCL_TEST  #ifdef TCL_TEST
44  extern int              TclObjTest_Init _ANSI_ARGS_((Tcl_Interp *interp));  extern int              TclObjTest_Init _ANSI_ARGS_((Tcl_Interp *interp));
45  extern int              Tcltest_Init _ANSI_ARGS_((Tcl_Interp *interp));  extern int              Tcltest_Init _ANSI_ARGS_((Tcl_Interp *interp));
46  #endif /* TCL_TEST */  #endif /* TCL_TEST */
47    
48  static BOOL consoleRequired = TRUE;  static BOOL consoleRequired = TRUE;
49    
50  /*  /*
51   * The following #if block allows you to change the AppInit   * The following #if block allows you to change the AppInit
52   * function by using a #define of TCL_LOCAL_APPINIT instead   * function by using a #define of TCL_LOCAL_APPINIT instead
53   * of rewriting this entire file.  The #if checks for that   * of rewriting this entire file.  The #if checks for that
54   * #define and uses Tcl_AppInit if it doesn't exist.   * #define and uses Tcl_AppInit if it doesn't exist.
55   */   */
56            
57  #ifndef TK_LOCAL_APPINIT  #ifndef TK_LOCAL_APPINIT
58  #define TK_LOCAL_APPINIT Tcl_AppInit      #define TK_LOCAL_APPINIT Tcl_AppInit    
59  #endif  #endif
60  extern int TK_LOCAL_APPINIT _ANSI_ARGS_((Tcl_Interp *interp));  extern int TK_LOCAL_APPINIT _ANSI_ARGS_((Tcl_Interp *interp));
61            
62  /*  /*
63   * The following #if block allows you to change how Tcl finds the startup   * The following #if block allows you to change how Tcl finds the startup
64   * script, prime the library or encoding paths, fiddle with the argv,   * script, prime the library or encoding paths, fiddle with the argv,
65   * etc., without needing to rewrite Tk_Main()   * etc., without needing to rewrite Tk_Main()
66   */   */
67    
68  #ifdef TK_LOCAL_MAIN_HOOK  #ifdef TK_LOCAL_MAIN_HOOK
69  extern int TK_LOCAL_MAIN_HOOK _ANSI_ARGS_((int *argc, char ***argv));  extern int TK_LOCAL_MAIN_HOOK _ANSI_ARGS_((int *argc, char ***argv));
70  #endif  #endif
71    
72    
73  /*  /*
74   *----------------------------------------------------------------------   *----------------------------------------------------------------------
75   *   *
76   * WinMain --   * WinMain --
77   *   *
78   *      Main entry point from Windows.   *      Main entry point from Windows.
79   *   *
80   * Results:   * Results:
81   *      Returns false if initialization fails, otherwise it never   *      Returns false if initialization fails, otherwise it never
82   *      returns.   *      returns.
83   *   *
84   * Side effects:   * Side effects:
85   *      Just about anything, since from here we call arbitrary Tcl code.   *      Just about anything, since from here we call arbitrary Tcl code.
86   *   *
87   *----------------------------------------------------------------------   *----------------------------------------------------------------------
88   */   */
89    
90  int APIENTRY  int APIENTRY
91  WinMain(hInstance, hPrevInstance, lpszCmdLine, nCmdShow)  WinMain(hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
92      HINSTANCE hInstance;      HINSTANCE hInstance;
93      HINSTANCE hPrevInstance;      HINSTANCE hPrevInstance;
94      LPSTR lpszCmdLine;      LPSTR lpszCmdLine;
95      int nCmdShow;      int nCmdShow;
96  {  {
97      char **argv;      char **argv;
98      int argc;      int argc;
99      char buffer[MAX_PATH+1];      char buffer[MAX_PATH+1];
100      char *p;      char *p;
101    
102      Tcl_SetPanicProc(WishPanic);      Tcl_SetPanicProc(WishPanic);
103    
104      /*      /*
105       * Increase the application queue size from default value of 8.       * Increase the application queue size from default value of 8.
106       * At the default value, cross application SendMessage of WM_KILLFOCUS       * At the default value, cross application SendMessage of WM_KILLFOCUS
107       * will fail because the handler will not be able to do a PostMessage!       * will fail because the handler will not be able to do a PostMessage!
108       * This is only needed for Windows 3.x, since NT dynamically expands       * This is only needed for Windows 3.x, since NT dynamically expands
109       * the queue.       * the queue.
110       */       */
111    
112      SetMessageQueue(64);      SetMessageQueue(64);
113    
114      /*      /*
115       * Create the console channels and install them as the standard       * Create the console channels and install them as the standard
116       * channels.  All I/O will be discarded until Tk_CreateConsoleWindow is       * channels.  All I/O will be discarded until Tk_CreateConsoleWindow is
117       * called to attach the console to a text widget.       * called to attach the console to a text widget.
118       */       */
119    
120      consoleRequired = TRUE;      consoleRequired = TRUE;
121    
122      /*      /*
123       * Set up the default locale to be standard "C" locale so parsing       * Set up the default locale to be standard "C" locale so parsing
124       * is performed correctly.       * is performed correctly.
125       */       */
126    
127      setlocale(LC_ALL, "C");      setlocale(LC_ALL, "C");
128      setargv(&argc, &argv);      setargv(&argc, &argv);
129    
130      /*      /*
131       * Replace argv[0] with full pathname of executable, and forward       * Replace argv[0] with full pathname of executable, and forward
132       * slashes substituted for backslashes.       * slashes substituted for backslashes.
133       */       */
134    
135      GetModuleFileName(NULL, buffer, sizeof(buffer));      GetModuleFileName(NULL, buffer, sizeof(buffer));
136      argv[0] = buffer;      argv[0] = buffer;
137      for (p = buffer; *p != '\0'; p++) {      for (p = buffer; *p != '\0'; p++) {
138          if (*p == '\\') {          if (*p == '\\') {
139              *p = '/';              *p = '/';
140          }          }
141      }      }
142    
143  #ifdef TK_LOCAL_MAIN_HOOK  #ifdef TK_LOCAL_MAIN_HOOK
144      TK_LOCAL_MAIN_HOOK(&argc, &argv);      TK_LOCAL_MAIN_HOOK(&argc, &argv);
145  #endif  #endif
146    
147      Tk_Main(argc, argv, Tcl_AppInit);      Tk_Main(argc, argv, Tcl_AppInit);
148    
149      return 1;      return 1;
150  }  }
151    
152    
153    
154  /*  /*
155   *----------------------------------------------------------------------   *----------------------------------------------------------------------
156   *   *
157   * Tcl_AppInit --   * Tcl_AppInit --
158   *   *
159   *      This procedure performs application-specific initialization.   *      This procedure performs application-specific initialization.
160   *      Most applications, especially those that incorporate additional   *      Most applications, especially those that incorporate additional
161   *      packages, will have their own version of this procedure.   *      packages, will have their own version of this procedure.
162   *   *
163   * Results:   * Results:
164   *      Returns a standard Tcl completion code, and leaves an error   *      Returns a standard Tcl completion code, and leaves an error
165   *      message in the interp's result if an error occurs.   *      message in the interp's result if an error occurs.
166   *   *
167   * Side effects:   * Side effects:
168   *      Depends on the startup script.   *      Depends on the startup script.
169   *   *
170   *----------------------------------------------------------------------   *----------------------------------------------------------------------
171   */   */
172    
173  int  int
174  Tcl_AppInit(interp)  Tcl_AppInit(interp)
175      Tcl_Interp *interp;         /* Interpreter for application. */      Tcl_Interp *interp;         /* Interpreter for application. */
176  {  {
177      if (Tcl_Init(interp) == TCL_ERROR) {      if (Tcl_Init(interp) == TCL_ERROR) {
178          goto error;          goto error;
179      }      }
180      if (Tk_Init(interp) == TCL_ERROR) {      if (Tk_Init(interp) == TCL_ERROR) {
181          goto error;          goto error;
182      }      }
183      Tcl_StaticPackage(interp, "Tk", Tk_Init, Tk_SafeInit);      Tcl_StaticPackage(interp, "Tk", Tk_Init, Tk_SafeInit);
184    
185      /*      /*
186       * Initialize the console only if we are running as an interactive       * Initialize the console only if we are running as an interactive
187       * application.       * application.
188       */       */
189    
190      if (consoleRequired) {      if (consoleRequired) {
191          if (Tk_CreateConsoleWindow(interp) == TCL_ERROR) {          if (Tk_CreateConsoleWindow(interp) == TCL_ERROR) {
192              goto error;              goto error;
193          }          }
194      }      }
195    
196  #ifdef TCL_TEST  #ifdef TCL_TEST
197      if (Tcltest_Init(interp) == TCL_ERROR) {      if (Tcltest_Init(interp) == TCL_ERROR) {
198          return TCL_ERROR;          return TCL_ERROR;
199      }      }
200      Tcl_StaticPackage(interp, "Tcltest", Tcltest_Init,      Tcl_StaticPackage(interp, "Tcltest", Tcltest_Init,
201              (Tcl_PackageInitProc *) NULL);              (Tcl_PackageInitProc *) NULL);
202      if (TclObjTest_Init(interp) == TCL_ERROR) {      if (TclObjTest_Init(interp) == TCL_ERROR) {
203          return TCL_ERROR;          return TCL_ERROR;
204      }      }
205  #endif /* TCL_TEST */  #endif /* TCL_TEST */
206    
207  #ifdef TK_TEST  #ifdef TK_TEST
208      if (Tktest_Init(interp) == TCL_ERROR) {      if (Tktest_Init(interp) == TCL_ERROR) {
209          goto error;          goto error;
210      }      }
211      Tcl_StaticPackage(interp, "Tktest", Tktest_Init,      Tcl_StaticPackage(interp, "Tktest", Tktest_Init,
212              (Tcl_PackageInitProc *) NULL);              (Tcl_PackageInitProc *) NULL);
213  #endif /* TK_TEST */  #endif /* TK_TEST */
214    
215      Tcl_SetVar(interp, "tcl_rcFileName", "~/wishrc.tcl", TCL_GLOBAL_ONLY);      Tcl_SetVar(interp, "tcl_rcFileName", "~/wishrc.tcl", TCL_GLOBAL_ONLY);
216      return TCL_OK;      return TCL_OK;
217    
218  error:  error:
219      MessageBeep(MB_ICONEXCLAMATION);      MessageBeep(MB_ICONEXCLAMATION);
220      MessageBox(NULL, Tcl_GetStringResult(interp), "Error in Wish",      MessageBox(NULL, Tcl_GetStringResult(interp), "Error in Wish",
221              MB_ICONSTOP | MB_OK | MB_TASKMODAL | MB_SETFOREGROUND);              MB_ICONSTOP | MB_OK | MB_TASKMODAL | MB_SETFOREGROUND);
222      ExitProcess(1);      ExitProcess(1);
223      /* we won't reach this, but we need the return */      /* we won't reach this, but we need the return */
224      return TCL_ERROR;      return TCL_ERROR;
225  }  }
226    
227  /*  /*
228   *----------------------------------------------------------------------   *----------------------------------------------------------------------
229   *   *
230   * WishPanic --   * WishPanic --
231   *   *
232   *      Display a message and exit.   *      Display a message and exit.
233   *   *
234   * Results:   * Results:
235   *      None.   *      None.
236   *   *
237   * Side effects:   * Side effects:
238   *      Exits the program.   *      Exits the program.
239   *   *
240   *----------------------------------------------------------------------   *----------------------------------------------------------------------
241   */   */
242    
243  void  void
244  WishPanic TCL_VARARGS_DEF(char *,arg1)  WishPanic TCL_VARARGS_DEF(char *,arg1)
245  {  {
246      va_list argList;      va_list argList;
247      char buf[1024];      char buf[1024];
248      char *format;      char *format;
249            
250      format = TCL_VARARGS_START(char *,arg1,argList);      format = TCL_VARARGS_START(char *,arg1,argList);
251      vsprintf(buf, format, argList);      vsprintf(buf, format, argList);
252    
253      MessageBeep(MB_ICONEXCLAMATION);      MessageBeep(MB_ICONEXCLAMATION);
254      MessageBox(NULL, buf, "Fatal Error in Wish",      MessageBox(NULL, buf, "Fatal Error in Wish",
255              MB_ICONSTOP | MB_OK | MB_TASKMODAL | MB_SETFOREGROUND);              MB_ICONSTOP | MB_OK | MB_TASKMODAL | MB_SETFOREGROUND);
256  #ifdef _MSC_VER  #ifdef _MSC_VER
257      DebugBreak();      DebugBreak();
258  #endif  #endif
259      ExitProcess(1);      ExitProcess(1);
260  }  }
261  /*  /*
262   *-------------------------------------------------------------------------   *-------------------------------------------------------------------------
263   *   *
264   * setargv --   * setargv --
265   *   *
266   *      Parse the Windows command line string into argc/argv.  Done here   *      Parse the Windows command line string into argc/argv.  Done here
267   *      because we don't trust the builtin argument parser in crt0.     *      because we don't trust the builtin argument parser in crt0.  
268   *      Windows applications are responsible for breaking their command   *      Windows applications are responsible for breaking their command
269   *      line into arguments.   *      line into arguments.
270   *   *
271   *      2N backslashes + quote -> N backslashes + begin quoted string   *      2N backslashes + quote -> N backslashes + begin quoted string
272   *      2N + 1 backslashes + quote -> literal   *      2N + 1 backslashes + quote -> literal
273   *      N backslashes + non-quote -> literal   *      N backslashes + non-quote -> literal
274   *      quote + quote in a quoted string -> single quote   *      quote + quote in a quoted string -> single quote
275   *      quote + quote not in quoted string -> empty string   *      quote + quote not in quoted string -> empty string
276   *      quote -> begin quoted string   *      quote -> begin quoted string
277   *   *
278   * Results:   * Results:
279   *      Fills argcPtr with the number of arguments and argvPtr with the   *      Fills argcPtr with the number of arguments and argvPtr with the
280   *      array of arguments.   *      array of arguments.
281   *   *
282   * Side effects:   * Side effects:
283   *      Memory allocated.   *      Memory allocated.
284   *   *
285   *--------------------------------------------------------------------------   *--------------------------------------------------------------------------
286   */   */
287    
288  static void  static void
289  setargv(argcPtr, argvPtr)  setargv(argcPtr, argvPtr)
290      int *argcPtr;               /* Filled with number of argument strings. */      int *argcPtr;               /* Filled with number of argument strings. */
291      char ***argvPtr;            /* Filled with argument strings (malloc'd). */      char ***argvPtr;            /* Filled with argument strings (malloc'd). */
292  {  {
293      char *cmdLine, *p, *arg, *argSpace;      char *cmdLine, *p, *arg, *argSpace;
294      char **argv;      char **argv;
295      int argc, size, inquote, copy, slashes;      int argc, size, inquote, copy, slashes;
296            
297      cmdLine = GetCommandLine(); /* INTL: BUG */      cmdLine = GetCommandLine(); /* INTL: BUG */
298    
299      /*      /*
300       * Precompute an overly pessimistic guess at the number of arguments       * Precompute an overly pessimistic guess at the number of arguments
301       * in the command line by counting non-space spans.       * in the command line by counting non-space spans.
302       */       */
303    
304      size = 2;      size = 2;
305      for (p = cmdLine; *p != '\0'; p++) {      for (p = cmdLine; *p != '\0'; p++) {
306          if ((*p == ' ') || (*p == '\t')) {      /* INTL: ISO space. */          if ((*p == ' ') || (*p == '\t')) {      /* INTL: ISO space. */
307              size++;              size++;
308              while ((*p == ' ') || (*p == '\t')) { /* INTL: ISO space. */              while ((*p == ' ') || (*p == '\t')) { /* INTL: ISO space. */
309                  p++;                  p++;
310              }              }
311              if (*p == '\0') {              if (*p == '\0') {
312                  break;                  break;
313              }              }
314          }          }
315      }      }
316      argSpace = (char *) Tcl_Alloc(      argSpace = (char *) Tcl_Alloc(
317              (unsigned) (size * sizeof(char *) + strlen(cmdLine) + 1));              (unsigned) (size * sizeof(char *) + strlen(cmdLine) + 1));
318      argv = (char **) argSpace;      argv = (char **) argSpace;
319      argSpace += size * sizeof(char *);      argSpace += size * sizeof(char *);
320      size--;      size--;
321    
322      p = cmdLine;      p = cmdLine;
323      for (argc = 0; argc < size; argc++) {      for (argc = 0; argc < size; argc++) {
324          argv[argc] = arg = argSpace;          argv[argc] = arg = argSpace;
325          while ((*p == ' ') || (*p == '\t')) {   /* INTL: ISO space. */          while ((*p == ' ') || (*p == '\t')) {   /* INTL: ISO space. */
326              p++;              p++;
327          }          }
328          if (*p == '\0') {          if (*p == '\0') {
329              break;              break;
330          }          }
331    
332          inquote = 0;          inquote = 0;
333          slashes = 0;          slashes = 0;
334          while (1) {          while (1) {
335              copy = 1;              copy = 1;
336              while (*p == '\\') {              while (*p == '\\') {
337                  slashes++;                  slashes++;
338                  p++;                  p++;
339              }              }
340              if (*p == '"') {              if (*p == '"') {
341                  if ((slashes & 1) == 0) {                  if ((slashes & 1) == 0) {
342                      copy = 0;                      copy = 0;
343                      if ((inquote) && (p[1] == '"')) {                      if ((inquote) && (p[1] == '"')) {
344                          p++;                          p++;
345                          copy = 1;                          copy = 1;
346                      } else {                      } else {
347                          inquote = !inquote;                          inquote = !inquote;
348                      }                      }
349                  }                  }
350                  slashes >>= 1;                  slashes >>= 1;
351              }              }
352    
353              while (slashes) {              while (slashes) {
354                  *arg = '\\';                  *arg = '\\';
355                  arg++;                  arg++;
356                  slashes--;                  slashes--;
357              }              }
358    
359              if ((*p == '\0')              if ((*p == '\0')
360                      || (!inquote && ((*p == ' ') || (*p == '\t')))) { /* INTL: ISO space. */                      || (!inquote && ((*p == ' ') || (*p == '\t')))) { /* INTL: ISO space. */
361                  break;                  break;
362              }              }
363              if (copy != 0) {              if (copy != 0) {
364                  *arg = *p;                  *arg = *p;
365                  arg++;                  arg++;
366              }              }
367              p++;              p++;
368          }          }
369          *arg = '\0';          *arg = '\0';
370          argSpace = arg + 1;          argSpace = arg + 1;
371      }      }
372      argv[argc] = NULL;      argv[argc] = NULL;
373    
374      *argcPtr = argc;      *argcPtr = argc;
375      *argvPtr = argv;      *argvPtr = argv;
376  }  }
377    
378    
379  /*  /*
380   *----------------------------------------------------------------------   *----------------------------------------------------------------------
381   *   *
382   * main --   * main --
383   *   *
384   *      Main entry point from the console.   *      Main entry point from the console.
385   *   *
386   * Results:   * Results:
387   *      None: Tk_Main never returns here, so this procedure never   *      None: Tk_Main never returns here, so this procedure never
388   *      returns either.   *      returns either.
389   *   *
390   * Side effects:   * Side effects:
391   *      Whatever the applications does.   *      Whatever the applications does.
392   *   *
393   *----------------------------------------------------------------------   *----------------------------------------------------------------------
394   */   */
395    
396  int main(int argc, char **argv)  int main(int argc, char **argv)
397  {  {
398      Tcl_SetPanicProc(WishPanic);      Tcl_SetPanicProc(WishPanic);
399    
400      /*      /*
401       * Set up the default locale to be standard "C" locale so parsing       * Set up the default locale to be standard "C" locale so parsing
402       * is performed correctly.       * is performed correctly.
403       */       */
404    
405      setlocale(LC_ALL, "C");      setlocale(LC_ALL, "C");
406      /*      /*
407       * Increase the application queue size from default value of 8.       * Increase the application queue size from default value of 8.
408       * At the default value, cross application SendMessage of WM_KILLFOCUS       * At the default value, cross application SendMessage of WM_KILLFOCUS
409       * will fail because the handler will not be able to do a PostMessage!       * will fail because the handler will not be able to do a PostMessage!
410       * This is only needed for Windows 3.x, since NT dynamically expands       * This is only needed for Windows 3.x, since NT dynamically expands
411       * the queue.       * the queue.
412       */       */
413    
414      SetMessageQueue(64);      SetMessageQueue(64);
415    
416      /*      /*
417       * Create the console channels and install them as the standard       * Create the console channels and install them as the standard
418       * channels.  All I/O will be discarded until Tk_CreateConsoleWindow is       * channels.  All I/O will be discarded until Tk_CreateConsoleWindow is
419       * called to attach the console to a text widget.       * called to attach the console to a text widget.
420       */       */
421    
422      consoleRequired = FALSE;      consoleRequired = FALSE;
423    
424      Tk_Main(argc, argv, Tcl_AppInit);      Tk_Main(argc, argv, Tcl_AppInit);
425      return 0;      return 0;
426  }  }
427    
428  /* End of winmain.c */  /* End of winmain.c */

Legend:
Removed from v.70  
changed lines
  Added in v.71

dashley@gmail.com
ViewVC Help
Powered by ViewVC 1.1.25