| 40 |
#include <setupapi.h> |
#include <setupapi.h> |
| 41 |
#include <locale.h> |
#include <locale.h> |
| 42 |
#include <htmlhelp.h> |
#include <htmlhelp.h> |
| 43 |
|
#include <assert.h> |
| 44 |
|
#include <crtdbg.h> |
| 45 |
|
|
| 46 |
#define DllExport __declspec(dllexport) |
#define DllExport __declspec(dllexport) |
| 47 |
#include "language.h" |
#include "language.h" |
| 54 |
#include "compat_w95.h" |
#include "compat_w95.h" |
| 55 |
#include "tt_res.h" |
#include "tt_res.h" |
| 56 |
#include "codeconv.h" |
#include "codeconv.h" |
| 57 |
|
#include "compat_win.h" |
| 58 |
|
|
| 59 |
#define DllExport __declspec(dllexport) |
#define DllExport __declspec(dllexport) |
| 60 |
#include "ttcommon.h" |
#include "ttcommon.h" |
| 1463 |
return c; |
return c; |
| 1464 |
} |
} |
| 1465 |
|
|
| 1466 |
int WINAPI CommRawOut(PComVar cv, PCHAR B, int C) |
int WINAPI CommRawOut(PComVar cv, /*const*/ PCHAR B, int C) |
| 1467 |
{ |
{ |
| 1468 |
int a; |
int a; |
| 1469 |
|
|
| 1523 |
return i; |
return i; |
| 1524 |
} |
} |
| 1525 |
|
|
| 1526 |
|
/** |
| 1527 |
|
* データ(文字列)を出力バッファへ書き込む |
| 1528 |
|
* |
| 1529 |
|
* 指定データがすべて書き込めない場合は書き込まない |
| 1530 |
|
* CommRawOut() は書き込める分だけ書き込む |
| 1531 |
|
* |
| 1532 |
|
* @retval TRUE 出力できた |
| 1533 |
|
* @retval FALSE 出力できなかった(buffer full) |
| 1534 |
|
*/ |
| 1535 |
|
static BOOL WriteOutBuff(PComVar cv, const char *TempStr, int TempLen) |
| 1536 |
|
{ |
| 1537 |
|
BOOL output; |
| 1538 |
|
|
| 1539 |
|
if (TempLen == 0) { |
| 1540 |
|
// 長さ0で書き込みに来る場合あり |
| 1541 |
|
return TRUE; |
| 1542 |
|
} |
| 1543 |
|
|
| 1544 |
|
output = FALSE; |
| 1545 |
|
if (cv->TelLineMode) { |
| 1546 |
|
const BOOL Full = OutBuffSize - cv->LineModeBuffCount - TempLen < 0; |
| 1547 |
|
if (!Full) { |
| 1548 |
|
output = TRUE; |
| 1549 |
|
memcpy(&(cv->LineModeBuff[cv->LineModeBuffCount]), TempStr, TempLen); |
| 1550 |
|
cv->LineModeBuffCount += TempLen; |
| 1551 |
|
if (cv->Flush) { |
| 1552 |
|
cv->FlushLen = cv->LineModeBuffCount; |
| 1553 |
|
} |
| 1554 |
|
} |
| 1555 |
|
if (cv->FlushLen > 0) { |
| 1556 |
|
const int OutLen = CommRawOut(cv, cv->LineModeBuff, cv->FlushLen); |
| 1557 |
|
cv->FlushLen -= OutLen; |
| 1558 |
|
cv->LineModeBuffCount -= OutLen; |
| 1559 |
|
memmove(cv->LineModeBuff, &(cv->LineModeBuff[OutLen]), cv->LineModeBuffCount); |
| 1560 |
|
} |
| 1561 |
|
cv->Flush = FALSE; |
| 1562 |
|
} |
| 1563 |
|
else { |
| 1564 |
|
const BOOL Full = OutBuffSize-cv->OutBuffCount-TempLen < 0; |
| 1565 |
|
if (! Full) { |
| 1566 |
|
output = TRUE; |
| 1567 |
|
CommRawOut(cv, (char *)TempStr, TempLen); |
| 1568 |
|
} |
| 1569 |
|
} |
| 1570 |
|
return output; |
| 1571 |
|
} |
| 1572 |
|
|
| 1573 |
|
/** |
| 1574 |
|
* データ(文字列)を入力バッファへ書き込む |
| 1575 |
|
* 入力バッファへ入れる -> エコーされる |
| 1576 |
|
* |
| 1577 |
|
* @retval TRUE 出力できた |
| 1578 |
|
* @retval FALSE 出力できなかった(buffer full) |
| 1579 |
|
*/ |
| 1580 |
|
static BOOL WriteInBuff(PComVar cv, const char *TempStr, int TempLen) |
| 1581 |
|
{ |
| 1582 |
|
BOOL Full; |
| 1583 |
|
|
| 1584 |
|
if (TempLen == 0) { |
| 1585 |
|
return TRUE; |
| 1586 |
|
} |
| 1587 |
|
|
| 1588 |
|
Full = InBuffSize-cv->InBuffCount-TempLen < 0; |
| 1589 |
|
if (! Full) { |
| 1590 |
|
memcpy(&(cv->InBuff[cv->InBuffCount]),TempStr,TempLen); |
| 1591 |
|
cv->InBuffCount = cv->InBuffCount + TempLen; |
| 1592 |
|
return TRUE; |
| 1593 |
|
} |
| 1594 |
|
return FALSE; |
| 1595 |
|
} |
| 1596 |
|
|
| 1597 |
|
/** |
| 1598 |
|
* 入力バッファの先頭に空きがあったら詰める |
| 1599 |
|
*/ |
| 1600 |
|
static void PackInBuff(PComVar cv) |
| 1601 |
|
{ |
| 1602 |
|
if ( (cv->InPtr>0) && (cv->InBuffCount>0) ) { |
| 1603 |
|
memmove(cv->InBuff,&(cv->InBuff[cv->InPtr]),cv->InBuffCount); |
| 1604 |
|
cv->InPtr = 0; |
| 1605 |
|
} |
| 1606 |
|
} |
| 1607 |
|
|
| 1608 |
int WINAPI CommBinaryBuffOut(PComVar cv, PCHAR B, int C) |
int WINAPI CommBinaryBuffOut(PComVar cv, PCHAR B, int C) |
| 1609 |
{ |
{ |
| 1610 |
int a, i, Len, OutLen; |
int a, i, Len; |
| 1611 |
char d[3]; |
char d[3]; |
| 1612 |
|
|
| 1613 |
if ( ! cv->Ready ) { |
if ( ! cv->Ready ) { |
| 1634 |
d[Len++] = '\xff'; |
d[Len++] = '\xff'; |
| 1635 |
} |
} |
| 1636 |
|
|
| 1637 |
if (cv->TelLineMode) { |
if (WriteOutBuff(cv, d, Len)) { |
| 1638 |
if (OutBuffSize - cv->LineModeBuffCount - Len >= 0) { |
a = 1; |
| 1639 |
memcpy(&(cv->LineModeBuff[cv->LineModeBuffCount]), d, Len); |
i++; |
| 1640 |
cv->LineModeBuffCount += Len; |
} else { |
| 1641 |
if (cv->Flush) { |
a = 0; |
|
cv->FlushLen = cv->LineModeBuffCount; |
|
|
} |
|
|
a = 1; |
|
|
} |
|
|
else { |
|
|
a = 0; |
|
|
} |
|
|
if (cv->FlushLen > 0) { |
|
|
OutLen = CommRawOut(cv, cv->LineModeBuff, cv->FlushLen); |
|
|
cv->FlushLen -= OutLen; |
|
|
cv->LineModeBuffCount -= OutLen; |
|
|
memmove(cv->LineModeBuff, &(cv->LineModeBuff[OutLen]), cv->LineModeBuffCount); |
|
|
} |
|
|
cv->Flush = FALSE; |
|
|
} |
|
|
else { |
|
|
if ( OutBuffSize - cv->OutBuffCount - Len >= 0 ) { |
|
|
CommRawOut(cv, d, Len); |
|
|
a = 1; |
|
|
} |
|
|
else { |
|
|
a = 0; |
|
|
} |
|
| 1642 |
} |
} |
|
|
|
|
i += a; |
|
| 1643 |
} |
} |
| 1644 |
return i; |
return i; |
| 1645 |
} |
} |
| 1665 |
// |
// |
| 1666 |
static int TextOutMBCS(PComVar cv, PCHAR B, int C) |
static int TextOutMBCS(PComVar cv, PCHAR B, int C) |
| 1667 |
{ |
{ |
| 1668 |
int i, TempLen, OutLen; |
int i, TempLen; |
| 1669 |
WORD K; |
WORD K; |
| 1670 |
char TempStr[12]; |
char TempStr[12]; |
|
int SendCodeNew; |
|
| 1671 |
BYTE d; |
BYTE d; |
| 1672 |
BOOL Full, KanjiFlagNew; |
BOOL Full; |
| 1673 |
|
int SendCodeNew; // 送信コード |
| 1674 |
|
BOOL KanjiFlagNew; // TRUE=次の文字と合わせて漢字とする |
| 1675 |
|
|
| 1676 |
Full = FALSE; |
Full = FALSE; |
| 1677 |
i = 0; |
i = 0; |
| 1829 |
} |
} |
| 1830 |
} // if (cv->SendKanjiFlag) else if ... else ... end |
} // if (cv->SendKanjiFlag) else if ... else ... end |
| 1831 |
|
|
| 1832 |
if (cv->TelLineMode) { |
if (WriteOutBuff(cv, TempStr, TempLen)) { |
| 1833 |
if (TempLen == 0) { |
i++; // 1文字処理した |
| 1834 |
i++; |
// 漢字の状態を保存する |
| 1835 |
cv->SendCode = SendCodeNew; |
cv->SendCode = SendCodeNew; |
| 1836 |
cv->SendKanjiFlag = KanjiFlagNew; |
cv->SendKanjiFlag = KanjiFlagNew; |
| 1837 |
} |
} else { |
| 1838 |
else { |
Full = TRUE; |
|
Full = OutBuffSize - cv->LineModeBuffCount - TempLen < 0; |
|
|
if (!Full) { |
|
|
i++; |
|
|
cv->SendCode = SendCodeNew; |
|
|
cv->SendKanjiFlag = KanjiFlagNew; |
|
|
memcpy(&(cv->LineModeBuff[cv->LineModeBuffCount]), TempStr, TempLen); |
|
|
cv->LineModeBuffCount += TempLen; |
|
|
if (cv->Flush) { |
|
|
cv->FlushLen = cv->LineModeBuffCount; |
|
|
} |
|
|
} |
|
|
} |
|
|
if (cv->FlushLen > 0) { |
|
|
OutLen = CommRawOut(cv, cv->LineModeBuff, cv->FlushLen); |
|
|
cv->FlushLen -= OutLen; |
|
|
cv->LineModeBuffCount -= OutLen; |
|
|
memmove(cv->LineModeBuff, &(cv->LineModeBuff[OutLen]), cv->LineModeBuffCount); |
|
|
} |
|
|
cv->Flush = FALSE; |
|
|
} |
|
|
else { |
|
|
if (TempLen == 0) { |
|
|
i++; |
|
|
cv->SendCode = SendCodeNew; |
|
|
cv->SendKanjiFlag = KanjiFlagNew; |
|
|
} |
|
|
else { |
|
|
Full = OutBuffSize-cv->OutBuffCount-TempLen < 0; |
|
|
if (! Full) { |
|
|
i++; |
|
|
cv->SendCode = SendCodeNew; |
|
|
cv->SendKanjiFlag = KanjiFlagNew; |
|
|
CommRawOut(cv,TempStr,TempLen); |
|
|
} |
|
|
} |
|
| 1839 |
} |
} |
| 1840 |
|
|
| 1841 |
} // end of "while {}" |
} // end of "while {}" |
| 1845 |
|
|
| 1846 |
int WINAPI CommTextOut(PComVar cv, PCHAR B, int C) |
int WINAPI CommTextOut(PComVar cv, PCHAR B, int C) |
| 1847 |
{ |
{ |
| 1848 |
int i, TempLen, OutLen; |
int i, TempLen; |
| 1849 |
char TempStr[12]; |
char TempStr[12]; |
| 1850 |
BYTE d; |
BYTE d; |
| 1851 |
BOOL Full; |
BOOL Full; |
| 1916 |
} |
} |
| 1917 |
} |
} |
| 1918 |
|
|
| 1919 |
|
if (WriteOutBuff(cv, TempStr, TempLen)) { |
| 1920 |
|
i++; // 1文字処理した |
| 1921 |
|
} else { |
| 1922 |
|
Full = TRUE; |
| 1923 |
|
} |
| 1924 |
|
|
| 1925 |
|
} // end of while {} |
| 1926 |
|
|
| 1927 |
|
return i; |
| 1928 |
|
} |
| 1929 |
|
|
| 1930 |
|
/** |
| 1931 |
|
* @retval true 日本語の半角カタカナ |
| 1932 |
|
* @retval false その他 |
| 1933 |
|
*/ |
| 1934 |
|
static BOOL IsHalfWidthKatakana(unsigned int u32) |
| 1935 |
|
{ |
| 1936 |
|
// Halfwidth CJK punctuation (U+FF61〜FF64) |
| 1937 |
|
// Halfwidth Katakana variants (U+FF65〜FF9F) |
| 1938 |
|
return (0xff61 <= u32 && u32 <= 0xff9f); |
| 1939 |
|
} |
| 1940 |
|
|
| 1941 |
|
/** |
| 1942 |
|
* 出力用、 TODO echo用を作る |
| 1943 |
|
* @param cv |
| 1944 |
|
* @param u32 入力文字 |
| 1945 |
|
* @param check_only TRUEで処理は行わず、 |
| 1946 |
|
* @param TempStr 出力文字数 |
| 1947 |
|
* @param StrLen TempStrへの出力文字数 |
| 1948 |
|
* @retval 処理を行った |
| 1949 |
|
*/ |
| 1950 |
|
static BOOL OutControl(PComVar cv, unsigned int u32, BOOL check_only, char *TempStr, size_t *StrLen) |
| 1951 |
|
{ |
| 1952 |
|
const wchar_t d = u32; |
| 1953 |
|
size_t TempLen = 0; |
| 1954 |
|
BOOL retval = FALSE; |
| 1955 |
|
if (check_only == TRUE) { |
| 1956 |
|
/* チェックのみ */ |
| 1957 |
|
if (d == CR || d == BS || d == 0x15/*ctrl-u*/) { |
| 1958 |
|
return TRUE; |
| 1959 |
|
} else { |
| 1960 |
|
return FALSE; |
| 1961 |
|
} |
| 1962 |
|
} |
| 1963 |
|
if (d==CR) { |
| 1964 |
|
TempStr[TempLen++] = 0x0d; |
| 1965 |
|
if (cv->CRSend==IdCRLF) { |
| 1966 |
|
TempStr[TempLen++] = 0x0a; |
| 1967 |
|
} |
| 1968 |
|
else if ((cv->CRSend ==IdCR) && |
| 1969 |
|
cv->TelFlag && ! cv->TelBinSend) { |
| 1970 |
|
TempStr[TempLen++] = 0; |
| 1971 |
|
} |
| 1972 |
|
else if (cv->CRSend == IdLF) { |
| 1973 |
|
TempStr[TempLen-1] = 0x0a; |
| 1974 |
|
} |
| 1975 |
|
if (cv->TelLineMode) { |
| 1976 |
|
cv->Flush = TRUE; |
| 1977 |
|
} |
| 1978 |
|
retval = TRUE; |
| 1979 |
|
} |
| 1980 |
|
else if (d== BS) { |
| 1981 |
if (cv->TelLineMode) { |
if (cv->TelLineMode) { |
| 1982 |
Full = OutBuffSize - cv->LineModeBuffCount - TempLen < 0; |
if (cv->FlushLen < cv->LineModeBuffCount) { |
| 1983 |
if (!Full) { |
cv->LineModeBuffCount--; |
|
i++; |
|
|
memcpy(&(cv->LineModeBuff[cv->LineModeBuffCount]), TempStr, TempLen); |
|
|
cv->LineModeBuffCount += TempLen; |
|
|
if (cv->Flush) { |
|
|
cv->FlushLen = cv->LineModeBuffCount; |
|
|
} |
|
|
} |
|
|
if (cv->FlushLen > 0) { |
|
|
OutLen = CommRawOut(cv, cv->LineModeBuff, cv->FlushLen); |
|
|
cv->FlushLen -= OutLen; |
|
|
cv->LineModeBuffCount -= OutLen; |
|
|
memmove(cv->LineModeBuff, &(cv->LineModeBuff[OutLen]), cv->LineModeBuffCount); |
|
| 1984 |
} |
} |
|
cv->Flush = FALSE; |
|
| 1985 |
} |
} |
| 1986 |
else { |
else { |
| 1987 |
Full = OutBuffSize - cv->OutBuffCount - TempLen < 0; |
TempStr[TempLen++] = BS; |
| 1988 |
if (! Full) { |
} |
| 1989 |
i++; |
retval = TRUE; |
| 1990 |
CommRawOut(cv,TempStr,TempLen); |
} |
| 1991 |
|
else if (d==0x15) { // ctrl-u |
| 1992 |
|
if (cv->TelLineMode) { |
| 1993 |
|
cv->LineModeBuffCount = cv->FlushLen; |
| 1994 |
|
} |
| 1995 |
|
else { |
| 1996 |
|
TempStr[TempLen++] = 0x15; |
| 1997 |
|
} |
| 1998 |
|
retval = TRUE; |
| 1999 |
|
} |
| 2000 |
|
*StrLen = TempLen; |
| 2001 |
|
return retval; |
| 2002 |
|
} |
| 2003 |
|
static BOOL ControlEcho(PComVar cv, unsigned int u32, BOOL check_only, char *TempStr, size_t *StrLen) |
| 2004 |
|
{ |
| 2005 |
|
const wchar_t d = u32; |
| 2006 |
|
size_t TempLen = 0; |
| 2007 |
|
BOOL retval = FALSE; |
| 2008 |
|
if (check_only == TRUE) { |
| 2009 |
|
/* チェックのみ */ |
| 2010 |
|
if (d == CR || (d == 0x15/*ctrl-u*/ && cv->TelLineMode)) { |
| 2011 |
|
return TRUE; |
| 2012 |
|
} else { |
| 2013 |
|
return FALSE; |
| 2014 |
|
} |
| 2015 |
|
} |
| 2016 |
|
if (d==CR) { |
| 2017 |
|
TempStr[TempLen++] = 0x0d; |
| 2018 |
|
if (cv->CRSend==IdCRLF) { |
| 2019 |
|
TempStr[TempLen++] = 0x0a; |
| 2020 |
|
} |
| 2021 |
|
else if ((cv->CRSend ==IdCR) && cv->TelFlag && ! cv->TelBinSend) { |
| 2022 |
|
TempStr[TempLen++] = 0; |
| 2023 |
|
} |
| 2024 |
|
else if (cv->CRSend == IdLF) { |
| 2025 |
|
TempStr[TempLen-1] = 0x0a; |
| 2026 |
|
} |
| 2027 |
|
retval = TRUE; |
| 2028 |
|
} |
| 2029 |
|
else if (d==0x15/*ctrl-u*/ && cv->TelLineMode) { |
| 2030 |
|
// Move to top of line (CHA "\033[G") and erase line (EL "\033[K") |
| 2031 |
|
memcpy(TempStr, "\033[G\033[K", 6); |
| 2032 |
|
TempLen += 6; |
| 2033 |
|
retval = TRUE; |
| 2034 |
|
} |
| 2035 |
|
*StrLen = TempLen; |
| 2036 |
|
return retval; |
| 2037 |
|
} |
| 2038 |
|
|
| 2039 |
|
/** |
| 2040 |
|
* 出力用文字列を作成する |
| 2041 |
|
* |
| 2042 |
|
* @retval 消費した文字数 |
| 2043 |
|
*/ |
| 2044 |
|
typedef struct { |
| 2045 |
|
int KanjiCode; // [in]出力文字コード(sjis,jisなど) |
| 2046 |
|
BOOL (*ControlOut)(PComVar cv, unsigned int u32, BOOL check_only, char *TempStr, size_t *StrLen); |
| 2047 |
|
// stateを保存する必要がある文字コードで使用 |
| 2048 |
|
BOOL JIS7Katakana; // [in](Kanji JIS)kana |
| 2049 |
|
int SendCode; // [in,out](Kanji JIS)直前の送信コード Ascii/Kana/Kanji |
| 2050 |
|
BOOL KanjiFlag; // [in,out](MBCS)直前の1byteが漢字だったか?(2byte文字だったか?) |
| 2051 |
|
BYTE KanjiFirst; // [in,out](MBCS)直前の1byte |
| 2052 |
|
} OutputCharState; |
| 2053 |
|
|
| 2054 |
|
/** |
| 2055 |
|
* unicode(UTF-16)からunicode(UTF-32)を1文字取り出して |
| 2056 |
|
* 出力データ(TempStr)を作成する |
| 2057 |
|
*/ |
| 2058 |
|
static size_t MakeOutputString(PComVar cv, OutputCharState *states, |
| 2059 |
|
const wchar_t *B, int C, |
| 2060 |
|
char *TempStr, int *TempLen_) |
| 2061 |
|
{ |
| 2062 |
|
BOOL (*ControlOut)(PComVar cv, unsigned int u32, BOOL check_only, char *TempStr, size_t *StrLen) |
| 2063 |
|
= states->ControlOut; |
| 2064 |
|
// |
| 2065 |
|
int TempLen = 0; |
| 2066 |
|
size_t TempLen2; |
| 2067 |
|
size_t output_char_count; // 消費した文字数 |
| 2068 |
|
|
| 2069 |
|
// UTF-32 を1文字取り出す |
| 2070 |
|
unsigned int u32; |
| 2071 |
|
size_t u16_len = UTF16ToUTF32(B, C, &u32); |
| 2072 |
|
if (u16_len == 0) { |
| 2073 |
|
// デコードできない? あり得ないのでは? |
| 2074 |
|
assert(FALSE); |
| 2075 |
|
u32 = '?'; |
| 2076 |
|
u16_len = 1; |
| 2077 |
|
} |
| 2078 |
|
output_char_count = u16_len; |
| 2079 |
|
|
| 2080 |
|
// 各種シフト状態を通常に戻す |
| 2081 |
|
if (u32 < 0x100 || ControlOut(cv, u32, TRUE, NULL, NULL)) { |
| 2082 |
|
if (cv->Language == IdJapanese && states->KanjiCode == IdJIS) { |
| 2083 |
|
// 今のところ、日本語,JISしかない |
| 2084 |
|
if (cv->SendCode == IdKanji) { |
| 2085 |
|
// 漢字ではないので、漢字OUT |
| 2086 |
|
TempStr[TempLen++] = 0x1B; |
| 2087 |
|
TempStr[TempLen++] = '('; |
| 2088 |
|
switch (cv->KanjiOut) { |
| 2089 |
|
case IdKanjiOutJ: |
| 2090 |
|
TempStr[TempLen++] = 'J'; |
| 2091 |
|
break; |
| 2092 |
|
case IdKanjiOutH: |
| 2093 |
|
TempStr[TempLen++] = 'H'; |
| 2094 |
|
break; |
| 2095 |
|
default: |
| 2096 |
|
TempStr[TempLen++] = 'B'; |
| 2097 |
|
} |
| 2098 |
|
} |
| 2099 |
|
|
| 2100 |
|
if (states->JIS7Katakana == 1) { |
| 2101 |
|
if (cv->SendCode == IdKatakana) { |
| 2102 |
|
TempStr[TempLen++] = SO; |
| 2103 |
|
} |
| 2104 |
} |
} |
| 2105 |
|
|
| 2106 |
|
states->SendCode = IdASCII; |
| 2107 |
} |
} |
| 2108 |
} // end of while {} |
} |
| 2109 |
|
|
| 2110 |
return i; |
// 1文字処理する |
| 2111 |
|
if (ControlOut(cv, u32, FALSE, TempStr, &TempLen2)) { |
| 2112 |
|
// 特別な文字を処理した |
| 2113 |
|
TempLen += TempLen2; |
| 2114 |
|
output_char_count = 1; |
| 2115 |
|
} else if (cv->Language == IdUtf8 || |
| 2116 |
|
(cv->Language == IdJapanese && states->KanjiCode == IdUTF8) || |
| 2117 |
|
(cv->Language == IdKorean && states->KanjiCode == IdUTF8)) |
| 2118 |
|
{ |
| 2119 |
|
// UTF-8 で出力 |
| 2120 |
|
size_t utf8_len = sizeof(TempStr); |
| 2121 |
|
utf8_len = UTF32ToUTF8(u32, TempStr, utf8_len); |
| 2122 |
|
TempLen += utf8_len; |
| 2123 |
|
} else if (cv->Language == IdJapanese && *cv->CodePage == 932) { |
| 2124 |
|
// 日本語 |
| 2125 |
|
// まず CP932(SJIS) に変換してから出力 |
| 2126 |
|
char mb_char[2]; |
| 2127 |
|
size_t mb_len = sizeof(mb_char); |
| 2128 |
|
mb_len = UTF32ToMBCP(u32, 932, mb_char, mb_len); |
| 2129 |
|
if (mb_len == 0) { |
| 2130 |
|
// SJISに変換できない |
| 2131 |
|
TempStr[TempLen++] = '?'; |
| 2132 |
|
} else { |
| 2133 |
|
switch (states->KanjiCode) { |
| 2134 |
|
case IdEUC: |
| 2135 |
|
// TODO 半角カナ |
| 2136 |
|
if (mb_len == 1) { |
| 2137 |
|
TempStr[TempLen++] = mb_char[0]; |
| 2138 |
|
} else { |
| 2139 |
|
WORD K; |
| 2140 |
|
K = (((WORD)(unsigned char)mb_char[0]) << 8) + |
| 2141 |
|
(WORD)(unsigned char)mb_char[1]; |
| 2142 |
|
K = SJIS2EUC(K); |
| 2143 |
|
TempStr[TempLen++] = HIBYTE(K); |
| 2144 |
|
TempStr[TempLen++] = LOBYTE(K); |
| 2145 |
|
} |
| 2146 |
|
break; |
| 2147 |
|
case IdJIS: |
| 2148 |
|
if (u32 < 0x100) { |
| 2149 |
|
// ASCII |
| 2150 |
|
TempStr[TempLen++] = mb_char[0]; |
| 2151 |
|
states->SendCode = IdASCII; |
| 2152 |
|
} else if (IsHalfWidthKatakana(u32)) { |
| 2153 |
|
// 半角カタカナ |
| 2154 |
|
if (states->JIS7Katakana==1) { |
| 2155 |
|
if (cv->SendCode != IdKatakana) { |
| 2156 |
|
TempStr[TempLen++] = SI; |
| 2157 |
|
} |
| 2158 |
|
TempStr[TempLen++] = mb_char[0] & 0x7f; |
| 2159 |
|
} else { |
| 2160 |
|
TempStr[TempLen++] = mb_char[0]; |
| 2161 |
|
} |
| 2162 |
|
states->SendCode = IdKatakana; |
| 2163 |
|
} else { |
| 2164 |
|
// 漢字 |
| 2165 |
|
WORD K; |
| 2166 |
|
K = (((WORD)(unsigned char)mb_char[0]) << 8) + |
| 2167 |
|
(WORD)(unsigned char)mb_char[1]; |
| 2168 |
|
K = SJIS2JIS(K); |
| 2169 |
|
if (states->SendCode != IdKanji) { |
| 2170 |
|
// 漢字IN |
| 2171 |
|
TempStr[TempLen++] = 0x1B; |
| 2172 |
|
TempStr[TempLen++] = '$'; |
| 2173 |
|
if (cv->KanjiIn == IdKanjiInB) { |
| 2174 |
|
TempStr[TempLen++] = 'B'; |
| 2175 |
|
} |
| 2176 |
|
else { |
| 2177 |
|
TempStr[TempLen++] = '@'; |
| 2178 |
|
} |
| 2179 |
|
states->SendCode = IdKanji; |
| 2180 |
|
} |
| 2181 |
|
TempStr[TempLen++] = HIBYTE(K); |
| 2182 |
|
TempStr[TempLen++] = LOBYTE(K); |
| 2183 |
|
} |
| 2184 |
|
break; |
| 2185 |
|
case IdSJIS: |
| 2186 |
|
if (mb_len == 1) { |
| 2187 |
|
TempStr[TempLen++] = mb_char[0]; |
| 2188 |
|
} else { |
| 2189 |
|
TempStr[TempLen++] = mb_char[0]; |
| 2190 |
|
TempStr[TempLen++] = mb_char[1]; |
| 2191 |
|
} |
| 2192 |
|
break; |
| 2193 |
|
default: |
| 2194 |
|
assert(FALSE); |
| 2195 |
|
break; |
| 2196 |
|
} |
| 2197 |
|
} |
| 2198 |
|
} else if (cv->Language == IdRussian) { |
| 2199 |
|
/* まずCP1251に変換して出力 */ |
| 2200 |
|
char mb_char[2]; |
| 2201 |
|
size_t mb_len = sizeof(mb_char); |
| 2202 |
|
BYTE b; |
| 2203 |
|
mb_len = UTF32ToMBCP(u32, 1251, mb_char, mb_len); |
| 2204 |
|
if (mb_len != 1) { |
| 2205 |
|
b = '?'; |
| 2206 |
|
} else { |
| 2207 |
|
b = RussConv(IdWindows, cv->RussHost, mb_char[0]); |
| 2208 |
|
} |
| 2209 |
|
TempStr[TempLen++] = b; |
| 2210 |
|
} else if (cv->Language == IdKorean && *cv->CodePage == 51949) { |
| 2211 |
|
/* CP51949に変換して出力 */ |
| 2212 |
|
char mb_char[2]; |
| 2213 |
|
size_t mb_len = sizeof(mb_char); |
| 2214 |
|
mb_len = UTF32ToMBCP(u32, 51949, mb_char, mb_len); |
| 2215 |
|
if (mb_len == 0) { |
| 2216 |
|
TempStr[TempLen++] = '?'; |
| 2217 |
|
} |
| 2218 |
|
else if (mb_len == 1) { |
| 2219 |
|
TempStr[TempLen++] = mb_char[0]; |
| 2220 |
|
} else { |
| 2221 |
|
TempStr[TempLen++] = mb_char[0]; |
| 2222 |
|
TempStr[TempLen++] = mb_char[1]; |
| 2223 |
|
} |
| 2224 |
|
} else if (cv->Language == IdEnglish) { |
| 2225 |
|
TempStr[TempLen++] = u32; |
| 2226 |
|
} else { |
| 2227 |
|
// CodePageで変換 |
| 2228 |
|
char mb_char[2]; |
| 2229 |
|
size_t mb_len = sizeof(mb_char); |
| 2230 |
|
mb_len = UTF32ToMBCP(u32, *cv->CodePage, mb_char, mb_len); |
| 2231 |
|
if (mb_len == 0) { |
| 2232 |
|
TempStr[TempLen++] = '?'; |
| 2233 |
|
} |
| 2234 |
|
else if (mb_len == 1) { |
| 2235 |
|
TempStr[TempLen++] = mb_char[0]; |
| 2236 |
|
} else { |
| 2237 |
|
TempStr[TempLen++] = mb_char[0]; |
| 2238 |
|
TempStr[TempLen++] = mb_char[1]; |
| 2239 |
|
} |
| 2240 |
|
} |
| 2241 |
|
|
| 2242 |
|
*TempLen_ = TempLen; |
| 2243 |
|
return output_char_count; |
| 2244 |
} |
} |
| 2245 |
|
|
| 2246 |
// TODO: UTF-16から直接変換して出力する |
|
| 2247 |
|
/** |
| 2248 |
|
* CommTextOut() の wchar_t 版 |
| 2249 |
|
* |
| 2250 |
|
* @retval 出力文字数(wchar_t単位) |
| 2251 |
|
*/ |
| 2252 |
int WINAPI CommTextOutW(PComVar cv, const wchar_t *B, int C) |
int WINAPI CommTextOutW(PComVar cv, const wchar_t *B, int C) |
| 2253 |
{ |
{ |
| 2254 |
int CodePage = *cv->CodePage; |
char TempStr[12]; |
| 2255 |
size_t mb_len; |
BOOL Full = FALSE; |
| 2256 |
int r; |
int i = 0; |
| 2257 |
char *mb_str = _WideCharToMultiByte(B, C, CodePage, &mb_len); |
while (! Full && (i < C)) { |
| 2258 |
if (mb_str == NULL) { |
// 出力用データを作成 |
| 2259 |
r = 0; |
int TempLen = 0; |
| 2260 |
} else { |
size_t output_char_count; // 消費した文字数 |
| 2261 |
r = CommTextOut(cv, mb_str, mb_len); |
OutputCharState state; |
| 2262 |
free(mb_str); |
state.KanjiCode = cv->KanjiCodeSend; |
| 2263 |
} |
state.ControlOut = OutControl; |
| 2264 |
return r; |
state.SendCode = cv->SendCode; |
| 2265 |
|
state.JIS7Katakana = cv->JIS7KatakanaSend; |
| 2266 |
|
output_char_count = MakeOutputString(cv, &state, &B[i], C-i, TempStr, &TempLen); |
| 2267 |
|
|
| 2268 |
|
// データを出力バッファへ |
| 2269 |
|
if (WriteOutBuff(cv, TempStr, TempLen)) { |
| 2270 |
|
i += output_char_count; // output_char_count 文字数 処理した |
| 2271 |
|
// 漢字の状態を保存する |
| 2272 |
|
cv->SendCode = state.SendCode; |
| 2273 |
|
} else { |
| 2274 |
|
Full = TRUE; |
| 2275 |
|
} |
| 2276 |
|
} // end of "while {}" |
| 2277 |
|
_CrtCheckMemory(); |
| 2278 |
|
return i; |
| 2279 |
} |
} |
| 2280 |
|
|
| 2281 |
// TODO: UTF-16から直接変換して出力する |
/** |
| 2282 |
|
* CommTextEcho() の wchar_t 版 |
| 2283 |
|
* |
| 2284 |
|
* @retval 出力文字数(wchar_t単位) |
| 2285 |
|
*/ |
| 2286 |
int WINAPI CommTextEchoW(PComVar cv, const wchar_t *B, int C) |
int WINAPI CommTextEchoW(PComVar cv, const wchar_t *B, int C) |
| 2287 |
{ |
{ |
| 2288 |
int CodePage = *cv->CodePage; |
char TempStr[12]; |
| 2289 |
size_t mb_len; |
BOOL Full = FALSE; |
| 2290 |
int r; |
int i = 0; |
| 2291 |
char *mb_str = _WideCharToMultiByte(B, C, CodePage, &mb_len); |
while (! Full && (i < C)) { |
| 2292 |
if (mb_str == NULL) { |
// 出力用データを作成 |
| 2293 |
r = 0; |
int TempLen = 0; |
| 2294 |
} else { |
size_t output_char_count; // 消費した文字数 |
| 2295 |
r = CommTextEcho(cv, mb_str, mb_len); |
OutputCharState state; |
| 2296 |
free(mb_str); |
state.KanjiCode = cv->KanjiCodeEcho; |
| 2297 |
} |
state.ControlOut = ControlEcho; |
| 2298 |
return r; |
state.SendCode = cv->EchoCode; |
| 2299 |
|
state.JIS7Katakana = cv->JIS7KatakanaEcho; |
| 2300 |
|
output_char_count = MakeOutputString(cv, &state, &B[i], C-i, TempStr, &TempLen); |
| 2301 |
|
|
| 2302 |
|
// データを出力バッファへ |
| 2303 |
|
if (WriteInBuff(cv, TempStr, TempLen)) { |
| 2304 |
|
i += output_char_count; // output_char_count 文字数 処理した |
| 2305 |
|
// 漢字の状態を保存する |
| 2306 |
|
cv->EchoCode = state.SendCode; |
| 2307 |
|
} else { |
| 2308 |
|
Full = TRUE; |
| 2309 |
|
} |
| 2310 |
|
} // end of "while {}" |
| 2311 |
|
_CrtCheckMemory(); |
| 2312 |
|
return i; |
| 2313 |
} |
} |
| 2314 |
|
|
| 2315 |
int WINAPI CommBinaryEcho(PComVar cv, PCHAR B, int C) |
int WINAPI CommBinaryEcho(PComVar cv, PCHAR B, int C) |
| 2320 |
if ( ! cv->Ready ) |
if ( ! cv->Ready ) |
| 2321 |
return C; |
return C; |
| 2322 |
|
|
| 2323 |
if ( (cv->InPtr>0) && (cv->InBuffCount>0) ) { |
PackInBuff(cv); |
|
memmove(cv->InBuff,&(cv->InBuff[cv->InPtr]),cv->InBuffCount); |
|
|
cv->InPtr = 0; |
|
|
} |
|
| 2324 |
|
|
| 2325 |
i = 0; |
i = 0; |
| 2326 |
a = 1; |
a = 1; |
| 2341 |
Len++; |
Len++; |
| 2342 |
} |
} |
| 2343 |
|
|
| 2344 |
if ( InBuffSize-cv->InBuffCount-Len >=0 ) { |
if (WriteInBuff(cv, d, Len)) { |
|
memcpy(&(cv->InBuff[cv->InBuffCount]),d,Len); |
|
|
cv->InBuffCount = cv->InBuffCount + Len; |
|
| 2345 |
a = 1; |
a = 1; |
| 2346 |
} |
i++; |
| 2347 |
else |
} else { |
| 2348 |
a = 0; |
a = 0; |
| 2349 |
i = i + a; |
} |
| 2350 |
} |
} |
| 2351 |
return i; |
return i; |
| 2352 |
} |
} |
| 2505 |
} |
} |
| 2506 |
} // if (cv->EchoKanjiFlag) else if ... else ... end |
} // if (cv->EchoKanjiFlag) else if ... else ... end |
| 2507 |
|
|
| 2508 |
if (TempLen == 0) { |
if (WriteInBuff(cv, TempStr, TempLen)) { |
| 2509 |
i++; |
i++; |
| 2510 |
cv->EchoCode = EchoCodeNew; |
cv->EchoCode = EchoCodeNew; |
| 2511 |
cv->EchoKanjiFlag = KanjiFlagNew; |
cv->EchoKanjiFlag = KanjiFlagNew; |
| 2512 |
} |
} else { |
| 2513 |
else { |
Full = FALSE; |
|
Full = InBuffSize-cv->InBuffCount-TempLen < 0; |
|
|
if (! Full) { |
|
|
i++; |
|
|
cv->EchoCode = EchoCodeNew; |
|
|
cv->EchoKanjiFlag = KanjiFlagNew; |
|
|
memcpy(&(cv->InBuff[cv->InBuffCount]),TempStr,TempLen); |
|
|
cv->InBuffCount = cv->InBuffCount + TempLen; |
|
|
} |
|
| 2514 |
} |
} |
| 2515 |
|
|
| 2516 |
} // end of "while {}" |
} // end of "while {}" |
| 2529 |
return C; |
return C; |
| 2530 |
} |
} |
| 2531 |
|
|
| 2532 |
if ( (cv->InPtr>0) && (cv->InBuffCount>0) ) { |
PackInBuff(cv); |
|
memmove(cv->InBuff,&(cv->InBuff[cv->InPtr]),cv->InBuffCount); |
|
|
cv->InPtr = 0; |
|
|
} |
|
| 2533 |
|
|
| 2534 |
switch (cv->Language) { |
switch (cv->Language) { |
| 2535 |
case IdUtf8: |
case IdUtf8: |
| 2581 |
} |
} |
| 2582 |
} |
} |
| 2583 |
|
|
| 2584 |
Full = InBuffSize-cv->InBuffCount-TempLen < 0; |
if(WriteInBuff(cv, TempStr,TempLen)) { |
|
if (! Full) { |
|
| 2585 |
i++; |
i++; |
| 2586 |
memcpy(&(cv->InBuff[cv->InBuffCount]),TempStr,TempLen); |
} else { |
| 2587 |
cv->InBuffCount = cv->InBuffCount + TempLen; |
Full = TRUE; |
| 2588 |
} |
} |
| 2589 |
} // end of while {} |
} // end of while {} |
| 2590 |
|
|
| 3032 |
// dllロード失敗、teratermが起動しない |
// dllロード失敗、teratermが起動しない |
| 3033 |
return FALSE; |
return FALSE; |
| 3034 |
} |
} |
| 3035 |
|
WinCompatInit(); |
| 3036 |
break; |
break; |
| 3037 |
case DLL_PROCESS_DETACH: |
case DLL_PROCESS_DETACH: |
| 3038 |
/* do process cleanup */ |
/* do process cleanup */ |