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 9913 - (show annotations) (download) (as text)
Sun May 8 13:25:16 2022 UTC (23 months ago) by zmatsuo
File MIME type: text/x-csrc
File size: 37654 byte(s)
Eterm風 背景画像 が設定できなくなっていたので修正

- theme/以下の設定ファイル(テーマファイル)が保存できない場合があった
- 保存できるよう修正
  - 起動時に設定ファイルがないとき、
    個人設定フォルダへ設定ファイルをコピーするが、
    そのときにthemeフォルダのファイルもコピーするようにした
  - iniファイル保存時に theme フォルダを作成するようにした
- テーマファイルの書き込み時のファイルパスをUnicode化
- ETERM_SECTION を削除
  - BG_SECTION へ置き換え
- 書き換えを行わないデータに const を追加
- far キーワードを削除

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

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