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 9547 - (show annotations) (download) (as text)
Sat Nov 27 13:49:15 2021 UTC (2 years, 4 months ago) by zmatsuo
File MIME type: text/x-csrc
File size: 36959 byte(s)
セッションの複製が動作しなかったので修正

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

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