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 9499 - (show annotations) (download) (as text)
Sat Oct 23 16:09:57 2021 UTC (2 years, 5 months ago) by zmatsuo
File MIME type: text/x-csrc
File size: 34843 byte(s)
Languate=Chinese時クラッシュすることがあったので修正

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

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