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 9598 - (show annotations) (download) (as text)
Sat Dec 11 16:31:48 2021 UTC (2 years, 3 months ago) by zmatsuo
File MIME type: text/x-csrc
File size: 37617 byte(s)
iso8859 8ビット文字コードを使用できるようにした

- ttpdlg/ttdlg.c 内の文字コード関連部分を common/ttlib_charset.cpp に移動
- 1byte文字コードテスト用ツールを追加
  - tests/various_code_texts/dump_code.pl
- ttpcmnから../teraterm/unicode.c をリンクするようにした
  - Visual Studio 2005
  - Visual Studio 2019
  - CMakeLists.txt
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 <htmlhelp.h>
37 #include <assert.h>
38 #include <crtdbg.h>
39 #include <time.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 #include "win32helper.h"
52 #include "asprintf.h"
53 #include "fileread.h"
54 #include "../teraterm/unicode.h"
55
56 #include "ttcmn_dup.h"
57
58 #define DllExport __declspec(dllexport)
59 #include "ttcommon.h"
60
61 /* shared memory */
62 typedef struct {
63 size_t size_tmap; /* sizeof TMap */
64 size_t size_tttset; /* sizeof TTTSet */
65 // Window list
66 int NWin;
67 HWND WinList[MAXNWIN];
68 /* COM port use flag
69 * bit 8 7 6 5 4 3 2 1
70 * char[0] : COM 8 7 6 5 4 3 2 1
71 * char[1] : COM16 15 14 13 12 11 10 9 ...
72 */
73 unsigned char ComFlag[(MAXCOMPORT-1)/CHAR_BIT+1];
74 /* Previous window rect (Tera Term 4.78 or later) */
75 WINDOWPLACEMENT WinPrevRect[MAXNWIN];
76 BOOL WinUndoFlag;
77 int WinUndoStyle;
78 // Duplicate Teraterm data
79 HANDLE DuplicateDataHandle;
80 DWORD DuplicateDataSizeLow;
81 } TMap;
82 typedef TMap *PMap;
83
84 // TMap ���i�[�����t�@�C���}�b�s���O�I�u�W�F�N�g(���L������)�����O
85 // TMap(�����������o)���X�V�������o�[�W�������������N���������������K�v��������
86 // �A�������o�[�W�����������g�����������X�������A���������������X�����K�v������
87 #define TT_FILEMAPNAME "ttset_memfilemap_" TT_VERSION_STR("_")
88
89 /* first instance flag */
90 static BOOL FirstInstance = TRUE;
91
92 static HINSTANCE hInst;
93
94 static PMap pm;
95
96 static HANDLE HMap = NULL;
97 #define VTCLASSNAME "VTWin32"
98 #define TEKCLASSNAME "TEKWin32"
99
100 enum window_style {
101 WIN_CASCADE,
102 WIN_STACKED,
103 WIN_SIDEBYSIDE,
104 };
105
106 static const char DupDataName[] = "dupdata";
107
108 void WINAPI CopyShmemToTTSet(PTTSet ts)
109 {
110 DWORD size = pm->DuplicateDataSizeLow;
111 HANDLE handle = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, size, DupDataName);
112 void *ptr = (void *)MapViewOfFile(handle, FILE_MAP_ALL_ACCESS, 0, 0, 0);
113 TTCMNUnserialize(ptr, (size_t)size, ts);
114 UnmapViewOfFile(ptr);
115 CloseHandle(handle);
116 pm->DuplicateDataSizeLow = 0;
117 }
118
119 void WINAPI CopyTTSetToShmem(PTTSet ts)
120 {
121 size_t size;
122 void *ptr = TTCMNSerialize(ts, &size);
123 if (ptr != NULL) {
124 HANDLE handle = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, (DWORD)size, DupDataName);
125 void *dest = (void *)MapViewOfFile(handle, FILE_MAP_ALL_ACCESS,0,0,0);
126 memcpy(dest, ptr, size);
127 UnmapViewOfFile(dest);
128 //CloseHandle(handle); do not close, �g�p����������������������������������
129
130 if (pm->DuplicateDataHandle != NULL) {
131 // 1���O����������������
132 CloseHandle(pm->DuplicateDataHandle);
133 }
134 pm->DuplicateDataHandle = handle;
135 pm->DuplicateDataSizeLow = (DWORD)size;
136 free(ptr);
137 }
138 }
139
140 static void CopyFiles(const wchar_t *file_list[], const wchar_t *src_dir, const wchar_t *dest_dir)
141 {
142 for (;;) {
143 wchar_t *dest;
144 size_t len;
145 const wchar_t *filename = *file_list;
146 file_list++;
147 if (filename == NULL) {
148 break;
149 }
150
151 dest = NULL;
152 awcscats(&dest, dest_dir, L"\\", filename, NULL);
153
154 len = wcslen(dest);
155 if (dest[len - 1] == '\\') {
156 // �t�H���_����
157 CreateDirectoryW(dest, NULL);
158 }
159 else {
160 wchar_t *src = NULL;
161 awcscats(&src, src_dir, L"\\", filename, NULL);
162 CopyFileW(src, dest, TRUE); // TRUE = do not copy if exists
163 free(src);
164 }
165 free(dest);
166 }
167 }
168
169 static void ConvertIniFiles(const wchar_t *filelist[], const wchar_t *dir, const wchar_t *date_str)
170 {
171 while(1) {
172 wchar_t *fname;
173 if (*filelist == NULL) {
174 break;
175 }
176
177 fname = NULL;
178 awcscats(&fname, dir, L"\\", *filelist, NULL);
179 ConvertIniFileCharCode(fname, date_str);
180 free(fname);
181 filelist++;
182 }
183 }
184
185 BOOL WINAPI StartTeraTerm(PTTSet ts)
186 {
187 if (FirstInstance) {
188 // init window list
189 pm->NWin = 0;
190 }
191 else {
192 /* only the first instance uses saved position */
193 ts->VTPos.x = CW_USEDEFAULT;
194 ts->VTPos.y = CW_USEDEFAULT;
195 ts->TEKPos.x = CW_USEDEFAULT;
196 ts->TEKPos.y = CW_USEDEFAULT;
197 }
198
199 // if (FirstInstance) { �������������� (2008.3.13 maya)
200 // �N���������A���L�������� HomeDir �� SetupFName ����������
201 /* Get home directory (ttermpro.exe���t�H���_) */
202 ts->ExeDirW = GetExeDirW(hInst);
203
204 // LogDir
205 ts->LogDirW = GetLogDirW();
206 CreateDirectoryW(ts->LogDirW, NULL);
207
208 // HomeDir
209 ts->HomeDirW = GetHomeDirW(hInst);
210 WideCharToACP_t(ts->HomeDirW, ts->HomeDir, _countof(ts->HomeDir));
211 CreateDirectoryW(ts->HomeDirW, NULL);
212 SetCurrentDirectoryW(ts->HomeDirW); // TODO �K�v??
213
214 // TERATERM.INI ���t���p�X
215 ts->SetupFNameW = NULL;
216 awcscats(&ts->SetupFNameW, ts->HomeDirW, L"\\TERATERM.INI", NULL);
217 WideCharToACP_t(ts->SetupFNameW, ts->SetupFName, _countof(ts->SetupFName));
218
219 // KEYBOARD.CNF ���t���p�X
220 ts->KeyCnfFNW = NULL;
221 awcscats(&ts->KeyCnfFNW, ts->HomeDirW, L"\\KEYBOARD.CNF", NULL);
222 WideCharToACP_t(ts->KeyCnfFNW, ts->KeyCnfFN, _countof(ts->KeyCnfFN));
223
224 // TERATERM.INI ����������������
225 // �����t�@�C�������l�t�H���_���R�s�[����
226 if (GetFileAttributesW(ts->SetupFNameW) == INVALID_FILE_ATTRIBUTES) {
227 static const wchar_t *filelist[] = {
228 L"TERATERM.INI",
229 L"KEYBOARD.CNF",
230 L"cygterm.cfg",
231 #if 0
232 L"theme\\",
233 L"theme\\Advanced.sample",
234 L"theme\\ImageFile.INI",
235 L"theme\\scale\\",
236 L"theme\\scale\\23.jpg",
237 L"theme\\scale\\43.jpg",
238 L"theme\\Scale.INI",
239 L"theme\\tile\\",
240 L"theme\\tile\\03.jpg",
241 L"theme\\tile\\44.jpg",
242 L"theme\\Tile.INI",
243 #endif
244 NULL,
245 };
246 CopyFiles(filelist, ts->ExeDirW, ts->HomeDirW);
247 }
248
249 // ini�t�@�C���������R�[�h����������
250 {
251 static const wchar_t *filelist[] = {
252 L"TERATERM.INI",
253 L"KEYBOARD.CNF",
254 NULL,
255 };
256
257 // backup �t�@�C�������������t������
258 wchar_t *date_str = MakeISO8601Str(0);
259 awcscat(&date_str, L"_");
260
261 // ini�t�@�C������������
262 ConvertIniFiles(filelist, ts->HomeDirW, date_str);
263
264 free(date_str);
265 }
266
267 if (FirstInstance) {
268 FirstInstance = FALSE;
269 return TRUE;
270 }
271 else {
272 return FALSE;
273 }
274 }
275
276 // �����t�@�C�����f�B�X�N���������ATera Term�{�������N�������B
277 // (2012.4.30 yutaka)
278 // �g����������?
279 void WINAPI RestartTeraTerm(HWND hwnd, PTTSet ts)
280 {
281 wchar_t *path;
282 int ret;
283
284 static const TTMessageBoxInfoW info = {
285 "Tera Term",
286 NULL, L"Tera Term: Configuration Warning",
287 "MSG_TT_TAKE_EFFECT",
288 L"This option takes effect the next time a session is started.\n"
289 L"Are you sure that you want to relaunch Tera Term?",
290 MB_YESNO | MB_ICONEXCLAMATION | MB_DEFBUTTON2
291 };
292 ret = TTMessageBoxA(hwnd, &info, ts->UILanguageFile);
293 if (ret != IDYES)
294 return;
295
296 SendMessage(hwnd, WM_COMMAND, ID_SETUP_SAVE, 0);
297 // ID_FILE_EXIT ���b�Z�[�W�����A�v�������������������������AWM_QUIT ���|�X�g�����B
298 //PostMessage(hwnd, WM_COMMAND, ID_FILE_EXIT, 0);
299 PostQuitMessage(0);
300
301 // ���v���Z�X�����N���B
302 if (hGetModuleFileNameW(NULL, &path) == 0) {
303 TTWinExec(path);
304 free(path);
305 }
306 }
307
308 void WINAPI SetCOMFlag(int Com)
309 {
310 pm->ComFlag[(Com-1)/CHAR_BIT] |= 1 << ((Com-1)%CHAR_BIT);
311 }
312
313 void WINAPI ClearCOMFlag(int Com)
314 {
315 pm->ComFlag[(Com-1)/CHAR_BIT] &= ~(1 << ((Com-1)%CHAR_BIT));
316 }
317
318 int WINAPI CheckCOMFlag(int Com)
319 {
320 return ((pm->ComFlag[(Com-1)/CHAR_BIT] & 1 << (Com-1)%CHAR_BIT) > 0);
321 }
322
323 int WINAPI RegWin(HWND HWinVT, HWND HWinTEK)
324 {
325 int i, j;
326
327 if (pm->NWin>=MAXNWIN)
328 return 0;
329 if (HWinVT==NULL)
330 return 0;
331 if (HWinTEK!=NULL) {
332 i = 0;
333 while ((i<pm->NWin) && (pm->WinList[i]!=HWinVT))
334 i++;
335 if (i>=pm->NWin)
336 return 0;
337 for (j=pm->NWin-1 ; j>i ; j--)
338 pm->WinList[j+1] = pm->WinList[j];
339 pm->WinList[i+1] = HWinTEK;
340 pm->NWin++;
341 return 0;
342 }
343 pm->WinList[pm->NWin++] = HWinVT;
344 memset(&pm->WinPrevRect[pm->NWin - 1], 0, sizeof(pm->WinPrevRect[pm->NWin - 1])); // RECT clear
345 if (pm->NWin==1) {
346 return 1;
347 }
348 else {
349 return (int)(SendMessage(pm->WinList[pm->NWin-2],
350 WM_USER_GETSERIALNO,0,0)+1);
351 }
352 }
353
354 void WINAPI UnregWin(HWND HWin)
355 {
356 int i, j;
357
358 i = 0;
359 while ((i<pm->NWin) && (pm->WinList[i]!=HWin)) {
360 i++;
361 }
362 if (pm->WinList[i]!=HWin) {
363 return;
364 }
365 for (j=i ; j<pm->NWin-1 ; j++) {
366 pm->WinList[j] = pm->WinList[j+1];
367 pm->WinPrevRect[j] = pm->WinPrevRect[j+1]; // RECT shift
368 }
369 if (pm->NWin>0) {
370 pm->NWin--;
371 }
372 }
373
374 char GetWindowTypeChar(HWND Hw, HWND HWin)
375 {
376 #if 0
377 if (HWin == Hw)
378 return '*';
379 else if (!IsWindowVisible(Hw))
380 #else
381 if (!IsWindowVisible(Hw))
382 #endif
383 return '#';
384 else if (IsIconic(Hw))
385 return '-';
386 else if (IsZoomed(Hw))
387 return '@';
388 else
389 return '+';
390 }
391
392 void WINAPI SetWinMenu(HMENU menu, PCHAR buf, int buflen, PCHAR langFile, int VTFlag)
393 {
394 int i;
395 char Temp[MAXPATHLEN];
396 HWND Hw;
397 wchar_t uimsg[MAX_UIMSG];
398
399 // delete all items in Window menu
400 i = GetMenuItemCount(menu);
401 if (i>0)
402 do {
403 i--;
404 RemoveMenu(menu,i,MF_BYPOSITION);
405 } while (i>0);
406
407 i = 0;
408 while (i<pm->NWin) {
409 Hw = pm->WinList[i]; // get window handle
410 if ((GetClassName(Hw,Temp,sizeof(Temp))>0) &&
411 ((strcmp(Temp,VTCLASSNAME)==0) ||
412 (strcmp(Temp,TEKCLASSNAME)==0))) {
413 Temp[0] = '&';
414 Temp[1] = (char)(0x31 + i);
415 Temp[2] = ' ';
416 Temp[3] = GetWindowTypeChar(Hw, NULL);
417 Temp[4] = ' ';
418 GetWindowText(Hw,&Temp[5],sizeof(Temp)-6);
419 AppendMenu(menu,MF_ENABLED | MF_STRING,ID_WINDOW_1+i,Temp);
420 i++;
421 if (i>8) {
422 i = pm->NWin;
423 }
424 }
425 else {
426 UnregWin(Hw);
427 }
428 }
429 if (VTFlag == 1) {
430 static const DlgTextInfo MenuTextInfo[] = {
431 { ID_WINDOW_WINDOW, "MENU_WINDOW_WINDOW" },
432 { ID_WINDOW_MINIMIZEALL, "MENU_WINDOW_MINIMIZEALL" },
433 { ID_WINDOW_RESTOREALL, "MENU_WINDOW_RESTOREALL" },
434 { ID_WINDOW_CASCADEALL, "MENU_WINDOW_CASCADE" },
435 { ID_WINDOW_STACKED, "MENU_WINDOW_STACKED" },
436 { ID_WINDOW_SIDEBYSIDE, "MENU_WINDOW_SIDEBYSIDE" },
437 };
438
439 AppendMenu(menu, MF_SEPARATOR, 0, NULL);
440 AppendMenu(menu, MF_ENABLED | MF_STRING, ID_WINDOW_WINDOW, "&Window");
441 AppendMenu(menu, MF_ENABLED | MF_STRING, ID_WINDOW_MINIMIZEALL, "&Minimize All");
442 AppendMenu(menu, MF_ENABLED | MF_STRING, ID_WINDOW_RESTOREALL, "&Restore All");
443 AppendMenu(menu, MF_ENABLED | MF_STRING, ID_WINDOW_CASCADEALL, "&Cascade");
444 AppendMenu(menu, MF_ENABLED | MF_STRING, ID_WINDOW_STACKED, "&Stacked");
445 AppendMenu(menu, MF_ENABLED | MF_STRING, ID_WINDOW_SIDEBYSIDE, "Side &by Side");
446
447 SetI18nMenuStrs("Tera Term", menu, MenuTextInfo, _countof(MenuTextInfo), langFile);
448
449 if (pm->WinUndoFlag) {
450 if (pm->WinUndoStyle == WIN_CASCADE)
451 get_lang_msgW("MENU_WINDOW_CASCADE_UNDO", uimsg, _countof(uimsg), L"&Undo - Cascade", langFile);
452 else if (pm->WinUndoStyle == WIN_STACKED)
453 get_lang_msgW("MENU_WINDOW_STACKED_UNDO", uimsg, _countof(uimsg), L"&Undo - Stacked", langFile);
454 else
455 get_lang_msgW("MENU_WINDOW_SIDEBYSIDE_UNDO", uimsg, _countof(uimsg), L"&Undo - Side by Side", langFile);
456 AppendMenuW(menu, MF_ENABLED | MF_STRING, ID_WINDOW_UNDO, uimsg); // TODO UNICODE
457 }
458
459 }
460 else {
461 get_lang_msgW("MENU_WINDOW_WINDOW", uimsg, _countof(uimsg), L"&Window", langFile);
462 AppendMenuW(menu,MF_ENABLED | MF_STRING,ID_TEKWINDOW_WINDOW, uimsg);
463 }
464 }
465
466 void WINAPI SetWinList(HWND HWin, HWND HDlg, int IList)
467 {
468 int i;
469 char Temp[MAXPATHLEN];
470 HWND Hw;
471
472 for (i=0; i<pm->NWin; i++) {
473 Hw = pm->WinList[i]; // get window handle
474 if ((GetClassName(Hw,Temp,sizeof(Temp))>0) &&
475 ((strcmp(Temp,VTCLASSNAME)==0) ||
476 (strcmp(Temp,TEKCLASSNAME)==0))) {
477 Temp[0] = GetWindowTypeChar(Hw, HWin);
478 Temp[1] = ' ';
479 GetWindowText(Hw,&Temp[2],sizeof(Temp)-3);
480 SendDlgItemMessage(HDlg, IList, LB_ADDSTRING,
481 0, (LPARAM)Temp);
482 if (Hw==HWin) {
483 SendDlgItemMessage(HDlg, IList, LB_SETCURSEL, i,0);
484 }
485 }
486 else {
487 UnregWin(Hw);
488 }
489 }
490 }
491
492 void WINAPI SelectWin(int WinId)
493 {
494 if ((WinId>=0) && (WinId<pm->NWin)) {
495 /* �E�B���h�E�����������������������������������A���������������������������A
496 * SW_SHOWNORMAL ���� SW_SHOW �����X�����B
497 * (2009.11.8 yutaka)
498 * �E�B���h�E�����������������������������T�C�Y������(SW_RESTORE)�����������B
499 * (2009.11.9 maya)
500 */
501 if (IsIconic(pm->WinList[WinId])) {
502 ShowWindow(pm->WinList[WinId],SW_RESTORE);
503 }
504 else {
505 ShowWindow(pm->WinList[WinId],SW_SHOW);
506 }
507 SetForegroundWindow(pm->WinList[WinId]);
508 }
509 }
510
511 void WINAPI SelectNextWin(HWND HWin, int Next, BOOL SkipIconic)
512 {
513 int i;
514
515 i = 0;
516 while ((i < pm->NWin) && (pm->WinList[i]!=HWin)) {
517 i++;
518 }
519 if (pm->WinList[i]!=HWin) {
520 return;
521 }
522
523 do {
524 i += Next;
525 if (i >= pm->NWin) {
526 i = 0;
527 }
528 else if (i < 0) {
529 i = pm->NWin-1;
530 }
531
532 if (pm->WinList[i] == HWin) {
533 break;
534 }
535 } while ((SkipIconic && IsIconic(pm->WinList[i])) || !IsWindowVisible(pm->WinList[i]));
536
537 SelectWin(i);
538 }
539
540 void WINAPI ShowAllWin(int stat) {
541 int i;
542
543 for (i=0; i < pm->NWin; i++) {
544 ShowWindow(pm->WinList[i], stat);
545 }
546 }
547
548 void WINAPI UndoAllWin(void) {
549 int i;
550 WINDOWPLACEMENT rc0;
551 RECT rc;
552 int stat = SW_RESTORE;
553 int multi_mon = 0;
554
555 if (HasMultiMonitorSupport()) {
556 multi_mon = 1;
557 }
558
559 // ���x�A�����������t���O���������B
560 pm->WinUndoFlag = FALSE;
561
562 memset(&rc0, 0, sizeof(rc0));
563
564 for (i=0; i < pm->NWin; i++) {
565 // �����w�����A�O�����������c���������������A�E�B���h�E�����������������B
566 if (stat == SW_RESTORE && memcmp(&pm->WinPrevRect[i], &rc0, sizeof(rc0)) != 0) {
567 rc = pm->WinPrevRect[i].rcNormalPosition;
568
569 // NT4.0, 95 ���}���`���j�^API��������
570 if (multi_mon) {
571 // �������j�^������������
572 HMONITOR hMonitor;
573 MONITORINFO mi;
574 hMonitor = pMonitorFromRect(&rc, MONITOR_DEFAULTTONEAREST);
575 mi.cbSize = sizeof(MONITORINFO);
576 pGetMonitorInfoA(hMonitor, &mi);
577
578 // ���u�����i�����O���������x���������������������������j
579 if (rc.right > mi.rcMonitor.right) {
580 rc.left -= rc.right - mi.rcMonitor.right;
581 rc.right = mi.rcMonitor.right;
582 }
583 if (rc.left < mi.rcMonitor.left) {
584 rc.right += mi.rcMonitor.left - rc.left;
585 rc.left = mi.rcMonitor.left;
586 }
587 if (rc.bottom > mi.rcMonitor.bottom) {
588 rc.top -= rc.bottom - mi.rcMonitor.bottom;
589 rc.bottom = mi.rcMonitor.bottom;
590 }
591 if (rc.top < mi.rcMonitor.top) {
592 rc.bottom += mi.rcMonitor.top - rc.top;
593 rc.top = mi.rcMonitor.top;
594 }
595 }
596
597 // �E�B���h�E���u����
598 SetWindowPos(
599 pm->WinList[i], NULL,
600 rc.left,
601 rc.top,
602 rc.right - rc.left,
603 rc.bottom - rc.top,
604 SWP_NOZORDER);
605
606 // �E�B���h�E����������
607 ShowWindow(pm->WinList[i], pm->WinPrevRect[i].showCmd);
608
609 } else {
610 ShowWindow(pm->WinList[i], stat);
611 }
612 }
613 }
614
615 void WINAPI OpenHelp(UINT Command, DWORD Data, char *UILanguageFile)
616 {
617 wchar_t Temp[MAX_PATH];
618 HWND HWin;
619 wchar_t *HelpFN;
620 wchar_t uimsg[MAX_UIMSG];
621 wchar_t *HomeDirW;
622
623 /* Get home directory TODO ts.HomeDirW ���������� */
624 if (GetModuleFileNameW(NULL,Temp,_countof(Temp)) == 0) {
625 return;
626 }
627 HomeDirW = ExtractDirNameW(Temp);
628 get_lang_msgW("HELPFILE", uimsg, _countof(uimsg), L"teraterm.chm", UILanguageFile);
629 aswprintf(&HelpFN, L"%s\\%s", HomeDirW, uimsg);
630 free(HomeDirW);
631
632 // �w���v���I�[�i�[�������f�X�N�g�b�v������ (2007.5.12 maya)
633 HWin = GetDesktopWindow();
634 if (_HtmlHelpW(HWin, HelpFN, Command, Data) == NULL) {
635 // �w���v���J����������
636 static const TTMessageBoxInfoW info = {
637 "Tera Term",
638 NULL, L"Tera Term: HTML help",
639 "MSG_OPENHELP_ERROR", L"Can't open HTML help file(%s).",
640 MB_OK | MB_ICONERROR };
641 TTMessageBoxA(HWin, &info, UILanguageFile, HelpFN);
642 }
643 free(HelpFN);
644 }
645
646 HWND WINAPI GetNthWin(int n)
647 {
648 if (n<pm->NWin) {
649 return pm->WinList[n];
650 }
651 else {
652 return NULL;
653 }
654 }
655
656 int WINAPI GetRegisteredWindowCount(void)
657 {
658 return (pm->NWin);
659 }
660
661 // �L�����E�B���h�E���T���A�������u���L�������������B
662 static void get_valid_window_and_memorize_rect(HWND myhwnd, HWND hwnd[], int *num, int style)
663 {
664 int i, n;
665 WINDOWPLACEMENT wndPlace;
666
667 // ��������(Undo)���j���[�����x�����\���������B
668 if (pm->WinUndoFlag == FALSE) {
669 pm->WinUndoFlag = TRUE;
670 } else {
671 // ���������j���[���\�������������A�������O�������X�^�C�����I�����������A
672 // ���j���[�������B
673 // Windows8�����A�������A�����������X�^�C�����I�����������j���[�����������������A
674 // Tera Term�������j���[���\�������������A�������������B
675 if (pm->WinUndoStyle == style)
676 pm->WinUndoFlag = FALSE;
677 }
678 pm->WinUndoStyle = style;
679
680 n = 0;
681 for (i = 0 ; i < pm->NWin ; i++) {
682 // �������u���o���������B
683 wndPlace.length = sizeof(WINDOWPLACEMENT);
684 GetWindowPlacement(pm->WinList[i], &wndPlace);
685 pm->WinPrevRect[i] = wndPlace;
686
687 // �������g�������������B
688 if (pm->WinList[i] == myhwnd) {
689 hwnd[n] = hwnd[0];
690 hwnd[0] = myhwnd;
691 } else {
692 hwnd[n] = pm->WinList[i];
693 }
694 n++;
695 }
696 *num = n;
697 }
698
699 // �E�B���h�E�����E���������\������(Show Windows Side by Side)
700 void WINAPI ShowAllWinSidebySide(HWND myhwnd)
701 {
702 int n;
703 HWND hwnd[MAXNWIN];
704
705 get_valid_window_and_memorize_rect(myhwnd, hwnd, &n, WIN_SIDEBYSIDE);
706 TileWindows(NULL, MDITILE_VERTICAL, NULL, n, hwnd);
707 }
708
709 // �E�B���h�E���������������\������(Show Windows Stacked)
710 void WINAPI ShowAllWinStacked(HWND myhwnd)
711 {
712 int n;
713 HWND hwnd[MAXNWIN];
714
715 get_valid_window_and_memorize_rect(myhwnd, hwnd, &n, WIN_STACKED);
716 TileWindows(NULL, MDITILE_HORIZONTAL, NULL, n, hwnd);
717 }
718
719 // �E�B���h�E���d�����\������(Cascade)
720 void WINAPI ShowAllWinCascade(HWND myhwnd)
721 {
722 int n;
723 HWND hwnd[MAXNWIN];
724
725 get_valid_window_and_memorize_rect(myhwnd, hwnd, &n, WIN_CASCADE);
726 CascadeWindows(NULL, MDITILE_SKIPDISABLED, NULL, n, hwnd);
727 }
728
729 // �STera Term���I���w�����o���B
730 void WINAPI BroadcastClosingMessage(HWND myhwnd)
731 {
732 int i, max;
733 HWND hwnd[MAXNWIN];
734
735 // Tera Term���I�����������A���L���������������������A
736 // ���������o�b�t�@���R�s�[���������B
737 max = pm->NWin;
738 for (i = 0 ; i < pm->NWin ; i++) {
739 hwnd[i] = pm->WinList[i];
740 }
741
742 for (i = 0 ; i < max ; i++) {
743 // �������g�������������B
744 if (hwnd[i] == myhwnd)
745 continue;
746
747 PostMessage(hwnd[i], WM_USER_NONCONFIRM_CLOSE, 0, 0);
748 }
749 PostMessage(myhwnd, WM_USER_NONCONFIRM_CLOSE, 0, 0);
750 }
751
752
753 int WINAPI CommReadRawByte(PComVar cv, LPBYTE b)
754 {
755 if ( ! cv->Ready ) {
756 return 0;
757 }
758
759 if ( cv->InBuffCount>0 ) {
760 *b = cv->InBuff[cv->InPtr];
761 cv->InPtr++;
762 cv->InBuffCount--;
763 if ( cv->InBuffCount==0 ) {
764 cv->InPtr = 0;
765 }
766 return 1;
767 }
768 else {
769 cv->InPtr = 0;
770 return 0;
771 }
772 }
773
774 static void LogBinSkip(PComVar cv, int add)
775 {
776 if (cv->LogBinSkip != NULL) {
777 cv->LogBinSkip(add);
778 }
779 }
780
781 void WINAPI CommInsert1Byte(PComVar cv, BYTE b)
782 {
783 if ( ! cv->Ready ) {
784 return;
785 }
786
787 if (cv->InPtr == 0) {
788 memmove(&(cv->InBuff[1]),&(cv->InBuff[0]),cv->InBuffCount);
789 }
790 else {
791 cv->InPtr--;
792 }
793 cv->InBuff[cv->InPtr] = b;
794 cv->InBuffCount++;
795
796 LogBinSkip(cv, 1);
797 }
798
799 static void Log1Bin(PComVar cv, BYTE b)
800 {
801 if (cv->Log1Bin != NULL) {
802 cv->Log1Bin(b);
803 }
804 }
805
806 int WINAPI CommRead1Byte(PComVar cv, LPBYTE b)
807 {
808 int c;
809
810 if ( ! cv->Ready ) {
811 return 0;
812 }
813
814 if ( cv->TelMode ) {
815 c = 0;
816 }
817 else {
818 c = CommReadRawByte(cv,b);
819 }
820
821 if ((c==1) && cv->TelCRFlag) {
822 cv->TelCRFlag = FALSE;
823 if (*b==0) {
824 c = 0;
825 }
826 }
827
828 if ( c==1 ) {
829 if ( cv->IACFlag ) {
830 cv->IACFlag = FALSE;
831 if ( *b != 0xFF ) {
832 cv->TelMode = TRUE;
833 CommInsert1Byte(cv,*b);
834 LogBinSkip(cv, -1);
835 c = 0;
836 }
837 }
838 else if ((cv->PortType==IdTCPIP) && (*b==0xFF)) {
839 if (!cv->TelFlag && cv->TelAutoDetect) { /* TTPLUG */
840 cv->TelFlag = TRUE;
841 }
842 if (cv->TelFlag) {
843 cv->IACFlag = TRUE;
844 c = 0;
845 }
846 }
847 else if (cv->TelFlag && ! cv->TelBinRecv && (*b==0x0D)) {
848 cv->TelCRFlag = TRUE;
849 }
850 }
851
852 if (c == 1) {
853 Log1Bin(cv, *b);
854 }
855
856 return c;
857 }
858
859 int WINAPI CommRawOut(PComVar cv, /*const*/ PCHAR B, int C)
860 {
861 int a;
862
863 if ( ! cv->Ready ) {
864 return C;
865 }
866
867 if (C > OutBuffSize - cv->OutBuffCount) {
868 a = OutBuffSize - cv->OutBuffCount;
869 }
870 else {
871 a = C;
872 }
873 if ( cv->OutPtr > 0 ) {
874 memmove(&(cv->OutBuff[0]),&(cv->OutBuff[cv->OutPtr]),cv->OutBuffCount);
875 cv->OutPtr = 0;
876 }
877 memcpy(&(cv->OutBuff[cv->OutBuffCount]),B,a);
878 cv->OutBuffCount = cv->OutBuffCount + a;
879 return a;
880 }
881
882 int WINAPI CommBinaryOut(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 ( cv->TelFlag && (B[i]=='\x0d') && ! cv->TelBinSend ) {
900 d[Len++] = '\x00';
901 }
902 else if ( cv->TelFlag && (B[i]=='\xff') ) {
903 d[Len++] = '\xff';
904 }
905
906 if ( OutBuffSize - cv->OutBuffCount - Len >= 0 ) {
907 CommRawOut(cv, d, Len);
908 a = 1;
909 }
910 else {
911 a = 0;
912 }
913
914 i += a;
915 }
916 return i;
917 }
918
919 /**
920 * �f�[�^(������)���o���o�b�t�@����������
921 *
922 * �w���f�[�^��������������������������������������
923 * CommRawOut() ��������������������������
924 *
925 * @retval TRUE �o��������
926 * @retval FALSE �o��������������(buffer full)
927 */
928 static BOOL WriteOutBuff(PComVar cv, const char *TempStr, int TempLen)
929 {
930 BOOL output;
931
932 if (TempLen == 0) {
933 // ����0������������������������
934 return TRUE;
935 }
936
937 output = FALSE;
938 if (cv->TelLineMode) {
939 const BOOL Full = OutBuffSize - cv->LineModeBuffCount - TempLen < 0;
940 if (!Full) {
941 output = TRUE;
942 memcpy(&(cv->LineModeBuff[cv->LineModeBuffCount]), TempStr, TempLen);
943 cv->LineModeBuffCount += TempLen;
944 if (cv->Flush) {
945 cv->FlushLen = cv->LineModeBuffCount;
946 }
947 }
948 if (cv->FlushLen > 0) {
949 const int OutLen = CommRawOut(cv, cv->LineModeBuff, cv->FlushLen);
950 cv->FlushLen -= OutLen;
951 cv->LineModeBuffCount -= OutLen;
952 memmove(cv->LineModeBuff, &(cv->LineModeBuff[OutLen]), cv->LineModeBuffCount);
953 }
954 cv->Flush = FALSE;
955 }
956 else {
957 const BOOL Full = OutBuffSize-cv->OutBuffCount-TempLen < 0;
958 if (! Full) {
959 output = TRUE;
960 CommRawOut(cv, (char *)TempStr, TempLen);
961 }
962 }
963 return output;
964 }
965
966 /**
967 * �f�[�^(������)�������o�b�t�@����������
968 * �����o�b�t�@�������� -> �G�R�[������
969 *
970 * @retval TRUE �o��������
971 * @retval FALSE �o��������������(buffer full)
972 */
973 static BOOL WriteInBuff(PComVar cv, const char *TempStr, int TempLen)
974 {
975 BOOL Full;
976
977 if (TempLen == 0) {
978 return TRUE;
979 }
980
981 Full = InBuffSize-cv->InBuffCount-TempLen < 0;
982 if (! Full) {
983 memcpy(&(cv->InBuff[cv->InBuffCount]),TempStr,TempLen);
984 cv->InBuffCount = cv->InBuffCount + TempLen;
985 return TRUE;
986 }
987 return FALSE;
988 }
989
990 /**
991 * �����o�b�t�@�����������������������l����
992 */
993 static void PackInBuff(PComVar cv)
994 {
995 if ( (cv->InPtr>0) && (cv->InBuffCount>0) ) {
996 memmove(cv->InBuff,&(cv->InBuff[cv->InPtr]),cv->InBuffCount);
997 cv->InPtr = 0;
998 }
999 }
1000
1001 int WINAPI CommBinaryBuffOut(PComVar cv, PCHAR B, int C)
1002 {
1003 int a, i, Len;
1004 char d[3];
1005
1006 if ( ! cv->Ready ) {
1007 return C;
1008 }
1009
1010 i = 0;
1011 a = 1;
1012 while ((a>0) && (i<C)) {
1013 Len = 0;
1014
1015 d[Len] = B[i];
1016 Len++;
1017
1018 if (B[i] == CR) {
1019 if ( cv->TelFlag && ! cv->TelBinSend ) {
1020 d[Len++] = '\x00';
1021 }
1022 if (cv->TelLineMode) {
1023 cv->Flush = TRUE;
1024 }
1025 }
1026 else if ( cv->TelFlag && (B[i]=='\xff') ) {
1027 d[Len++] = '\xff';
1028 }
1029
1030 if (WriteOutBuff(cv, d, Len)) {
1031 a = 1;
1032 i++;
1033 } else {
1034 a = 0;
1035 }
1036 }
1037 return i;
1038 }
1039
1040 /**
1041 * @retval true ���{�������p�J�^�J�i
1042 * @retval false ������
1043 */
1044 static BOOL IsHalfWidthKatakana(unsigned int u32)
1045 {
1046 // Halfwidth CJK punctuation (U+FF61�`FF64)
1047 // Halfwidth Katakana variants (U+FF65�`FF9F)
1048 return (0xff61 <= u32 && u32 <= 0xff9f);
1049 }
1050
1051 /**
1052 * �o���p�A TODO echo�p������
1053 * @param cv
1054 * @param u32 ��������
1055 * @param check_only TRUE���������s�����A
1056 * @param TempStr �o��������
1057 * @param StrLen TempStr�����o��������
1058 * @retval �������s����
1059 */
1060 static BOOL OutControl(PComVar cv, unsigned int u32, BOOL check_only, char *TempStr, size_t *StrLen)
1061 {
1062 const wchar_t d = u32;
1063 size_t TempLen = 0;
1064 BOOL retval = FALSE;
1065 if (check_only == TRUE) {
1066 /* �`�F�b�N���� */
1067 if (d == CR || d == BS || d == 0x15/*ctrl-u*/) {
1068 return TRUE;
1069 } else {
1070 return FALSE;
1071 }
1072 }
1073 if (d==CR) {
1074 TempStr[TempLen++] = 0x0d;
1075 if (cv->CRSend==IdCRLF) {
1076 TempStr[TempLen++] = 0x0a;
1077 }
1078 else if ((cv->CRSend ==IdCR) &&
1079 cv->TelFlag && ! cv->TelBinSend) {
1080 TempStr[TempLen++] = 0;
1081 }
1082 else if (cv->CRSend == IdLF) {
1083 TempStr[TempLen-1] = 0x0a;
1084 }
1085 if (cv->TelLineMode) {
1086 cv->Flush = TRUE;
1087 }
1088 retval = TRUE;
1089 }
1090 else if (d== BS) {
1091 if (cv->TelLineMode) {
1092 if (cv->FlushLen < cv->LineModeBuffCount) {
1093 cv->LineModeBuffCount--;
1094 }
1095 }
1096 else {
1097 TempStr[TempLen++] = BS;
1098 }
1099 retval = TRUE;
1100 }
1101 else if (d==0x15) { // ctrl-u
1102 if (cv->TelLineMode) {
1103 cv->LineModeBuffCount = cv->FlushLen;
1104 }
1105 else {
1106 TempStr[TempLen++] = 0x15;
1107 }
1108 retval = TRUE;
1109 }
1110 *StrLen = TempLen;
1111 return retval;
1112 }
1113 static BOOL ControlEcho(PComVar cv, unsigned int u32, BOOL check_only, char *TempStr, size_t *StrLen)
1114 {
1115 const wchar_t d = u32;
1116 size_t TempLen = 0;
1117 BOOL retval = FALSE;
1118 if (check_only == TRUE) {
1119 /* �`�F�b�N���� */
1120 if (d == CR || (d == 0x15/*ctrl-u*/ && cv->TelLineMode)) {
1121 return TRUE;
1122 } else {
1123 return FALSE;
1124 }
1125 }
1126 if (d==CR) {
1127 TempStr[TempLen++] = 0x0d;
1128 if (cv->CRSend==IdCRLF) {
1129 TempStr[TempLen++] = 0x0a;
1130 }
1131 else if ((cv->CRSend ==IdCR) && cv->TelFlag && ! cv->TelBinSend) {
1132 TempStr[TempLen++] = 0;
1133 }
1134 else if (cv->CRSend == IdLF) {
1135 TempStr[TempLen-1] = 0x0a;
1136 }
1137 retval = TRUE;
1138 }
1139 else if (d==0x15/*ctrl-u*/ && cv->TelLineMode) {
1140 // Move to top of line (CHA "\033[G") and erase line (EL "\033[K")
1141 memcpy(TempStr, "\033[G\033[K", 6);
1142 TempLen += 6;
1143 retval = TRUE;
1144 }
1145 *StrLen = TempLen;
1146 return retval;
1147 }
1148
1149 /**
1150 * �o���p����������������
1151 *
1152 * @retval ��������������
1153 */
1154 typedef struct {
1155 int KanjiCode; // [in]�o�������R�[�h(sjis,jis����)
1156 BOOL (*ControlOut)(PComVar cv, unsigned int u32, BOOL check_only, char *TempStr, size_t *StrLen);
1157 // state�����������K�v�����������R�[�h���g�p
1158 BOOL JIS7Katakana; // [in](Kanji JIS)kana
1159 int SendCode; // [in,out](Kanji JIS)���O�����M�R�[�h Ascii/Kana/Kanji
1160 BOOL KanjiFlag; // [in,out](MBCS)���O��1byte��������������?(2byte������������?)
1161 BYTE KanjiFirst; // [in,out](MBCS)���O��1byte
1162 } OutputCharState;
1163
1164 /**
1165 * unicode(UTF-16)����unicode(UTF-32)��1���������o����
1166 * �o���f�[�^(TempStr)����������
1167 */
1168 static size_t MakeOutputString(PComVar cv, OutputCharState *states,
1169 const wchar_t *B, int C,
1170 char *TempStr, int *TempLen_)
1171 {
1172 BOOL (*ControlOut)(PComVar cv, unsigned int u32, BOOL check_only, char *TempStr, size_t *StrLen)
1173 = states->ControlOut;
1174 //
1175 int TempLen = 0;
1176 size_t TempLen2;
1177 size_t output_char_count; // ��������������
1178
1179 // UTF-32 ��1���������o��
1180 unsigned int u32;
1181 size_t u16_len = UTF16ToUTF32(B, C, &u32);
1182 if (u16_len == 0) {
1183 // �f�R�[�h��������? ����������������?
1184 assert(FALSE);
1185 u32 = '?';
1186 u16_len = 1;
1187 }
1188 output_char_count = u16_len;
1189
1190 // �e���V�t�g����������������
1191 if (u32 < 0x100 || ControlOut(cv, u32, TRUE, NULL, NULL)) {
1192 if (cv->Language == IdJapanese && states->KanjiCode == IdJIS) {
1193 // �����������A���{��,JIS��������
1194 if (cv->SendCode == IdKanji) {
1195 // �����������������A����OUT
1196 TempStr[TempLen++] = 0x1B;
1197 TempStr[TempLen++] = '(';
1198 switch (cv->KanjiOut) {
1199 case IdKanjiOutJ:
1200 TempStr[TempLen++] = 'J';
1201 break;
1202 case IdKanjiOutH:
1203 TempStr[TempLen++] = 'H';
1204 break;
1205 default:
1206 TempStr[TempLen++] = 'B';
1207 }
1208 }
1209
1210 if (states->JIS7Katakana == 1) {
1211 if (cv->SendCode == IdKatakana) {
1212 TempStr[TempLen++] = SO;
1213 }
1214 }
1215
1216 states->SendCode = IdASCII;
1217 }
1218 }
1219
1220 // 1������������
1221 if (ControlOut(cv, u32, FALSE, TempStr, &TempLen2)) {
1222 // ��������������������
1223 TempLen += TempLen2;
1224 output_char_count = 1;
1225 } else if (cv->Language == IdUtf8 ||
1226 (cv->Language == IdJapanese && states->KanjiCode == IdUTF8) ||
1227 (cv->Language == IdKorean && states->KanjiCode == IdUTF8) ||
1228 (cv->Language == IdChinese && states->KanjiCode == IdUTF8))
1229 {
1230 // UTF-8 ���o��
1231 size_t utf8_len = sizeof(TempStr);
1232 utf8_len = UTF32ToUTF8(u32, TempStr, utf8_len);
1233 TempLen += utf8_len;
1234 } else if (cv->Language == IdJapanese) {
1235 // ���{��
1236 // ���� CP932(SJIS) ���������������o��
1237 char mb_char[2];
1238 size_t mb_len = sizeof(mb_char);
1239 mb_len = UTF32ToMBCP(u32, 932, mb_char, mb_len);
1240 if (mb_len == 0) {
1241 // SJIS��������������
1242 TempStr[TempLen++] = '?';
1243 } else {
1244 switch (states->KanjiCode) {
1245 case IdEUC:
1246 // TODO ���p�J�i
1247 if (mb_len == 1) {
1248 TempStr[TempLen++] = mb_char[0];
1249 } else {
1250 WORD K;
1251 K = (((WORD)(unsigned char)mb_char[0]) << 8) +
1252 (WORD)(unsigned char)mb_char[1];
1253 K = SJIS2EUC(K);
1254 TempStr[TempLen++] = HIBYTE(K);
1255 TempStr[TempLen++] = LOBYTE(K);
1256 }
1257 break;
1258 case IdJIS:
1259 if (u32 < 0x100) {
1260 // ASCII
1261 TempStr[TempLen++] = mb_char[0];
1262 states->SendCode = IdASCII;
1263 } else if (IsHalfWidthKatakana(u32)) {
1264 // ���p�J�^�J�i
1265 if (states->JIS7Katakana==1) {
1266 if (cv->SendCode != IdKatakana) {
1267 TempStr[TempLen++] = SI;
1268 }
1269 TempStr[TempLen++] = mb_char[0] & 0x7f;
1270 } else {
1271 TempStr[TempLen++] = mb_char[0];
1272 }
1273 states->SendCode = IdKatakana;
1274 } else {
1275 // ����
1276 WORD K;
1277 K = (((WORD)(unsigned char)mb_char[0]) << 8) +
1278 (WORD)(unsigned char)mb_char[1];
1279 K = SJIS2JIS(K);
1280 if (states->SendCode != IdKanji) {
1281 // ����IN
1282 TempStr[TempLen++] = 0x1B;
1283 TempStr[TempLen++] = '$';
1284 if (cv->KanjiIn == IdKanjiInB) {
1285 TempStr[TempLen++] = 'B';
1286 }
1287 else {
1288 TempStr[TempLen++] = '@';
1289 }
1290 states->SendCode = IdKanji;
1291 }
1292 TempStr[TempLen++] = HIBYTE(K);
1293 TempStr[TempLen++] = LOBYTE(K);
1294 }
1295 break;
1296 case IdSJIS:
1297 if (mb_len == 1) {
1298 TempStr[TempLen++] = mb_char[0];
1299 } else {
1300 TempStr[TempLen++] = mb_char[0];
1301 TempStr[TempLen++] = mb_char[1];
1302 }
1303 break;
1304 default:
1305 assert(FALSE);
1306 break;
1307 }
1308 }
1309 } else if (cv->Language == IdRussian) {
1310 /* ����CP1251�����������o�� */
1311 char mb_char[2];
1312 size_t mb_len = sizeof(mb_char);
1313 BYTE b;
1314 mb_len = UTF32ToMBCP(u32, 1251, mb_char, mb_len);
1315 if (mb_len != 1) {
1316 b = '?';
1317 } else {
1318 b = RussConv(IdWindows, states->KanjiCode, mb_char[0]);
1319 }
1320 TempStr[TempLen++] = b;
1321 } else if (cv->Language == IdKorean || cv->Language == IdChinese) {
1322 int code_page;
1323 char mb_char[2];
1324 size_t mb_len;
1325 if (cv->Language == IdKorean) {
1326 code_page = 51949;
1327 } else if (cv->Language == IdChinese) {
1328 switch (states->KanjiCode) {
1329 case IdCnGB2312:
1330 code_page = 936;
1331 break;
1332 case IdCnBig5:
1333 code_page = 950;
1334 break;
1335 default:
1336 assert(FALSE);
1337 code_page = 936;
1338 break;
1339 }
1340 }
1341 /* code_page �����������o�� */
1342 mb_len = sizeof(mb_char);
1343 mb_len = UTF32ToMBCP(u32, code_page, mb_char, mb_len);
1344 if (mb_len == 0) {
1345 TempStr[TempLen++] = '?';
1346 }
1347 else if (mb_len == 1) {
1348 TempStr[TempLen++] = mb_char[0];
1349 } else {
1350 TempStr[TempLen++] = mb_char[0];
1351 TempStr[TempLen++] = mb_char[1];
1352 }
1353 } else if (cv->Language == IdEnglish) {
1354 char byte;
1355 int part = KanjiCodeToISO8859Part(states->KanjiCode);
1356 int r = UnicodeToISO8859(part, u32, &byte);
1357 TempStr[TempLen++] = byte;
1358 } else {
1359 assert(FALSE);
1360 }
1361
1362 *TempLen_ = TempLen;
1363 return output_char_count;
1364 }
1365
1366
1367 /**
1368 * CommTextOut() �� wchar_t ��
1369 *
1370 * @retval �o��������(wchar_t�P��)
1371 */
1372 int WINAPI CommTextOutW(PComVar cv, const wchar_t *B, int C)
1373 {
1374 char TempStr[12];
1375 BOOL Full = FALSE;
1376 int i = 0;
1377 while (! Full && (i < C)) {
1378 // �o���p�f�[�^������
1379 int TempLen = 0;
1380 size_t output_char_count; // ��������������
1381 OutputCharState state;
1382 state.KanjiCode = cv->KanjiCodeSend;
1383 state.ControlOut = OutControl;
1384 state.SendCode = cv->SendCode;
1385 state.JIS7Katakana = cv->JIS7KatakanaSend;
1386 output_char_count = MakeOutputString(cv, &state, &B[i], C-i, TempStr, &TempLen);
1387
1388 // �f�[�^���o���o�b�t�@��
1389 if (WriteOutBuff(cv, TempStr, TempLen)) {
1390 i += output_char_count; // output_char_count ������ ��������
1391 // ��������������������
1392 cv->SendCode = state.SendCode;
1393 } else {
1394 Full = TRUE;
1395 }
1396 } // end of "while {}"
1397 _CrtCheckMemory();
1398 return i;
1399 }
1400
1401 /**
1402 * CommTextEcho() �� wchar_t ��
1403 *
1404 * @retval �o��������(wchar_t�P��)
1405 */
1406 int WINAPI CommTextEchoW(PComVar cv, const wchar_t *B, int C)
1407 {
1408 char TempStr[12];
1409 BOOL Full = FALSE;
1410 int i = 0;
1411 while (! Full && (i < C)) {
1412 // �o���p�f�[�^������
1413 int TempLen = 0;
1414 size_t output_char_count; // ��������������
1415 OutputCharState state;
1416 state.KanjiCode = cv->KanjiCodeEcho;
1417 state.ControlOut = ControlEcho;
1418 state.SendCode = cv->EchoCode;
1419 state.JIS7Katakana = cv->JIS7KatakanaEcho;
1420 output_char_count = MakeOutputString(cv, &state, &B[i], C-i, TempStr, &TempLen);
1421
1422 // �f�[�^���o���o�b�t�@��
1423 if (WriteInBuff(cv, TempStr, TempLen)) {
1424 i += output_char_count; // output_char_count ������ ��������
1425 // ��������������������
1426 cv->EchoCode = state.SendCode;
1427 } else {
1428 Full = TRUE;
1429 }
1430 } // end of "while {}"
1431 _CrtCheckMemory();
1432 return i;
1433 }
1434
1435 int WINAPI CommBinaryEcho(PComVar cv, PCHAR B, int C)
1436 {
1437 int a, i, Len;
1438 char d[3];
1439
1440 if ( ! cv->Ready )
1441 return C;
1442
1443 PackInBuff(cv);
1444
1445 i = 0;
1446 a = 1;
1447 while ((a>0) && (i<C)) {
1448 Len = 0;
1449
1450 d[Len] = B[i];
1451 Len++;
1452
1453 if ( cv->TelFlag && (B[i]=='\x0d') &&
1454 ! cv->TelBinSend ) {
1455 d[Len] = 0x00;
1456 Len++;
1457 }
1458
1459 if ( cv->TelFlag && (B[i]=='\xff') ) {
1460 d[Len] = '\xff';
1461 Len++;
1462 }
1463
1464 if (WriteInBuff(cv, d, Len)) {
1465 a = 1;
1466 i++;
1467 } else {
1468 a = 0;
1469 }
1470 }
1471 return i;
1472 }
1473
1474 /*
1475 * @return �G���[���L������ FALSE
1476 * @param[in] BOOL first_instance
1477 */
1478 static BOOL OpenSharedMemory(BOOL *first_instance_)
1479 {
1480 int i;
1481 HMap = NULL;
1482 pm = NULL;
1483 for (i = 0; i < 100; i++) {
1484 char tmp[32];
1485 HANDLE hMap;
1486 BOOL first_instance;
1487 TMap *map;
1488 _snprintf_s(tmp, sizeof(tmp), _TRUNCATE, i == 0 ? "%s" : "%s_%d", TT_FILEMAPNAME, i);
1489 hMap = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE,
1490 0, sizeof(TMap), tmp);
1491 if (hMap == NULL) {
1492 return FALSE;
1493 }
1494
1495 first_instance = (GetLastError() != ERROR_ALREADY_EXISTS);
1496
1497 map = (TMap *)MapViewOfFile(hMap,FILE_MAP_WRITE,0,0,0);
1498 if (map == NULL) {
1499 return FALSE;
1500 }
1501
1502 if (first_instance ||
1503 (map->size_tmap == sizeof(TMap) &&
1504 map->size_tttset == sizeof(TTTSet)))
1505 {
1506 map->size_tmap = sizeof(TMap);
1507 map->size_tttset = sizeof(TTTSet);
1508 HMap = hMap;
1509 pm = map;
1510 *first_instance_ = first_instance;
1511 return TRUE;
1512 }
1513
1514 // next try
1515 UnmapViewOfFile(map);
1516 CloseHandle(hMap);
1517 }
1518 return FALSE;
1519 }
1520
1521 BOOL WINAPI DllMain(HANDLE hInstance,
1522 ULONG ul_reason_for_call,
1523 LPVOID lpReserved)
1524 {
1525 switch( ul_reason_for_call ) {
1526 case DLL_THREAD_ATTACH:
1527 /* do thread initialization */
1528 break;
1529 case DLL_THREAD_DETACH:
1530 /* do thread cleanup */
1531 break;
1532 case DLL_PROCESS_ATTACH:
1533 /* do process initialization */
1534 #ifdef _DEBUG
1535 _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
1536 #endif
1537 hInst = hInstance;
1538 if (OpenSharedMemory(&FirstInstance) == FALSE) {
1539 // dll���[�h���s�Ateraterm���N��������
1540 return FALSE;
1541 }
1542 WinCompatInit();
1543 break;
1544 case DLL_PROCESS_DETACH:
1545 /* do process cleanup */
1546 UnmapViewOfFile(pm);
1547 CloseHandle(HMap);
1548 break;
1549 }
1550 return TRUE;
1551 }

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