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 9568 - (show annotations) (download) (as text)
Sun Dec 5 13:07:54 2021 UTC (2 years, 4 months ago) by zmatsuo
File MIME type: text/x-csrc
File size: 36779 byte(s)
RestartTeraTerm() を Unicode化

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

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