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 9743 - (show annotations) (download) (as text)
Sat Feb 12 15:38:15 2022 UTC (2 years, 1 month ago) by zmatsuo
File MIME type: text/x-csrc
File size: 37543 byte(s)
フォルダ文字列取得時にフォルダを作成するようにした

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

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