2 static char *RCSid() { return RCSid("$Id: winmain.c,v 1.22.2.1 2007/03/22 05:08:26 sfeam Exp $"); }
5 /* GNUPLOT - win/winmain.c */
7 * Copyright 1992, 1993, 1998, 2004 Maurice Castro, Russell Lang
9 * Permission to use, copy, and distribute this software and its
10 * documentation for any purpose with or without fee is hereby granted,
11 * provided that the above copyright notice appear in all copies and
12 * that both that copyright notice and this permission notice appear
13 * in supporting documentation.
15 * Permission to modify the software is granted, but not the right to
16 * distribute the complete modified source code. Modifications are to
17 * be distributed as patches to the released version. Permission to
18 * distribute binaries produced by compiling modified sources is granted,
20 * 1. distribute the corresponding source modifications from the
21 * released version in the form of a patch file along with the binaries,
22 * 2. add special version identification to distinguish your version
23 * in addition to the base release version number,
24 * 3. provide your name and address as the primary contact for the
25 * support of your modified version, and
26 * 4. retain our contact information in regard to use of the base
28 * Permission to distribute the released version of the source code along
29 * with corresponding source modifications in the form of a patch file is
30 * granted with same provisions 2 through 4 for binary distributions.
32 * This software is provided "as is" without express or implied warranty
33 * to the extent permitted by applicable law.
44 /* This file implements the initialization code for running gnuplot */
45 /* under Microsoft Windows. The code currently compiles only with the */
46 /* Borland C++ 3.1 compiler. */
48 /* The modifications to allow Gnuplot to run under Windows were made */
49 /* by Maurice Castro. (maurice@bruce.cs.monash.edu.au) 3 Jul 1992 */
50 /* and Russell Lang (rjl@monu1.cc.monash.edu.au) 30 Nov 1992 */
68 #ifdef __TURBOC__ /* HBB 981201: MinGW32 doesn't have this */
72 # define mktemp _mktemp
84 # define _WIN32_IE 0x0400
88 /* workaround for old header files */
89 # ifndef CSIDL_APPDATA
90 # define CSIDL_APPDATA (0x001a)
96 #define MAXPRINTF 1024
106 #define MENUNAME "wgnuplot.mnu"
107 #ifndef HELPFILE /* HBB 981203: makefile.win predefines this... */
108 #define HELPFILE "wgnuplot.hlp"
117 int gnu_main(int argc, char *argv[], char *env[]);
120 CheckMemory(LPSTR str)
122 if (str == (LPSTR)NULL) {
123 MessageBox(NULL, "out of memory", "gnuplot", MB_ICONSTOP | MB_OK);
131 pausewin.Message = str;
132 return (PauseBox(&pausewin) == IDOK);
136 kill_pending_Pause_dialog ()
138 if (pausewin.bPause == FALSE) /* no Pause dialog displayed */
140 /* Pause dialog displayed, thus kill it */
141 DestroyWindow(pausewin.hWndPause);
144 FreeProcInstance((FARPROC)pausewin.lpfnPauseButtonProc);
147 pausewin.bPause = FALSE;
150 /* atexit procedure */
156 #ifndef __MINGW32__ /* HBB 980809: FIXME: doesn't exist for MinGW32. So...? */
159 if (graphwin.hWndGraph && IsWindow(graphwin.hWndGraph))
160 GraphClose(&graphwin);
161 TextMessage(); /* process messages */
162 WinHelp(textwin.hWndText,(LPSTR)winhelpname,HELP_QUIT,(DWORD)NULL);
164 TextMessage(); /* process messages */
168 /* call back function from Text Window WM_CLOSE */
169 int CALLBACK WINEXPORT
178 /* This function can be used to retrieve version information from
179 * Window's Shell and common control libraries such (Comctl32.dll,
180 * Shell32.dll, and Shlwapi.dll) The code was copied from the MSDN
181 * article "Shell and Common Controls Versions" */
183 GetDllVersion(LPCTSTR lpszDllName)
188 /* For security purposes, LoadLibrary should be provided with a
189 fully-qualified path to the DLL. The lpszDllName variable should be
190 tested to ensure that it is a fully qualified path before it is used. */
191 hinstDll = LoadLibrary(lpszDllName);
194 DLLGETVERSIONPROC pDllGetVersion;
195 pDllGetVersion = (DLLGETVERSIONPROC)GetProcAddress(hinstDll,
198 /* Because some DLLs might not implement this function, you
199 must test for it explicitly. Depending on the particular
200 DLL, the lack of a DllGetVersion function can be a useful
201 indicator of the version. */
202 if (pDllGetVersion) {
206 ZeroMemory(&dvi, sizeof(dvi));
207 dvi.cbSize = sizeof(dvi);
208 hr = (*pDllGetVersion)(&dvi);
210 dwVersion = PACKVERSION(dvi.dwMajorVersion, dvi.dwMinorVersion);
212 FreeLibrary(hinstDll);
219 appdata_directory(void)
222 FARPROC pSHGetSpecialFolderPath;
223 static char dir[MAX_PATH] = "";
228 /* Make sure that SHGetSpecialFolderPath is supported. */
229 hShell32 = LoadLibrary(TEXT("shell32.dll"));
231 pSHGetSpecialFolderPath =
232 GetProcAddress(hShell32,
233 TEXT("SHGetSpecialFolderPathA"));
234 if (pSHGetSpecialFolderPath)
235 (*pSHGetSpecialFolderPath)(NULL, dir, CSIDL_APPDATA, FALSE);
236 FreeModule(hShell32);
240 /* use APPDATA environment variable as fallback */
241 if (dir[0] == '\0') {
242 char *appdata = getenv("APPDATA");
244 strcpy(dir, appdata);
254 int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
255 LPSTR lpszCmdLine, int nCmdShow)
257 /*WNDCLASS wndclass;*/
260 #ifdef __MSC__ /* MSC doesn't give us _argc and _argv[] so ... */
261 # ifdef WIN32 /* WIN32 has __argc and __argv */
262 # define _argv __argv
263 # define _argc __argc
265 # define MAXCMDTOKENS 128
267 LPSTR _argv[MAXCMDTOKENS];
268 _argv[_argc] = "wgnuplot.exe";
269 _argv[++_argc] = _fstrtok( lpszCmdLine, " ");
270 while (_argv[_argc] != NULL)
271 _argv[++_argc] = _fstrtok( NULL, " ");
276 # define _argv __argv
277 # define _argc __argc
280 szModuleName = (LPSTR)farmalloc(MAXSTR+1);
281 CheckMemory(szModuleName);
283 /* get path to EXE */
284 GetModuleFileName(hInstance, (LPSTR) szModuleName, MAXSTR);
286 if (CheckWGNUPLOTVersion(WGNUPLOTVERSION)) {
287 MessageBox(NULL, "Wrong version of WGNUPLOT.DLL", szModuleName, MB_ICONSTOP | MB_OK);
291 if ((tail = (LPSTR)_fstrrchr(szModuleName,'\\')) != (LPSTR)NULL)
296 szModuleName = (LPSTR)farrealloc(szModuleName, _fstrlen(szModuleName)+1);
297 CheckMemory(szModuleName);
299 winhelpname = (LPSTR)farmalloc(_fstrlen(szModuleName)+_fstrlen(HELPFILE)+1);
300 CheckMemory(winhelpname);
301 _fstrcpy(winhelpname,szModuleName);
302 _fstrcat(winhelpname,HELPFILE);
304 szMenuName = (LPSTR)farmalloc(_fstrlen(szModuleName)+_fstrlen(MENUNAME)+1);
305 CheckMemory(szMenuName);
306 _fstrcpy(szMenuName,szModuleName);
307 _fstrcat(szMenuName,MENUNAME);
309 textwin.hInstance = hInstance;
310 textwin.hPrevInstance = hPrevInstance;
311 textwin.nCmdShow = nCmdShow;
312 textwin.Title = "gnuplot";
314 get_user_env(); /* this hasn't been called yet */
315 textwin.IniFile = gp_strdup("~\\wgnuplot.ini");
316 gp_expand_tilde(&(textwin.IniFile));
318 /* if tilde expansion fails use current directory as
319 default - that was the previous default behaviour */
320 if (textwin.IniFile[0] == '~') {
321 free(textwin.IniFile);
322 textwin.IniFile = "wgnuplot.ini";
324 textwin.IniSection = "WGNUPLOT";
325 textwin.DragPre = "load '";
326 textwin.DragPost = "'\n";
327 textwin.lpmw = &menuwin;
328 textwin.ScreenSize.x = 80;
329 textwin.ScreenSize.y = 80;
330 textwin.KeyBufSize = 2048;
331 textwin.CursorFlag = 1; /* scroll to cursor after \n & \r */
332 textwin.shutdown = MakeProcInstance((FARPROC)ShutDown, hInstance);
333 textwin.AboutText = (LPSTR)farmalloc(1024);
334 CheckMemory(textwin.AboutText);
335 sprintf(textwin.AboutText,"Version %s\nPatchlevel %s\nLast Modified %s\n%s\n%s, %s and many others",
336 gnuplot_version, gnuplot_patchlevel, gnuplot_date, gnuplot_copyright, authors[1], authors[0]);
337 textwin.AboutText = (LPSTR)farrealloc(textwin.AboutText, _fstrlen(textwin.AboutText)+1);
338 CheckMemory(textwin.AboutText);
340 menuwin.szMenuName = szMenuName;
342 pausewin.hInstance = hInstance;
343 pausewin.hPrevInstance = hPrevInstance;
344 pausewin.Title = "gnuplot pause";
346 graphwin.hInstance = hInstance;
347 graphwin.hPrevInstance = hPrevInstance;
348 graphwin.Title = "gnuplot graph";
349 graphwin.lptw = &textwin;
350 graphwin.IniFile = textwin.IniFile;
351 graphwin.IniSection = textwin.IniSection;
353 graphwin.fontsize = WINFONTSIZE;
355 if (TextInit(&textwin))
357 textwin.hIcon = LoadIcon(hInstance, "TEXTICON");
359 SetClassLong(textwin.hWndParent, GCL_HICON, (DWORD)textwin.hIcon);
361 SetClassWord(textwin.hWndParent, GCW_HICON, (WORD)textwin.hIcon);
365 for (i=0; i<_argc; ++i)
366 if (!stricmp(_argv[i],"-noend") || !stricmp(_argv[i],"/noend")
367 || !stricmp(_argv[i],"-persist"))
370 ShowWindow(textwin.hWndParent, textwin.nCmdShow);
373 ShowWindow(textwin.hWndParent, textwin.nCmdShow);
374 if (IsIconic(textwin.hWndParent)) { /* update icon */
376 GetClientRect(textwin.hWndParent, (LPRECT) &rect);
377 InvalidateRect(textwin.hWndParent, (LPRECT) &rect, 1);
378 UpdateWindow(textwin.hWndParent);
384 gnu_main(_argc, _argv, environ);
390 /* replacement stdio routines that use Text Window for stdin/stdout */
391 /* WARNING: Do not write to stdout/stderr with functions not listed
419 #if defined(__MSC__)|| defined(WIN32)
420 #define isterm(f) (f==stdin || f==stdout || f==stderr)
422 #define isterm(f) isatty(fileno(f))
428 return TextPutCh(&textwin, (BYTE)ch);
434 return TextKBHit(&textwin);
440 return TextGetCh(&textwin);
446 return TextGetChE(&textwin);
461 TextPutS(&textwin,"\nDANGER: gets() used\n");
462 MyFGetS(str,80,stdin);
464 && str[strlen(str)-1]=='\n')
465 str[strlen(str)-1] = '\0';
470 MyFGetS(char *str, unsigned int size, FILE *file)
475 p = TextGetS(&textwin, str, size);
476 if (p != (char FAR *)NULL)
480 return fgets(str,size,file);
484 MyFPutC(int ch, FILE *file)
491 return fputc(ch,file);
495 MyFPutS(const char *str, FILE *file)
498 TextPutS(&textwin, (char*) str);
500 return (*str); /* different from Borland library */
502 return fputs(str,file);
508 TextPutS(&textwin, str);
511 return 0; /* different from Borland library */
515 MyFPrintF(FILE *file, const char *fmt, ...)
524 count = vsprintf(buf,fmt,args);
525 TextPutS(&textwin,&buf[0]);
527 count = vfprintf(file, fmt, args);
533 MyVFPrintF(FILE *file, const char *fmt, va_list args)
539 count = vsprintf(buf,fmt,args);
540 TextPutS(&textwin, buf);
542 count = vfprintf(file, fmt, args);
547 MyPrintF(const char *fmt, ...)
554 count = vsprintf(buf,fmt,args);
555 TextPutS(&textwin,buf);
561 MyFWrite(const void *ptr, size_t size, size_t n, FILE *file)
566 TextPutCh(&textwin, ((BYTE *)ptr)[i]);
570 return fwrite(ptr, size, n, file);
574 MyFRead(void *ptr, size_t size, size_t n, FILE *file)
580 ((BYTE *)ptr)[i] = TextGetChE(&textwin);
584 return fread(ptr, size, n, file);
587 /* public interface to printer routines : Windows PRN emulation
588 * (formerly in win.trm)
591 #define MAX_PRT_LEN 256
592 static char win_prntmp[MAX_PRT_LEN+1];
599 if ((temp = getenv("TEMP")) == (char *)NULL)
602 strncpy(win_prntmp,temp,MAX_PRT_LEN);
603 /* stop X's in path being converted by mktemp */
604 for (temp=win_prntmp; *temp; temp++)
605 *temp = tolower(*temp);
606 if ( strlen(win_prntmp) && (win_prntmp[strlen(win_prntmp)-1]!='\\') )
607 strcat(win_prntmp,"\\");
609 strncat(win_prntmp, "_gptmp",MAX_PRT_LEN-strlen(win_prntmp));
610 strncat(win_prntmp, "XXXXXX",MAX_PRT_LEN-strlen(win_prntmp));
612 return fopen(win_prntmp, "w");
616 close_printer(FILE *outfile)
619 DumpPrinter(graphwin.hWndGraph, graphwin.Title, win_prntmp);
625 GraphPrint(&graphwin);
629 win_raise_terminal_window()
631 ShowWindow(graphwin.hWndGraph, SW_SHOWNORMAL);
632 BringWindowToTop(graphwin.hWndGraph);
636 win_lower_terminal_window()
638 SetWindowPos(graphwin.hWndGraph, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);