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 9532 - (show annotations) (download) (as text)
Tue Nov 16 14:16:59 2021 UTC (2 years, 4 months ago) by zmatsuo
File MIME type: text/x-csrc
File size: 36097 byte(s)
起動時初期設定ファイルを %APPDATA%/teraterm5/ にコピー

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

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