2011-05-29 13:13:04 +02:00
|
|
|
/* Main program for ngspice under Windows OS
|
2017-02-10 20:45:10 +01:00
|
|
|
Autor: Wolfgang Muees
|
|
|
|
|
Stand: 28.10.97
|
2019-07-20 09:16:42 +02:00
|
|
|
Copyright: Holger Vogt
|
2017-10-04 13:06:19 +02:00
|
|
|
Stand: 09.01.2018
|
2019-07-20 09:16:42 +02:00
|
|
|
Stand: 20.07.2019
|
2019-12-07 20:38:26 +01:00
|
|
|
Stand: 07.12.2019
|
2019-07-20 09:16:42 +02:00
|
|
|
Modified BSD license
|
2005-05-18 22:59:11 +02:00
|
|
|
*/
|
2017-02-10 20:45:10 +01:00
|
|
|
|
2011-12-27 12:33:01 +01:00
|
|
|
#include "ngspice/config.h"
|
2017-02-10 20:45:10 +01:00
|
|
|
|
2013-03-23 09:54:44 +01:00
|
|
|
#ifdef HAS_WINGUI
|
2005-05-18 22:59:11 +02:00
|
|
|
|
2010-01-02 19:05:07 +01:00
|
|
|
#define STRICT // strict type checking
|
2005-05-18 22:59:11 +02:00
|
|
|
#define WIN32_LEAN_AND_MEAN
|
2010-01-02 19:05:07 +01:00
|
|
|
#include <windows.h> // standard Windows calls
|
|
|
|
|
#include <windowsx.h> // Win32 message cracker
|
|
|
|
|
#include <stdio.h> // sprintf and co
|
|
|
|
|
#include <stdlib.h> // exit codes
|
|
|
|
|
#include <stdarg.h> // var. arguments
|
|
|
|
|
#include <assert.h> // assert macro
|
2011-12-17 18:16:29 +01:00
|
|
|
#include "ngspice/stringutil.h" // copy
|
2009-10-31 12:11:13 +01:00
|
|
|
#include <io.h> // _read
|
2005-05-18 22:59:11 +02:00
|
|
|
#include <errno.h>
|
|
|
|
|
#include <signal.h>
|
2005-05-20 15:00:17 +02:00
|
|
|
#include <ctype.h>
|
2009-09-13 21:42:19 +02:00
|
|
|
#include <sys/types.h>
|
|
|
|
|
#include <sys/timeb.h>
|
2019-06-01 18:15:43 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
#include "hist_info.h" /* history management */
|
2017-02-10 20:45:10 +01:00
|
|
|
#include "ngspice/bool.h" /* bool defined as unsigned char */
|
2009-09-13 21:42:19 +02:00
|
|
|
#include "misc/misc_time.h" /* timediff */
|
2017-10-04 13:06:19 +02:00
|
|
|
#include "ngspice/memory.h" /* TMALLOC */
|
2019-06-01 18:15:43 +02:00
|
|
|
#include "winmain.h"
|
2009-09-13 21:42:19 +02:00
|
|
|
|
2005-05-24 11:44:22 +02:00
|
|
|
/* Constants */
|
2011-08-08 21:39:15 +02:00
|
|
|
#define TBufSize 65536 // size of text buffer
|
2010-01-02 19:05:07 +01:00
|
|
|
#define CR VK_RETURN // Carriage Return
|
2012-04-23 22:55:43 +02:00
|
|
|
#define VK_EOT 0x1A // End of Transmission, should emulate ctrl-z
|
2009-10-18 12:32:11 +02:00
|
|
|
#define LF 10 // Line Feed
|
|
|
|
|
#define SE 0 // String termination
|
2010-01-02 19:05:07 +01:00
|
|
|
#define BorderSize 8 // Umrandung des Stringfeldes
|
2019-12-22 15:53:27 +01:00
|
|
|
#define SBufSize 300 // Groesze des Stringbuffers
|
2013-01-25 23:53:32 +01:00
|
|
|
#define IOBufSize 16348 // Groesze des printf-Buffers
|
2019-06-01 18:15:43 +02:00
|
|
|
#define HIST_SIZE 20 /* Max # commands held in history */
|
|
|
|
|
#define N_BYTE_HIST_BUF 512 /* Initial size of history buffer in bytes */
|
2009-10-18 12:32:11 +02:00
|
|
|
#define StatusHeight 25 // Hoehe des Status Bars
|
|
|
|
|
#define StatusFrame 2 // Abstand Statusbar / StatusElement
|
2005-05-18 22:59:11 +02:00
|
|
|
#define StatusElHeight (StatusHeight - 2 * StatusFrame)
|
2009-10-18 12:32:11 +02:00
|
|
|
#define SourceLength 500 // Platz fuer Source File Name
|
|
|
|
|
#define AnalyseLength 100 // Platz fuer Analyse
|
|
|
|
|
#define QuitButtonLength 80
|
2005-05-18 22:59:11 +02:00
|
|
|
|
2019-06-01 18:15:43 +02:00
|
|
|
/* Define the macro below to create a larger main window that is useful
|
|
|
|
|
* for seeing debug output that is generated before the window can be
|
|
|
|
|
* resized */
|
|
|
|
|
//#define BIG_WINDOW_FOR_DEBUGGING
|
|
|
|
|
|
2011-05-21 14:44:27 +02:00
|
|
|
/* macro to ignore unused variables and parameters */
|
|
|
|
|
#define NG_IGNORE(x) (void)x
|
|
|
|
|
|
2011-08-06 11:07:21 +02:00
|
|
|
#define QUIT_BUTTON_ID 2
|
|
|
|
|
|
2005-05-24 11:44:22 +02:00
|
|
|
/* Types */
|
2017-02-10 20:45:10 +01:00
|
|
|
typedef char SBufLine[SBufSize + 1]; // Eingabezeile
|
2005-05-18 22:59:11 +02:00
|
|
|
|
2005-05-24 11:44:22 +02:00
|
|
|
/* Global variables */
|
2009-10-18 12:32:11 +02:00
|
|
|
HINSTANCE hInst; /* Application instance */
|
|
|
|
|
int WinLineWidth = 690; /* Window width */
|
|
|
|
|
HWND hwMain; /* Main Window of the application */
|
|
|
|
|
HWND twText; /* Text window */
|
|
|
|
|
HWND swString; /* input string */
|
|
|
|
|
HWND hwStatus; /* status bar */
|
|
|
|
|
HWND hwSource; /* display of source name */
|
|
|
|
|
HWND hwAnalyse; /* analysis window */
|
|
|
|
|
HWND hwQuitButton; /* Pause button */
|
|
|
|
|
static int nReturnCode = 0; /* WinMain return value */
|
|
|
|
|
static int nShowState; /* Display mode of main window */
|
2019-12-21 23:55:58 +01:00
|
|
|
#ifdef EXT_ASC
|
2009-10-18 12:32:11 +02:00
|
|
|
static WNDCLASS hwMainClass; /* Class definition for the main window */
|
|
|
|
|
static LPCTSTR hwClassName = "SPICE_TEXT_WND";/* Class name of the main window */
|
|
|
|
|
static LPCTSTR hwWindowName = PACKAGE_STRING; /* main window displayed name */
|
|
|
|
|
static WNDCLASS twTextClass; /* Class definition for the text box */
|
|
|
|
|
static LPCTSTR twClassName = "SPICE_TEXT_BOX"; /* Class name for the text box */
|
|
|
|
|
static LPCTSTR twWindowName = "TextOut"; /* text box name */
|
|
|
|
|
static WNDCLASS swStringClass; /* Class definition of string window */
|
|
|
|
|
static LPCTSTR swClassName = "SPICE_STR_IN"; /* Class name of text input */
|
|
|
|
|
static LPCTSTR swWindowName = "StringIn"; /* Window name */
|
|
|
|
|
static WNDCLASS hwElementClass; /* Class definition of status displays */
|
2005-05-18 22:59:11 +02:00
|
|
|
static LPCTSTR hwElementClassName = "ElementClass";
|
|
|
|
|
static LPCTSTR hwSourceWindowName = "SourceDisplay";
|
|
|
|
|
static LPCTSTR hwAnalyseWindowName = "AnalyseDisplay";
|
2019-12-21 23:55:58 +01:00
|
|
|
#else
|
|
|
|
|
static WNDCLASSW hwMainClassW; /* Class definition for the main window */
|
|
|
|
|
static LPCWSTR hwClassNameW = L"SPICE_TEXT_WND";/* Class name of the main window */
|
|
|
|
|
static LPCWSTR hwWindowNameW = L"ngspice 26"; /* main window displayed name */
|
|
|
|
|
static WNDCLASSW twTextClassW; /* Class definition for the text box */
|
|
|
|
|
static LPCWSTR twClassNameW = L"SPICE_TEXT_BOX"; /* Class name for the text box */
|
|
|
|
|
static LPCWSTR twWindowNameW = L"TextOut"; /* text box name */
|
|
|
|
|
static WNDCLASSW swStringClassW; /* Class definition of string window */
|
|
|
|
|
static LPCWSTR swClassNameW = L"SPICE_STR_IN"; /* Class name of text input */
|
|
|
|
|
static LPCWSTR swWindowNameW = L"StringIn"; /* Window name */
|
2017-10-04 13:06:19 +02:00
|
|
|
static WNDCLASSW hwElementClassW; /* Class definition of status displays */
|
|
|
|
|
static LPCWSTR hwElementClassNameW = L"ElementClass";
|
|
|
|
|
static LPCWSTR hwSourceWindowNameW = L"SourceDisplay";
|
|
|
|
|
static LPCWSTR hwAnalyseWindowNameW = L"AnalyseDisplay";
|
2019-12-21 23:55:58 +01:00
|
|
|
#endif
|
|
|
|
|
static size_t TBufEnd = 0; /* Pointer to \0 */
|
|
|
|
|
static char TBuffer[TBufSize + 1]; /* Text buffer */
|
|
|
|
|
static SBufLine SBuffer; /* Input buffer */
|
|
|
|
|
static char CRLF[] = {CR, LF, SE}; /* CR/LF */
|
2009-10-18 12:32:11 +02:00
|
|
|
static int RowHeight = 16; /* Height of line of text */
|
|
|
|
|
static int LineHeight = 25; /* Height of input line */
|
|
|
|
|
static int VisibleRows = 10; /* Number of visible lines in text window */
|
|
|
|
|
static BOOL DoUpdate = FALSE; /* Update text window */
|
|
|
|
|
static WNDPROC swProc = NULL; /* original string window procedure */
|
|
|
|
|
static WNDPROC twProc = NULL; /* original text window procedure */
|
2017-10-04 13:06:19 +02:00
|
|
|
static HFONT sfont; /* Font for source and analysis window */
|
2009-10-18 12:32:11 +02:00
|
|
|
|
|
|
|
|
extern bool ft_ngdebug; /* some additional debug info printed */
|
|
|
|
|
extern bool ft_batchmode;
|
2011-07-01 21:19:59 +02:00
|
|
|
extern FILE *flogp; /* definition see xmain.c, stdout redirected to file */
|
2009-10-18 12:32:11 +02:00
|
|
|
|
2017-04-08 17:09:58 +02:00
|
|
|
extern void cp_doquit(void);
|
|
|
|
|
|
2019-06-01 18:15:43 +02:00
|
|
|
static struct History_info *init_history(void);
|
2017-02-10 20:45:10 +01:00
|
|
|
|
2005-05-18 22:59:11 +02:00
|
|
|
// ---------------------------<Message Handling>-------------------------------
|
|
|
|
|
|
|
|
|
|
// Warte, bis keine Messages mehr zu bearbeiten sind
|
2017-02-10 21:44:23 +01:00
|
|
|
void
|
|
|
|
|
WaitForIdle(void)
|
2005-05-18 22:59:11 +02:00
|
|
|
{
|
2009-10-18 12:32:11 +02:00
|
|
|
MSG m;
|
|
|
|
|
// arbeite alle Nachrichten ab
|
2017-02-10 20:45:10 +01:00
|
|
|
while (PeekMessage(&m, NULL, 0, 0, PM_REMOVE)) {
|
|
|
|
|
TranslateMessage(&m);
|
|
|
|
|
DispatchMessage(&m);
|
2009-10-18 12:32:11 +02:00
|
|
|
}
|
2005-05-18 22:59:11 +02:00
|
|
|
}
|
|
|
|
|
|
2017-02-10 20:45:10 +01:00
|
|
|
|
2005-05-18 22:59:11 +02:00
|
|
|
// ---------------------------<Message Handling>-------------------------------
|
|
|
|
|
|
|
|
|
|
// Warte, bis keine Messages mehr zu bearbeiten sind,
|
|
|
|
|
// dann warte auf neue Message (Input handling ohne Dauerloop)
|
2017-02-10 21:44:23 +01:00
|
|
|
static void
|
|
|
|
|
WaitForMessage(void)
|
2005-05-18 22:59:11 +02:00
|
|
|
{
|
2009-10-18 12:32:11 +02:00
|
|
|
MSG m;
|
|
|
|
|
// arbeite alle Nachrichten ab
|
2017-02-10 20:45:10 +01:00
|
|
|
while (PeekMessage(&m, NULL, 0, 0, PM_REMOVE)) {
|
|
|
|
|
TranslateMessage(&m);
|
|
|
|
|
DispatchMessage(&m);
|
2009-10-18 12:32:11 +02:00
|
|
|
}
|
|
|
|
|
WaitMessage();
|
2005-05-18 22:59:11 +02:00
|
|
|
}
|
|
|
|
|
|
2017-02-10 20:45:10 +01:00
|
|
|
|
2005-05-18 22:59:11 +02:00
|
|
|
// -----------------------------<Stringfenster>--------------------------------
|
|
|
|
|
|
|
|
|
|
// Loeschen des Stringfensters
|
2017-02-10 21:44:23 +01:00
|
|
|
static void
|
|
|
|
|
ClearInput(void)
|
2005-05-18 22:59:11 +02:00
|
|
|
{
|
2009-10-18 12:32:11 +02:00
|
|
|
// Darstellen
|
2017-02-10 20:45:10 +01:00
|
|
|
Edit_SetText(swString, "");
|
2005-05-18 22:59:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ---------------------------<SourceFile-Fenster>-----------------------------
|
|
|
|
|
|
2009-09-15 00:34:17 +02:00
|
|
|
/* New text to Source file window */
|
2017-02-10 21:44:23 +01:00
|
|
|
void
|
|
|
|
|
SetSource(char *Name)
|
2005-05-18 22:59:11 +02:00
|
|
|
{
|
2009-10-18 12:32:11 +02:00
|
|
|
if (hwSource) {
|
2017-10-04 13:06:19 +02:00
|
|
|
#ifdef EXT_ASC
|
2017-02-10 20:45:10 +01:00
|
|
|
SetWindowText(hwSource, Name);
|
2017-10-04 13:06:19 +02:00
|
|
|
#else
|
|
|
|
|
wchar_t *NameW;
|
|
|
|
|
NameW = TMALLOC(wchar_t, 2 * strlen(Name) + 1);
|
2019-12-07 20:38:26 +01:00
|
|
|
MultiByteToWideChar(CP_UTF8, 0, Name, -1, NameW, 2 * (int)strlen(Name) + 1);
|
2017-10-04 13:06:19 +02:00
|
|
|
SetWindowTextW(hwSource, NameW);
|
|
|
|
|
tfree(NameW);
|
|
|
|
|
#endif
|
2017-02-10 20:45:10 +01:00
|
|
|
InvalidateRgn(hwSource, NULL, TRUE);
|
2017-10-04 13:06:19 +02:00
|
|
|
}
|
2005-05-18 22:59:11 +02:00
|
|
|
}
|
|
|
|
|
|
2017-02-10 20:45:10 +01:00
|
|
|
|
2005-05-18 22:59:11 +02:00
|
|
|
// ------------------------------<Analyse-Fenster>-----------------------------
|
|
|
|
|
|
2009-09-13 21:42:19 +02:00
|
|
|
/* New progress report into analysis window.
|
|
|
|
|
Update only every DELTATIME milliseconds */
|
2017-02-10 20:45:10 +01:00
|
|
|
|
2009-09-13 21:42:19 +02:00
|
|
|
#define DELTATIME 150
|
2017-02-10 20:45:10 +01:00
|
|
|
|
2017-02-10 21:44:23 +01:00
|
|
|
void
|
|
|
|
|
SetAnalyse(char *Analyse, /* in: analysis type */
|
|
|
|
|
int DecaPercent) /* in: 10 times the progress [%] */
|
|
|
|
|
{
|
2017-02-10 20:45:10 +01:00
|
|
|
static int OldPercent = -2; /* Previous progress value */
|
|
|
|
|
static char OldAn[128]; /* Previous analysis type */
|
|
|
|
|
char s[128], t[128]; /* outputs to analysis window and task bar */
|
|
|
|
|
static struct timeb timebefore; /* previous time stamp */
|
|
|
|
|
struct timeb timenow; /* actual time stamp */
|
|
|
|
|
int diffsec, diffmillisec; /* differences actual minus prev. time stamp */
|
|
|
|
|
|
|
|
|
|
WaitForIdle();
|
|
|
|
|
|
2019-12-07 20:38:26 +01:00
|
|
|
if (((DecaPercent == OldPercent) && !strcmp(OldAn, Analyse)) || !strcmp(Analyse, "or"))
|
2017-02-10 21:44:23 +01:00
|
|
|
return;
|
2017-02-10 20:45:10 +01:00
|
|
|
|
|
|
|
|
/* get actual time */
|
|
|
|
|
ftime(&timenow);
|
|
|
|
|
timediff(&timenow, &timebefore, &diffsec, &diffmillisec);
|
|
|
|
|
|
|
|
|
|
/* info every one percent of progress:
|
|
|
|
|
actual time, progress,
|
|
|
|
|
to catch linearity of progress of simulation */
|
|
|
|
|
if (ft_ngdebug && !strcmp(Analyse, "tran"))
|
2017-02-10 21:44:23 +01:00
|
|
|
if ((int)((double)DecaPercent/10.) > (int)((double)OldPercent/10.))
|
2017-02-10 20:45:10 +01:00
|
|
|
win_x_printf("%3.1f%% percent progress after %4.2f seconds.\n", (double)DecaPercent/10., seconds());
|
|
|
|
|
|
|
|
|
|
OldPercent = DecaPercent;
|
|
|
|
|
/* output only into hwAnalyse window and if time elapsed is larger than
|
|
|
|
|
DELTATIME given value, or if analysis has changed, else return */
|
2017-10-04 13:06:19 +02:00
|
|
|
if (hwAnalyse && ((diffsec > 0) || (diffmillisec > DELTATIME) || strcmp(OldAn, Analyse))) {
|
2009-10-18 12:32:11 +02:00
|
|
|
if (DecaPercent < 0) {
|
2017-10-04 13:06:19 +02:00
|
|
|
sprintf(s, " -- ready --");
|
2017-02-10 20:45:10 +01:00
|
|
|
sprintf(t, "%s", PACKAGE_STRING);
|
|
|
|
|
}
|
|
|
|
|
else if (DecaPercent == 0) {
|
|
|
|
|
sprintf(s, "%s", Analyse);
|
|
|
|
|
sprintf(t, "%s %s", PACKAGE_STRING, Analyse);
|
|
|
|
|
}
|
|
|
|
|
else if (!strcmp(Analyse, "shooting")) {
|
|
|
|
|
sprintf(s, "%s: %d", Analyse, DecaPercent);
|
|
|
|
|
sprintf(t, "%s %d", PACKAGE_STRING, DecaPercent);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
sprintf(s, "%s: %3.1f%%", Analyse, (double)DecaPercent/10.);
|
|
|
|
|
sprintf(t, "%s %3.1f%%", PACKAGE_STRING, (double)DecaPercent/10.);
|
|
|
|
|
}
|
|
|
|
|
timebefore.dstflag = timenow.dstflag;
|
|
|
|
|
timebefore.millitm = timenow.millitm;
|
|
|
|
|
timebefore.time = timenow.time;
|
|
|
|
|
timebefore.timezone = timenow.timezone;
|
|
|
|
|
/* info when previous analysis period has finished */
|
|
|
|
|
if (strcmp(OldAn, Analyse)) {
|
|
|
|
|
if (ft_ngdebug && (strcmp(OldAn, "")))
|
|
|
|
|
win_x_printf("%s finished after %4.2f seconds.\n", OldAn, seconds());
|
|
|
|
|
strncpy(OldAn, Analyse, 127);
|
|
|
|
|
}
|
|
|
|
|
|
2017-10-04 13:06:19 +02:00
|
|
|
#ifdef EXT_ASC
|
2017-02-10 20:45:10 +01:00
|
|
|
SetWindowText(hwAnalyse, s);
|
|
|
|
|
SetWindowText(hwMain, t);
|
2017-10-04 13:06:19 +02:00
|
|
|
#else
|
|
|
|
|
wchar_t sw[256];
|
|
|
|
|
wchar_t tw[256];
|
|
|
|
|
swprintf(sw, 256, L"%S", s);
|
|
|
|
|
swprintf(tw, 256, L"%S", t);
|
|
|
|
|
SetWindowTextW(hwAnalyse, sw);
|
|
|
|
|
SetWindowTextW(hwMain, tw);
|
|
|
|
|
#endif
|
2017-02-10 20:45:10 +01:00
|
|
|
InvalidateRgn(hwAnalyse, NULL, TRUE);
|
|
|
|
|
InvalidateRgn(hwMain, NULL, TRUE);
|
|
|
|
|
}
|
|
|
|
|
UpdateWindow(hwAnalyse);
|
|
|
|
|
UpdateWindow(hwMain);
|
2005-05-18 22:59:11 +02:00
|
|
|
}
|
|
|
|
|
|
2017-02-10 20:45:10 +01:00
|
|
|
|
2005-05-18 22:59:11 +02:00
|
|
|
// ------------------------------<Textfenster>---------------------------------
|
|
|
|
|
|
|
|
|
|
// Anpassen des Scrollers im Textfenster
|
|
|
|
|
// Stellt gleichzeitig den Text neu dar
|
2017-02-10 21:44:23 +01:00
|
|
|
static void
|
|
|
|
|
AdjustScroller(void)
|
2005-05-18 22:59:11 +02:00
|
|
|
{
|
2009-10-18 12:32:11 +02:00
|
|
|
int LineCount;
|
|
|
|
|
int FirstLine;
|
|
|
|
|
int MyFirstLine;
|
2017-02-10 20:45:10 +01:00
|
|
|
LineCount = Edit_GetLineCount(twText);
|
|
|
|
|
FirstLine = Edit_GetFirstVisibleLine(twText);
|
2009-10-18 12:32:11 +02:00
|
|
|
MyFirstLine = LineCount - VisibleRows;
|
2017-02-10 20:45:10 +01:00
|
|
|
|
2017-02-10 21:44:23 +01:00
|
|
|
if (MyFirstLine < 0 )
|
|
|
|
|
MyFirstLine = 0;
|
2017-02-10 20:45:10 +01:00
|
|
|
|
2019-05-29 22:57:40 +02:00
|
|
|
Edit_Scroll(twText, (WPARAM) MyFirstLine - FirstLine, 0);
|
2009-10-18 12:32:11 +02:00
|
|
|
// Das wars
|
|
|
|
|
DoUpdate = FALSE;
|
2005-05-18 22:59:11 +02:00
|
|
|
}
|
|
|
|
|
|
2017-02-10 20:45:10 +01:00
|
|
|
|
2005-05-18 22:59:11 +02:00
|
|
|
// Loeschen einer Zeile im Textbuffer
|
2017-02-10 21:44:23 +01:00
|
|
|
static void
|
|
|
|
|
_DeleteFirstLine(void)
|
2005-05-18 22:59:11 +02:00
|
|
|
{
|
2017-02-10 20:45:10 +01:00
|
|
|
char *cp = strchr(TBuffer, LF);
|
2009-10-18 12:32:11 +02:00
|
|
|
if (!cp) {
|
|
|
|
|
// Buffer leeren
|
|
|
|
|
TBufEnd = 0;
|
|
|
|
|
TBuffer[TBufEnd] = SE;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
cp++;
|
2011-07-09 18:27:36 +02:00
|
|
|
TBufEnd -= (size_t)(cp - TBuffer);
|
2017-02-10 20:45:10 +01:00
|
|
|
memmove(TBuffer, cp, TBufEnd);
|
2009-10-18 12:32:11 +02:00
|
|
|
TBuffer[TBufEnd] = SE;
|
2005-05-18 22:59:11 +02:00
|
|
|
}
|
|
|
|
|
|
2019-07-20 11:35:48 +02:00
|
|
|
/* Compare old system time with current system time.
|
|
|
|
|
If difference is larger than ms milliseconds, return TRUE.
|
|
|
|
|
If time is less than the delay time (in milliseconds), return TRUE. */
|
|
|
|
|
static bool
|
|
|
|
|
CompareTime(int ms, int delay)
|
|
|
|
|
{
|
|
|
|
|
static __int64 prevfileTime64Bit;
|
|
|
|
|
static __int64 startfileTime64Bit;
|
|
|
|
|
/* conversion: time in ms -> 100ns */
|
|
|
|
|
__int64 reftime = ms * 10000;
|
|
|
|
|
__int64 delaytime = delay * 10000;
|
|
|
|
|
FILETIME newtime;
|
|
|
|
|
/* get time in 100ns units */
|
|
|
|
|
GetSystemTimeAsFileTime(&newtime);
|
|
|
|
|
ULARGE_INTEGER theTime;
|
|
|
|
|
theTime.LowPart = newtime.dwLowDateTime;
|
|
|
|
|
theTime.HighPart = newtime.dwHighDateTime;
|
|
|
|
|
__int64 fileTime64Bit = theTime.QuadPart;
|
|
|
|
|
__int64 difffileTime64Bit = fileTime64Bit - prevfileTime64Bit;
|
|
|
|
|
/* Catch the delay start time */
|
|
|
|
|
if ((startfileTime64Bit) == 0) {
|
|
|
|
|
startfileTime64Bit = fileTime64Bit;
|
|
|
|
|
}
|
|
|
|
|
if ((fileTime64Bit - startfileTime64Bit) < delaytime)
|
|
|
|
|
return TRUE;
|
|
|
|
|
if ((difffileTime64Bit) > reftime) {
|
|
|
|
|
prevfileTime64Bit = fileTime64Bit;
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
2017-02-10 20:45:10 +01:00
|
|
|
|
2019-07-20 11:35:48 +02:00
|
|
|
// Add a char to the text buffer
|
2017-02-10 21:44:23 +01:00
|
|
|
static void
|
|
|
|
|
AppendChar(char c)
|
2005-05-18 22:59:11 +02:00
|
|
|
{
|
2019-07-20 11:35:48 +02:00
|
|
|
// Limit the text buffer size to TBufSize
|
2017-02-10 20:45:10 +01:00
|
|
|
while ((TBufEnd + 4) >= TBufSize)
|
2009-10-18 12:32:11 +02:00
|
|
|
_DeleteFirstLine();
|
2019-07-20 11:35:48 +02:00
|
|
|
// Add character
|
2009-10-18 12:32:11 +02:00
|
|
|
TBuffer[TBufEnd++] = c;
|
|
|
|
|
TBuffer[TBufEnd] = SE;
|
|
|
|
|
DoUpdate = TRUE;
|
2019-07-20 11:35:48 +02:00
|
|
|
|
|
|
|
|
/* If line is complete, and waiting time has passed, show it in text window.
|
|
|
|
|
If time is less than delay time, always show the line (useful during start-up) */
|
2019-08-11 17:08:19 +02:00
|
|
|
if (c == LF && CompareTime(30, 500)) {
|
2017-02-10 20:45:10 +01:00
|
|
|
DisplayText();
|
2019-07-20 09:16:42 +02:00
|
|
|
WaitForIdle();
|
|
|
|
|
}
|
2005-05-18 22:59:11 +02:00
|
|
|
}
|
|
|
|
|
|
2017-02-10 20:45:10 +01:00
|
|
|
|
2005-05-18 22:59:11 +02:00
|
|
|
// Anfuegen eines Strings an den TextBuffer
|
2017-02-10 21:44:23 +01:00
|
|
|
static void
|
|
|
|
|
AppendString(const char *Line)
|
2005-05-18 22:59:11 +02:00
|
|
|
{
|
2009-10-18 12:32:11 +02:00
|
|
|
size_t i;
|
2017-02-10 21:44:23 +01:00
|
|
|
if (!Line)
|
|
|
|
|
return;
|
2009-10-18 12:32:11 +02:00
|
|
|
|
|
|
|
|
// Zeilenlaenge bestimmen
|
|
|
|
|
i = strlen(Line);
|
|
|
|
|
// Textbuffer nicht zu grosz werden lassen
|
2017-02-10 20:45:10 +01:00
|
|
|
while ((i + TBufEnd + 3) >= TBufSize)
|
2009-10-18 12:32:11 +02:00
|
|
|
_DeleteFirstLine();
|
|
|
|
|
// Zeile dranhaengen
|
2017-02-10 20:45:10 +01:00
|
|
|
strcpy(&TBuffer[TBufEnd], Line);
|
2009-10-18 12:32:11 +02:00
|
|
|
TBufEnd += i;
|
|
|
|
|
DoUpdate = TRUE;
|
2005-05-18 22:59:11 +02:00
|
|
|
}
|
|
|
|
|
|
2017-02-10 20:45:10 +01:00
|
|
|
|
2005-05-18 22:59:11 +02:00
|
|
|
// Text neu darstellen
|
2017-02-10 21:44:23 +01:00
|
|
|
static void
|
|
|
|
|
DisplayText(void)
|
2005-05-18 22:59:11 +02:00
|
|
|
{
|
2017-10-04 13:06:19 +02:00
|
|
|
// Show text
|
|
|
|
|
#ifdef EXT_ASC
|
2017-02-10 20:45:10 +01:00
|
|
|
Edit_SetText(twText, TBuffer);
|
2017-10-04 13:06:19 +02:00
|
|
|
#else
|
|
|
|
|
wchar_t *TWBuffer;
|
|
|
|
|
TWBuffer = TMALLOC(wchar_t, 2 * strlen(TBuffer) + 1);
|
2019-12-07 20:38:26 +01:00
|
|
|
if (MultiByteToWideChar(CP_UTF8, 0, TBuffer, -1, TWBuffer, 2 * (int)strlen(TBuffer) + 1) == 0)
|
2017-10-04 13:06:19 +02:00
|
|
|
swprintf(TWBuffer, 2 * strlen(TBuffer), L"UTF-8 to UTF-16 conversion failed with 0x%x\n%hs could not be converted\n", GetLastError(), TBuffer);
|
|
|
|
|
SetWindowTextW(twText, TWBuffer);
|
|
|
|
|
tfree(TWBuffer);
|
|
|
|
|
#endif
|
2009-10-18 12:32:11 +02:00
|
|
|
// Scroller updaten, neuen Text darstellen
|
|
|
|
|
AdjustScroller();
|
2005-05-18 22:59:11 +02:00
|
|
|
}
|
2017-02-10 20:45:10 +01:00
|
|
|
|
|
|
|
|
|
2005-05-18 22:59:11 +02:00
|
|
|
// Anfuegen einer Zeile an den Textbuffer
|
2017-02-10 21:44:23 +01:00
|
|
|
#if 0
|
|
|
|
|
void
|
|
|
|
|
AppendLine(const char *Line)
|
2005-05-18 22:59:11 +02:00
|
|
|
{
|
2017-02-10 21:44:23 +01:00
|
|
|
if (!Line)
|
|
|
|
|
return;
|
2005-05-18 22:59:11 +02:00
|
|
|
|
2009-10-18 12:32:11 +02:00
|
|
|
// String anhaengen
|
2017-02-10 20:45:10 +01:00
|
|
|
AppendString(Line);
|
2005-05-18 22:59:11 +02:00
|
|
|
|
2009-10-18 12:32:11 +02:00
|
|
|
// CRLF anhaengen
|
2017-02-10 20:45:10 +01:00
|
|
|
AppendString(CRLF);
|
2005-05-18 22:59:11 +02:00
|
|
|
}
|
2017-02-10 21:44:23 +01:00
|
|
|
#endif
|
2017-02-10 20:45:10 +01:00
|
|
|
|
|
|
|
|
|
2005-05-18 22:59:11 +02:00
|
|
|
// -----------------------------------<User-IO>--------------------------------
|
|
|
|
|
|
|
|
|
|
// Lese ein Zeichen ein
|
2017-02-10 21:44:23 +01:00
|
|
|
static int
|
|
|
|
|
w_getch(void)
|
2005-05-18 22:59:11 +02:00
|
|
|
{
|
2009-10-18 12:32:11 +02:00
|
|
|
int c;
|
|
|
|
|
|
|
|
|
|
// Sind noch Zeichen da?
|
|
|
|
|
c = SBuffer[0];
|
|
|
|
|
if (!c) {
|
|
|
|
|
// Alte Informationen darstellen
|
|
|
|
|
if (DoUpdate)
|
|
|
|
|
DisplayText();
|
|
|
|
|
// Focus setzen
|
2017-02-10 20:45:10 +01:00
|
|
|
SetFocus(swString);
|
2009-10-18 12:32:11 +02:00
|
|
|
// Cursor = normal
|
2017-02-10 20:45:10 +01:00
|
|
|
SetCursor(LoadCursor(NULL, IDC_IBEAM));
|
2009-10-18 12:32:11 +02:00
|
|
|
// Analyse ist fertig
|
2017-02-10 20:45:10 +01:00
|
|
|
SetAnalyse("", -1);
|
2009-10-18 12:32:11 +02:00
|
|
|
// Warten auf die Eingabe
|
|
|
|
|
do {
|
|
|
|
|
WaitForMessage();
|
|
|
|
|
c = SBuffer[0];
|
2017-02-10 20:45:10 +01:00
|
|
|
} while (!c);
|
2009-10-18 12:32:11 +02:00
|
|
|
// Zeichen an die Ausgabe anhaengen
|
2017-02-10 20:45:10 +01:00
|
|
|
AppendString(SBuffer);
|
2009-10-18 12:32:11 +02:00
|
|
|
// Cursor = warten
|
2017-02-10 20:45:10 +01:00
|
|
|
SetCursor(LoadCursor(NULL, IDC_WAIT));
|
2009-10-18 12:32:11 +02:00
|
|
|
}
|
2019-05-29 22:38:02 +02:00
|
|
|
|
|
|
|
|
/* Shift out the character being returned. After the entire
|
|
|
|
|
* contents of the buffer is read, it first byte is '\0' from
|
|
|
|
|
* the null termination of the buffer.
|
|
|
|
|
*
|
|
|
|
|
* Inefficient way to process the string, but it should work */
|
|
|
|
|
(void) memmove(SBuffer, SBuffer + 1, sizeof SBuffer - 1);
|
2009-10-18 12:32:11 +02:00
|
|
|
return c;
|
2005-05-18 22:59:11 +02:00
|
|
|
}
|
|
|
|
|
|
2017-02-10 20:45:10 +01:00
|
|
|
|
2005-05-18 22:59:11 +02:00
|
|
|
// Gebe ein Zeichen aus
|
2017-02-10 21:44:23 +01:00
|
|
|
static int
|
|
|
|
|
w_putch(int c)
|
2005-05-18 22:59:11 +02:00
|
|
|
{
|
2009-10-18 12:32:11 +02:00
|
|
|
if (c)
|
2017-02-10 20:45:10 +01:00
|
|
|
AppendChar((char) c);
|
2009-10-18 12:32:11 +02:00
|
|
|
return c;
|
2005-05-18 22:59:11 +02:00
|
|
|
}
|
|
|
|
|
|
2017-02-10 20:45:10 +01:00
|
|
|
|
2009-10-18 12:32:11 +02:00
|
|
|
/* -------------------------------<Window procedures>-------------------------- */
|
2005-05-18 22:59:11 +02:00
|
|
|
|
2009-10-18 12:32:11 +02:00
|
|
|
/* Main window changes size */
|
2017-02-10 21:44:23 +01:00
|
|
|
static void
|
|
|
|
|
Main_OnSize(HWND hwnd, UINT state, int cx, int cy)
|
2005-05-18 22:59:11 +02:00
|
|
|
{
|
2009-10-18 12:32:11 +02:00
|
|
|
int h = cy - LineHeight - StatusHeight;
|
2005-05-18 22:59:11 +02:00
|
|
|
|
2011-05-21 14:44:27 +02:00
|
|
|
NG_IGNORE(hwnd);
|
|
|
|
|
NG_IGNORE(state);
|
|
|
|
|
|
2009-10-18 12:32:11 +02:00
|
|
|
/* Expand text window */
|
2017-02-10 20:45:10 +01:00
|
|
|
MoveWindow(twText, 0, 0, cx, h , TRUE);
|
|
|
|
|
VisibleRows = (h / RowHeight) - 1;
|
2009-10-18 12:32:11 +02:00
|
|
|
AdjustScroller();
|
2005-05-18 22:59:11 +02:00
|
|
|
|
2009-10-18 12:32:11 +02:00
|
|
|
/* Expand string window */
|
2017-02-10 20:45:10 +01:00
|
|
|
MoveWindow(swString, 0, h, cx, LineHeight, TRUE);
|
2005-05-18 22:59:11 +02:00
|
|
|
|
2009-10-18 12:32:11 +02:00
|
|
|
/* Expand Status Elements */
|
2017-10-04 13:06:19 +02:00
|
|
|
h = cy - LineHeight + StatusFrame - 2;
|
|
|
|
|
int statbegin = 3 * StatusFrame + QuitButtonLength + AnalyseLength + 4;
|
|
|
|
|
MoveWindow(hwSource, StatusFrame, h, cx - statbegin - BorderSize, StatusElHeight, TRUE);
|
|
|
|
|
MoveWindow( hwAnalyse, cx - statbegin, h, AnalyseLength, StatusElHeight, TRUE);
|
|
|
|
|
MoveWindow( hwQuitButton, cx - StatusFrame - QuitButtonLength - 1,
|
|
|
|
|
h + 1, QuitButtonLength, StatusElHeight, TRUE);
|
2005-05-18 22:59:11 +02:00
|
|
|
}
|
|
|
|
|
|
2017-02-10 20:45:10 +01:00
|
|
|
|
2009-10-18 12:32:11 +02:00
|
|
|
/* Write a command into the command buffer */
|
2017-02-10 21:44:23 +01:00
|
|
|
static void
|
|
|
|
|
PostSpiceCommand(const char * const cmd)
|
2005-05-18 22:59:11 +02:00
|
|
|
{
|
2017-02-10 20:45:10 +01:00
|
|
|
strcpy(SBuffer, cmd);
|
|
|
|
|
strcat(SBuffer, CRLF);
|
2005-05-18 22:59:11 +02:00
|
|
|
}
|
|
|
|
|
|
2017-02-10 20:45:10 +01:00
|
|
|
|
2009-10-18 12:32:11 +02:00
|
|
|
/* Main Window procedure */
|
2017-02-10 21:44:23 +01:00
|
|
|
static LRESULT CALLBACK
|
|
|
|
|
MainWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
2005-05-18 22:59:11 +02:00
|
|
|
{
|
2009-10-18 12:32:11 +02:00
|
|
|
switch (uMsg) {
|
|
|
|
|
|
2017-02-10 20:45:10 +01:00
|
|
|
/* command issued by pushing the "Quit" button */
|
2009-10-18 12:32:11 +02:00
|
|
|
case WM_COMMAND:
|
|
|
|
|
if (HIWORD(wParam) == BN_CLICKED)
|
2017-02-10 21:44:23 +01:00
|
|
|
if (ft_batchmode &&
|
|
|
|
|
(MessageBox(NULL, "Do you want to quit ngspice?", "Quit", MB_OKCANCEL | MB_ICONERROR) == IDCANCEL))
|
|
|
|
|
goto DEFAULT_AFTER;
|
|
|
|
|
if (LOWORD(wParam) == QUIT_BUTTON_ID)
|
2017-02-10 20:45:10 +01:00
|
|
|
SendMessage(GetParent((HWND)lParam), WM_CLOSE, 0, 0);
|
|
|
|
|
/* write all achieved so far to log file */
|
2017-02-10 21:44:23 +01:00
|
|
|
if (flogp)
|
|
|
|
|
win_x_fflush(flogp);
|
2009-10-18 12:32:11 +02:00
|
|
|
goto DEFAULT_AFTER;
|
2012-04-23 22:55:43 +02:00
|
|
|
|
2009-10-18 12:32:11 +02:00
|
|
|
case WM_CLOSE:
|
2017-04-08 17:09:58 +02:00
|
|
|
cp_doquit();
|
|
|
|
|
/* continue if the user declined the 'quit' command */
|
2009-10-18 12:32:11 +02:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
case WM_SIZE:
|
2017-02-10 20:45:10 +01:00
|
|
|
HANDLE_WM_SIZE(hwnd, wParam, lParam, Main_OnSize);
|
2009-10-18 12:32:11 +02:00
|
|
|
goto DEFAULT_AFTER;
|
|
|
|
|
|
|
|
|
|
default:
|
2017-02-10 20:45:10 +01:00
|
|
|
DEFAULT_AFTER:
|
2017-10-04 13:06:19 +02:00
|
|
|
#ifdef EXT_ASC
|
2017-02-10 20:45:10 +01:00
|
|
|
return DefWindowProc(hwnd, uMsg, wParam, lParam);
|
2017-10-04 13:06:19 +02:00
|
|
|
#else
|
|
|
|
|
return DefWindowProcW(hwnd, uMsg, wParam, lParam);
|
|
|
|
|
#endif
|
2009-10-18 12:32:11 +02:00
|
|
|
}
|
2005-05-18 22:59:11 +02:00
|
|
|
}
|
|
|
|
|
|
2017-02-10 20:45:10 +01:00
|
|
|
|
2019-05-26 19:10:29 +02:00
|
|
|
/* Procedure for string (input) window */
|
2017-02-10 21:44:23 +01:00
|
|
|
static LRESULT CALLBACK
|
|
|
|
|
StringWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
2005-05-18 22:59:11 +02:00
|
|
|
{
|
2019-06-01 18:15:43 +02:00
|
|
|
static struct History_info **pp_hi; /* handle to history */
|
2009-10-18 12:32:11 +02:00
|
|
|
|
|
|
|
|
switch (uMsg) {
|
2019-06-01 18:15:43 +02:00
|
|
|
case WM_CREATE:
|
|
|
|
|
/* Get access to history information */
|
2019-12-21 23:55:58 +01:00
|
|
|
#ifdef EXT_ASC
|
2019-06-01 18:15:43 +02:00
|
|
|
pp_hi = (struct History_info **)
|
|
|
|
|
((LPCREATESTRUCT) lParam)->lpCreateParams;
|
2019-12-21 23:55:58 +01:00
|
|
|
#else
|
|
|
|
|
pp_hi = (struct History_info **)
|
|
|
|
|
((LPCREATESTRUCTW) lParam)->lpCreateParams;
|
|
|
|
|
#endif
|
2019-06-01 18:15:43 +02:00
|
|
|
break;
|
|
|
|
|
case WM_KEYDOWN: {
|
|
|
|
|
const UINT i = (UINT) wParam;
|
2009-10-18 12:32:11 +02:00
|
|
|
if ((i == VK_UP) || (i == VK_DOWN)) {
|
|
|
|
|
/* Set old text to new */
|
2019-12-21 23:55:58 +01:00
|
|
|
#ifdef EXT_ASC
|
2019-06-01 18:15:43 +02:00
|
|
|
SetWindowText(hwnd, (i == VK_UP) ?
|
|
|
|
|
history_get_prev(*pp_hi, NULL) :
|
|
|
|
|
history_get_next(*pp_hi, NULL));
|
2019-12-22 15:53:27 +01:00
|
|
|
/* Put cursor to end of line */
|
|
|
|
|
CallWindowProc(swProc, hwnd, uMsg, (WPARAM) VK_END, lParam);
|
2019-12-21 23:55:58 +01:00
|
|
|
#else
|
|
|
|
|
const char *newtext = (i == VK_UP) ?
|
|
|
|
|
history_get_prev(*pp_hi, NULL) :
|
|
|
|
|
history_get_next(*pp_hi, NULL);
|
|
|
|
|
wchar_t *newtextW;
|
|
|
|
|
newtextW = TMALLOC(wchar_t, 2 * strlen(newtext) + 1);
|
|
|
|
|
MultiByteToWideChar(
|
|
|
|
|
CP_UTF8, 0, newtext, -1, newtextW, 2 * (int) strlen(newtext) + 1);
|
2019-12-22 15:53:27 +01:00
|
|
|
SetWindowTextW(swString, newtextW);
|
2019-12-21 23:55:58 +01:00
|
|
|
tfree(newtextW);
|
2009-10-18 12:32:11 +02:00
|
|
|
/* Put cursor to end of line */
|
2019-12-22 15:53:27 +01:00
|
|
|
CallWindowProcW(swProc, hwnd, uMsg, (WPARAM) VK_END, lParam);
|
|
|
|
|
#endif
|
2009-10-18 12:32:11 +02:00
|
|
|
return 0;
|
|
|
|
|
}
|
2017-02-10 20:45:10 +01:00
|
|
|
if (i == VK_ESCAPE) {
|
2009-10-18 12:32:11 +02:00
|
|
|
ClearInput();
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2019-06-01 18:15:43 +02:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case WM_CHAR: {
|
|
|
|
|
const char c = (char) wParam;
|
2017-02-10 20:45:10 +01:00
|
|
|
if (c == CR) {
|
2019-05-29 22:38:02 +02:00
|
|
|
/* Get text from the window. Must leave space for crlf
|
|
|
|
|
* that is appended. -1 accounts for NULL as follows:
|
|
|
|
|
* The last argument to GetWindowText is the size of the
|
|
|
|
|
* buffer for writing the string + NULL. The NULL will be
|
|
|
|
|
* overwritten by the strcpy below, so it should not be
|
|
|
|
|
* counted in the size needed for the CRLF string. */
|
2019-12-21 23:55:58 +01:00
|
|
|
#ifdef EXT_ASC
|
2019-05-29 22:38:02 +02:00
|
|
|
const int n_char_returned = GetWindowText(
|
|
|
|
|
hwnd, SBuffer, sizeof SBuffer - (sizeof CRLF - 1));
|
2019-12-21 23:55:58 +01:00
|
|
|
#else
|
|
|
|
|
wchar_t *WBuffer = TMALLOC(wchar_t, sizeof(SBuffer));
|
2019-12-22 15:53:27 +01:00
|
|
|
/* for utf-8 the number of characters is not the number of bytes returned */
|
|
|
|
|
GetWindowTextW(hwnd, WBuffer, sizeof SBuffer - (sizeof CRLF - 1));
|
|
|
|
|
/* retrive here the number of bytes returned */
|
|
|
|
|
const int n_char_returned = WideCharToMultiByte(CP_UTF8, 0, WBuffer,
|
|
|
|
|
-1, SBuffer, sizeof SBuffer - 1, NULL, NULL);
|
2019-12-21 23:55:58 +01:00
|
|
|
tfree(WBuffer);
|
|
|
|
|
#endif
|
2019-06-01 18:15:43 +02:00
|
|
|
unsigned int n_char_prev_cmd;
|
|
|
|
|
|
|
|
|
|
/* Add the command to the history if it is different from the
|
|
|
|
|
* previous one. This avoids filling the buffer with the same
|
|
|
|
|
* command and allows faster scrolling through the commands.
|
|
|
|
|
* history_get_newest() is called rather than history_get_prev()
|
|
|
|
|
* since the current return position may not be the last one
|
|
|
|
|
* and the position should not be changed. */
|
|
|
|
|
const char *cmd_prev = history_get_newest(
|
|
|
|
|
*pp_hi, &n_char_prev_cmd);
|
|
|
|
|
if ((int) n_char_prev_cmd != n_char_returned ||
|
|
|
|
|
strcmp(SBuffer, cmd_prev) != 0) {
|
|
|
|
|
/* Different, so add */
|
|
|
|
|
history_add(pp_hi, n_char_returned, SBuffer);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
history_reset_pos(*pp_hi);
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-29 22:38:02 +02:00
|
|
|
strcpy(SBuffer + n_char_returned, CRLF);
|
2017-02-10 20:45:10 +01:00
|
|
|
ClearInput();
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
if (c == VK_ESCAPE)
|
|
|
|
|
return 0;
|
|
|
|
|
/* ctrl-z ends input from string window (like a console input),
|
|
|
|
|
FIXME: not yet working */
|
|
|
|
|
if (c == VK_EOT) {
|
|
|
|
|
// strcat(SBuffer, "");
|
|
|
|
|
SBuffer[0] = c; // '\004';
|
|
|
|
|
SBuffer[1] = '\n';
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
/* ctrl-c interrupts simulation */
|
|
|
|
|
if (c == VK_CANCEL) {
|
|
|
|
|
raise (SIGINT);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2009-10-18 12:32:11 +02:00
|
|
|
}
|
2019-06-01 18:15:43 +02:00
|
|
|
} /* end of switch over handled messages */
|
|
|
|
|
|
|
|
|
|
/* Fowrard to be processed further by swProc */
|
2017-10-04 13:06:19 +02:00
|
|
|
#ifdef EXT_ASC
|
|
|
|
|
return CallWindowProc(swProc, hwnd, uMsg, wParam, lParam);
|
|
|
|
|
#else
|
|
|
|
|
return CallWindowProcW( swProc, hwnd, uMsg, wParam, lParam);
|
|
|
|
|
#endif
|
2005-05-18 22:59:11 +02:00
|
|
|
}
|
|
|
|
|
|
2017-02-10 20:45:10 +01:00
|
|
|
|
2009-10-18 12:32:11 +02:00
|
|
|
/* Procedure for text window */
|
2017-02-10 21:44:23 +01:00
|
|
|
static LRESULT CALLBACK
|
|
|
|
|
TextWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
2005-05-18 22:59:11 +02:00
|
|
|
{
|
2009-10-18 12:32:11 +02:00
|
|
|
unsigned char c;
|
|
|
|
|
UINT i;
|
|
|
|
|
|
|
|
|
|
switch (uMsg) {
|
|
|
|
|
|
|
|
|
|
case WM_KEYDOWN:
|
|
|
|
|
i = (UINT) wParam;
|
|
|
|
|
if ((i == VK_UP) || (i == VK_DOWN) || (i == VK_ESCAPE)) {
|
2012-04-23 22:55:43 +02:00
|
|
|
/* redirect input into string window */
|
2017-02-10 20:45:10 +01:00
|
|
|
SetFocus(swString);
|
|
|
|
|
return SendMessage(swString, uMsg, wParam, lParam);
|
2009-10-18 12:32:11 +02:00
|
|
|
}
|
|
|
|
|
goto DEFAULT_TEXT;
|
|
|
|
|
|
|
|
|
|
case WM_CHAR:
|
|
|
|
|
c = (unsigned char) wParam;
|
2017-02-10 20:45:10 +01:00
|
|
|
if ((c == CR) || (c >= ' ') || (c == VK_ESCAPE)) {
|
2012-04-23 22:55:43 +02:00
|
|
|
/* redirect input into string window */
|
2017-02-10 20:45:10 +01:00
|
|
|
SetFocus(swString);
|
|
|
|
|
return SendMessage(swString, uMsg, wParam, lParam);
|
2009-10-18 12:32:11 +02:00
|
|
|
}
|
2012-04-23 22:55:43 +02:00
|
|
|
/* ctrl-c interrupts simulation */
|
|
|
|
|
if (c == VK_CANCEL) {
|
|
|
|
|
raise (SIGINT);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2009-10-18 12:32:11 +02:00
|
|
|
default:
|
2017-02-10 20:45:10 +01:00
|
|
|
DEFAULT_TEXT:
|
2017-10-04 13:06:19 +02:00
|
|
|
#ifdef EXT_ASC
|
2017-02-10 20:45:10 +01:00
|
|
|
return CallWindowProc(twProc, hwnd, uMsg, wParam, lParam);
|
2017-10-04 13:06:19 +02:00
|
|
|
#else
|
|
|
|
|
return CallWindowProcW( twProc, hwnd, uMsg, wParam, lParam);
|
|
|
|
|
#endif
|
2009-10-18 12:32:11 +02:00
|
|
|
}
|
2005-05-18 22:59:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2017-02-10 21:44:23 +01:00
|
|
|
static void
|
|
|
|
|
Element_OnPaint(HWND hwnd)
|
2005-05-18 22:59:11 +02:00
|
|
|
{
|
2009-10-18 12:32:11 +02:00
|
|
|
PAINTSTRUCT ps;
|
|
|
|
|
RECT r;
|
|
|
|
|
RECT s;
|
|
|
|
|
HGDIOBJ o;
|
2017-10-04 13:06:19 +02:00
|
|
|
#ifdef EXT_ASC
|
2009-10-18 12:32:11 +02:00
|
|
|
char buffer[128];
|
2017-10-04 13:06:19 +02:00
|
|
|
#else
|
|
|
|
|
wchar_t bufferW[256];
|
|
|
|
|
#endif
|
2009-10-18 12:32:11 +02:00
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
/* Prepare */
|
2017-02-10 20:45:10 +01:00
|
|
|
HDC hdc = BeginPaint(hwnd, &ps);
|
|
|
|
|
GetClientRect(hwnd, &r);
|
2009-10-18 12:32:11 +02:00
|
|
|
|
|
|
|
|
/* Draw frame */
|
2017-02-10 20:45:10 +01:00
|
|
|
o = GetStockObject(GRAY_BRUSH);
|
2009-10-18 12:32:11 +02:00
|
|
|
s.left = r.left;
|
|
|
|
|
s.right = r.right;
|
|
|
|
|
s.top = r.top;
|
2017-02-10 20:45:10 +01:00
|
|
|
s.bottom = r.top + 1;
|
|
|
|
|
FillRect(hdc, &s, o);
|
2009-10-18 12:32:11 +02:00
|
|
|
|
2017-02-10 20:45:10 +01:00
|
|
|
s.right = r.left + 1;
|
2009-10-18 12:32:11 +02:00
|
|
|
s.bottom = r.bottom;
|
2017-02-10 20:45:10 +01:00
|
|
|
FillRect(hdc, &s, o);
|
2009-10-18 12:32:11 +02:00
|
|
|
|
2017-02-10 20:45:10 +01:00
|
|
|
o = GetStockObject(WHITE_BRUSH);
|
2009-10-18 12:32:11 +02:00
|
|
|
s.right = r.right;
|
2017-02-10 20:45:10 +01:00
|
|
|
s.top = r.bottom - 1;
|
|
|
|
|
FillRect(hdc, &s, o);
|
2009-10-18 12:32:11 +02:00
|
|
|
|
2017-02-10 20:45:10 +01:00
|
|
|
s.left = r.right - 1;
|
2009-10-18 12:32:11 +02:00
|
|
|
s.top = r.top;
|
2017-02-10 20:45:10 +01:00
|
|
|
FillRect(hdc, &s, o);
|
2009-10-18 12:32:11 +02:00
|
|
|
|
|
|
|
|
/* Draw contents */
|
2017-10-04 13:06:19 +02:00
|
|
|
#ifdef EXT_ASC
|
2009-10-18 12:32:11 +02:00
|
|
|
buffer[0] = '\0';
|
2017-02-10 20:45:10 +01:00
|
|
|
i = GetWindowText(hwnd, buffer, 127);
|
|
|
|
|
s.left = r.left + 1;
|
|
|
|
|
s.right = r.right - 1;
|
|
|
|
|
s.top = r.top + 1;
|
|
|
|
|
s.bottom = r.bottom - 1;
|
|
|
|
|
o = GetStockObject(LTGRAY_BRUSH);
|
|
|
|
|
FillRect(hdc, &s, o);
|
|
|
|
|
SetBkMode(hdc, TRANSPARENT);
|
|
|
|
|
ExtTextOut(hdc, s.left + 1, s.top + 1, ETO_CLIPPED, &s, buffer, (unsigned)i, NULL);
|
2017-10-04 13:06:19 +02:00
|
|
|
#else
|
|
|
|
|
bufferW[0] = '\0';
|
|
|
|
|
i = GetWindowTextW(hwnd, bufferW, 255);
|
|
|
|
|
s.left = r.left + 1;
|
|
|
|
|
s.right = r.right - 1;
|
|
|
|
|
s.top = r.top + 1;
|
|
|
|
|
s.bottom = r.bottom - 1;
|
|
|
|
|
o = GetSysColorBrush(COLOR_BTNFACE);
|
|
|
|
|
FillRect(hdc, &s, o);
|
|
|
|
|
SetBkMode(hdc, TRANSPARENT);
|
|
|
|
|
SelectObject(hdc, sfont);
|
|
|
|
|
ExtTextOutW(hdc, s.left + 1, s.top + 1, ETO_CLIPPED, &s, bufferW, (unsigned)i, NULL);
|
|
|
|
|
#endif
|
2009-10-18 12:32:11 +02:00
|
|
|
/* End */
|
2017-02-10 20:45:10 +01:00
|
|
|
EndPaint(hwnd, &ps);
|
2005-05-18 22:59:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2009-10-18 12:32:11 +02:00
|
|
|
/* Procedure for element window */
|
2017-02-10 21:44:23 +01:00
|
|
|
static LRESULT CALLBACK
|
|
|
|
|
ElementWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
2005-05-18 22:59:11 +02:00
|
|
|
{
|
2009-10-18 12:32:11 +02:00
|
|
|
switch (uMsg) {
|
2005-05-18 22:59:11 +02:00
|
|
|
|
2009-10-18 12:32:11 +02:00
|
|
|
case WM_PAINT:
|
|
|
|
|
HANDLE_WM_PAINT(hwnd, wParam, lParam, Element_OnPaint);
|
|
|
|
|
return 0;
|
2005-05-18 22:59:11 +02:00
|
|
|
|
2009-10-18 12:32:11 +02:00
|
|
|
default:
|
2017-10-04 13:06:19 +02:00
|
|
|
#ifdef EXT_ASC
|
2017-02-10 20:45:10 +01:00
|
|
|
return DefWindowProc(hwnd, uMsg, wParam, lParam);
|
2017-10-04 13:06:19 +02:00
|
|
|
#else
|
|
|
|
|
return DefWindowProcW( hwnd, uMsg, wParam, lParam);
|
|
|
|
|
#endif
|
2009-10-18 12:32:11 +02:00
|
|
|
}
|
2005-05-18 22:59:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2009-10-18 12:32:11 +02:00
|
|
|
#define SPACE ' '
|
|
|
|
|
#define QUOTE '\"'
|
|
|
|
|
#define DELIMITER 26 /* for the lack of anything better */
|
|
|
|
|
#define DELIMITERSTRING "\26"
|
2005-05-18 22:59:11 +02:00
|
|
|
|
|
|
|
|
/*
|
2017-02-10 20:45:10 +01:00
|
|
|
This function converts a string into an argc/argv represenation.
|
|
|
|
|
INPUT:
|
|
|
|
|
cmdline - a string
|
|
|
|
|
OUTPUT:
|
|
|
|
|
argc - the number of equivalent argv strings
|
|
|
|
|
which is also the number of strings in argv
|
|
|
|
|
argv - the argv given the input string which
|
|
|
|
|
consists of seperate strings for each argument
|
|
|
|
|
RETURNS:
|
|
|
|
|
0 on success
|
|
|
|
|
-1 on failure
|
2005-05-18 22:59:11 +02:00
|
|
|
*/
|
2017-02-10 20:45:10 +01:00
|
|
|
|
2017-02-10 21:44:23 +01:00
|
|
|
static int
|
|
|
|
|
MakeArgcArgv(char *cmdline, int *argc, char ***argv)
|
2005-05-18 22:59:11 +02:00
|
|
|
{
|
2017-02-10 20:45:10 +01:00
|
|
|
char *pC1; /* a temporary character pointer */
|
|
|
|
|
char *pWorkString = NULL; /* a working copy of cmdline */
|
|
|
|
|
int i; /* a loop counter */
|
|
|
|
|
int quoteflag = 0; /* for the finite state machine parsing cmdline */
|
|
|
|
|
bool firstspace = TRUE; /* count only the first space */
|
2017-02-10 21:44:23 +01:00
|
|
|
int numargs = 1; /* the number of command line arguments,
|
|
|
|
|
later copied to *argc */
|
2017-02-10 20:45:10 +01:00
|
|
|
char **tmpargv; /* the temporary argv, later copied to *argv */
|
2009-10-18 12:32:11 +02:00
|
|
|
int status = ERROR_SUCCESS; /* status */
|
2017-02-10 20:45:10 +01:00
|
|
|
char buffer[MAX_PATH + 1];
|
2009-10-18 12:32:11 +02:00
|
|
|
char deli[2];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* make sure we aren't dealing with any NULL pointers */
|
2017-02-10 21:44:23 +01:00
|
|
|
if ((NULL == argc) || (NULL == argv))
|
2009-10-18 12:32:11 +02:00
|
|
|
{
|
|
|
|
|
status = -1;
|
|
|
|
|
goto outahere;
|
|
|
|
|
}
|
2017-02-10 20:45:10 +01:00
|
|
|
|
2009-10-18 12:32:11 +02:00
|
|
|
*argc = 0; /* set the count to zero to start */
|
|
|
|
|
*argv = NULL; /* set the pointer to NULL to start */
|
2017-02-10 20:45:10 +01:00
|
|
|
|
2009-10-18 12:32:11 +02:00
|
|
|
/* if the string passed in was a NULL pointer, consider this
|
|
|
|
|
to be an empty command line and give back only
|
|
|
|
|
an argc of 1 and an argv[0] */
|
|
|
|
|
if (NULL != cmdline)
|
|
|
|
|
{
|
2017-02-10 20:45:10 +01:00
|
|
|
/* make a copy of the string so that we can modify it
|
2009-10-18 12:32:11 +02:00
|
|
|
without messing up the original */
|
2009-11-07 12:14:54 +01:00
|
|
|
pWorkString = copy(cmdline);
|
2009-10-18 12:32:11 +02:00
|
|
|
if (NULL == pWorkString)
|
|
|
|
|
return -1; /* memory allocation error */
|
|
|
|
|
/* Now, to make sure we don't have any quoted arguments
|
|
|
|
|
with spaces in them, replace all spaces except those
|
|
|
|
|
between " marks with our own special delimiter for
|
|
|
|
|
strtok */
|
|
|
|
|
/* trim all the whitespace off the end of the string. */
|
2017-02-10 20:45:10 +01:00
|
|
|
for (i = (signed)strlen(pWorkString) - 1; i >= 0; i--)
|
2016-03-08 21:26:16 +01:00
|
|
|
if (isspace((unsigned char) pWorkString[i]))
|
2009-10-18 12:32:11 +02:00
|
|
|
pWorkString[i] = '\0';
|
|
|
|
|
else
|
|
|
|
|
break;
|
2008-04-13 16:30:28 +02:00
|
|
|
#if defined(__CYGWIN__)
|
2009-10-18 12:32:11 +02:00
|
|
|
/* for CYGWIN: trim off the leading white space delivered by lpszCmdLine. */
|
2017-02-10 20:45:10 +01:00
|
|
|
pWorkString = rlead(pWorkString);
|
2008-04-13 16:30:28 +02:00
|
|
|
#endif
|
2009-10-18 12:32:11 +02:00
|
|
|
/* If we still have a string left, parse it for all
|
|
|
|
|
the arguments. */
|
|
|
|
|
if (strlen(pWorkString))
|
|
|
|
|
{
|
|
|
|
|
/* This could probably be done with strtok as well
|
|
|
|
|
but strtok is destructive if I wanted to look for " \""
|
|
|
|
|
and I couldn't tell what delimiter that I had bumped
|
|
|
|
|
against */
|
2017-02-10 20:45:10 +01:00
|
|
|
for (i = 0; i < (signed)strlen(pWorkString); i++)
|
2009-10-18 12:32:11 +02:00
|
|
|
switch (pWorkString[i])
|
|
|
|
|
{
|
|
|
|
|
case SPACE:
|
2017-02-10 21:44:23 +01:00
|
|
|
if (!quoteflag) {
|
2009-10-18 12:32:11 +02:00
|
|
|
pWorkString[i] = DELIMITER; /* change space to delimiter */
|
2017-02-10 21:44:23 +01:00
|
|
|
if (firstspace) /* count only the first space */
|
|
|
|
|
numargs++;
|
2009-10-18 12:32:11 +02:00
|
|
|
firstspace = FALSE;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case QUOTE:
|
|
|
|
|
quoteflag = !quoteflag; /* turns on and off as we pass quotes */
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
firstspace = TRUE;
|
|
|
|
|
break;
|
|
|
|
|
}
|
2017-02-10 20:45:10 +01:00
|
|
|
|
2009-10-18 12:32:11 +02:00
|
|
|
/* Now, we should have ctrl-Zs everywhere that
|
|
|
|
|
there used to be a space not protected by
|
|
|
|
|
quote marks. We should also have the number
|
|
|
|
|
of command line arguments that were in the
|
|
|
|
|
command line (not including argv[0] which should
|
|
|
|
|
be the program name). We should add one more
|
|
|
|
|
to numargs to take into account argv[0]. */
|
|
|
|
|
numargs++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
/* malloc an argv */
|
2017-02-10 20:45:10 +01:00
|
|
|
tmpargv = (char**) malloc((unsigned)numargs * sizeof(char *));
|
2009-10-18 12:32:11 +02:00
|
|
|
if (NULL == tmpargv)
|
|
|
|
|
{
|
|
|
|
|
status = -1;
|
|
|
|
|
goto outahere;
|
|
|
|
|
}
|
|
|
|
|
/* API to give the program name */
|
|
|
|
|
GetModuleFileName(NULL, buffer, sizeof(buffer));
|
|
|
|
|
|
2009-10-31 12:11:13 +01:00
|
|
|
tmpargv[0] = copy(buffer); /* add program name to argv */
|
2005-05-18 22:59:11 +02:00
|
|
|
|
2008-04-13 16:30:28 +02:00
|
|
|
deli[0] = DELIMITER;
|
2009-10-18 12:32:11 +02:00
|
|
|
deli[1] = '\0'; /* delimiter for strtok */
|
2017-02-10 20:45:10 +01:00
|
|
|
|
2009-10-18 12:32:11 +02:00
|
|
|
pC1 = NULL;
|
|
|
|
|
/* Now actually strdup all the arguments out of the string
|
|
|
|
|
and store them in the argv */
|
2017-02-10 21:44:23 +01:00
|
|
|
for (i = 1; i < numargs; i++) {
|
2009-10-18 12:32:11 +02:00
|
|
|
if (NULL == pC1)
|
|
|
|
|
pC1 = pWorkString;
|
|
|
|
|
|
2017-02-10 21:44:23 +01:00
|
|
|
if (i == 1)
|
|
|
|
|
tmpargv[i] = copy(strtok(pC1, deli));
|
|
|
|
|
else
|
|
|
|
|
tmpargv[i] = copy(strtok(NULL, deli));
|
2009-10-18 12:32:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* copy the working values over to the arguments */
|
|
|
|
|
*argc = numargs;
|
|
|
|
|
*argv = tmpargv;
|
2017-02-10 20:45:10 +01:00
|
|
|
|
|
|
|
|
outahere:
|
2009-10-18 12:32:11 +02:00
|
|
|
/* free the working string if one was allocated */
|
|
|
|
|
if (pWorkString)
|
|
|
|
|
free(pWorkString);
|
2017-02-10 20:45:10 +01:00
|
|
|
|
2009-10-18 12:32:11 +02:00
|
|
|
return status;
|
2005-05-18 22:59:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2005-05-24 11:44:22 +02:00
|
|
|
/* Main entry point for our Windows application */
|
2017-10-04 13:06:19 +02:00
|
|
|
#ifdef EXT_ASC
|
|
|
|
|
int WINAPI
|
|
|
|
|
WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpszCmdLine, _In_ int nCmdShow)
|
|
|
|
|
#elif __MINGW32__ /* MINGW bug not knowing wWinMain */
|
|
|
|
|
int WINAPI
|
|
|
|
|
WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR nolpszCmdLine, _In_ int nCmdShow)
|
|
|
|
|
#else
|
2017-02-10 21:44:23 +01:00
|
|
|
int WINAPI
|
2017-10-04 13:06:19 +02:00
|
|
|
wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR wlpszCmdLine, _In_ int nCmdShow)
|
|
|
|
|
#endif
|
2005-05-18 22:59:11 +02:00
|
|
|
{
|
2009-10-18 12:32:11 +02:00
|
|
|
int ix, iy; /* width and height of screen */
|
|
|
|
|
int status;
|
2017-02-10 20:45:10 +01:00
|
|
|
|
2009-10-18 12:32:11 +02:00
|
|
|
int argc;
|
|
|
|
|
char **argv;
|
|
|
|
|
|
2019-06-01 18:15:43 +02:00
|
|
|
/* Initialize history info to a maximum of HIST_SIZE commands.
|
|
|
|
|
* The initial buffer for storage is N_BYTE_HIST_BUF bytes. */
|
|
|
|
|
struct History_info *p_hi = init_history();
|
|
|
|
|
if (p_hi == (struct History_info *) NULL) {
|
|
|
|
|
goto THE_END;
|
|
|
|
|
}
|
|
|
|
|
|
2017-02-10 20:45:10 +01:00
|
|
|
RECT wsize; /* size of usable window */
|
2010-01-02 19:05:07 +01:00
|
|
|
|
2011-05-21 14:44:27 +02:00
|
|
|
NG_IGNORE(hPrevInstance);
|
|
|
|
|
|
2017-10-04 13:06:19 +02:00
|
|
|
#ifndef EXT_ASC
|
|
|
|
|
/* convert wchar to utf-8 */
|
|
|
|
|
|
|
|
|
|
/* MINGW not knowing wWinMain
|
|
|
|
|
https://github.com/coderforlife/mingw-unicode-main/blob/master/mingw-unicode-gui.c
|
|
|
|
|
*/
|
|
|
|
|
#ifdef __MINGW32__
|
|
|
|
|
NG_IGNORE(nolpszCmdLine);
|
|
|
|
|
char lpszCmdLine[1024];
|
|
|
|
|
wchar_t *lpCmdLine = GetCommandLineW();
|
|
|
|
|
if (__argc == 1) { // avoids GetCommandLineW bug that does not always quote the program name if no arguments
|
|
|
|
|
do { ++lpCmdLine; } while (*lpCmdLine);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
BOOL quoted = lpCmdLine[0] == L'"';
|
|
|
|
|
++lpCmdLine; // skips the " or the first letter (all paths are at least 1 letter)
|
|
|
|
|
while (*lpCmdLine) {
|
|
|
|
|
if (quoted && lpCmdLine[0] == L'"') { quoted = FALSE; } // found end quote
|
|
|
|
|
else if (!quoted && lpCmdLine[0] == L' ') {
|
|
|
|
|
// found an unquoted space, now skip all spaces
|
|
|
|
|
do { ++lpCmdLine; } while (lpCmdLine[0] == L' ');
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
++lpCmdLine;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
WideCharToMultiByte(CP_UTF8, 0, lpCmdLine, -1, lpszCmdLine, 1023, NULL, NULL);
|
|
|
|
|
#else
|
|
|
|
|
char lpszCmdLine[1024];
|
|
|
|
|
WideCharToMultiByte(CP_UTF8, 0, wlpszCmdLine, -1, lpszCmdLine, 1023, NULL, NULL);
|
|
|
|
|
#endif
|
|
|
|
|
#endif
|
2009-10-18 12:32:11 +02:00
|
|
|
/* fill global variables */
|
|
|
|
|
hInst = hInstance;
|
|
|
|
|
nShowState = nCmdShow;
|
|
|
|
|
|
|
|
|
|
/* Initialize text buffer */
|
|
|
|
|
TBufEnd = 0;
|
|
|
|
|
TBuffer[TBufEnd] = SE;
|
|
|
|
|
SBuffer[0] = SE;
|
|
|
|
|
|
|
|
|
|
/* Define main window class */
|
2017-10-04 13:06:19 +02:00
|
|
|
#ifdef EXT_ASC
|
2009-10-18 12:32:11 +02:00
|
|
|
hwMainClass.style = CS_HREDRAW | CS_VREDRAW;
|
|
|
|
|
hwMainClass.lpfnWndProc = MainWindowProc;
|
|
|
|
|
hwMainClass.cbClsExtra = 0;
|
|
|
|
|
hwMainClass.cbWndExtra = 0;
|
|
|
|
|
hwMainClass.hInstance = hInst;
|
2018-12-01 00:02:37 +01:00
|
|
|
hwMainClass.hIcon = LoadIcon(hInst, MAKEINTRESOURCE(101));
|
2017-02-10 20:45:10 +01:00
|
|
|
hwMainClass.hCursor = LoadCursor(NULL, IDC_ARROW);
|
|
|
|
|
hwMainClass.hbrBackground = GetStockObject(LTGRAY_BRUSH);
|
2009-10-18 12:32:11 +02:00
|
|
|
hwMainClass.lpszMenuName = NULL;
|
|
|
|
|
hwMainClass.lpszClassName = hwClassName;
|
2017-02-10 20:45:10 +01:00
|
|
|
|
2017-02-10 21:44:23 +01:00
|
|
|
if (!RegisterClass(&hwMainClass))
|
|
|
|
|
goto THE_END;
|
2017-10-04 13:06:19 +02:00
|
|
|
#else
|
|
|
|
|
hwMainClassW.style = CS_HREDRAW | CS_VREDRAW;
|
|
|
|
|
hwMainClassW.lpfnWndProc = MainWindowProc;
|
|
|
|
|
hwMainClassW.cbClsExtra = 0;
|
|
|
|
|
hwMainClassW.cbWndExtra = 0;
|
|
|
|
|
hwMainClassW.hInstance = hInst;
|
|
|
|
|
hwMainClassW.hIcon = LoadIconW(hInst, MAKEINTRESOURCEW(1));
|
|
|
|
|
hwMainClassW.hCursor = LoadCursorW(NULL, MAKEINTRESOURCEW(32512));
|
|
|
|
|
hwMainClassW.hbrBackground = GetStockObject(LTGRAY_BRUSH);
|
|
|
|
|
hwMainClassW.lpszMenuName = NULL;
|
|
|
|
|
hwMainClassW.lpszClassName = hwClassNameW;
|
|
|
|
|
if (!RegisterClassW(&hwMainClassW))
|
|
|
|
|
goto THE_END;
|
|
|
|
|
#endif
|
2009-10-18 12:32:11 +02:00
|
|
|
|
|
|
|
|
/* Define text window class */
|
2017-10-04 13:06:19 +02:00
|
|
|
#ifdef EXT_ASC
|
2017-02-10 21:44:23 +01:00
|
|
|
if (!GetClassInfo(NULL, "EDIT", &twTextClass))
|
|
|
|
|
goto THE_END;
|
2017-02-10 20:45:10 +01:00
|
|
|
|
2009-10-18 12:32:11 +02:00
|
|
|
twProc = twTextClass.lpfnWndProc;
|
|
|
|
|
twTextClass.lpfnWndProc = TextWindowProc;
|
|
|
|
|
twTextClass.hInstance = hInst;
|
|
|
|
|
twTextClass.lpszMenuName = NULL;
|
|
|
|
|
twTextClass.lpszClassName = twClassName;
|
2017-02-10 20:45:10 +01:00
|
|
|
|
2017-02-10 21:44:23 +01:00
|
|
|
if (!RegisterClass(&twTextClass))
|
|
|
|
|
goto THE_END;
|
2017-10-04 13:06:19 +02:00
|
|
|
#else
|
|
|
|
|
if (!GetClassInfoW(NULL, L"EDIT", &twTextClassW)) goto THE_END;
|
|
|
|
|
twProc = twTextClassW.lpfnWndProc;
|
|
|
|
|
twTextClassW.lpfnWndProc = TextWindowProc;
|
|
|
|
|
twTextClassW.hInstance = hInst;
|
|
|
|
|
twTextClassW.lpszMenuName = NULL;
|
|
|
|
|
twTextClassW.lpszClassName = twClassNameW;
|
|
|
|
|
if (!RegisterClassW(&twTextClassW))
|
|
|
|
|
goto THE_END;
|
|
|
|
|
#endif
|
2009-10-18 12:32:11 +02:00
|
|
|
|
|
|
|
|
/* Define string window class */
|
2017-10-04 13:06:19 +02:00
|
|
|
#ifdef EXT_ASC
|
2017-02-10 21:44:23 +01:00
|
|
|
if (!GetClassInfo(NULL, "EDIT", &swStringClass))
|
|
|
|
|
goto THE_END;
|
2017-02-10 20:45:10 +01:00
|
|
|
|
2009-10-18 12:32:11 +02:00
|
|
|
swProc = swStringClass.lpfnWndProc;
|
|
|
|
|
swStringClass.lpfnWndProc = StringWindowProc;
|
|
|
|
|
swStringClass.hInstance = hInst;
|
|
|
|
|
swStringClass.lpszMenuName = NULL;
|
|
|
|
|
swStringClass.lpszClassName = swClassName;
|
2017-02-10 20:45:10 +01:00
|
|
|
|
2017-02-10 21:44:23 +01:00
|
|
|
if (!RegisterClass(&swStringClass))
|
|
|
|
|
goto THE_END;
|
2017-10-04 13:06:19 +02:00
|
|
|
#else
|
|
|
|
|
if (!GetClassInfoW(NULL, L"EDIT", &swStringClassW)) goto THE_END;
|
|
|
|
|
swProc = swStringClassW.lpfnWndProc;
|
|
|
|
|
swStringClassW.lpfnWndProc = StringWindowProc;
|
|
|
|
|
swStringClassW.hInstance = hInst;
|
|
|
|
|
swStringClassW.lpszMenuName = NULL;
|
|
|
|
|
swStringClassW.lpszClassName = swClassNameW;
|
|
|
|
|
if (!RegisterClassW(&swStringClassW))
|
|
|
|
|
goto THE_END;
|
|
|
|
|
#endif
|
2009-10-18 12:32:11 +02:00
|
|
|
|
|
|
|
|
/* Define status element class */
|
2017-10-04 13:06:19 +02:00
|
|
|
#ifdef EXT_ASC
|
2009-10-18 12:32:11 +02:00
|
|
|
hwElementClass.style = CS_HREDRAW | CS_VREDRAW;
|
|
|
|
|
hwElementClass.lpfnWndProc = ElementWindowProc;
|
|
|
|
|
hwElementClass.cbClsExtra = 0;
|
|
|
|
|
hwElementClass.cbWndExtra = 0;
|
|
|
|
|
hwElementClass.hInstance = hInst;
|
|
|
|
|
hwElementClass.hIcon = NULL;
|
2017-02-10 20:45:10 +01:00
|
|
|
hwElementClass.hCursor = LoadCursor(NULL, IDC_ARROW);
|
|
|
|
|
hwElementClass.hbrBackground = GetStockObject(LTGRAY_BRUSH);
|
2009-10-18 12:32:11 +02:00
|
|
|
hwElementClass.lpszMenuName = NULL;
|
|
|
|
|
hwElementClass.lpszClassName = hwElementClassName;
|
2017-02-10 20:45:10 +01:00
|
|
|
|
2017-02-10 21:44:23 +01:00
|
|
|
if (!RegisterClass(&hwElementClass))
|
|
|
|
|
goto THE_END;
|
2017-10-04 13:06:19 +02:00
|
|
|
#else
|
|
|
|
|
hwElementClassW.style = CS_HREDRAW | CS_VREDRAW;
|
|
|
|
|
hwElementClassW.lpfnWndProc = ElementWindowProc;
|
|
|
|
|
hwElementClassW.cbClsExtra = 0;
|
|
|
|
|
hwElementClassW.cbWndExtra = 0;
|
|
|
|
|
hwElementClassW.hInstance = hInst;
|
|
|
|
|
hwElementClassW.hIcon = NULL;
|
|
|
|
|
hwElementClassW.hCursor = LoadCursorW(NULL, MAKEINTRESOURCEW(32512));
|
|
|
|
|
hwElementClassW.hbrBackground = GetStockObject(LTGRAY_BRUSH);
|
|
|
|
|
hwElementClassW.lpszMenuName = NULL;
|
|
|
|
|
hwElementClassW.lpszClassName = hwElementClassNameW;
|
|
|
|
|
if (!RegisterClassW(&hwElementClassW))
|
|
|
|
|
goto THE_END;
|
|
|
|
|
#endif
|
2009-10-18 12:32:11 +02:00
|
|
|
|
2017-10-04 13:06:19 +02:00
|
|
|
/* Font for element status windows (source, analysis) */
|
|
|
|
|
sfont = CreateFontW(16, 0, 0, 0, FW_SEMIBOLD, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY, VARIABLE_PITCH, L"");
|
|
|
|
|
// sfont = CreateFontW(15, 0, 0, 0, FW_SEMIBOLD, FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, NONANTIALIASED_QUALITY, FIXED_PITCH | FF_MODERN, L"Courier"); /*Create main window */
|
|
|
|
|
#ifdef EXT_ASC
|
2019-06-01 18:15:43 +02:00
|
|
|
SystemParametersInfo(SPI_GETWORKAREA, 0, &wsize, 0);
|
2017-10-04 13:06:19 +02:00
|
|
|
#else
|
|
|
|
|
SystemParametersInfoW(SPI_GETWORKAREA, 0, &wsize, 0);
|
|
|
|
|
#endif
|
2019-06-01 18:15:43 +02:00
|
|
|
iy = wsize.bottom;
|
|
|
|
|
ix = wsize.right;
|
|
|
|
|
#ifndef BIG_WINDOW_FOR_DEBUGGING
|
|
|
|
|
const int iyt = iy / 3; /* height of screen divided by 3 */
|
2017-10-04 13:06:19 +02:00
|
|
|
#ifdef EXT_ASC
|
2017-02-10 20:45:10 +01:00
|
|
|
hwMain = CreateWindow(hwClassName, hwWindowName, WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
|
2019-06-01 18:15:43 +02:00
|
|
|
#else
|
2017-10-04 13:06:19 +02:00
|
|
|
hwMain = CreateWindowW(hwClassNameW, hwWindowNameW, WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
|
|
|
|
|
0, iyt * 2, ix, iyt, NULL, NULL, hInst, NULL);
|
|
|
|
|
#endif
|
|
|
|
|
#else
|
|
|
|
|
#ifdef EXT_ASC
|
2019-06-01 18:15:43 +02:00
|
|
|
hwMain = CreateWindow(hwClassName, hwWindowName, WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
|
|
|
|
|
0, 0, ix, iy, NULL, NULL, hInst, NULL);
|
2017-10-04 13:06:19 +02:00
|
|
|
#else
|
|
|
|
|
hwMain = CreateWindowW(hwClassName, hwWindowName, WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
|
|
|
|
|
0, 0, ix, iy, NULL, NULL, hInst, NULL);
|
|
|
|
|
#endif
|
2019-06-01 18:15:43 +02:00
|
|
|
#endif
|
|
|
|
|
|
2017-02-10 21:44:23 +01:00
|
|
|
if (!hwMain)
|
|
|
|
|
goto THE_END;
|
2009-10-18 12:32:11 +02:00
|
|
|
|
|
|
|
|
/* Create text window */
|
2017-10-04 13:06:19 +02:00
|
|
|
#ifdef EXT_ASC
|
2009-10-18 12:32:11 +02:00
|
|
|
twText = CreateWindowEx(WS_EX_NOPARENTNOTIFY, twClassName, twWindowName,
|
2017-02-10 20:45:10 +01:00
|
|
|
ES_LEFT | ES_MULTILINE | ES_READONLY | WS_CHILD | WS_BORDER | WS_VSCROLL,
|
|
|
|
|
20, 20, 300, 100, hwMain, NULL, hInst, NULL);
|
2017-10-04 13:06:19 +02:00
|
|
|
#else
|
|
|
|
|
twText = CreateWindowExW(WS_EX_NOPARENTNOTIFY, twClassNameW, twWindowNameW,
|
|
|
|
|
ES_LEFT | ES_MULTILINE | ES_READONLY | WS_CHILD | WS_BORDER | WS_VSCROLL,
|
|
|
|
|
20,20,300,100, hwMain, NULL, hInst, NULL);
|
|
|
|
|
#endif
|
2017-02-10 21:44:23 +01:00
|
|
|
if (!twText)
|
|
|
|
|
goto THE_END;
|
2017-02-10 20:45:10 +01:00
|
|
|
|
2009-10-18 12:32:11 +02:00
|
|
|
/* Ansii fixed font */
|
2017-10-04 13:06:19 +02:00
|
|
|
#ifdef EXT_ASC
|
2009-10-18 12:32:11 +02:00
|
|
|
{
|
|
|
|
|
HDC textDC;
|
|
|
|
|
HFONT font;
|
|
|
|
|
TEXTMETRIC tm;
|
2017-02-10 20:45:10 +01:00
|
|
|
font = GetStockFont(ANSI_FIXED_FONT);
|
|
|
|
|
SetWindowFont(twText, font, FALSE);
|
|
|
|
|
textDC = GetDC(twText);
|
2009-10-18 12:32:11 +02:00
|
|
|
if (textDC) {
|
2017-02-10 20:45:10 +01:00
|
|
|
SelectObject(textDC, font);
|
|
|
|
|
if (GetTextMetrics(textDC, &tm)) {
|
2009-10-18 12:32:11 +02:00
|
|
|
RowHeight = tm.tmHeight;
|
|
|
|
|
WinLineWidth = 90 * tm.tmAveCharWidth;
|
|
|
|
|
}
|
2017-02-10 20:45:10 +01:00
|
|
|
ReleaseDC(twText, textDC);
|
2009-10-18 12:32:11 +02:00
|
|
|
}
|
|
|
|
|
}
|
2017-10-04 13:06:19 +02:00
|
|
|
#else
|
|
|
|
|
{
|
|
|
|
|
HDC textDC;
|
|
|
|
|
HFONT font;
|
|
|
|
|
TEXTMETRICW tm;
|
|
|
|
|
// font = CreateFontW(14, 0, 0, 0, FW_MEDIUM, FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, NONANTIALIASED_QUALITY, FIXED_PITCH | FF_MODERN, L"Lucida Console");
|
|
|
|
|
// if(!font)
|
|
|
|
|
font = CreateFontW(15, 0, 0, 0, FW_MEDIUM, FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, NONANTIALIASED_QUALITY, FIXED_PITCH | FF_MODERN, L"Courier");
|
|
|
|
|
if(!font)
|
|
|
|
|
font = GetStockFont(ANSI_FIXED_FONT);
|
|
|
|
|
SetWindowFont( twText, font, FALSE);
|
|
|
|
|
textDC = GetDC( twText);
|
|
|
|
|
if (textDC) {
|
|
|
|
|
SelectObject( textDC, font);
|
|
|
|
|
if (GetTextMetricsW( textDC, &tm)) {
|
|
|
|
|
RowHeight = tm.tmHeight;
|
|
|
|
|
WinLineWidth = 90 * tm.tmAveCharWidth;
|
|
|
|
|
}
|
|
|
|
|
ReleaseDC( twText, textDC);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endif
|
2009-10-18 12:32:11 +02:00
|
|
|
|
2019-06-01 18:15:43 +02:00
|
|
|
/* Create string window for input. Give a handle to history info to
|
|
|
|
|
* the window for saving and retrieving commands */
|
2017-10-04 13:06:19 +02:00
|
|
|
#ifdef EXT_ASC
|
2009-10-18 12:32:11 +02:00
|
|
|
swString = CreateWindowEx(WS_EX_NOPARENTNOTIFY, swClassName, swWindowName,
|
2019-05-26 19:10:29 +02:00
|
|
|
ES_LEFT | WS_CHILD | WS_BORDER |
|
|
|
|
|
ES_AUTOHSCROLL, /* Allow text to scroll */
|
2019-06-01 18:15:43 +02:00
|
|
|
20, 20, 300, 100, hwMain, NULL, hInst, &p_hi);
|
|
|
|
|
if (!swString) {
|
2017-02-10 21:44:23 +01:00
|
|
|
goto THE_END;
|
2019-06-01 18:15:43 +02:00
|
|
|
}
|
2017-02-10 20:45:10 +01:00
|
|
|
|
2009-10-18 12:32:11 +02:00
|
|
|
{
|
|
|
|
|
HDC stringDC;
|
|
|
|
|
TEXTMETRIC tm;
|
2017-02-10 20:45:10 +01:00
|
|
|
stringDC = GetDC(swString);
|
2009-10-18 12:32:11 +02:00
|
|
|
if (stringDC) {
|
2017-02-10 20:45:10 +01:00
|
|
|
if (GetTextMetrics(stringDC, &tm))
|
2009-10-18 12:32:11 +02:00
|
|
|
LineHeight = tm.tmHeight + tm.tmExternalLeading + BorderSize;
|
2017-02-10 20:45:10 +01:00
|
|
|
ReleaseDC(swString, stringDC);
|
2009-10-18 12:32:11 +02:00
|
|
|
}
|
2017-10-04 13:06:19 +02:00
|
|
|
}
|
|
|
|
|
#else
|
|
|
|
|
swString = CreateWindowExW(WS_EX_NOPARENTNOTIFY, swClassNameW, swWindowNameW,
|
2019-12-21 23:55:58 +01:00
|
|
|
ES_LEFT | WS_CHILD | WS_BORDER |
|
|
|
|
|
ES_AUTOHSCROLL, /* Allow text to scroll */
|
|
|
|
|
20, 20, 300, 100, hwMain, NULL, hInst, &p_hi);
|
2017-10-04 13:06:19 +02:00
|
|
|
if (!swString)
|
|
|
|
|
goto THE_END;
|
|
|
|
|
{
|
|
|
|
|
HDC stringDC;
|
2019-12-07 20:38:26 +01:00
|
|
|
TEXTMETRICW tm;
|
2017-10-04 13:06:19 +02:00
|
|
|
stringDC = GetDC(swString);
|
|
|
|
|
if (stringDC) {
|
|
|
|
|
if (GetTextMetricsW(stringDC, &tm))
|
|
|
|
|
LineHeight = tm.tmHeight + tm.tmExternalLeading + BorderSize;
|
|
|
|
|
ReleaseDC(swString, stringDC);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2009-10-18 12:32:11 +02:00
|
|
|
|
|
|
|
|
/* Create source window */
|
2017-10-04 13:06:19 +02:00
|
|
|
#ifdef EXT_ASC
|
2017-02-10 21:44:23 +01:00
|
|
|
hwSource = CreateWindowEx(WS_EX_NOPARENTNOTIFY, hwElementClassName, hwSourceWindowName,
|
|
|
|
|
WS_CHILD,
|
|
|
|
|
0, 0, SourceLength, StatusElHeight, hwMain, NULL, hInst, NULL);
|
|
|
|
|
if (!hwSource)
|
|
|
|
|
goto THE_END;
|
2017-10-04 13:06:19 +02:00
|
|
|
#else
|
|
|
|
|
hwSource = CreateWindowExW(WS_EX_NOPARENTNOTIFY, hwElementClassNameW, hwSourceWindowNameW,
|
|
|
|
|
WS_CHILD,
|
|
|
|
|
0, 0, SourceLength, StatusElHeight, hwMain, NULL, hInst, NULL);
|
|
|
|
|
if (!hwSource) goto THE_END;
|
|
|
|
|
#endif
|
2009-10-18 12:32:11 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Create analysis window */
|
2017-10-04 13:06:19 +02:00
|
|
|
#ifdef EXT_ASC
|
2017-02-10 21:44:23 +01:00
|
|
|
hwAnalyse = CreateWindowEx(WS_EX_NOPARENTNOTIFY, hwElementClassName, hwAnalyseWindowName,
|
|
|
|
|
WS_CHILD,
|
|
|
|
|
0, 0, AnalyseLength, StatusElHeight, hwMain, NULL, hInst, NULL);
|
2017-10-04 13:06:19 +02:00
|
|
|
#else
|
|
|
|
|
hwAnalyse = CreateWindowExW(WS_EX_NOPARENTNOTIFY, hwElementClassNameW, hwAnalyseWindowNameW,
|
|
|
|
|
WS_CHILD,
|
|
|
|
|
0,0, AnalyseLength, StatusElHeight, hwMain, NULL, hInst, NULL);
|
|
|
|
|
#endif
|
2017-02-10 21:44:23 +01:00
|
|
|
if (!hwAnalyse)
|
|
|
|
|
goto THE_END;
|
2009-10-18 12:32:11 +02:00
|
|
|
|
|
|
|
|
/* Create "Quit" button */
|
2017-10-04 13:06:19 +02:00
|
|
|
#ifdef EXT_ASC
|
2017-02-10 21:44:23 +01:00
|
|
|
hwQuitButton = CreateWindow("BUTTON", "Quit", WS_CHILD | BS_PUSHBUTTON, 0, 0, QuitButtonLength,
|
2017-02-10 20:45:10 +01:00
|
|
|
StatusElHeight, hwMain, (HMENU)(UINT_PTR)QUIT_BUTTON_ID, hInst, NULL);
|
2017-10-04 13:06:19 +02:00
|
|
|
#else
|
|
|
|
|
hwQuitButton = CreateWindowW(L"BUTTON", L"Quit", WS_CHILD | BS_PUSHBUTTON, 0, 0, QuitButtonLength,
|
|
|
|
|
StatusElHeight, hwMain, (HMENU)(UINT_PTR)QUIT_BUTTON_ID, hInst, NULL);
|
|
|
|
|
#endif
|
2017-02-10 20:45:10 +01:00
|
|
|
|
2017-02-10 21:44:23 +01:00
|
|
|
if (!hwQuitButton)
|
|
|
|
|
goto THE_END;
|
2017-10-04 13:06:19 +02:00
|
|
|
/* Define a minimum width */
|
|
|
|
|
int MinWidth = AnalyseLength + SourceLength + QuitButtonLength + 48;
|
|
|
|
|
if (WinLineWidth < MinWidth)
|
|
|
|
|
WinLineWidth = MinWidth;
|
2009-10-18 12:32:11 +02:00
|
|
|
|
|
|
|
|
/* Make main window and subwindows visible.
|
2017-02-10 20:45:10 +01:00
|
|
|
Size of windows allows display of 80 character line.
|
|
|
|
|
Limit window to screen size (if only VGA). */
|
|
|
|
|
if (WinLineWidth > ix)
|
|
|
|
|
WinLineWidth = ix;
|
2019-06-01 18:15:43 +02:00
|
|
|
#ifndef BIG_WINDOW_FOR_DEBUGGING
|
2017-02-10 20:45:10 +01:00
|
|
|
MoveWindow(hwMain, 0, (iyt * 2), WinLineWidth, iyt, FALSE);
|
2019-06-01 18:15:43 +02:00
|
|
|
#endif
|
2017-02-10 20:45:10 +01:00
|
|
|
ShowWindow(hwMain, nShowState);
|
|
|
|
|
ShowWindow(twText, SW_SHOWNORMAL);
|
|
|
|
|
ShowWindow(swString, SW_SHOWNORMAL);
|
|
|
|
|
ShowWindow(hwSource, SW_SHOWNORMAL);
|
|
|
|
|
ShowWindow(hwAnalyse, SW_SHOWNORMAL);
|
|
|
|
|
ShowWindow(hwQuitButton, SW_SHOWNORMAL);
|
2009-10-18 12:32:11 +02:00
|
|
|
ClearInput();
|
|
|
|
|
DisplayText();
|
2017-02-10 20:45:10 +01:00
|
|
|
SetSource("");
|
2009-10-18 12:32:11 +02:00
|
|
|
SetAnalyse("Start", 0);
|
2017-02-10 20:45:10 +01:00
|
|
|
UpdateWindow(hwMain);
|
|
|
|
|
SetFocus(swString);
|
2005-05-18 22:59:11 +02:00
|
|
|
|
2017-02-10 20:45:10 +01:00
|
|
|
status = MakeArgcArgv(lpszCmdLine, &argc, &argv);
|
2005-05-18 22:59:11 +02:00
|
|
|
|
2009-10-18 12:32:11 +02:00
|
|
|
/* Wait until everything is settled */
|
|
|
|
|
WaitForIdle();
|
2005-05-18 22:59:11 +02:00
|
|
|
|
2009-10-18 12:32:11 +02:00
|
|
|
/* Go to main() */
|
|
|
|
|
nReturnCode = xmain(argc, argv);
|
2005-05-18 22:59:11 +02:00
|
|
|
|
2019-06-01 18:15:43 +02:00
|
|
|
THE_END:
|
2009-10-18 12:32:11 +02:00
|
|
|
/* terminate */
|
2019-06-01 18:15:43 +02:00
|
|
|
|
|
|
|
|
/* Free history information if initialized */
|
|
|
|
|
if (p_hi != (struct History_info *) NULL) {
|
|
|
|
|
history_free(p_hi);
|
|
|
|
|
}
|
|
|
|
|
|
2009-10-18 12:32:11 +02:00
|
|
|
return nReturnCode;
|
2019-05-29 22:57:40 +02:00
|
|
|
} /* end of function WinMain */
|
|
|
|
|
|
2005-05-18 22:59:11 +02:00
|
|
|
|
|
|
|
|
|
2019-06-01 18:15:43 +02:00
|
|
|
/* This funtion initializes the history buffering with a welcome command */
|
|
|
|
|
static struct History_info *init_history(void)
|
|
|
|
|
{
|
|
|
|
|
static struct History_info_opt hi_opt = {
|
|
|
|
|
sizeof hi_opt,
|
|
|
|
|
HIST_SIZE, HIST_SIZE, N_BYTE_HIST_BUF,
|
|
|
|
|
4, 20, 10
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct History_info *p_hi = history_init(&hi_opt);
|
|
|
|
|
if (p_hi == (struct History_info *) NULL) {
|
|
|
|
|
return (struct History_info *) NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
{
|
2020-01-05 15:28:25 +01:00
|
|
|
/* Initialize history buffer with empty input line */
|
|
|
|
|
static const char cmd_welcome[] = "";
|
2019-06-01 18:15:43 +02:00
|
|
|
(void) history_add(&p_hi, sizeof cmd_welcome - 1, cmd_welcome);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return p_hi;
|
|
|
|
|
} /* end of function init_history */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2005-05-18 22:59:11 +02:00
|
|
|
// -----------------------------------<User-IO>--------------------------------
|
|
|
|
|
|
|
|
|
|
/* Eigentlich wollte ich die Standard-Streams durch einen Hook in der Library umleiten,
|
2017-02-10 20:45:10 +01:00
|
|
|
aber so etwas gibt es anscheinend nicht. Deswegen musz ich praktisch alle
|
|
|
|
|
IO-Funktionen umdefinieren (siehe wstdio.h). Leider geht das nicht bei allen.
|
|
|
|
|
Man schaue also nach, bevor man eine Funktion benutzt!
|
2005-05-18 22:59:11 +02:00
|
|
|
*/
|
|
|
|
|
|
2017-02-10 21:44:23 +01:00
|
|
|
int
|
|
|
|
|
win_x_fflush(FILE *stream)
|
2005-05-18 22:59:11 +02:00
|
|
|
{
|
2017-02-10 19:50:42 +01:00
|
|
|
if (((stream == stdout) && !flogp) || (stream == stderr))
|
2009-10-18 12:32:11 +02:00
|
|
|
return 0;
|
|
|
|
|
else
|
2017-02-10 19:50:42 +01:00
|
|
|
return fflush(stream);
|
2005-05-18 22:59:11 +02:00
|
|
|
}
|
|
|
|
|
|
2017-02-10 20:45:10 +01:00
|
|
|
|
2017-02-10 21:44:23 +01:00
|
|
|
int
|
|
|
|
|
win_x_fgetc(FILE *stream)
|
2005-05-18 22:59:11 +02:00
|
|
|
{
|
2017-02-10 19:50:42 +01:00
|
|
|
if (stream == stdin) {
|
2009-10-18 12:32:11 +02:00
|
|
|
int c;
|
2017-02-10 21:44:23 +01:00
|
|
|
do
|
2009-10-18 12:32:11 +02:00
|
|
|
c = w_getch();
|
2017-02-10 21:44:23 +01:00
|
|
|
while (c == CR);
|
2009-10-18 12:32:11 +02:00
|
|
|
return c;
|
|
|
|
|
} else
|
2017-02-10 19:50:42 +01:00
|
|
|
return fgetc(stream);
|
2005-05-18 22:59:11 +02:00
|
|
|
}
|
|
|
|
|
|
2017-02-10 20:45:10 +01:00
|
|
|
|
2017-02-10 21:44:23 +01:00
|
|
|
int
|
|
|
|
|
win_x_fgetpos(FILE *stream, fpos_t *pos)
|
2005-05-18 22:59:11 +02:00
|
|
|
{
|
2009-10-18 12:32:11 +02:00
|
|
|
int result;
|
2017-02-10 19:50:42 +01:00
|
|
|
if ((stream == stdin) || ((stream == stdout) && !flogp) || (stream == stderr)) {
|
2009-10-18 12:32:11 +02:00
|
|
|
assert(FALSE);
|
|
|
|
|
return 0;
|
|
|
|
|
} else
|
2017-02-10 19:50:42 +01:00
|
|
|
result = fgetpos(stream, pos);
|
2009-10-18 12:32:11 +02:00
|
|
|
return result;
|
2005-05-18 22:59:11 +02:00
|
|
|
}
|
|
|
|
|
|
2017-02-10 20:45:10 +01:00
|
|
|
|
2017-02-10 21:44:23 +01:00
|
|
|
char *
|
|
|
|
|
win_x_fgets(char *s, int n, FILE *stream)
|
2005-05-18 22:59:11 +02:00
|
|
|
{
|
2017-02-10 19:50:42 +01:00
|
|
|
if (stream == stdin) {
|
2009-10-18 12:32:11 +02:00
|
|
|
int i = 0;
|
|
|
|
|
int c;
|
2017-02-10 20:45:10 +01:00
|
|
|
while (i < (n - 1)) {
|
2009-10-18 12:32:11 +02:00
|
|
|
c = w_getch();
|
|
|
|
|
if (c == LF) {
|
2017-02-10 19:50:42 +01:00
|
|
|
s[i++] = LF;
|
2009-10-18 12:32:11 +02:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if (c != CR)
|
2017-02-10 19:50:42 +01:00
|
|
|
s[i++] = (char)c;
|
2009-10-18 12:32:11 +02:00
|
|
|
}
|
2017-02-10 19:50:42 +01:00
|
|
|
s[i] = SE;
|
|
|
|
|
return s;
|
2009-10-18 12:32:11 +02:00
|
|
|
} else
|
2017-02-10 20:45:10 +01:00
|
|
|
return fgets(s, n, stream);
|
2005-05-18 22:59:11 +02:00
|
|
|
}
|
|
|
|
|
|
2017-02-10 20:45:10 +01:00
|
|
|
|
2017-02-10 21:44:23 +01:00
|
|
|
int
|
|
|
|
|
win_x_fputc(int c, FILE *stream)
|
2005-05-18 22:59:11 +02:00
|
|
|
{
|
2017-02-10 19:50:42 +01:00
|
|
|
if (!flogp && ((stream == stdout) || (stream == stderr))) {
|
2017-02-10 20:45:10 +01:00
|
|
|
if (c == LF)
|
|
|
|
|
w_putch(CR);
|
2017-02-10 19:50:42 +01:00
|
|
|
return w_putch(c);
|
2005-05-18 22:59:11 +02:00
|
|
|
// Ausgabe in Datei *.log 14.6.2000
|
2017-02-10 19:50:42 +01:00
|
|
|
} else if (flogp && ((stream == stdout) || stream == stderr)) {
|
2017-02-10 20:45:10 +01:00
|
|
|
return fputc(c, flogp);
|
2009-10-18 12:32:11 +02:00
|
|
|
} else
|
2017-02-10 20:45:10 +01:00
|
|
|
return fputc(c, stream);
|
2005-05-18 22:59:11 +02:00
|
|
|
}
|
|
|
|
|
|
2017-02-10 20:45:10 +01:00
|
|
|
|
2017-02-10 21:44:23 +01:00
|
|
|
int
|
|
|
|
|
win_x_fputs(const char *s, FILE *stream)
|
2005-05-18 22:59:11 +02:00
|
|
|
{
|
2017-02-10 19:50:42 +01:00
|
|
|
// if (((stream == stdout) && !flogp) || (stream == stderr)) { hvogt 14.6.2000
|
|
|
|
|
if ((stream == stdout) || (stream == stderr)) {
|
2009-10-18 12:32:11 +02:00
|
|
|
|
|
|
|
|
int c = SE;
|
2017-02-10 21:44:23 +01:00
|
|
|
if (!s)
|
|
|
|
|
return EOF;
|
2010-09-07 22:07:57 +02:00
|
|
|
for (;;) {
|
2017-02-10 19:50:42 +01:00
|
|
|
if (*s) {
|
|
|
|
|
c = *s++;
|
|
|
|
|
win_x_fputc(c, stream);
|
2009-10-18 12:32:11 +02:00
|
|
|
} else
|
|
|
|
|
return c;
|
2010-09-07 22:07:57 +02:00
|
|
|
}
|
2009-10-18 12:32:11 +02:00
|
|
|
} else
|
2017-02-10 20:45:10 +01:00
|
|
|
return fputs(s, stream);
|
2005-05-18 22:59:11 +02:00
|
|
|
}
|
|
|
|
|
|
2017-02-10 20:45:10 +01:00
|
|
|
|
2017-02-10 21:44:23 +01:00
|
|
|
int
|
|
|
|
|
win_x_fprintf(FILE *stream, const char *format, ...)
|
2005-05-18 22:59:11 +02:00
|
|
|
{
|
2009-10-18 12:32:11 +02:00
|
|
|
int result;
|
2017-02-10 20:45:10 +01:00
|
|
|
char s[IOBufSize];
|
2009-10-18 12:32:11 +02:00
|
|
|
va_list args;
|
2017-02-10 20:45:10 +01:00
|
|
|
|
2017-02-10 19:50:42 +01:00
|
|
|
va_start(args, format);
|
2005-05-18 22:59:11 +02:00
|
|
|
|
2017-02-10 19:50:42 +01:00
|
|
|
// if (((stream == stdout) && !flogp) || (stream == stderr)) {
|
|
|
|
|
if ((stream == stdout) || (stream == stderr)) {
|
2005-05-18 22:59:11 +02:00
|
|
|
|
2009-10-18 12:32:11 +02:00
|
|
|
s[0] = SE;
|
2017-02-10 20:45:10 +01:00
|
|
|
result = vsprintf(s, format, args);
|
|
|
|
|
win_x_fputs(s, stream);
|
2009-10-18 12:32:11 +02:00
|
|
|
} else
|
2017-02-10 20:45:10 +01:00
|
|
|
result = vfprintf(stream, format, args);
|
2005-05-18 22:59:11 +02:00
|
|
|
|
2009-10-18 12:32:11 +02:00
|
|
|
va_end(args);
|
|
|
|
|
return result;
|
2005-05-18 22:59:11 +02:00
|
|
|
}
|
|
|
|
|
|
2017-02-10 20:45:10 +01:00
|
|
|
|
2017-02-10 21:44:23 +01:00
|
|
|
int
|
|
|
|
|
win_x_fclose(FILE *stream)
|
2005-05-18 22:59:11 +02:00
|
|
|
{
|
2017-02-10 19:50:42 +01:00
|
|
|
if ((stream == stdin) || ((stream == stdout) && !flogp) || (stream == stderr)) {
|
2009-10-18 12:32:11 +02:00
|
|
|
assert(FALSE);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2017-02-10 20:45:10 +01:00
|
|
|
return fclose(stream);
|
2005-05-18 22:59:11 +02:00
|
|
|
}
|
|
|
|
|
|
2017-02-10 20:45:10 +01:00
|
|
|
|
2017-02-10 21:44:23 +01:00
|
|
|
size_t
|
|
|
|
|
win_x_fread(void *ptr, size_t size, size_t n, FILE *stream)
|
2005-05-18 22:59:11 +02:00
|
|
|
{
|
2017-02-10 19:50:42 +01:00
|
|
|
// if ((stream == stdin) || ((stream == stdout) && !flogp) || (stream == stderr)) {
|
|
|
|
|
if (((stream == stdout) && !flogp) || (stream == stderr)) {
|
2009-10-18 12:32:11 +02:00
|
|
|
assert(FALSE);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2017-02-10 20:45:10 +01:00
|
|
|
|
2017-02-10 19:50:42 +01:00
|
|
|
if (stream == stdin) {
|
2009-10-18 12:32:11 +02:00
|
|
|
size_t i = 0;
|
|
|
|
|
int c;
|
2019-06-01 17:06:07 +02:00
|
|
|
char *s = (char *) ptr;
|
2017-02-10 20:45:10 +01:00
|
|
|
while (i < (size * n - 1)) {
|
2009-10-18 12:32:11 +02:00
|
|
|
c = w_getch();
|
|
|
|
|
if (c == LF) {
|
|
|
|
|
// s[i++] = LF;
|
|
|
|
|
break;
|
|
|
|
|
}
|
2019-06-01 17:06:07 +02:00
|
|
|
if (c != CR) {
|
|
|
|
|
s[i++] = (char) c;
|
|
|
|
|
}
|
2009-10-18 12:32:11 +02:00
|
|
|
}
|
|
|
|
|
// s[i] = SE;
|
2019-06-01 17:06:07 +02:00
|
|
|
return (size_t) (i / size);
|
|
|
|
|
} /* end of case of stdin */
|
2017-02-10 20:45:10 +01:00
|
|
|
|
|
|
|
|
return fread(ptr, size, n, stream);
|
2005-05-18 22:59:11 +02:00
|
|
|
}
|
|
|
|
|
|
2017-02-10 20:45:10 +01:00
|
|
|
|
2017-02-10 21:44:23 +01:00
|
|
|
FILE *
|
|
|
|
|
win_x_freopen(const char *path, const char *mode, FILE *stream)
|
2005-05-18 22:59:11 +02:00
|
|
|
{
|
2017-02-10 19:50:42 +01:00
|
|
|
if ((stream == stdin)/* || ((stream == stdout) && !flogp) || (stream == stderr)*/) {
|
2009-10-18 12:32:11 +02:00
|
|
|
assert(FALSE);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2017-02-10 20:45:10 +01:00
|
|
|
return freopen(path, mode, stream);
|
2005-05-18 22:59:11 +02:00
|
|
|
}
|
|
|
|
|
|
2017-02-10 20:45:10 +01:00
|
|
|
|
2017-02-10 21:44:23 +01:00
|
|
|
int
|
|
|
|
|
win_x_fscanf(FILE *stream, const char *format, ...)
|
2005-05-18 22:59:11 +02:00
|
|
|
{
|
2009-10-18 12:32:11 +02:00
|
|
|
int result;
|
|
|
|
|
va_list args;
|
2017-02-10 20:45:10 +01:00
|
|
|
|
2017-02-10 19:50:42 +01:00
|
|
|
va_start(args, format);
|
|
|
|
|
if ((stream == stdin) || ((stream == stdout) && !flogp) || (stream == stderr)) {
|
2009-10-18 12:32:11 +02:00
|
|
|
assert(FALSE);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2017-02-10 19:50:42 +01:00
|
|
|
result = vfscanf(stream, format, args);
|
2009-10-18 12:32:11 +02:00
|
|
|
va_end(args);
|
|
|
|
|
return result;
|
2005-05-18 22:59:11 +02:00
|
|
|
}
|
|
|
|
|
|
2017-02-10 20:45:10 +01:00
|
|
|
|
2017-02-10 21:44:23 +01:00
|
|
|
int
|
|
|
|
|
win_x_fseek(FILE *stream, long offset, int whence)
|
2005-05-18 22:59:11 +02:00
|
|
|
{
|
2017-02-10 19:50:42 +01:00
|
|
|
if ((stream == stdin) || ((stream == stdout) && !flogp) || (stream == stderr)) {
|
2009-10-18 12:32:11 +02:00
|
|
|
assert(FALSE);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2017-02-10 20:45:10 +01:00
|
|
|
return fseek(stream, offset, whence);
|
2005-05-18 22:59:11 +02:00
|
|
|
}
|
|
|
|
|
|
2017-02-10 20:45:10 +01:00
|
|
|
|
2017-02-10 21:44:23 +01:00
|
|
|
int
|
|
|
|
|
win_x_fsetpos(FILE *stream, const fpos_t *pos)
|
2005-05-18 22:59:11 +02:00
|
|
|
{
|
2017-02-10 19:50:42 +01:00
|
|
|
if ((stream == stdin) || ((stream == stdout) && !flogp) || (stream == stderr)) {
|
2009-10-18 12:32:11 +02:00
|
|
|
assert(FALSE);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2017-02-10 20:45:10 +01:00
|
|
|
return fsetpos(stream, pos);
|
2005-05-18 22:59:11 +02:00
|
|
|
}
|
|
|
|
|
|
2017-02-10 20:45:10 +01:00
|
|
|
|
2017-02-10 21:44:23 +01:00
|
|
|
long
|
|
|
|
|
win_x_ftell(FILE *stream)
|
2005-05-18 22:59:11 +02:00
|
|
|
{
|
2017-02-10 19:50:42 +01:00
|
|
|
if ((stream == stdin) || ((stream == stdout) && !flogp) || (stream == stderr)) {
|
2009-10-18 12:32:11 +02:00
|
|
|
assert(FALSE);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2017-02-10 20:45:10 +01:00
|
|
|
return ftell(stream);
|
2005-05-18 22:59:11 +02:00
|
|
|
}
|
|
|
|
|
|
2017-02-10 20:45:10 +01:00
|
|
|
|
2017-02-10 21:44:23 +01:00
|
|
|
size_t
|
|
|
|
|
win_x_fwrite(const void *ptr, size_t size, size_t n, FILE *stream)
|
2005-05-18 22:59:11 +02:00
|
|
|
{
|
2017-02-10 19:50:42 +01:00
|
|
|
// win_x_printf("entered fwrite, size %d, n %d \n", size, n);
|
2017-02-10 20:45:10 +01:00
|
|
|
if (stream == stdin) {
|
2009-10-18 12:32:11 +02:00
|
|
|
assert(FALSE);
|
2017-02-10 19:50:42 +01:00
|
|
|
// win_x_printf("False \n");
|
2009-10-18 12:32:11 +02:00
|
|
|
return 0;
|
|
|
|
|
}
|
2017-02-10 19:50:42 +01:00
|
|
|
if ((stream == stdout) || (stream == stderr)) {
|
2017-02-10 20:45:10 +01:00
|
|
|
const char *s = ptr;
|
2009-10-18 12:32:11 +02:00
|
|
|
int c = SE;
|
|
|
|
|
size_t i = 0;
|
|
|
|
|
// char *out;
|
|
|
|
|
|
2017-02-10 19:50:42 +01:00
|
|
|
// win_x_printf("test1 %s\n", s);
|
2009-10-18 12:32:11 +02:00
|
|
|
|
2017-02-10 21:44:23 +01:00
|
|
|
if (!s)
|
|
|
|
|
return 0 /* EOF */;
|
2017-02-10 20:45:10 +01:00
|
|
|
|
|
|
|
|
for (i = 0; i < (size * n); i++) {
|
2017-02-10 19:50:42 +01:00
|
|
|
if (*s) {
|
|
|
|
|
c = *s++;
|
|
|
|
|
win_x_fputc(c, stream);
|
2009-10-18 12:32:11 +02:00
|
|
|
} else
|
|
|
|
|
break;
|
2012-08-07 21:20:36 +02:00
|
|
|
}
|
2017-02-10 19:50:42 +01:00
|
|
|
// win_x_fread(out, size, n, stream);
|
|
|
|
|
// win_x_printf("test2 %s", out);
|
2017-02-10 20:45:10 +01:00
|
|
|
return (int)(i / size);
|
2009-10-18 12:32:11 +02:00
|
|
|
}
|
2017-02-10 19:50:42 +01:00
|
|
|
// win_x_printf("test3 %s\n", ptr);
|
2017-02-10 20:45:10 +01:00
|
|
|
return fwrite(ptr, size, n, stream);
|
2005-05-18 22:59:11 +02:00
|
|
|
}
|
|
|
|
|
|
2017-02-10 20:45:10 +01:00
|
|
|
|
2017-02-10 21:44:23 +01:00
|
|
|
char *
|
|
|
|
|
win_x_gets(char *s)
|
2005-05-18 22:59:11 +02:00
|
|
|
{
|
2017-02-10 20:45:10 +01:00
|
|
|
return win_x_fgets(s, 10000, stdin);
|
2005-05-18 22:59:11 +02:00
|
|
|
}
|
|
|
|
|
|
2017-02-10 20:45:10 +01:00
|
|
|
|
2017-02-10 21:44:23 +01:00
|
|
|
void
|
|
|
|
|
win_x_perror(const char *s)
|
2005-05-18 22:59:11 +02:00
|
|
|
{
|
2017-02-10 20:45:10 +01:00
|
|
|
const char *cp;
|
|
|
|
|
// char s[IOBufSize];
|
2009-10-18 12:32:11 +02:00
|
|
|
cp = strerror(errno);
|
2017-02-10 19:50:42 +01:00
|
|
|
win_x_fprintf(stderr, "%s: %s\n", s, cp);
|
2017-02-10 20:45:10 +01:00
|
|
|
/* output to message box
|
|
|
|
|
sprintf(s, "%s: %s\n", s, cp);
|
|
|
|
|
if (!flogp) winmessage(s);*/
|
2005-05-18 22:59:11 +02:00
|
|
|
}
|
|
|
|
|
|
2017-02-10 20:45:10 +01:00
|
|
|
|
2017-02-10 21:44:23 +01:00
|
|
|
int
|
|
|
|
|
win_x_printf(const char *format, ...)
|
2005-05-18 22:59:11 +02:00
|
|
|
{
|
2009-10-18 12:32:11 +02:00
|
|
|
int result;
|
2017-02-10 20:45:10 +01:00
|
|
|
char s[IOBufSize];
|
2009-10-18 12:32:11 +02:00
|
|
|
va_list args;
|
2005-05-18 22:59:11 +02:00
|
|
|
|
2017-02-10 20:45:10 +01:00
|
|
|
va_start(args, format);
|
2009-10-18 12:32:11 +02:00
|
|
|
s[0] = SE;
|
2017-02-10 20:45:10 +01:00
|
|
|
result = vsprintf(s, format, args);
|
|
|
|
|
win_x_fputs(s, stdout);
|
2009-10-18 12:32:11 +02:00
|
|
|
va_end(args);
|
2017-02-10 20:45:10 +01:00
|
|
|
|
2009-10-18 12:32:11 +02:00
|
|
|
return result;
|
2005-05-18 22:59:11 +02:00
|
|
|
}
|
|
|
|
|
|
2017-02-10 20:45:10 +01:00
|
|
|
|
2017-02-10 21:44:23 +01:00
|
|
|
int
|
|
|
|
|
win_x_puts(const char *s)
|
2005-05-18 22:59:11 +02:00
|
|
|
{
|
2017-02-10 20:45:10 +01:00
|
|
|
return win_x_fputs(s, stdout);
|
2005-05-18 22:59:11 +02:00
|
|
|
}
|
|
|
|
|
|
2017-02-10 20:45:10 +01:00
|
|
|
|
2017-02-10 21:44:23 +01:00
|
|
|
int
|
|
|
|
|
win_x_scanf(const char *format, ...)
|
2005-05-18 22:59:11 +02:00
|
|
|
{
|
2017-02-10 19:50:42 +01:00
|
|
|
NG_IGNORE(format);
|
2017-02-10 20:45:10 +01:00
|
|
|
assert(FALSE);
|
2009-10-18 12:32:11 +02:00
|
|
|
return FALSE;
|
2005-05-18 22:59:11 +02:00
|
|
|
}
|
|
|
|
|
|
2017-02-10 20:45:10 +01:00
|
|
|
|
2017-02-10 21:44:23 +01:00
|
|
|
int
|
|
|
|
|
win_x_ungetc(int c, FILE *stream)
|
2005-05-18 22:59:11 +02:00
|
|
|
{
|
2017-02-10 19:50:42 +01:00
|
|
|
NG_IGNORE(c);
|
|
|
|
|
NG_IGNORE(stream);
|
2017-02-10 20:45:10 +01:00
|
|
|
assert(FALSE);
|
2009-10-18 12:32:11 +02:00
|
|
|
return FALSE;
|
2005-05-18 22:59:11 +02:00
|
|
|
}
|
|
|
|
|
|
2017-02-10 20:45:10 +01:00
|
|
|
|
2017-02-10 21:44:23 +01:00
|
|
|
int
|
|
|
|
|
win_x_vfprintf(FILE *stream, const char *format, void *arglist)
|
2005-05-18 22:59:11 +02:00
|
|
|
{
|
2009-10-18 12:32:11 +02:00
|
|
|
int result;
|
2017-02-10 20:45:10 +01:00
|
|
|
char s[IOBufSize];
|
2005-05-18 22:59:11 +02:00
|
|
|
|
2009-10-18 12:32:11 +02:00
|
|
|
s[0] = SE;
|
2017-02-10 19:50:42 +01:00
|
|
|
// if (((stream == stdout) && !flogp) || (stream == stderr)) {
|
|
|
|
|
if ((stream == stdout) || (stream == stderr)) {
|
2005-05-18 22:59:11 +02:00
|
|
|
|
2017-02-10 20:45:10 +01:00
|
|
|
result = vsprintf(s, format, arglist);
|
|
|
|
|
win_x_fputs(s, stdout);
|
2009-10-18 12:32:11 +02:00
|
|
|
} else
|
2017-02-10 20:45:10 +01:00
|
|
|
result = vfprintf(stream, format, arglist);
|
2009-10-18 12:32:11 +02:00
|
|
|
return result;
|
2005-05-18 22:59:11 +02:00
|
|
|
}
|
|
|
|
|
|
2017-02-10 20:45:10 +01:00
|
|
|
|
2017-02-10 21:44:23 +01:00
|
|
|
#if 0
|
|
|
|
|
int
|
|
|
|
|
win_x_vfscanf(FILE *stream, const char *format, void *arglist)
|
2005-05-18 22:59:11 +02:00
|
|
|
{
|
2017-02-10 19:50:42 +01:00
|
|
|
if (stream == stdin) {
|
2009-10-18 12:32:11 +02:00
|
|
|
assert(FALSE);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2017-02-10 20:45:10 +01:00
|
|
|
return vfscanf(stream, format, arglist);
|
2005-05-18 22:59:11 +02:00
|
|
|
}
|
2017-02-10 21:44:23 +01:00
|
|
|
#endif
|
2017-02-10 20:45:10 +01:00
|
|
|
|
|
|
|
|
|
2017-02-10 21:44:23 +01:00
|
|
|
int
|
|
|
|
|
win_x_vprintf(const char *format, void *arglist)
|
2005-05-18 22:59:11 +02:00
|
|
|
{
|
2009-10-18 12:32:11 +02:00
|
|
|
int result;
|
2017-02-10 20:45:10 +01:00
|
|
|
char s[IOBufSize];
|
2005-05-18 22:59:11 +02:00
|
|
|
|
2009-10-18 12:32:11 +02:00
|
|
|
s[0] = SE;
|
2017-02-10 20:45:10 +01:00
|
|
|
result = vsprintf(s, format, arglist);
|
|
|
|
|
win_x_fputs(s, stdout);
|
2009-10-18 12:32:11 +02:00
|
|
|
return result;
|
2005-05-18 22:59:11 +02:00
|
|
|
}
|
|
|
|
|
|
2017-02-10 20:45:10 +01:00
|
|
|
|
2017-02-10 21:44:23 +01:00
|
|
|
#if 0
|
|
|
|
|
int
|
|
|
|
|
win_x_vscanf(const char *format, void *arglist)
|
2005-05-18 22:59:11 +02:00
|
|
|
{
|
2017-02-10 20:45:10 +01:00
|
|
|
assert(FALSE);
|
2009-10-18 12:32:11 +02:00
|
|
|
return FALSE;
|
2017-02-10 21:44:23 +01:00
|
|
|
}
|
|
|
|
|
#endif
|
2005-05-18 22:59:11 +02:00
|
|
|
|
2017-02-10 20:45:10 +01:00
|
|
|
|
2017-02-10 21:44:23 +01:00
|
|
|
int
|
|
|
|
|
win_x_getc(FILE *fp)
|
2005-05-18 22:59:11 +02:00
|
|
|
{
|
2017-02-10 20:45:10 +01:00
|
|
|
return win_x_fgetc(fp);
|
2005-05-18 22:59:11 +02:00
|
|
|
}
|
|
|
|
|
|
2017-02-10 20:45:10 +01:00
|
|
|
|
2017-02-10 21:44:23 +01:00
|
|
|
int
|
|
|
|
|
win_x_getchar(void)
|
2005-05-18 22:59:11 +02:00
|
|
|
{
|
2017-02-10 20:45:10 +01:00
|
|
|
return win_x_fgetc(stdin);
|
2005-05-18 22:59:11 +02:00
|
|
|
}
|
|
|
|
|
|
2017-02-10 20:45:10 +01:00
|
|
|
|
2017-02-10 21:44:23 +01:00
|
|
|
int
|
|
|
|
|
win_x_putchar(const int c)
|
2005-05-18 22:59:11 +02:00
|
|
|
{
|
2017-02-10 20:45:10 +01:00
|
|
|
return win_x_fputc(c, stdout);
|
2005-05-18 22:59:11 +02:00
|
|
|
}
|
|
|
|
|
|
2017-02-10 20:45:10 +01:00
|
|
|
|
2017-02-10 21:44:23 +01:00
|
|
|
int
|
|
|
|
|
win_x_putc(const int c, FILE *fp)
|
2005-05-18 22:59:11 +02:00
|
|
|
{
|
2017-02-10 20:45:10 +01:00
|
|
|
return win_x_fputc(c, fp);
|
2005-05-18 22:59:11 +02:00
|
|
|
}
|
|
|
|
|
|
2017-02-10 20:45:10 +01:00
|
|
|
|
2017-02-10 21:44:23 +01:00
|
|
|
int
|
|
|
|
|
win_x_feof(FILE *fp)
|
2005-05-18 22:59:11 +02:00
|
|
|
{
|
2017-02-10 19:50:42 +01:00
|
|
|
if ((fp == stdin) || (fp == stdout) || (fp == stderr)) {
|
2009-10-18 12:32:11 +02:00
|
|
|
assert(FALSE);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2017-02-10 20:45:10 +01:00
|
|
|
return feof(fp);
|
2005-05-18 22:59:11 +02:00
|
|
|
}
|
|
|
|
|
|
2017-02-10 20:45:10 +01:00
|
|
|
|
2017-02-10 21:44:23 +01:00
|
|
|
int
|
|
|
|
|
win_x_ferror(FILE *fp)
|
2005-05-18 22:59:11 +02:00
|
|
|
{
|
2017-02-10 19:50:42 +01:00
|
|
|
if ((fp == stdin) || (fp == stdout) || (fp == stderr)) {
|
2009-10-18 12:32:11 +02:00
|
|
|
assert(FALSE);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2017-02-10 20:45:10 +01:00
|
|
|
return ferror(fp);
|
2005-05-18 22:59:11 +02:00
|
|
|
}
|
|
|
|
|
|
2017-02-10 20:45:10 +01:00
|
|
|
|
2017-02-10 21:44:23 +01:00
|
|
|
int
|
|
|
|
|
win_x_fputchar(int c)
|
2005-05-18 22:59:11 +02:00
|
|
|
{
|
2017-02-10 20:45:10 +01:00
|
|
|
return win_x_fputc(c, stdout);
|
2005-05-18 22:59:11 +02:00
|
|
|
}
|
|
|
|
|
|
2017-02-10 20:45:10 +01:00
|
|
|
|
2005-05-18 22:59:11 +02:00
|
|
|
// --------------------------<Verfuegbarer Speicher>----------------------------
|
2017-02-10 20:45:10 +01:00
|
|
|
|
2017-02-10 21:44:23 +01:00
|
|
|
#if 0
|
|
|
|
|
size_t
|
|
|
|
|
_memavl(void)
|
2005-05-18 22:59:11 +02:00
|
|
|
{
|
2009-10-18 12:32:11 +02:00
|
|
|
MEMORYSTATUS ms;
|
|
|
|
|
DWORD sum;
|
|
|
|
|
ms.dwLength = sizeof(MEMORYSTATUS);
|
2017-02-10 20:45:10 +01:00
|
|
|
GlobalMemoryStatus(&ms);
|
2009-10-18 12:32:11 +02:00
|
|
|
sum = ms.dwAvailPhys + ms.dwAvailPageFile;
|
|
|
|
|
return (size_t) sum;
|
2005-05-18 22:59:11 +02:00
|
|
|
}
|
2017-02-10 21:44:23 +01:00
|
|
|
#endif
|
2010-01-02 16:24:03 +01:00
|
|
|
|
2017-02-10 20:45:10 +01:00
|
|
|
|
2005-05-18 22:59:11 +02:00
|
|
|
// ---------------------<Aufruf eines anderen Programms>-----------------------
|
2017-02-10 20:45:10 +01:00
|
|
|
|
2017-02-10 21:44:23 +01:00
|
|
|
#if 0
|
2008-04-13 16:30:28 +02:00
|
|
|
#ifndef _MSC_VER
|
2017-02-10 21:44:23 +01:00
|
|
|
int
|
|
|
|
|
system(const char *command)
|
2005-05-18 22:59:11 +02:00
|
|
|
{
|
2009-10-18 12:32:11 +02:00
|
|
|
// info-Bloecke
|
|
|
|
|
STARTUPINFO si;
|
|
|
|
|
PROCESS_INFORMATION pi;
|
|
|
|
|
DWORD ExitStatus;
|
|
|
|
|
|
|
|
|
|
// Datenstrukturen fuellen
|
2017-02-10 20:45:10 +01:00
|
|
|
memset(&si, 0, sizeof(STARTUPINFO));
|
|
|
|
|
si.cb = sizeof(STARTUPINFO);
|
|
|
|
|
memset(&pi, 0, sizeof(PROCESS_INFORMATION));
|
2009-10-18 12:32:11 +02:00
|
|
|
|
|
|
|
|
// starte den neuen Prozess
|
|
|
|
|
if (!CreateProcess(
|
2017-02-10 20:45:10 +01:00
|
|
|
NULL, // address of module name
|
|
|
|
|
(char *) command, // address of command line
|
|
|
|
|
NULL, // address of process security attributes
|
|
|
|
|
NULL, // address of thread security attributes
|
|
|
|
|
FALSE, // new process inherits handles
|
|
|
|
|
NORMAL_PRIORITY_CLASS, // creation flags
|
|
|
|
|
NULL, // address of new environment block
|
|
|
|
|
NULL, // address of current directory name
|
|
|
|
|
&si, // address of STARTUPINFO
|
|
|
|
|
&pi // address of PROCESS_INFORMATION
|
2017-02-10 21:44:23 +01:00
|
|
|
))
|
|
|
|
|
return -1;
|
2009-10-18 12:32:11 +02:00
|
|
|
|
|
|
|
|
// dieses Handle musz da sein
|
2017-02-10 21:44:23 +01:00
|
|
|
if (!pi.hProcess)
|
|
|
|
|
return -1;
|
2009-10-18 12:32:11 +02:00
|
|
|
|
|
|
|
|
do {
|
|
|
|
|
// Multitasking ermoeglichen
|
|
|
|
|
WaitForIdle();
|
|
|
|
|
// hole mir den Exit-Code des Prozesses
|
2017-02-10 21:44:23 +01:00
|
|
|
if (!GetExitCodeProcess(pi.hProcess, &ExitStatus))
|
|
|
|
|
return -1;
|
2009-10-18 12:32:11 +02:00
|
|
|
// solange er existiert
|
2017-02-10 20:45:10 +01:00
|
|
|
} while (ExitStatus == STILL_ACTIVE);
|
2009-10-18 12:32:11 +02:00
|
|
|
|
|
|
|
|
// Handles freigeben
|
2017-02-10 21:44:23 +01:00
|
|
|
if (pi.hThread)
|
|
|
|
|
CloseHandle(pi.hThread);
|
|
|
|
|
if (pi.hProcess)
|
|
|
|
|
CloseHandle(pi.hProcess);
|
2009-10-18 12:32:11 +02:00
|
|
|
|
|
|
|
|
// fertig
|
|
|
|
|
return 0;
|
2005-05-18 22:59:11 +02:00
|
|
|
} // system Windows95
|
2008-04-13 16:30:28 +02:00
|
|
|
#endif
|
2017-02-10 21:44:23 +01:00
|
|
|
#endif
|
2013-05-15 21:10:39 +02:00
|
|
|
|
2017-02-10 20:45:10 +01:00
|
|
|
|
2013-05-15 21:10:39 +02:00
|
|
|
#ifdef __CYGWIN__
|
2017-02-10 20:45:10 +01:00
|
|
|
|
2009-10-18 12:32:11 +02:00
|
|
|
/* Strip leading spaces, return a copy of s */
|
2017-02-10 20:45:10 +01:00
|
|
|
static char *
|
2013-05-15 21:10:39 +02:00
|
|
|
rlead(char *s)
|
2008-04-13 16:30:28 +02:00
|
|
|
{
|
2017-02-10 20:45:10 +01:00
|
|
|
int i, j = 0;
|
|
|
|
|
static char temp[512];
|
|
|
|
|
bool has_space = TRUE;
|
|
|
|
|
for (i = 0; s[i] != '\0'; i++)
|
|
|
|
|
{
|
|
|
|
|
if (isspace((unsigned char) s[i]) && has_space)
|
|
|
|
|
{
|
|
|
|
|
; //Do nothing
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
temp[j] = s[i];
|
|
|
|
|
j++;
|
|
|
|
|
has_space = FALSE;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
temp[j] = '\0';
|
|
|
|
|
return copy(temp);
|
|
|
|
|
}
|
|
|
|
|
|
2013-05-15 21:10:39 +02:00
|
|
|
#endif
|
2008-04-13 16:30:28 +02:00
|
|
|
|
2017-02-10 20:45:10 +01:00
|
|
|
|
2017-02-10 21:44:23 +01:00
|
|
|
void
|
|
|
|
|
winmessage(char *new_msg)
|
2008-04-13 16:30:28 +02:00
|
|
|
{
|
2009-10-18 12:32:11 +02:00
|
|
|
/* open a message box only if message is not written into -o xxx.log */
|
2017-02-10 20:45:10 +01:00
|
|
|
if (!flogp)
|
|
|
|
|
MessageBox(NULL, new_msg, "Ngspice Info", MB_OK | MB_ICONERROR);
|
2008-04-13 16:30:28 +02:00
|
|
|
}
|
2005-05-18 22:59:11 +02:00
|
|
|
|
|
|
|
|
|
2020-02-14 22:52:09 +01:00
|
|
|
|
|
|
|
|
#else /* HAS_WINGUI not defined */
|
|
|
|
|
/* Prevent warning regarding empty translation unit */
|
|
|
|
|
static void dummy(void)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
} /* end of function dummy */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2017-02-10 20:45:10 +01:00
|
|
|
#endif /* HAS_WINGUI */
|