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 9501 - (show annotations) (download) (as text)
Wed Oct 27 12:48:49 2021 UTC (2 years, 5 months ago) by zmatsuo
File MIME type: text/x-csrc
File size: 35576 byte(s)
設定ファイルを置くフォルダを変更

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

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