diff --git a/doc/en/html/about/history.html b/doc/en/html/about/history.html index a6729ee20..dbeabbeb9 100644 --- a/doc/en/html/about/history.html +++ b/doc/en/html/about/history.html @@ -81,6 +81,15 @@

YYYY.MM.DD (Ver 5.7.0 not released yet)

Previously, since short filename,SFN (DOS filename, 8.3 format) is used, "ttxtest.dll-" was treated as "TTXTEST.DLL" and loaded. +
  • + Changed DPI awareness setting to process-wide instead of GUI thread only. + (issue #1314) +
  • +
  • + When Terminal ID is "dumb", + Output timestamps to both the VT window and log file when logging. + (issue #255) +
  • diff --git a/doc/en/html/menu/setup-additional-log.html b/doc/en/html/menu/setup-additional-log.html index 110ec7820..0a4cb21fe 100644 --- a/doc/en/html/menu/setup-additional-log.html +++ b/doc/en/html/menu/setup-additional-log.html @@ -141,7 +141,11 @@

    Additional settings / "Log" Tab ([Setup]
    Timestamp
    - If you select this option, a timestamp is added on top of each log line. The timestamp is added when the first character of the line appears.
    + If you select this option, timestamp is output when first character of the line appears.
    + When Terminal ID is dumb, + timestamp is output to both VTWin and log file.
    + When it is other than dumb, the timestamp is output to log file.
    +
    The timestamp type can be selected from following.
    Local Time
    diff --git a/doc/en/html/menu/setup-additional-terminal.html b/doc/en/html/menu/setup-additional-terminal.html index abb1a0c01..acab432c6 100644 --- a/doc/en/html/menu/setup-additional-terminal.html +++ b/doc/en/html/menu/setup-additional-terminal.html @@ -77,7 +77,8 @@

    Additional settings / "Terminal" tab ([S

    dumb
    - Emulates dumb terminal. + Emulates dumb terminal.
    + log Timestamp is output to VT window and log file.
    diff --git a/doc/ja/html/about/history.html b/doc/ja/html/about/history.html index 17d482239..1b4ae35e9 100644 --- a/doc/ja/html/about/history.html +++ b/doc/ja/html/about/history.html @@ -81,6 +81,15 @@

    YYYY.MM.DD (Ver 5.7.0 not released yet)

    従来はショートファイル名,SFN(DOSファイル名,8.3形式)で扱っていたため、 "ttxtest.dll-" は "TTXTEST.DLL" として扱われ、ロードされていた。 +
  • + 高DPI設定をGUIスレッドのみではなく、プロセス全体で行うようにした。 + (issue #1314) +
  • +
  • + Terminal ID が "dumb" の時、 + ログ取得時のタイムスタンプをVT Windowとログファイルへ出力するようにした。 + (issue #255) +
  • diff --git a/doc/ja/html/menu/setup-additional-log.html b/doc/ja/html/menu/setup-additional-log.html index dfe647c43..b3bb7a4c8 100644 --- a/doc/ja/html/menu/setup-additional-log.html +++ b/doc/ja/html/menu/setup-additional-log.html @@ -137,7 +137,11 @@

    Additional settings / "Log"
    Timestamp
    - ログの行頭に時刻を追加したい場合は選択してください。行の最初の文字が出力された時刻が追加されます。
    + 選択時、行の最初の文字が出力された時に、時刻が出力されます。
    + Terminal IDがdumbの時、 + 時刻はVTWinとログファイルに出力されます。
    + dumb以外の時、時刻はログファイルに出力されます。
    +
    タイムスタンプの種別として以下が選択できます。
    Local Time
    diff --git a/doc/ja/html/menu/setup-additional-terminal.html b/doc/ja/html/menu/setup-additional-terminal.html index 1bc80a17d..42f769d7a 100644 --- a/doc/ja/html/menu/setup-additional-terminal.html +++ b/doc/ja/html/menu/setup-additional-terminal.html @@ -77,7 +77,8 @@

    Additional settings / "Terminal"

    dumb
    - ダム端末をエミュレートします。 + ダム端末をエミュレートします。
    + ログのTimestampがVT windowに出力されます
    diff --git a/teraterm/common/ttlib.c b/teraterm/common/ttlib.c index 12d865a08..5961857fc 100644 --- a/teraterm/common/ttlib.c +++ b/teraterm/common/ttlib.c @@ -844,110 +844,22 @@ DWORD get_OPENFILENAME_SIZEW() return CDSIZEOF_STRUCT(OPENFILENAMEW,lpTemplateName); } -/* +/** * 迴セ蝨ィ縺ョ譎る俣繧呈枚蟄怜励↓縺励※霑斐☆ * + * @param format strftime like縺ェ繝輔か繝シ繝槭ャ繝 + * @param utc_flag TRUE / FALSE = UTC縺ァ蜃コ蜉 / 繝ュ繝シ繧ォ繝ォ繧ソ繧、繝縺ァ蜃コ蜉 * @return 邨碁℃譎ょ綾譁蟄怜 * 荳崎ヲ√↓縺ェ縺」縺溘ifree()縺吶k縺薙→ */ char *mctimelocal(const char *format, BOOL utc_flag) { - SYSTEMTIME systime; - const size_t sizeof_strtime = 29; - char *strtime = malloc(sizeof_strtime); - static const char week[][4] = { - "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" - }; - static const char month[][4] = { - "Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" - }; - char tmp[5]; - unsigned int i = strlen(format); - - *strtime = '\0'; - if (utc_flag) { - GetSystemTime(&systime); - } - else { - GetLocalTime(&systime); - } - for (i=0; imicro->milli + time_t now = now_ms / 1000; + + struct tm tm; + if (utc_flag) { + // UTC + gmtime_s(&tm, &now); + } else { + // local + localtime_s(&tm, &now); + } + + // 迢ャ閾ェ繝輔か繝シ繝槭ャ繝医〒螻暮幕縺吶k + // 譛ェ蟇セ蠢懊ョ謖螳壼ュ舌ッ縺昴ョ縺セ縺セ蜃コ蜉帙☆繧 + size_t format_len = wcslen(format); + + // 蜃コ蜉帙ヰ繝繝輔ぃ + // 迢ャ閾ェ繝輔か繝シ繝槭ャ繝亥ア暮幕譎ゅョ譛螟ァ螻暮幕邇縺ッ %Y(2譁蟄->4譁蟄) 遲峨〒 2 蛟咲ィ句コヲ縲 + // 菴呵」輔r謖√▲縺ヲ format 髟キ縺ョ 4 蛟 + ホア 繧堤「コ菫昴☆繧九 + // (縺昴l縺ァ繧よコ「繧後k蝣エ蜷医ッ wcsncat_s 縺悟繧願ゥー繧√k縺溘a繧ェ繝シ繝舌シ繝輔Ο繝シ縺励↑縺) + size_t sizeof_strtime = format_len * 4 + 1; + wchar_t *strtime = malloc(sizeof(wchar_t) * sizeof_strtime); + if (strtime == NULL) { + return NULL; + } + + static const wchar_t week[][4] = { + L"Sun", L"Mon", L"Tue", L"Wed", L"Thu", L"Fri", L"Sat" + }; + static const wchar_t month[][4] = { + L"Jan", L"Feb", L"Mar", L"Apr", L"May", L"Jun", + L"Jul", L"Aug", L"Sep", L"Oct", L"Nov", L"Dec" + }; + size_t i; + + strtime[0] = L'\0'; + for (i = 0; i < format_len; i++) { + if (format[i] == L'%') { + wchar_t tmp[5]; + wchar_t c = format[i + 1]; + switch (c) { + case 'a': + _snwprintf_s(tmp, _countof(tmp), _TRUNCATE, L"%s", week[tm.tm_wday]); + wcsncat_s(strtime, sizeof_strtime, tmp, _TRUNCATE); + i++; + break; + // 'A' 譛ェ螳溯」 + case 'b': + _snwprintf_s(tmp, _countof(tmp), _TRUNCATE, L"%s", month[tm.tm_mon]); + wcsncat_s(strtime, sizeof_strtime, tmp, _TRUNCATE); + i++; + break; + // 'c' 譛ェ螳溯」 + case 'd': + _snwprintf_s(tmp, _countof(tmp), _TRUNCATE, L"%02d", tm.tm_mday); + wcsncat_s(strtime, sizeof_strtime, tmp, _TRUNCATE); + i++; + break; + case 'e': + // 繝槭ル繝・繧「繝ォ縺ォ險倩シ峨↑縺 + // %H縺ョ0蝓九a縺ェ縺("01"縺ァ縺ッ縺ェ縺"1"縺ェ縺ゥ)縲 + _snwprintf_s(tmp, _countof(tmp), _TRUNCATE, L"%2d", tm.tm_mday); + wcsncat_s(strtime, sizeof_strtime, tmp, _TRUNCATE); + i++; + break; + case 'H': + _snwprintf_s(tmp, _countof(tmp), _TRUNCATE, L"%02d", tm.tm_hour); + wcsncat_s(strtime, sizeof_strtime, tmp, _TRUNCATE); + i++; + break; + // 'I' 譛ェ螳溯」 + case 'N': + // Tera Term 繧ェ繝ェ繧ク繝翫Ν螳溯」 + // 繝溘Μ遘 3譯 + // 繝槭ル繝・繧「繝ォ縺ォ險倩シ峨↑縺 + _snwprintf_s(tmp, _countof(tmp), _TRUNCATE, L"%03d", (int)(now_ms % 1000)); + wcsncat_s(strtime, sizeof_strtime, tmp, _TRUNCATE); + i++; + break; + case 'm': + _snwprintf_s(tmp, _countof(tmp), _TRUNCATE, L"%02d", tm.tm_mon + 1); + wcsncat_s(strtime, sizeof_strtime, tmp, _TRUNCATE); + i++; + break; + case 'M': + _snwprintf_s(tmp, _countof(tmp), _TRUNCATE, L"%02d", tm.tm_min); + wcsncat_s(strtime, sizeof_strtime, tmp, _TRUNCATE); + i++; + break; + // 'p' 譛ェ螳溯」 + case 'S': + _snwprintf_s(tmp, _countof(tmp), _TRUNCATE, L"%02d", tm.tm_sec); + wcsncat_s(strtime, sizeof_strtime, tmp, _TRUNCATE); + i++; + break; + // 'U' 譛ェ螳溯」 + case 'w': + _snwprintf_s(tmp, _countof(tmp), _TRUNCATE, L"%d", tm.tm_wday); + wcsncat_s(strtime, sizeof_strtime, tmp, _TRUNCATE); + i++; + break; + // 'W' 譛ェ螳溯」 + // 'x' 譛ェ螳溯」 + // 'X' 譛ェ螳溯」 + case 'y': + // 蟷エ 2譯 + _snwprintf_s(tmp, _countof(tmp), _TRUNCATE, L"%02d", (tm.tm_year + 1900) % 100); + wcsncat_s(strtime, sizeof_strtime, tmp, _TRUNCATE); + i++; + break; + case 'Y': + // 蟷エ 4譯 + _snwprintf_s(tmp, _countof(tmp), _TRUNCATE, L"%04d", (tm.tm_year + 1900)); + wcsncat_s(strtime, sizeof_strtime, tmp, _TRUNCATE); + i++; + break; + // 'z' 譛ェ螳溯」 + // 'Z' 譛ェ螳溯」 + case '%': + wcsncat_s(strtime, sizeof_strtime, L"%", _TRUNCATE); + i++; + break; + case '\0': + default: + // 譛ェ蟇セ蠢懊ョ謖螳壼ュ舌ッ '%' 繧呈ョ九@縺ヲ縺昴ョ縺セ縺セ蜃コ蜉帙☆繧 + // (i 縺ッ騾イ繧√↑縺縺ョ縺ァ縲∵ャ。繝ォ繝シ繝励〒謖螳壼ュ先枚蟄励′繝ェ繝繝ゥ繝ォ縺ィ縺励※騾」邨舌&繧後k) + wcsncat_s(strtime, sizeof_strtime, L"%", _TRUNCATE); + break; + } + } + else { + const wchar_t lit[2] = { format[i], L'\0' }; + wcsncat_s(strtime, sizeof_strtime, lit, _TRUNCATE); + } + } + + return strtime; +} + +/* + * 迴セ蝨ィ縺セ縺ァ縺ョ邨碁℃譎る俣繧呈枚蟄怜励↓縺励※霑斐☆ + * + * @return 邨碁℃譎る俣縺ョ譁蟄怜 + * 荳崎ヲ√↓縺ェ縺」縺溘ifree()縺吶k縺薙→ + */ +wchar_t *strelapsedW(DWORD start_time) +{ + size_t sizeof_strtime = 20; + wchar_t *strtime = malloc(sizeof(wchar_t) * sizeof_strtime); + int days, hours, minutes, seconds, msecs; + DWORD delta = GetTickCount() - start_time; + + msecs = delta % 1000; + delta /= 1000; + + seconds = delta % 60; + delta /= 60; + + minutes = delta % 60; + delta /= 60; + + hours = delta % 24; + days = delta / 24; + + _snwprintf_s(strtime, sizeof_strtime, _TRUNCATE, + L"%d %02d:%02d:%02d.%03d", + days, hours, minutes, seconds, msecs); + + return strtime; +} + /* vim: set ts=4 sw=4 ff=dos : */ diff --git a/teraterm/common/tttypes.h b/teraterm/common/tttypes.h index 523ad1908..1121f95ba 100644 --- a/teraterm/common/tttypes.h +++ b/teraterm/common/tttypes.h @@ -556,7 +556,7 @@ struct tttset { int ZmodemTimeOutFin; WORD WaitCom; WORD reserve_ListHiddenFonts; - char LogTimestampFormat[48]; + char reserve_LogTimestampFormat[48]; int TerminalInputSpeed; int TerminalOutputSpeed; char reserve_DialogFontName[LF_FACESIZE]; // DialogFontNameW 縺ク遘サ陦 @@ -616,6 +616,7 @@ struct tttset { BYTE UnicodeOverrideCharWidthEnable; // 0/1=override縺励↑縺/縺吶k(譁蟄怜ケOverride險ュ螳壼ュ伜惠譎) BYTE UnicodeOverrideCharWidthSelected; // 0... int BroadcastSubmitKey; + wchar_t *LogTimestampFormatW; // Experimental BYTE ExperimentalTreePropertySheetEnable; diff --git a/teraterm/teraterm/filesys_log.cpp b/teraterm/teraterm/filesys_log.cpp index 26eb3ddf6..413dcceec 100644 --- a/teraterm/teraterm/filesys_log.cpp +++ b/teraterm/teraterm/filesys_log.cpp @@ -572,33 +572,52 @@ static void LogRotate(PFileVar fv) logfile_unlock(fv); } -static wchar_t *TimeStampStr(PFileVar fv) +/** + * 繧ソ繧、繝繧ケ繧ソ繝ウ繝礼畑譎る俣譁蟄怜励r菴懈舌☆繧 + * + * @param timestamp_type + * TIMESTAMP_LOCAL + * TIMESTAMP_UTC + * TIMESTAMP_ELAPSED_LOGSTART + * TIMESTAMP_ELAPSED_CONNECTED + * @param format LOCAL or UTC 譎ゅョ繝輔か繝シ繝槭ャ繝 + * @param start_time LOGSTART 縺ョ髢句ァ区凾髢 + * @param connected_time CONNECTED 縺ョ髢句ァ区凾髢 + * @return 譎る俣譁蟄怜励∽ク崎ヲ√↓縺ェ縺」縺溘ifree()縺吶k縺薙→ + */ +wchar_t* FLogTimeStampStrW(enum LogTimestampType timestamp_type, const wchar_t* format, + DWORD start_time, DWORD connected_time) { - char *strtime = NULL; - switch (ts.LogTimestampType) { - case TIMESTAMP_LOCAL: + wchar_t *time_strW = NULL; + switch (timestamp_type) { default: - strtime = mctimelocal(ts.LogTimestampFormat, FALSE); + assert(FALSE); + // FALLTHROUGH + case TIMESTAMP_LOCAL: + time_strW = ttstrftime(format, FALSE); break; case TIMESTAMP_UTC: - strtime = mctimelocal(ts.LogTimestampFormat, TRUE); + time_strW = ttstrftime(format, TRUE); break; case TIMESTAMP_ELAPSED_LOGSTART: - strtime = strelapsed(fv->StartTime); + time_strW = strelapsedW(start_time); break; case TIMESTAMP_ELAPSED_CONNECTED: - strtime = strelapsed(cv.ConnectedTime); + time_strW = strelapsedW(connected_time); break; } - char tmp[128]; - tmp[0] = 0; - strncat_s(tmp, sizeof(tmp), "[", _TRUNCATE); - strncat_s(tmp, sizeof(tmp), strtime, _TRUNCATE); - strncat_s(tmp, sizeof(tmp), "] ", _TRUNCATE); - free(strtime); + wchar_t *ret; + aswprintf(&ret, L"[%s] ", time_strW); + free(time_strW); - return ToWcharA(tmp); + return ret; +} + +static wchar_t *TimeStampStr(PFileVar fv) +{ + return FLogTimeStampStrW((enum LogTimestampType)ts.LogTimestampType, + ts.LogTimestampFormatW, fv->StartTime, cv.ConnectedTime); } /** @@ -1082,12 +1101,14 @@ static void FLogPutUTF32_(PFileVar fv, unsigned int u32) } // 陦碁ュ縺?(謾ケ陦後r蜃コ蜉帙@縺溽峩蠕) - if (ts.LogTimestamp && fv->eLineEnd) { - // 繧ソ繧、繝繧ケ繧ソ繝ウ繝励r蜃コ蜉 - fv->eLineEnd = Line_Other; /* clear endmark*/ - wchar_t* strtime = TimeStampStr(fv); - FLogWriteStr(strtime); - free(strtime); + if (ts.TerminalID != IdDUMB && ts.LogTimestamp) { + if (fv->eLineEnd) { + // 繧ソ繧、繝繧ケ繧ソ繝ウ繝励r蜃コ蜉 + fv->eLineEnd = Line_Other; /* clear endmark*/ + wchar_t* strtime = TimeStampStr(fv); + FLogWriteStr(strtime); + free(strtime); + } } switch(fv->log_code) { diff --git a/teraterm/teraterm/filesys_log.h b/teraterm/teraterm/filesys_log.h index 5b74fb422..e7b059aad 100644 --- a/teraterm/teraterm/filesys_log.h +++ b/teraterm/teraterm/filesys_log.h @@ -74,6 +74,8 @@ void FLogPutBinary(BYTE b); void FLogBinSkip(int add); void FLogOutputAllBuffer(void); +wchar_t* FLogTimeStampStrW(enum LogTimestampType timestamp_type, const wchar_t* format, + DWORD start_time, DWORD connected_time); #ifdef __cplusplus } diff --git a/teraterm/teraterm/vtterm.c b/teraterm/teraterm/vtterm.c index bb1a8722e..0d3217359 100644 --- a/teraterm/teraterm/vtterm.c +++ b/teraterm/teraterm/vtterm.c @@ -5408,6 +5408,19 @@ int VTParse() printf("%02x(%c) ", b, isprint(b) ? b : '.'); } #endif + if (ts.TerminalID == IdDUMB && ts.LogTimestamp) { + if (CursorX == 0) { + if (b != '\n' && b != '\r') { + wchar_t *time_strW = FLogTimeStampStrW(ts.LogTimestampType, + ts.LogTimestampFormatW, cv.ConnectedTime, + cv.ConnectedTime); + for (size_t i = 0; i < wcslen(time_strW); i++) { + PutU32(time_strW[i]); + } + free(time_strW); + } + } + } switch (ParseMode) { case ModeFirst: ParseFirst(charset_data, b); diff --git a/teraterm/ttpcmn/ttcmn_dup.cpp b/teraterm/ttpcmn/ttcmn_dup.cpp index d2161c9ce..d3841db9b 100644 --- a/teraterm/ttpcmn/ttcmn_dup.cpp +++ b/teraterm/ttpcmn/ttcmn_dup.cpp @@ -257,6 +257,7 @@ static const TSerializeInfo serialize_info[] = { { MALLOCED_WSTRING_INFO(TTTSet, DelimListW) }, { MALLOCED_WSTRING_INFO(TTTSet, ViewlogEditorW) }, { MALLOCED_WSTRING_INFO(TTTSet, ViewlogEditorArg) }, + { MALLOCED_WSTRING_INFO(TTTSet, LogTimestampFormatW) }, { 0, 0, TSerializeInfo::COPY }, }; diff --git a/teraterm/ttpset/ttset.c b/teraterm/ttpset/ttset.c index 6ac6c1631..03d794ecf 100644 --- a/teraterm/ttpset/ttset.c +++ b/teraterm/ttpset/ttset.c @@ -993,9 +993,8 @@ void PASCAL _ReadIniFile(const wchar_t *FName, PTTSet ts) ts->LogAllBuffIncludedInFirst = GetOnOff(Section, "LogIncludeScreenBuffer", FName, FALSE); /* Timestamp format of Log each line */ - GetPrivateProfileString(Section, "LogTimestampFormat", "%Y-%m-%d %H:%M:%S.%N", - ts->LogTimestampFormat, sizeof(ts->LogTimestampFormat), - FName); + hGetPrivateProfileStringW(SectionW, L"LogTimestampFormat", L"%Y-%m-%d %H:%M:%S.%N", FName, + &ts->LogTimestampFormatW); /* Timestamp type */ GetPrivateProfileString(Section, "LogTimestampType", "", Temp, sizeof(Temp), FName); @@ -2542,8 +2541,8 @@ void PASCAL _WriteIniFile(const wchar_t *FName, PTTSet ts) WriteOnOff(Section, "LogIncludeScreenBuffer", FName, ts->LogAllBuffIncludedInFirst); /* Timestamp format of Log each line */ - WritePrivateProfileString(Section, "LogTimestampFormat", - ts->LogTimestampFormat, FName); + WritePrivateProfileStringW(SectionW, L"LogTimestampFormat", + ts->LogTimestampFormatW, FName); /* Timestamp type */ switch (ts->LogTimestampType) { diff --git a/ttssh2/ttxssh/ttxssh.c b/ttssh2/ttxssh/ttxssh.c index b2f1421ee..dcce29d7c 100644 --- a/ttssh2/ttxssh/ttxssh.c +++ b/ttssh2/ttxssh/ttxssh.c @@ -830,14 +830,14 @@ void logputs(int level, char *msg) { if (level <= pvar->settings.LogLevel) { char *buf; - char *strtime; + wchar_t *strtime; int len; int file; BOOL enable_log = TRUE; BOOL enable_outputdebugstring = FALSE; - strtime = mctimelocal("%Y-%m-%d %H:%M:%S.%NZ", TRUE); - len = asprintf(&buf, "%s [%lu] %s\n", + strtime = ttstrftime(L"%Y-%m-%d %H:%M:%S.%NZ", TRUE); + len = asprintf(&buf, "%ls [%lu] %s\n", strtime, GetCurrentProcessId(), msg); free(strtime);