Develop and Download Open Source Software

Browse Subversion Repository

Contents of /trunk/teraterm/ttpcmn/ttcmn.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 9306 - (show annotations) (download) (as text)
Sat Jun 12 15:29:32 2021 UTC (2 years, 9 months ago) by zmatsuo
File MIME type: text/x-csrc
File size: 45888 byte(s)
TTTSet構造体のファイルを保持するメンバをUnicode化,動的バッファ化した

- common/tttypes.h
- 次のメンバを追加
  - wchar_t *HomeDirW;
  - wchar_t *SetupFNameW;
  - wchar_t *KeyCnfFNW;
  - wchar_t *LogFNW;
  - wchar_t *MacroFNW;
  - wchar_t *UILanguageFileW;
  - wchar_t *UILanguageFileW_ini;
  - 主要なメンバのみ
- 従来の(ANSI文字列版)メンバーも利用可能
  - Unicode版から変換
  - 従来通りのフォルダ名に従来通りのファイル名で使用すれば問題は起きないはず
- Tera Term内部はほとんど従来通り(ANSI文字版)を使用
1 /*
2 * Copyright (C) 1994-1998 T. Teranishi
3 * (C) 2004- TeraTerm Project
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30 /* TTCMN.DLL, main */
31 #include <direct.h>
32 #include <string.h>
33 #include <stdio.h>
34 #include <windows.h>
35 #include <setupapi.h>
36 #include <locale.h>
37 #include <htmlhelp.h>
38 #include <assert.h>
39 #include <crtdbg.h>
40
41 #define DllExport __declspec(dllexport)
42 #include "language.h"
43 #undef DllExport
44
45 #include "teraterm.h"
46 #include "tttypes.h"
47 #include "ttlib.h"
48 #include "tt_res.h"
49 #include "codeconv.h"
50 #include "compat_win.h"
51
52 #define DllExport __declspec(dllexport)
53 #include "ttcommon.h"
54 #include "layer_for_unicode.h"
55
56 /* shared memory */
57 typedef struct {
58 size_t size_tmap; /* sizeof TMap */
59 size_t size_tttset; /* sizeof TTTSet */
60 /* Setup information from "teraterm.ini" */
61 TTTSet ts;
62 // Window list
63 int NWin;
64 HWND WinList[MAXNWIN];
65 /* COM port use flag
66 * bit 8 7 6 5 4 3 2 1
67 * char[0] : COM 8 7 6 5 4 3 2 1
68 * char[1] : COM16 15 14 13 12 11 10 9 ...
69 */
70 unsigned char ComFlag[(MAXCOMPORT-1)/CHAR_BIT+1];
71 /* Previous window rect (Tera Term 4.78 or later) */
72 WINDOWPLACEMENT WinPrevRect[MAXNWIN];
73 BOOL WinUndoFlag;
74 int WinUndoStyle;
75 } TMap;
76 typedef TMap *PMap;
77
78 // TMap ���i�[�����t�@�C���}�b�s���O�I�u�W�F�N�g(���L������)�����O
79 // TMap(�����������o)���X�V�������o�[�W�������������N���������������K�v��������
80 // �A�������o�[�W�����������g�����������X�������A���������������X�����K�v������
81 #define TT_FILEMAPNAME "ttset_memfilemap_" TT_VERSION_STR("_")
82
83 /* first instance flag */
84 static BOOL FirstInstance = TRUE;
85
86 static HINSTANCE hInst;
87
88 static PMap pm;
89
90 static HANDLE HMap = NULL;
91 #define VTCLASSNAME "VTWin32"
92 #define TEKCLASSNAME "TEKWin32"
93
94 enum window_style {
95 WIN_CASCADE,
96 WIN_STACKED,
97 WIN_SIDEBYSIDE,
98 };
99
100
101 void WINAPI CopyShmemToTTSet(PTTSet ts)
102 {
103 // ���������������L�����������R�s�[����
104 memcpy(ts, &pm->ts, sizeof(TTTSet));
105 }
106
107 void WINAPI CopyTTSetToShmem(PTTSet ts)
108 {
109 // ���������������L���������R�s�[����
110 memcpy(&pm->ts, ts, sizeof(TTTSet));
111 }
112
113 BOOL WINAPI StartTeraTerm(PTTSet ts)
114 {
115 if (FirstInstance) {
116 // init window list
117 pm->NWin = 0;
118 }
119 else {
120 /* only the first instance uses saved position */
121 pm->ts.VTPos.x = CW_USEDEFAULT;
122 pm->ts.VTPos.y = CW_USEDEFAULT;
123 pm->ts.TEKPos.x = CW_USEDEFAULT;
124 pm->ts.TEKPos.y = CW_USEDEFAULT;
125 }
126
127 memcpy(ts,&(pm->ts),sizeof(TTTSet));
128
129 // if (FirstInstance) { �������������� (2008.3.13 maya)
130 // �N���������A���L�������� HomeDir �� SetupFName ����������
131 /* Get home directory (ttermpro.exe���t�H���_) */
132 ts->HomeDirW = GetHomeDirW(hInst);
133 WideCharToACP_t(ts->HomeDirW, ts->HomeDir, _countof(ts->HomeDir));
134 SetCurrentDirectoryW(ts->HomeDirW);
135
136 ts->SetupFNameW = GetDefaultSetupFNameW(ts->HomeDirW);
137 WideCharToACP_t(ts->SetupFNameW, ts->SetupFName, _countof(ts->SetupFName));
138
139 ts->KeyCnfFNW = GetDefaultFNameW(ts->HomeDirW, L"KEYBOARD.CNF");
140 WideCharToACP_t(ts->KeyCnfFNW, ts->KeyCnfFN, _countof(ts->KeyCnfFN));
141
142 if (FirstInstance) {
143 FirstInstance = FALSE;
144 return TRUE;
145 }
146 else {
147 return FALSE;
148 }
149 }
150
151 // �����t�@�C�����f�B�X�N���������ATera Term�{�������N�������B
152 // (2012.4.30 yutaka)
153 void WINAPI RestartTeraTerm(HWND hwnd, PTTSet ts)
154 {
155 char path[1024];
156 STARTUPINFO si;
157 PROCESS_INFORMATION pi;
158 int ret;
159
160 static const TTMessageBoxInfoW info = {
161 "Tera Term",
162 NULL, L"Tera Term: Configuration Warning",
163 "MSG_TT_TAKE_EFFECT",
164 L"This option takes effect the next time a session is started.\n"
165 L"Are you sure that you want to relaunch Tera Term?"
166 };
167 ret = TTMessageBoxW(hwnd, &info, MB_YESNO | MB_ICONEXCLAMATION | MB_DEFBUTTON2, ts->UILanguageFile);
168 if (ret != IDYES)
169 return;
170
171 SendMessage(hwnd, WM_COMMAND, ID_SETUP_SAVE, 0);
172 // ID_FILE_EXIT ���b�Z�[�W�����A�v�������������������������AWM_QUIT ���|�X�g�����B
173 //PostMessage(hwnd, WM_COMMAND, ID_FILE_EXIT, 0);
174 PostQuitMessage(0);
175
176 // ���v���Z�X�����N���B
177 if (GetModuleFileName(NULL, path, sizeof(path)) == 0) {
178 return;
179 }
180 memset(&si, 0, sizeof(si));
181 GetStartupInfo(&si);
182 memset(&pi, 0, sizeof(pi));
183 if (CreateProcess(NULL, path, NULL, NULL, FALSE, 0,
184 NULL, NULL, &si, &pi) == 0) {
185 }
186 }
187
188 void WINAPI SetCOMFlag(int Com)
189 {
190 pm->ComFlag[(Com-1)/CHAR_BIT] |= 1 << ((Com-1)%CHAR_BIT);
191 }
192
193 void WINAPI ClearCOMFlag(int Com)
194 {
195 pm->ComFlag[(Com-1)/CHAR_BIT] &= ~(1 << ((Com-1)%CHAR_BIT));
196 }
197
198 int WINAPI CheckCOMFlag(int Com)
199 {
200 return ((pm->ComFlag[(Com-1)/CHAR_BIT] & 1 << (Com-1)%CHAR_BIT) > 0);
201 }
202
203 int WINAPI RegWin(HWND HWinVT, HWND HWinTEK)
204 {
205 int i, j;
206
207 if (pm->NWin>=MAXNWIN)
208 return 0;
209 if (HWinVT==NULL)
210 return 0;
211 if (HWinTEK!=NULL) {
212 i = 0;
213 while ((i<pm->NWin) && (pm->WinList[i]!=HWinVT))
214 i++;
215 if (i>=pm->NWin)
216 return 0;
217 for (j=pm->NWin-1 ; j>i ; j--)
218 pm->WinList[j+1] = pm->WinList[j];
219 pm->WinList[i+1] = HWinTEK;
220 pm->NWin++;
221 return 0;
222 }
223 pm->WinList[pm->NWin++] = HWinVT;
224 memset(&pm->WinPrevRect[pm->NWin - 1], 0, sizeof(pm->WinPrevRect[pm->NWin - 1])); // RECT clear
225 if (pm->NWin==1) {
226 return 1;
227 }
228 else {
229 return (int)(SendMessage(pm->WinList[pm->NWin-2],
230 WM_USER_GETSERIALNO,0,0)+1);
231 }
232 }
233
234 void WINAPI UnregWin(HWND HWin)
235 {
236 int i, j;
237
238 i = 0;
239 while ((i<pm->NWin) && (pm->WinList[i]!=HWin)) {
240 i++;
241 }
242 if (pm->WinList[i]!=HWin) {
243 return;
244 }
245 for (j=i ; j<pm->NWin-1 ; j++) {
246 pm->WinList[j] = pm->WinList[j+1];
247 pm->WinPrevRect[j] = pm->WinPrevRect[j+1]; // RECT shift
248 }
249 if (pm->NWin>0) {
250 pm->NWin--;
251 }
252 }
253
254 char GetWindowTypeChar(HWND Hw, HWND HWin)
255 {
256 #if 0
257 if (HWin == Hw)
258 return '*';
259 else if (!IsWindowVisible(Hw))
260 #else
261 if (!IsWindowVisible(Hw))
262 #endif
263 return '#';
264 else if (IsIconic(Hw))
265 return '-';
266 else if (IsZoomed(Hw))
267 return '@';
268 else
269 return '+';
270 }
271
272 void WINAPI SetWinMenu(HMENU menu, PCHAR buf, int buflen, PCHAR langFile, int VTFlag)
273 {
274 int i;
275 char Temp[MAXPATHLEN];
276 HWND Hw;
277 wchar_t uimsg[MAX_UIMSG];
278
279 // delete all items in Window menu
280 i = GetMenuItemCount(menu);
281 if (i>0)
282 do {
283 i--;
284 RemoveMenu(menu,i,MF_BYPOSITION);
285 } while (i>0);
286
287 i = 0;
288 while (i<pm->NWin) {
289 Hw = pm->WinList[i]; // get window handle
290 if ((GetClassName(Hw,Temp,sizeof(Temp))>0) &&
291 ((strcmp(Temp,VTCLASSNAME)==0) ||
292 (strcmp(Temp,TEKCLASSNAME)==0))) {
293 Temp[0] = '&';
294 Temp[1] = (char)(0x31 + i);
295 Temp[2] = ' ';
296 Temp[3] = GetWindowTypeChar(Hw, NULL);
297 Temp[4] = ' ';
298 GetWindowText(Hw,&Temp[5],sizeof(Temp)-6);
299 AppendMenu(menu,MF_ENABLED | MF_STRING,ID_WINDOW_1+i,Temp);
300 i++;
301 if (i>8) {
302 i = pm->NWin;
303 }
304 }
305 else {
306 UnregWin(Hw);
307 }
308 }
309 if (VTFlag == 1) {
310 static const DlgTextInfo MenuTextInfo[] = {
311 { ID_WINDOW_WINDOW, "MENU_WINDOW_WINDOW" },
312 { ID_WINDOW_MINIMIZEALL, "MENU_WINDOW_MINIMIZEALL" },
313 { ID_WINDOW_RESTOREALL, "MENU_WINDOW_RESTOREALL" },
314 { ID_WINDOW_CASCADEALL, "MENU_WINDOW_CASCADE" },
315 { ID_WINDOW_STACKED, "MENU_WINDOW_STACKED" },
316 { ID_WINDOW_SIDEBYSIDE, "MENU_WINDOW_SIDEBYSIDE" },
317 };
318
319 AppendMenu(menu, MF_SEPARATOR, 0, NULL);
320 AppendMenu(menu, MF_ENABLED | MF_STRING, ID_WINDOW_WINDOW, "&Window");
321 AppendMenu(menu, MF_ENABLED | MF_STRING, ID_WINDOW_MINIMIZEALL, "&Minimize All");
322 AppendMenu(menu, MF_ENABLED | MF_STRING, ID_WINDOW_RESTOREALL, "&Restore All");
323 AppendMenu(menu, MF_ENABLED | MF_STRING, ID_WINDOW_CASCADEALL, "&Cascade");
324 AppendMenu(menu, MF_ENABLED | MF_STRING, ID_WINDOW_STACKED, "&Stacked");
325 AppendMenu(menu, MF_ENABLED | MF_STRING, ID_WINDOW_SIDEBYSIDE, "Side &by Side");
326
327 SetI18nMenuStrs("Tera Term", menu, MenuTextInfo, _countof(MenuTextInfo), langFile);
328
329 if (pm->WinUndoFlag) {
330 if (pm->WinUndoStyle == WIN_CASCADE)
331 get_lang_msgW("MENU_WINDOW_CASCADE_UNDO", uimsg, _countof(uimsg), L"&Undo - Cascade", langFile);
332 else if (pm->WinUndoStyle == WIN_STACKED)
333 get_lang_msgW("MENU_WINDOW_STACKED_UNDO", uimsg, _countof(uimsg), L"&Undo - Stacked", langFile);
334 else
335 get_lang_msgW("MENU_WINDOW_SIDEBYSIDE_UNDO", uimsg, _countof(uimsg), L"&Undo - Side by Side", langFile);
336 _AppendMenuW(menu, MF_ENABLED | MF_STRING, ID_WINDOW_UNDO, uimsg); // TODO UNICODE
337 }
338
339 }
340 else {
341 get_lang_msgW("MENU_WINDOW_WINDOW", uimsg, _countof(uimsg), L"&Window", langFile);
342 _AppendMenuW(menu,MF_ENABLED | MF_STRING,ID_TEKWINDOW_WINDOW, uimsg);
343 }
344 }
345
346 void WINAPI SetWinList(HWND HWin, HWND HDlg, int IList)
347 {
348 int i;
349 char Temp[MAXPATHLEN];
350 HWND Hw;
351
352 for (i=0; i<pm->NWin; i++) {
353 Hw = pm->WinList[i]; // get window handle
354 if ((GetClassName(Hw,Temp,sizeof(Temp))>0) &&
355 ((strcmp(Temp,VTCLASSNAME)==0) ||
356 (strcmp(Temp,TEKCLASSNAME)==0))) {
357 Temp[0] = GetWindowTypeChar(Hw, HWin);
358 Temp[1] = ' ';
359 GetWindowText(Hw,&Temp[2],sizeof(Temp)-3);
360 SendDlgItemMessage(HDlg, IList, LB_ADDSTRING,
361 0, (LPARAM)Temp);
362 if (Hw==HWin) {
363 SendDlgItemMessage(HDlg, IList, LB_SETCURSEL, i,0);
364 }
365 }
366 else {
367 UnregWin(Hw);
368 }
369 }
370 }
371
372 void WINAPI SelectWin(int WinId)
373 {
374 if ((WinId>=0) && (WinId<pm->NWin)) {
375 /* �E�B���h�E�����������������������������������A���������������������������A
376 * SW_SHOWNORMAL ���� SW_SHOW �����X�����B
377 * (2009.11.8 yutaka)
378 * �E�B���h�E�����������������������������T�C�Y������(SW_RESTORE)�����������B
379 * (2009.11.9 maya)
380 */
381 if (IsIconic(pm->WinList[WinId])) {
382 ShowWindow(pm->WinList[WinId],SW_RESTORE);
383 }
384 else {
385 ShowWindow(pm->WinList[WinId],SW_SHOW);
386 }
387 SetForegroundWindow(pm->WinList[WinId]);
388 }
389 }
390
391 void WINAPI SelectNextWin(HWND HWin, int Next, BOOL SkipIconic)
392 {
393 int i;
394
395 i = 0;
396 while ((i < pm->NWin) && (pm->WinList[i]!=HWin)) {
397 i++;
398 }
399 if (pm->WinList[i]!=HWin) {
400 return;
401 }
402
403 do {
404 i += Next;
405 if (i >= pm->NWin) {
406 i = 0;
407 }
408 else if (i < 0) {
409 i = pm->NWin-1;
410 }
411
412 if (pm->WinList[i] == HWin) {
413 break;
414 }
415 } while ((SkipIconic && IsIconic(pm->WinList[i])) || !IsWindowVisible(pm->WinList[i]));
416
417 SelectWin(i);
418 }
419
420 void WINAPI ShowAllWin(int stat) {
421 int i;
422
423 for (i=0; i < pm->NWin; i++) {
424 ShowWindow(pm->WinList[i], stat);
425 }
426 }
427
428 void WINAPI UndoAllWin(void) {
429 int i;
430 WINDOWPLACEMENT rc0;
431 RECT rc;
432 int stat = SW_RESTORE;
433 int multi_mon = 0;
434
435 if (HasMultiMonitorSupport()) {
436 multi_mon = 1;
437 }
438
439 // ���x�A�����������t���O���������B
440 pm->WinUndoFlag = FALSE;
441
442 memset(&rc0, 0, sizeof(rc0));
443
444 for (i=0; i < pm->NWin; i++) {
445 // �����w�����A�O�����������c���������������A�E�B���h�E�����������������B
446 if (stat == SW_RESTORE && memcmp(&pm->WinPrevRect[i], &rc0, sizeof(rc0)) != 0) {
447 rc = pm->WinPrevRect[i].rcNormalPosition;
448
449 // NT4.0, 95 ���}���`���j�^API��������
450 if (multi_mon) {
451 // �������j�^������������
452 HMONITOR hMonitor;
453 MONITORINFO mi;
454 hMonitor = pMonitorFromRect(&rc, MONITOR_DEFAULTTONEAREST);
455 mi.cbSize = sizeof(MONITORINFO);
456 pGetMonitorInfoA(hMonitor, &mi);
457
458 // ���u�����i�����O���������x���������������������������j
459 if (rc.right > mi.rcMonitor.right) {
460 rc.left -= rc.right - mi.rcMonitor.right;
461 rc.right = mi.rcMonitor.right;
462 }
463 if (rc.left < mi.rcMonitor.left) {
464 rc.right += mi.rcMonitor.left - rc.left;
465 rc.left = mi.rcMonitor.left;
466 }
467 if (rc.bottom > mi.rcMonitor.bottom) {
468 rc.top -= rc.bottom - mi.rcMonitor.bottom;
469 rc.bottom = mi.rcMonitor.bottom;
470 }
471 if (rc.top < mi.rcMonitor.top) {
472 rc.bottom += mi.rcMonitor.top - rc.top;
473 rc.top = mi.rcMonitor.top;
474 }
475 }
476
477 // �E�B���h�E���u����
478 SetWindowPos(
479 pm->WinList[i], NULL,
480 rc.left,
481 rc.top,
482 rc.right - rc.left,
483 rc.bottom - rc.top,
484 SWP_NOZORDER);
485
486 // �E�B���h�E����������
487 ShowWindow(pm->WinList[i], pm->WinPrevRect[i].showCmd);
488
489 } else {
490 ShowWindow(pm->WinList[i], stat);
491 }
492 }
493 }
494
495 void WINAPI OpenHelp(UINT Command, DWORD Data, char *UILanguageFile)
496 {
497 char HomeDir[MAX_PATH];
498 char Temp[MAX_PATH];
499 HWND HWin;
500 wchar_t HelpFN[MAX_PATH];
501 wchar_t uimsg[MAX_UIMSG];
502 wchar_t *HomeDirW;
503
504 /* Get home directory */
505 if (GetModuleFileNameA(NULL,Temp,_countof(Temp)) == 0) {
506 return;
507 }
508 ExtractDirName(Temp, HomeDir);
509 HomeDirW = ToWcharA(HomeDir);
510 get_lang_msgW("HELPFILE", uimsg, _countof(uimsg), L"teraterm.chm", UILanguageFile);
511 _snwprintf_s(HelpFN, _countof(HelpFN), _TRUNCATE, L"%s\\%s", HomeDirW, uimsg);
512 free(HomeDirW);
513
514 // �w���v���I�[�i�[�������f�X�N�g�b�v������ (2007.5.12 maya)
515 HWin = GetDesktopWindow();
516 if (_HtmlHelpW(HWin, HelpFN, Command, Data) == NULL) {
517 // �w���v���J����������
518 static const TTMessageBoxInfoW info = {
519 "Tera Term",
520 NULL, L"Tera Term: HTML help",
521 "MSG_OPENHELP_ERROR", L"Can't open HTML help file(%s)." };
522 TTMessageBoxW(HWin, &info, MB_OK | MB_ICONERROR, UILanguageFile, HelpFN);
523 return;
524 }
525 }
526
527 HWND WINAPI GetNthWin(int n)
528 {
529 if (n<pm->NWin) {
530 return pm->WinList[n];
531 }
532 else {
533 return NULL;
534 }
535 }
536
537 int WINAPI GetRegisteredWindowCount(void)
538 {
539 return (pm->NWin);
540 }
541
542 // �L�����E�B���h�E���T���A�������u���L�������������B
543 static void get_valid_window_and_memorize_rect(HWND myhwnd, HWND hwnd[], int *num, int style)
544 {
545 int i, n;
546 WINDOWPLACEMENT wndPlace;
547
548 // ��������(Undo)���j���[�����x�����\���������B
549 if (pm->WinUndoFlag == FALSE) {
550 pm->WinUndoFlag = TRUE;
551 } else {
552 // ���������j���[���\�������������A�������O�������X�^�C�����I�����������A
553 // ���j���[�������B
554 // Windows8�����A�������A�����������X�^�C�����I�����������j���[�����������������A
555 // Tera Term�������j���[���\�������������A�������������B
556 if (pm->WinUndoStyle == style)
557 pm->WinUndoFlag = FALSE;
558 }
559 pm->WinUndoStyle = style;
560
561 n = 0;
562 for (i = 0 ; i < pm->NWin ; i++) {
563 // �������u���o���������B
564 wndPlace.length = sizeof(WINDOWPLACEMENT);
565 GetWindowPlacement(pm->WinList[i], &wndPlace);
566 pm->WinPrevRect[i] = wndPlace;
567
568 // �������g�������������B
569 if (pm->WinList[i] == myhwnd) {
570 hwnd[n] = hwnd[0];
571 hwnd[0] = myhwnd;
572 } else {
573 hwnd[n] = pm->WinList[i];
574 }
575 n++;
576 }
577 *num = n;
578 }
579
580 // �E�B���h�E�����E���������\������(Show Windows Side by Side)
581 void WINAPI ShowAllWinSidebySide(HWND myhwnd)
582 {
583 int n;
584 HWND hwnd[MAXNWIN];
585
586 get_valid_window_and_memorize_rect(myhwnd, hwnd, &n, WIN_SIDEBYSIDE);
587 TileWindows(NULL, MDITILE_VERTICAL, NULL, n, hwnd);
588 }
589
590 // �E�B���h�E���������������\������(Show Windows Stacked)
591 void WINAPI ShowAllWinStacked(HWND myhwnd)
592 {
593 int n;
594 HWND hwnd[MAXNWIN];
595
596 get_valid_window_and_memorize_rect(myhwnd, hwnd, &n, WIN_STACKED);
597 TileWindows(NULL, MDITILE_HORIZONTAL, NULL, n, hwnd);
598 }
599
600 // �E�B���h�E���d�����\������(Cascade)
601 void WINAPI ShowAllWinCascade(HWND myhwnd)
602 {
603 int n;
604 HWND hwnd[MAXNWIN];
605
606 get_valid_window_and_memorize_rect(myhwnd, hwnd, &n, WIN_CASCADE);
607 CascadeWindows(NULL, MDITILE_SKIPDISABLED, NULL, n, hwnd);
608 }
609
610 // �STera Term���I���w�����o���B
611 void WINAPI BroadcastClosingMessage(HWND myhwnd)
612 {
613 int i, max;
614 HWND hwnd[MAXNWIN];
615
616 // Tera Term���I�����������A���L���������������������A
617 // ���������o�b�t�@���R�s�[���������B
618 max = pm->NWin;
619 for (i = 0 ; i < pm->NWin ; i++) {
620 hwnd[i] = pm->WinList[i];
621 }
622
623 for (i = 0 ; i < max ; i++) {
624 // �������g�������������B
625 if (hwnd[i] == myhwnd)
626 continue;
627
628 PostMessage(hwnd[i], WM_USER_NONCONFIRM_CLOSE, 0, 0);
629 }
630 PostMessage(myhwnd, WM_USER_NONCONFIRM_CLOSE, 0, 0);
631 }
632
633
634 int WINAPI CommReadRawByte(PComVar cv, LPBYTE b)
635 {
636 if ( ! cv->Ready ) {
637 return 0;
638 }
639
640 if ( cv->InBuffCount>0 ) {
641 *b = cv->InBuff[cv->InPtr];
642 cv->InPtr++;
643 cv->InBuffCount--;
644 if ( cv->InBuffCount==0 ) {
645 cv->InPtr = 0;
646 }
647 return 1;
648 }
649 else {
650 cv->InPtr = 0;
651 return 0;
652 }
653 }
654
655 static void LogBinSkip(PComVar cv, int add)
656 {
657 if (cv->LogBinSkip != NULL) {
658 cv->LogBinSkip(add);
659 }
660 }
661
662 void WINAPI CommInsert1Byte(PComVar cv, BYTE b)
663 {
664 if ( ! cv->Ready ) {
665 return;
666 }
667
668 if (cv->InPtr == 0) {
669 memmove(&(cv->InBuff[1]),&(cv->InBuff[0]),cv->InBuffCount);
670 }
671 else {
672 cv->InPtr--;
673 }
674 cv->InBuff[cv->InPtr] = b;
675 cv->InBuffCount++;
676
677 LogBinSkip(cv, 1);
678 }
679
680 static void Log1Bin(PComVar cv, BYTE b)
681 {
682 if (cv->Log1Bin != NULL) {
683 cv->Log1Bin(b);
684 }
685 }
686
687 int WINAPI CommRead1Byte(PComVar cv, LPBYTE b)
688 {
689 int c;
690
691 if ( ! cv->Ready ) {
692 return 0;
693 }
694
695 if ( cv->TelMode ) {
696 c = 0;
697 }
698 else {
699 c = CommReadRawByte(cv,b);
700 }
701
702 if ((c==1) && cv->TelCRFlag) {
703 cv->TelCRFlag = FALSE;
704 if (*b==0) {
705 c = 0;
706 }
707 }
708
709 if ( c==1 ) {
710 if ( cv->IACFlag ) {
711 cv->IACFlag = FALSE;
712 if ( *b != 0xFF ) {
713 cv->TelMode = TRUE;
714 CommInsert1Byte(cv,*b);
715 LogBinSkip(cv, -1);
716 c = 0;
717 }
718 }
719 else if ((cv->PortType==IdTCPIP) && (*b==0xFF)) {
720 if (!cv->TelFlag && cv->TelAutoDetect) { /* TTPLUG */
721 cv->TelFlag = TRUE;
722 }
723 if (cv->TelFlag) {
724 cv->IACFlag = TRUE;
725 c = 0;
726 }
727 }
728 else if (cv->TelFlag && ! cv->TelBinRecv && (*b==0x0D)) {
729 cv->TelCRFlag = TRUE;
730 }
731 }
732
733 if (c == 1) {
734 Log1Bin(cv, *b);
735 }
736
737 return c;
738 }
739
740 int WINAPI CommRawOut(PComVar cv, /*const*/ PCHAR B, int C)
741 {
742 int a;
743
744 if ( ! cv->Ready ) {
745 return C;
746 }
747
748 if (C > OutBuffSize - cv->OutBuffCount) {
749 a = OutBuffSize - cv->OutBuffCount;
750 }
751 else {
752 a = C;
753 }
754 if ( cv->OutPtr > 0 ) {
755 memmove(&(cv->OutBuff[0]),&(cv->OutBuff[cv->OutPtr]),cv->OutBuffCount);
756 cv->OutPtr = 0;
757 }
758 memcpy(&(cv->OutBuff[cv->OutBuffCount]),B,a);
759 cv->OutBuffCount = cv->OutBuffCount + a;
760 return a;
761 }
762
763 int WINAPI CommBinaryOut(PComVar cv, PCHAR B, int C)
764 {
765 int a, i, Len;
766 char d[3];
767
768 if ( ! cv->Ready ) {
769 return C;
770 }
771
772 i = 0;
773 a = 1;
774 while ((a>0) && (i<C)) {
775 Len = 0;
776
777 d[Len] = B[i];
778 Len++;
779
780 if ( cv->TelFlag && (B[i]=='\x0d') && ! cv->TelBinSend ) {
781 d[Len++] = '\x00';
782 }
783 else if ( cv->TelFlag && (B[i]=='\xff') ) {
784 d[Len++] = '\xff';
785 }
786
787 if ( OutBuffSize - cv->OutBuffCount - Len >= 0 ) {
788 CommRawOut(cv, d, Len);
789 a = 1;
790 }
791 else {
792 a = 0;
793 }
794
795 i += a;
796 }
797 return i;
798 }
799
800 /**
801 * �f�[�^(������)���o���o�b�t�@����������
802 *
803 * �w���f�[�^��������������������������������������
804 * CommRawOut() ��������������������������
805 *
806 * @retval TRUE �o��������
807 * @retval FALSE �o��������������(buffer full)
808 */
809 static BOOL WriteOutBuff(PComVar cv, const char *TempStr, int TempLen)
810 {
811 BOOL output;
812
813 if (TempLen == 0) {
814 // ����0������������������������
815 return TRUE;
816 }
817
818 output = FALSE;
819 if (cv->TelLineMode) {
820 const BOOL Full = OutBuffSize - cv->LineModeBuffCount - TempLen < 0;
821 if (!Full) {
822 output = TRUE;
823 memcpy(&(cv->LineModeBuff[cv->LineModeBuffCount]), TempStr, TempLen);
824 cv->LineModeBuffCount += TempLen;
825 if (cv->Flush) {
826 cv->FlushLen = cv->LineModeBuffCount;
827 }
828 }
829 if (cv->FlushLen > 0) {
830 const int OutLen = CommRawOut(cv, cv->LineModeBuff, cv->FlushLen);
831 cv->FlushLen -= OutLen;
832 cv->LineModeBuffCount -= OutLen;
833 memmove(cv->LineModeBuff, &(cv->LineModeBuff[OutLen]), cv->LineModeBuffCount);
834 }
835 cv->Flush = FALSE;
836 }
837 else {
838 const BOOL Full = OutBuffSize-cv->OutBuffCount-TempLen < 0;
839 if (! Full) {
840 output = TRUE;
841 CommRawOut(cv, (char *)TempStr, TempLen);
842 }
843 }
844 return output;
845 }
846
847 /**
848 * �f�[�^(������)�������o�b�t�@����������
849 * �����o�b�t�@�������� -> �G�R�[������
850 *
851 * @retval TRUE �o��������
852 * @retval FALSE �o��������������(buffer full)
853 */
854 static BOOL WriteInBuff(PComVar cv, const char *TempStr, int TempLen)
855 {
856 BOOL Full;
857
858 if (TempLen == 0) {
859 return TRUE;
860 }
861
862 Full = InBuffSize-cv->InBuffCount-TempLen < 0;
863 if (! Full) {
864 memcpy(&(cv->InBuff[cv->InBuffCount]),TempStr,TempLen);
865 cv->InBuffCount = cv->InBuffCount + TempLen;
866 return TRUE;
867 }
868 return FALSE;
869 }
870
871 /**
872 * �����o�b�t�@�����������������������l����
873 */
874 static void PackInBuff(PComVar cv)
875 {
876 if ( (cv->InPtr>0) && (cv->InBuffCount>0) ) {
877 memmove(cv->InBuff,&(cv->InBuff[cv->InPtr]),cv->InBuffCount);
878 cv->InPtr = 0;
879 }
880 }
881
882 int WINAPI CommBinaryBuffOut(PComVar cv, PCHAR B, int C)
883 {
884 int a, i, Len;
885 char d[3];
886
887 if ( ! cv->Ready ) {
888 return C;
889 }
890
891 i = 0;
892 a = 1;
893 while ((a>0) && (i<C)) {
894 Len = 0;
895
896 d[Len] = B[i];
897 Len++;
898
899 if (B[i] == CR) {
900 if ( cv->TelFlag && ! cv->TelBinSend ) {
901 d[Len++] = '\x00';
902 }
903 if (cv->TelLineMode) {
904 cv->Flush = TRUE;
905 }
906 }
907 else if ( cv->TelFlag && (B[i]=='\xff') ) {
908 d[Len++] = '\xff';
909 }
910
911 if (WriteOutBuff(cv, d, Len)) {
912 a = 1;
913 i++;
914 } else {
915 a = 0;
916 }
917 }
918 return i;
919 }
920
921 // �����R�[�h(CodePage)��UTF-8���o������
922 static int OutputTextUTF8(WORD K, char *TempStr, PComVar cv)
923 {
924 int CodePage = *cv->CodePage;
925 unsigned int code;
926 int outlen;
927
928 code = MBCP_UTF32(K, CodePage);
929 if (code == 0) {
930 // �������s
931 code = 0xfffd; // U+FFFD: Replacement Character
932 }
933 outlen = UTF32ToUTF8(code, TempStr, 4);
934 return outlen;
935 }
936
937 static int __isleadbyte_l(int d, PComVar cv)
938 {
939 int CodePage = *cv->CodePage;
940 return IsDBCSLeadByteEx(CodePage, d);
941 }
942
943 //
944 // MBCS�����e�������R�[�h�����������o�������B
945 //
946 static int TextOutMBCS(PComVar cv, PCHAR B, int C)
947 {
948 int i, TempLen;
949 WORD K;
950 char TempStr[12];
951 BYTE d;
952 BOOL Full;
953 int SendCodeNew; // ���M�R�[�h
954 BOOL KanjiFlagNew; // TRUE=����������������������������
955
956 Full = FALSE;
957 i = 0;
958 while (! Full && (i < C)) {
959 TempLen = 0;
960 d = (BYTE)B[i];
961 SendCodeNew = cv->SendCode;
962 KanjiFlagNew = FALSE;
963
964 if (cv->SendKanjiFlag) {
965 SendCodeNew = IdKanji;
966
967 K = (cv->SendKanjiFirst << 8) + d;
968
969 // UTF-8�����������s���B1�`3�o�C�g���������������������B
970 if (cv->KanjiCodeSend == IdUTF8 || cv->Language == IdUtf8) {
971 TempLen += OutputTextUTF8(K, TempStr, cv);
972 }
973 else {
974 switch (cv->Language) {
975 case IdJapanese:
976 switch (cv->KanjiCodeSend) {
977 case IdEUC:
978 K = SJIS2EUC(K);
979 break;
980 case IdJIS:
981 K = SJIS2JIS(K);
982 if ((cv->SendCode==IdKatakana) &&
983 (cv->JIS7KatakanaSend==1)) {
984 TempStr[TempLen++] = SI;
985 }
986 break;
987 case IdSJIS:
988 /* nothing to do */
989 break;
990 }
991 break;
992 case IdKorean:
993 break;
994 }
995 TempStr[TempLen++] = HIBYTE(K);
996 TempStr[TempLen++] = LOBYTE(K);
997 }
998 }
999 else if (__isleadbyte_l(d, cv)) {
1000 KanjiFlagNew = TRUE;
1001 cv->SendKanjiFirst = d;
1002 SendCodeNew = IdKanji;
1003
1004 if (cv->Language == IdJapanese) {
1005 if ((cv->SendCode!=IdKanji) && (cv->KanjiCodeSend==IdJIS)) {
1006 TempStr[0] = 0x1B;
1007 TempStr[1] = '$';
1008 if (cv->KanjiIn == IdKanjiInB) {
1009 TempStr[2] = 'B';
1010 }
1011 else {
1012 TempStr[2] = '@';
1013 }
1014 TempLen = 3;
1015 }
1016 }
1017 }
1018 else {
1019 if (cv->Language == IdJapanese) {
1020 if ((cv->SendCode==IdKanji) && (cv->KanjiCodeSend==IdJIS)) {
1021 TempStr[0] = 0x1B;
1022 TempStr[1] = '(';
1023 switch (cv->KanjiOut) {
1024 case IdKanjiOutJ:
1025 TempStr[2] = 'J';
1026 break;
1027 case IdKanjiOutH:
1028 TempStr[2] = 'H';
1029 break;
1030 default:
1031 TempStr[2] = 'B';
1032 }
1033 TempLen = 3;
1034 }
1035
1036 if ((0xa0<d) && (d<0xe0)) {
1037 SendCodeNew = IdKatakana;
1038 if ((cv->SendCode!=IdKatakana) &&
1039 (cv->KanjiCodeSend==IdJIS) &&
1040 (cv->JIS7KatakanaSend==1)) {
1041 TempStr[TempLen++] = SO;
1042 }
1043 }
1044 else {
1045 SendCodeNew = IdASCII;
1046 if ((cv->SendCode==IdKatakana) &&
1047 (cv->KanjiCodeSend==IdJIS) &&
1048 (cv->JIS7KatakanaSend==1)) {
1049 TempStr[TempLen++] = SI;
1050 }
1051 }
1052 }
1053
1054 if (d==CR) {
1055 TempStr[TempLen++] = 0x0d;
1056 if (cv->CRSend==IdCRLF) {
1057 TempStr[TempLen++] = 0x0a;
1058 }
1059 else if ((cv->CRSend==IdCR) &&
1060 cv->TelFlag && ! cv->TelBinSend) {
1061 TempStr[TempLen++] = 0;
1062 }
1063 else if (cv->CRSend == IdLF) {
1064 TempStr[TempLen-1] = 0x0a;
1065 }
1066 if (cv->TelLineMode) {
1067 cv->Flush = TRUE;
1068 }
1069 }
1070 else if (d==BS) {
1071 if (cv->TelLineMode) {
1072 if (cv->FlushLen < cv->LineModeBuffCount) {
1073 cv->LineModeBuffCount--;
1074 }
1075 }
1076 else {
1077 TempStr[TempLen++] = d;
1078 }
1079 }
1080 else if (d==0x15) { // Ctrl-U
1081 if (cv->TelLineMode) {
1082 cv->LineModeBuffCount = cv->FlushLen;
1083 }
1084 else {
1085 TempStr[TempLen++] = d;
1086 }
1087 }
1088 else if ((d>=0x80) && (cv->KanjiCodeSend==IdUTF8 || cv->Language==IdUtf8)) {
1089 TempLen += OutputTextUTF8((WORD)d, TempStr, cv);
1090 }
1091 else if ((d>=0xa1) && (d<=0xe0) && (cv->Language == IdJapanese)) {
1092 /* Katakana */
1093 if (cv->KanjiCodeSend==IdEUC) {
1094 TempStr[TempLen++] = (char)SS2;
1095 }
1096 if ((cv->KanjiCodeSend==IdJIS) &&
1097 (cv->JIS7KatakanaSend==1)) {
1098 TempStr[TempLen++] = d & 0x7f;
1099 }
1100 else {
1101 TempStr[TempLen++] = d;
1102 }
1103 }
1104 else {
1105 TempStr[TempLen++] = d;
1106 if (cv->TelFlag && (d==0xff)) {
1107 TempStr[TempLen++] = (char)0xff;
1108 }
1109 }
1110 } // if (cv->SendKanjiFlag) else if ... else ... end
1111
1112 if (WriteOutBuff(cv, TempStr, TempLen)) {
1113 i++; // 1������������
1114 // ��������������������
1115 cv->SendCode = SendCodeNew;
1116 cv->SendKanjiFlag = KanjiFlagNew;
1117 } else {
1118 Full = TRUE;
1119 }
1120
1121 } // end of "while {}"
1122
1123 return i;
1124 }
1125
1126 int WINAPI CommTextOut(PComVar cv, PCHAR B, int C)
1127 {
1128 int i, TempLen;
1129 char TempStr[12];
1130 BYTE d;
1131 BOOL Full;
1132
1133 if (! cv->Ready ) {
1134 return C;
1135 }
1136
1137 switch (cv->Language) {
1138 case IdUtf8:
1139 case IdJapanese:
1140 case IdKorean:
1141 return TextOutMBCS(cv, B, C);
1142 break;
1143 }
1144
1145 Full = FALSE;
1146 i = 0;
1147 while (! Full && (i < C)) {
1148 TempLen = 0;
1149 d = (BYTE)B[i];
1150
1151 switch (d) {
1152 case CR:
1153 TempStr[TempLen] = 0x0d;
1154 TempLen++;
1155 if (cv->CRSend==IdCRLF) {
1156 TempStr[TempLen++] = 0x0a;
1157 }
1158 else if (cv->CRSend==IdCR && cv->TelFlag && ! cv->TelBinSend) {
1159 TempStr[TempLen++] = 0;
1160 }
1161 else if (cv->CRSend == IdLF) {
1162 TempStr[TempLen-1] = 0x0a;
1163 }
1164 if (cv->TelLineMode) {
1165 cv->Flush = TRUE;
1166 }
1167 break;
1168
1169 case BS:
1170 if (cv->TelLineMode) {
1171 if (cv->FlushLen < cv->LineModeBuffCount) {
1172 cv->LineModeBuffCount--;
1173 }
1174 }
1175 else {
1176 TempStr[TempLen++] = d;
1177 }
1178 break;
1179
1180 case 0x15: // Ctrl-U
1181 if (cv->TelLineMode) {
1182 cv->LineModeBuffCount = cv->FlushLen;
1183 }
1184 else {
1185 TempStr[TempLen++] = d;
1186 }
1187 break;
1188
1189 default:
1190 if ((cv->Language==IdRussian) && (d>=128)) {
1191 d = RussConv(cv->RussClient, cv->RussHost, d);
1192 }
1193 TempStr[TempLen++] = d;
1194 if (cv->TelFlag && (d==0xff)) {
1195 TempStr[TempLen++] = (char)0xff;
1196 }
1197 }
1198
1199 if (WriteOutBuff(cv, TempStr, TempLen)) {
1200 i++; // 1������������
1201 } else {
1202 Full = TRUE;
1203 }
1204
1205 } // end of while {}
1206
1207 return i;
1208 }
1209
1210 /**
1211 * @retval true ���{�������p�J�^�J�i
1212 * @retval false ������
1213 */
1214 static BOOL IsHalfWidthKatakana(unsigned int u32)
1215 {
1216 // Halfwidth CJK punctuation (U+FF61�`FF64)
1217 // Halfwidth Katakana variants (U+FF65�`FF9F)
1218 return (0xff61 <= u32 && u32 <= 0xff9f);
1219 }
1220
1221 /**
1222 * �o���p�A TODO echo�p������
1223 * @param cv
1224 * @param u32 ��������
1225 * @param check_only TRUE���������s�����A
1226 * @param TempStr �o��������
1227 * @param StrLen TempStr�����o��������
1228 * @retval �������s����
1229 */
1230 static BOOL OutControl(PComVar cv, unsigned int u32, BOOL check_only, char *TempStr, size_t *StrLen)
1231 {
1232 const wchar_t d = u32;
1233 size_t TempLen = 0;
1234 BOOL retval = FALSE;
1235 if (check_only == TRUE) {
1236 /* �`�F�b�N���� */
1237 if (d == CR || d == BS || d == 0x15/*ctrl-u*/) {
1238 return TRUE;
1239 } else {
1240 return FALSE;
1241 }
1242 }
1243 if (d==CR) {
1244 TempStr[TempLen++] = 0x0d;
1245 if (cv->CRSend==IdCRLF) {
1246 TempStr[TempLen++] = 0x0a;
1247 }
1248 else if ((cv->CRSend ==IdCR) &&
1249 cv->TelFlag && ! cv->TelBinSend) {
1250 TempStr[TempLen++] = 0;
1251 }
1252 else if (cv->CRSend == IdLF) {
1253 TempStr[TempLen-1] = 0x0a;
1254 }
1255 if (cv->TelLineMode) {
1256 cv->Flush = TRUE;
1257 }
1258 retval = TRUE;
1259 }
1260 else if (d== BS) {
1261 if (cv->TelLineMode) {
1262 if (cv->FlushLen < cv->LineModeBuffCount) {
1263 cv->LineModeBuffCount--;
1264 }
1265 }
1266 else {
1267 TempStr[TempLen++] = BS;
1268 }
1269 retval = TRUE;
1270 }
1271 else if (d==0x15) { // ctrl-u
1272 if (cv->TelLineMode) {
1273 cv->LineModeBuffCount = cv->FlushLen;
1274 }
1275 else {
1276 TempStr[TempLen++] = 0x15;
1277 }
1278 retval = TRUE;
1279 }
1280 *StrLen = TempLen;
1281 return retval;
1282 }
1283 static BOOL ControlEcho(PComVar cv, unsigned int u32, BOOL check_only, char *TempStr, size_t *StrLen)
1284 {
1285 const wchar_t d = u32;
1286 size_t TempLen = 0;
1287 BOOL retval = FALSE;
1288 if (check_only == TRUE) {
1289 /* �`�F�b�N���� */
1290 if (d == CR || (d == 0x15/*ctrl-u*/ && cv->TelLineMode)) {
1291 return TRUE;
1292 } else {
1293 return FALSE;
1294 }
1295 }
1296 if (d==CR) {
1297 TempStr[TempLen++] = 0x0d;
1298 if (cv->CRSend==IdCRLF) {
1299 TempStr[TempLen++] = 0x0a;
1300 }
1301 else if ((cv->CRSend ==IdCR) && cv->TelFlag && ! cv->TelBinSend) {
1302 TempStr[TempLen++] = 0;
1303 }
1304 else if (cv->CRSend == IdLF) {
1305 TempStr[TempLen-1] = 0x0a;
1306 }
1307 retval = TRUE;
1308 }
1309 else if (d==0x15/*ctrl-u*/ && cv->TelLineMode) {
1310 // Move to top of line (CHA "\033[G") and erase line (EL "\033[K")
1311 memcpy(TempStr, "\033[G\033[K", 6);
1312 TempLen += 6;
1313 retval = TRUE;
1314 }
1315 *StrLen = TempLen;
1316 return retval;
1317 }
1318
1319 /**
1320 * �o���p����������������
1321 *
1322 * @retval ��������������
1323 */
1324 typedef struct {
1325 int KanjiCode; // [in]�o�������R�[�h(sjis,jis����)
1326 BOOL (*ControlOut)(PComVar cv, unsigned int u32, BOOL check_only, char *TempStr, size_t *StrLen);
1327 // state�����������K�v�����������R�[�h���g�p
1328 BOOL JIS7Katakana; // [in](Kanji JIS)kana
1329 int SendCode; // [in,out](Kanji JIS)���O�����M�R�[�h Ascii/Kana/Kanji
1330 BOOL KanjiFlag; // [in,out](MBCS)���O��1byte��������������?(2byte������������?)
1331 BYTE KanjiFirst; // [in,out](MBCS)���O��1byte
1332 } OutputCharState;
1333
1334 /**
1335 * unicode(UTF-16)����unicode(UTF-32)��1���������o����
1336 * �o���f�[�^(TempStr)����������
1337 */
1338 static size_t MakeOutputString(PComVar cv, OutputCharState *states,
1339 const wchar_t *B, int C,
1340 char *TempStr, int *TempLen_)
1341 {
1342 BOOL (*ControlOut)(PComVar cv, unsigned int u32, BOOL check_only, char *TempStr, size_t *StrLen)
1343 = states->ControlOut;
1344 //
1345 int TempLen = 0;
1346 size_t TempLen2;
1347 size_t output_char_count; // ��������������
1348
1349 // UTF-32 ��1���������o��
1350 unsigned int u32;
1351 size_t u16_len = UTF16ToUTF32(B, C, &u32);
1352 if (u16_len == 0) {
1353 // �f�R�[�h��������? ����������������?
1354 assert(FALSE);
1355 u32 = '?';
1356 u16_len = 1;
1357 }
1358 output_char_count = u16_len;
1359
1360 // �e���V�t�g����������������
1361 if (u32 < 0x100 || ControlOut(cv, u32, TRUE, NULL, NULL)) {
1362 if (cv->Language == IdJapanese && states->KanjiCode == IdJIS) {
1363 // �����������A���{��,JIS��������
1364 if (cv->SendCode == IdKanji) {
1365 // �����������������A����OUT
1366 TempStr[TempLen++] = 0x1B;
1367 TempStr[TempLen++] = '(';
1368 switch (cv->KanjiOut) {
1369 case IdKanjiOutJ:
1370 TempStr[TempLen++] = 'J';
1371 break;
1372 case IdKanjiOutH:
1373 TempStr[TempLen++] = 'H';
1374 break;
1375 default:
1376 TempStr[TempLen++] = 'B';
1377 }
1378 }
1379
1380 if (states->JIS7Katakana == 1) {
1381 if (cv->SendCode == IdKatakana) {
1382 TempStr[TempLen++] = SO;
1383 }
1384 }
1385
1386 states->SendCode = IdASCII;
1387 }
1388 }
1389
1390 // 1������������
1391 if (ControlOut(cv, u32, FALSE, TempStr, &TempLen2)) {
1392 // ��������������������
1393 TempLen += TempLen2;
1394 output_char_count = 1;
1395 } else if (cv->Language == IdUtf8 ||
1396 (cv->Language == IdJapanese && states->KanjiCode == IdUTF8) ||
1397 (cv->Language == IdKorean && states->KanjiCode == IdUTF8))
1398 {
1399 // UTF-8 ���o��
1400 size_t utf8_len = sizeof(TempStr);
1401 utf8_len = UTF32ToUTF8(u32, TempStr, utf8_len);
1402 TempLen += utf8_len;
1403 } else if (cv->Language == IdJapanese && *cv->CodePage == 932) {
1404 // ���{��
1405 // ���� CP932(SJIS) ���������������o��
1406 char mb_char[2];
1407 size_t mb_len = sizeof(mb_char);
1408 mb_len = UTF32ToMBCP(u32, 932, mb_char, mb_len);
1409 if (mb_len == 0) {
1410 // SJIS��������������
1411 TempStr[TempLen++] = '?';
1412 } else {
1413 switch (states->KanjiCode) {
1414 case IdEUC:
1415 // TODO ���p�J�i
1416 if (mb_len == 1) {
1417 TempStr[TempLen++] = mb_char[0];
1418 } else {
1419 WORD K;
1420 K = (((WORD)(unsigned char)mb_char[0]) << 8) +
1421 (WORD)(unsigned char)mb_char[1];
1422 K = SJIS2EUC(K);
1423 TempStr[TempLen++] = HIBYTE(K);
1424 TempStr[TempLen++] = LOBYTE(K);
1425 }
1426 break;
1427 case IdJIS:
1428 if (u32 < 0x100) {
1429 // ASCII
1430 TempStr[TempLen++] = mb_char[0];
1431 states->SendCode = IdASCII;
1432 } else if (IsHalfWidthKatakana(u32)) {
1433 // ���p�J�^�J�i
1434 if (states->JIS7Katakana==1) {
1435 if (cv->SendCode != IdKatakana) {
1436 TempStr[TempLen++] = SI;
1437 }
1438 TempStr[TempLen++] = mb_char[0] & 0x7f;
1439 } else {
1440 TempStr[TempLen++] = mb_char[0];
1441 }
1442 states->SendCode = IdKatakana;
1443 } else {
1444 // ����
1445 WORD K;
1446 K = (((WORD)(unsigned char)mb_char[0]) << 8) +
1447 (WORD)(unsigned char)mb_char[1];
1448 K = SJIS2JIS(K);
1449 if (states->SendCode != IdKanji) {
1450 // ����IN
1451 TempStr[TempLen++] = 0x1B;
1452 TempStr[TempLen++] = '$';
1453 if (cv->KanjiIn == IdKanjiInB) {
1454 TempStr[TempLen++] = 'B';
1455 }
1456 else {
1457 TempStr[TempLen++] = '@';
1458 }
1459 states->SendCode = IdKanji;
1460 }
1461 TempStr[TempLen++] = HIBYTE(K);
1462 TempStr[TempLen++] = LOBYTE(K);
1463 }
1464 break;
1465 case IdSJIS:
1466 if (mb_len == 1) {
1467 TempStr[TempLen++] = mb_char[0];
1468 } else {
1469 TempStr[TempLen++] = mb_char[0];
1470 TempStr[TempLen++] = mb_char[1];
1471 }
1472 break;
1473 default:
1474 assert(FALSE);
1475 break;
1476 }
1477 }
1478 } else if (cv->Language == IdRussian) {
1479 /* ����CP1251�����������o�� */
1480 char mb_char[2];
1481 size_t mb_len = sizeof(mb_char);
1482 BYTE b;
1483 mb_len = UTF32ToMBCP(u32, 1251, mb_char, mb_len);
1484 if (mb_len != 1) {
1485 b = '?';
1486 } else {
1487 b = RussConv(IdWindows, cv->RussHost, mb_char[0]);
1488 }
1489 TempStr[TempLen++] = b;
1490 } else if (cv->Language == IdKorean && *cv->CodePage == 51949) {
1491 /* CP51949�����������o�� */
1492 char mb_char[2];
1493 size_t mb_len = sizeof(mb_char);
1494 mb_len = UTF32ToMBCP(u32, 51949, mb_char, mb_len);
1495 if (mb_len == 0) {
1496 TempStr[TempLen++] = '?';
1497 }
1498 else if (mb_len == 1) {
1499 TempStr[TempLen++] = mb_char[0];
1500 } else {
1501 TempStr[TempLen++] = mb_char[0];
1502 TempStr[TempLen++] = mb_char[1];
1503 }
1504 } else if (cv->Language == IdEnglish) {
1505 TempStr[TempLen++] = u32;
1506 } else {
1507 // CodePage������
1508 char mb_char[2];
1509 size_t mb_len = sizeof(mb_char);
1510 mb_len = UTF32ToMBCP(u32, *cv->CodePage, mb_char, mb_len);
1511 if (mb_len == 0) {
1512 TempStr[TempLen++] = '?';
1513 }
1514 else if (mb_len == 1) {
1515 TempStr[TempLen++] = mb_char[0];
1516 } else {
1517 TempStr[TempLen++] = mb_char[0];
1518 TempStr[TempLen++] = mb_char[1];
1519 }
1520 }
1521
1522 *TempLen_ = TempLen;
1523 return output_char_count;
1524 }
1525
1526
1527 /**
1528 * CommTextOut() �� wchar_t ��
1529 *
1530 * @retval �o��������(wchar_t�P��)
1531 */
1532 int WINAPI CommTextOutW(PComVar cv, const wchar_t *B, int C)
1533 {
1534 char TempStr[12];
1535 BOOL Full = FALSE;
1536 int i = 0;
1537 while (! Full && (i < C)) {
1538 // �o���p�f�[�^������
1539 int TempLen = 0;
1540 size_t output_char_count; // ��������������
1541 OutputCharState state;
1542 state.KanjiCode = cv->KanjiCodeSend;
1543 state.ControlOut = OutControl;
1544 state.SendCode = cv->SendCode;
1545 state.JIS7Katakana = cv->JIS7KatakanaSend;
1546 output_char_count = MakeOutputString(cv, &state, &B[i], C-i, TempStr, &TempLen);
1547
1548 // �f�[�^���o���o�b�t�@��
1549 if (WriteOutBuff(cv, TempStr, TempLen)) {
1550 i += output_char_count; // output_char_count ������ ��������
1551 // ��������������������
1552 cv->SendCode = state.SendCode;
1553 } else {
1554 Full = TRUE;
1555 }
1556 } // end of "while {}"
1557 _CrtCheckMemory();
1558 return i;
1559 }
1560
1561 /**
1562 * CommTextEcho() �� wchar_t ��
1563 *
1564 * @retval �o��������(wchar_t�P��)
1565 */
1566 int WINAPI CommTextEchoW(PComVar cv, const wchar_t *B, int C)
1567 {
1568 char TempStr[12];
1569 BOOL Full = FALSE;
1570 int i = 0;
1571 while (! Full && (i < C)) {
1572 // �o���p�f�[�^������
1573 int TempLen = 0;
1574 size_t output_char_count; // ��������������
1575 OutputCharState state;
1576 state.KanjiCode = cv->KanjiCodeEcho;
1577 state.ControlOut = ControlEcho;
1578 state.SendCode = cv->EchoCode;
1579 state.JIS7Katakana = cv->JIS7KatakanaEcho;
1580 output_char_count = MakeOutputString(cv, &state, &B[i], C-i, TempStr, &TempLen);
1581
1582 // �f�[�^���o���o�b�t�@��
1583 if (WriteInBuff(cv, TempStr, TempLen)) {
1584 i += output_char_count; // output_char_count ������ ��������
1585 // ��������������������
1586 cv->EchoCode = state.SendCode;
1587 } else {
1588 Full = TRUE;
1589 }
1590 } // end of "while {}"
1591 _CrtCheckMemory();
1592 return i;
1593 }
1594
1595 int WINAPI CommBinaryEcho(PComVar cv, PCHAR B, int C)
1596 {
1597 int a, i, Len;
1598 char d[3];
1599
1600 if ( ! cv->Ready )
1601 return C;
1602
1603 PackInBuff(cv);
1604
1605 i = 0;
1606 a = 1;
1607 while ((a>0) && (i<C)) {
1608 Len = 0;
1609
1610 d[Len] = B[i];
1611 Len++;
1612
1613 if ( cv->TelFlag && (B[i]=='\x0d') &&
1614 ! cv->TelBinSend ) {
1615 d[Len] = 0x00;
1616 Len++;
1617 }
1618
1619 if ( cv->TelFlag && (B[i]=='\xff') ) {
1620 d[Len] = '\xff';
1621 Len++;
1622 }
1623
1624 if (WriteInBuff(cv, d, Len)) {
1625 a = 1;
1626 i++;
1627 } else {
1628 a = 0;
1629 }
1630 }
1631 return i;
1632 }
1633
1634 static int WINAPI TextEchoMBCS(PComVar cv, PCHAR B, int C)
1635 {
1636 int i, TempLen;
1637 WORD K;
1638 char TempStr[12];
1639 int EchoCodeNew;
1640 BYTE d;
1641 BOOL Full, KanjiFlagNew;
1642
1643 Full = FALSE;
1644 i = 0;
1645 while (! Full && (i < C)) {
1646 TempLen = 0;
1647 d = (BYTE)B[i];
1648 EchoCodeNew = cv->EchoCode;
1649 KanjiFlagNew = FALSE;
1650
1651 if (cv->EchoKanjiFlag) {
1652 EchoCodeNew = IdKanji;
1653
1654 K = (cv->EchoKanjiFirst << 8) + d;
1655
1656 // UTF-8�����������s���B1�`3�o�C�g���������������������B
1657 if (cv->KanjiCodeEcho == IdUTF8 || cv->Language==IdUtf8) {
1658 TempLen += OutputTextUTF8(K, TempStr, cv);
1659 }
1660 else {
1661 switch (cv->Language) {
1662 case IdJapanese:
1663 switch (cv->KanjiCodeEcho) {
1664 case IdEUC:
1665 K = SJIS2EUC(K);
1666 break;
1667 case IdJIS:
1668 K = SJIS2JIS(K);
1669 if ((cv->EchoCode==IdKatakana) &&
1670 (cv->JIS7KatakanaEcho==1)) {
1671 TempStr[TempLen++] = SI;
1672 }
1673 break;
1674 case IdSJIS:
1675 /* nothing to do */
1676 break;
1677 }
1678 break;
1679 case IdKorean:
1680 break;
1681 }
1682 TempStr[TempLen++] = HIBYTE(K);
1683 TempStr[TempLen++] = LOBYTE(K);
1684 }
1685 }
1686 else if (__isleadbyte_l(d, cv)) {
1687 KanjiFlagNew = TRUE;
1688 cv->EchoKanjiFirst = d;
1689 EchoCodeNew = IdKanji;
1690
1691 if (cv->Language == IdJapanese) {
1692 if ((cv->EchoCode!=IdKanji) && (cv->KanjiCodeEcho==IdJIS)) {
1693 TempStr[0] = 0x1B;
1694 TempStr[1] = '$';
1695 if (cv->KanjiIn == IdKanjiInB) {
1696 TempStr[2] = 'B';
1697 }
1698 else {
1699 TempStr[2] = '@';
1700 }
1701 TempLen = 3;
1702 }
1703 }
1704 }
1705 else {
1706 if (cv->Language == IdJapanese) {
1707 if ((cv->EchoCode==IdKanji) && (cv->KanjiCodeEcho==IdJIS)) {
1708 TempStr[0] = 0x1B;
1709 TempStr[1] = '(';
1710 switch (cv->KanjiOut) {
1711 case IdKanjiOutJ:
1712 TempStr[2] = 'J';
1713 break;
1714 case IdKanjiOutH:
1715 TempStr[2] = 'H';
1716 break;
1717 default:
1718 TempStr[2] = 'B';
1719 }
1720 TempLen = 3;
1721 }
1722
1723 if ((0xa0<d) && (d<0xe0)) {
1724 EchoCodeNew = IdKatakana;
1725 if ((cv->EchoCode!=IdKatakana) &&
1726 (cv->KanjiCodeEcho==IdJIS) &&
1727 (cv->JIS7KatakanaEcho==1)) {
1728 TempStr[TempLen++] = SO;
1729 }
1730 }
1731 else {
1732 EchoCodeNew = IdASCII;
1733 if ((cv->EchoCode==IdKatakana) &&
1734 (cv->KanjiCodeEcho==IdJIS) &&
1735 (cv->JIS7KatakanaEcho==1)) {
1736 TempStr[TempLen++] = SI;
1737 }
1738 }
1739 }
1740
1741 if (d==CR) {
1742 TempStr[TempLen++] = 0x0d;
1743 if (cv->CRSend==IdCRLF) {
1744 TempStr[TempLen++] = 0x0a;
1745 }
1746 else if ((cv->CRSend==IdCR) &&
1747 cv->TelFlag && ! cv->TelBinSend) {
1748 TempStr[TempLen++] = 0;
1749 }
1750 else if (cv->CRSend == IdLF) {
1751 TempStr[TempLen-1] = 0x0a;
1752 }
1753 }
1754 else if (d==0x15) { // Ctrl-U
1755 if (cv->TelLineMode) {
1756 // Move to top of line (CHA "\033[G") and erase line (EL "\033[K")
1757 strncpy_s(TempStr, sizeof(TempStr), "\033[G\033[K", _TRUNCATE);
1758 TempLen += 6;
1759 }
1760 else {
1761 TempStr[TempLen++] = d;
1762 }
1763 }
1764 else if ((d>=0x80) && (cv->KanjiCodeEcho==IdUTF8 || cv->Language==IdUtf8)) {
1765 TempLen += OutputTextUTF8((WORD)d, TempStr, cv);
1766 }
1767 else if ((d>=0xa1) && (d<=0xe0) && (cv->Language == IdJapanese)) {
1768 /* Katakana */
1769 if (cv->KanjiCodeEcho==IdEUC) {
1770 TempStr[TempLen++] = (char)SS2;
1771 }
1772 if ((cv->KanjiCodeEcho==IdJIS) &&
1773 (cv->JIS7KatakanaEcho==1)) {
1774 TempStr[TempLen++] = d & 0x7f;
1775 }
1776 else {
1777 TempStr[TempLen++] = d;
1778 }
1779 }
1780 else {
1781 TempStr[TempLen++] = d;
1782 if (cv->TelFlag && (d==0xff)) {
1783 TempStr[TempLen++] = (char)0xff;
1784 }
1785 }
1786 } // if (cv->EchoKanjiFlag) else if ... else ... end
1787
1788 if (WriteInBuff(cv, TempStr, TempLen)) {
1789 i++;
1790 cv->EchoCode = EchoCodeNew;
1791 cv->EchoKanjiFlag = KanjiFlagNew;
1792 } else {
1793 Full = FALSE;
1794 }
1795
1796 } // end of "while {}"
1797
1798 return i;
1799 }
1800
1801 int WINAPI CommTextEcho(PComVar cv, PCHAR B, int C)
1802 {
1803 int i, TempLen;
1804 char TempStr[11];
1805 BYTE d;
1806 BOOL Full;
1807
1808 if ( ! cv->Ready ) {
1809 return C;
1810 }
1811
1812 PackInBuff(cv);
1813
1814 switch (cv->Language) {
1815 case IdUtf8:
1816 case IdJapanese:
1817 case IdKorean:
1818 return TextEchoMBCS(cv,B,C);
1819 break;
1820 }
1821
1822 Full = FALSE;
1823 i = 0;
1824 while (! Full && (i < C)) {
1825 TempLen = 0;
1826 d = (BYTE)B[i];
1827
1828 switch (d) {
1829 case CR:
1830 TempStr[TempLen] = 0x0d;
1831 TempLen++;
1832 if (cv->CRSend==IdCRLF) {
1833 TempStr[TempLen++] = 0x0a;
1834 }
1835 else if (cv->CRSend==IdCR && cv->TelFlag && ! cv->TelBinSend) {
1836 TempStr[TempLen++] = 0;
1837 }
1838 else if (cv->CRSend == IdLF) {
1839 TempStr[TempLen-1] = 0x0a;
1840 }
1841 break;
1842
1843 case 0x15: // Ctrl-U
1844 if (cv->TelLineMode) {
1845 // Move to top of line (CHA "\033[G") and erase line (EL "\033[K")
1846 strncpy_s(TempStr, sizeof(TempStr), "\033[G\033[K", _TRUNCATE);
1847 TempLen += 6;
1848 }
1849 else {
1850 TempStr[TempLen++] = d;
1851 }
1852 break;
1853
1854 default:
1855 if ((cv->Language==IdRussian) && (d>=128)) {
1856 d = RussConv(cv->RussClient,cv->RussHost,d);
1857 }
1858 TempStr[TempLen++] = d;
1859 if (cv->TelFlag && (d==0xff)) {
1860 TempStr[TempLen++] = (char)0xff;
1861 }
1862 }
1863
1864 if(WriteInBuff(cv, TempStr,TempLen)) {
1865 i++;
1866 } else {
1867 Full = TRUE;
1868 }
1869 } // end of while {}
1870
1871 return i;
1872 }
1873
1874 /*
1875 * @return �G���[���L������ FALSE
1876 * @param[in] BOOL first_instance
1877 */
1878 static BOOL OpenSharedMemory(BOOL *first_instance_)
1879 {
1880 int i;
1881 HMap = NULL;
1882 pm = NULL;
1883 for (i = 0; i < 100; i++) {
1884 char tmp[32];
1885 HANDLE hMap;
1886 BOOL first_instance;
1887 TMap *map;
1888 _snprintf_s(tmp, sizeof(tmp), _TRUNCATE, i == 0 ? "%s" : "%s_%d", TT_FILEMAPNAME, i);
1889 hMap = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE,
1890 0, sizeof(TMap), tmp);
1891 if (hMap == NULL) {
1892 return FALSE;
1893 }
1894
1895 first_instance = (GetLastError() != ERROR_ALREADY_EXISTS);
1896
1897 map = (TMap *)MapViewOfFile(hMap,FILE_MAP_WRITE,0,0,0);
1898 if (map == NULL) {
1899 return FALSE;
1900 }
1901
1902 if (first_instance ||
1903 (map->size_tmap == sizeof(TMap) &&
1904 map->size_tttset == sizeof(TTTSet)))
1905 {
1906 map->size_tmap = sizeof(TMap);
1907 map->size_tttset = sizeof(TTTSet);
1908 HMap = hMap;
1909 pm = map;
1910 *first_instance_ = first_instance;
1911 return TRUE;
1912 }
1913
1914 // next try
1915 UnmapViewOfFile(map);
1916 CloseHandle(hMap);
1917 }
1918 return FALSE;
1919 }
1920
1921 BOOL WINAPI DllMain(HANDLE hInstance,
1922 ULONG ul_reason_for_call,
1923 LPVOID lpReserved)
1924 {
1925 switch( ul_reason_for_call ) {
1926 case DLL_THREAD_ATTACH:
1927 /* do thread initialization */
1928 break;
1929 case DLL_THREAD_DETACH:
1930 /* do thread cleanup */
1931 break;
1932 case DLL_PROCESS_ATTACH:
1933 /* do process initialization */
1934 hInst = hInstance;
1935 if (OpenSharedMemory(&FirstInstance) == FALSE) {
1936 // dll���[�h���s�Ateraterm���N��������
1937 return FALSE;
1938 }
1939 WinCompatInit();
1940 break;
1941 case DLL_PROCESS_DETACH:
1942 /* do process cleanup */
1943 UnmapViewOfFile(pm);
1944 CloseHandle(HMap);
1945 break;
1946 }
1947 return TRUE;
1948 }

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26