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 9230 - (show annotations) (download) (as text)
Mon May 3 15:04:42 2021 UTC (2 years, 11 months ago) by zmatsuo
File MIME type: text/x-csrc
File size: 61632 byte(s)
_WIN32_WINNTをコンパイルオプションで指定

- Tera Term は _WIN32_WINNT >= 0x0501 でビルドすることが前提となっている
  - 0x0501=_WIN32_WINNT_WINXP
    - Windows XP
    - Windows Server 2003
  - Visual Studio 2005 のプロジェクトファイルに /D_WIN32_WINNT=0x0501 追加済み(r9191)
- teraterm_conf.h を削除
  - WIN32_WINNT をコンパイルオプションで指定するため r7554 で追加した
  - コマンドラインで明示的に指定するようになったた不要となった
    - SDK 7.0 では _WIN32_WINNT が自動で設定されない
    - SDK 7.0 より新しいSDKでは、特に指定されていない場合、自動で設定される
      - SDKのバージョンによって自動で設定される_WIN32_WINNT の値は異なっている
      - SDK 7.1 の場合 0x0601
      - SDK 10.0.18362.0 の場合 0x0A00
      - sdkddkver.h 内で設定される
        - MinGWの場合は _mingw.h
- Visual Studio 2005 では次のSDKでビルドできることを確認済み
  - SDK 7.0
  - SDK 7.1
- Tera Term は Visual Studio 2005 以上をサポート
  - MSC_VER >= 1400
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 <tchar.h>
36 #include <setupapi.h>
37 #include <locale.h>
38 #include <htmlhelp.h>
39 #include <assert.h>
40 #include <crtdbg.h>
41
42 #define DllExport __declspec(dllexport)
43 #include "language.h"
44 #undef DllExport
45
46 #include "teraterm.h"
47 #include "tttypes.h"
48 #include "ttlib.h"
49 #include "tt_res.h"
50 #include "codeconv.h"
51 #include "compat_win.h"
52
53 #define DllExport __declspec(dllexport)
54 #include "ttcommon.h"
55 #include "layer_for_unicode.h"
56
57 /* shared memory */
58 typedef struct {
59 size_t size_tmap; /* sizeof TMap */
60 size_t size_tttset; /* sizeof TTTSet */
61 /* Setup information from "teraterm.ini" */
62 TTTSet ts;
63 /* Key code map from "keyboard.def" */
64 TKeyMap km;
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 } 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 _T("VTWin32")
95 #define TEKCLASSNAME _T("TEKWin32")
96
97 enum window_style {
98 WIN_CASCADE,
99 WIN_STACKED,
100 WIN_SIDEBYSIDE,
101 };
102
103
104 void WINAPI CopyShmemToTTSet(PTTSet ts)
105 {
106 // ���������������L�����������R�s�[����
107 memcpy(ts, &pm->ts, sizeof(TTTSet));
108 }
109
110 void WINAPI CopyTTSetToShmem(PTTSet ts)
111 {
112 // ���������������L���������R�s�[����
113 memcpy(&pm->ts, ts, sizeof(TTTSet));
114 }
115
116
117 BOOL WINAPI StartTeraTerm(PTTSet ts)
118 {
119 if (FirstInstance) {
120 // init window list
121 pm->NWin = 0;
122 }
123 else {
124 /* only the first instance uses saved position */
125 pm->ts.VTPos.x = CW_USEDEFAULT;
126 pm->ts.VTPos.y = CW_USEDEFAULT;
127 pm->ts.TEKPos.x = CW_USEDEFAULT;
128 pm->ts.TEKPos.y = CW_USEDEFAULT;
129 }
130
131 memcpy(ts,&(pm->ts),sizeof(TTTSet));
132
133 // if (FirstInstance) { �������������� (2008.3.13 maya)
134 // �N���������A���L�������� HomeDir �� SetupFName ����������
135 /* Get home directory */
136 GetHomeDir(hInst, ts->HomeDir, sizeof(ts->HomeDir));
137 _chdir(ts->HomeDir);
138 GetDefaultSetupFName(ts->HomeDir, ts->SetupFName, sizeof(ts->SetupFName));
139
140 strncpy_s(ts->KeyCnfFN, sizeof(ts->KeyCnfFN), ts->HomeDir, _TRUNCATE);
141 AppendSlash(ts->KeyCnfFN, sizeof(ts->KeyCnfFN));
142 strncat_s(ts->KeyCnfFN, sizeof(ts->KeyCnfFN), "KEYBOARD.CNF", _TRUNCATE);
143
144 if (FirstInstance) {
145 FirstInstance = FALSE;
146 return TRUE;
147 }
148 else {
149 return FALSE;
150 }
151 }
152
153 // �����t�@�C�����f�B�X�N���������ATera Term�{�������N�������B
154 // (2012.4.30 yutaka)
155 void WINAPI RestartTeraTerm(HWND hwnd, PTTSet ts)
156 {
157 char path[1024];
158 STARTUPINFO si;
159 PROCESS_INFORMATION pi;
160 int ret;
161
162 static const TTMessageBoxInfoW info = {
163 "Tera Term",
164 NULL, L"Tera Term: Configuration Warning",
165 "MSG_TT_TAKE_EFFECT",
166 L"This option takes effect the next time a session is started.\n"
167 L"Are you sure that you want to relaunch Tera Term?"
168 };
169 ret = TTMessageBoxW(hwnd, &info, MB_YESNO | MB_ICONEXCLAMATION | MB_DEFBUTTON2, ts->UILanguageFile);
170 if (ret != IDYES)
171 return;
172
173 SendMessage(hwnd, WM_COMMAND, ID_SETUP_SAVE, 0);
174 // ID_FILE_EXIT ���b�Z�[�W�����A�v�������������������������AWM_QUIT ���|�X�g�����B
175 //PostMessage(hwnd, WM_COMMAND, ID_FILE_EXIT, 0);
176 PostQuitMessage(0);
177
178 // ���v���Z�X�����N���B
179 if (GetModuleFileName(NULL, path, sizeof(path)) == 0) {
180 return;
181 }
182 memset(&si, 0, sizeof(si));
183 GetStartupInfo(&si);
184 memset(&pi, 0, sizeof(pi));
185 if (CreateProcess(NULL, path, NULL, NULL, FALSE, 0,
186 NULL, NULL, &si, &pi) == 0) {
187 }
188 }
189
190 void WINAPI ChangeDefaultSet(PTTSet ts, PKeyMap km)
191 {
192 if ((ts!=NULL) &&
193 (_stricmp(ts->SetupFName, pm->ts.SetupFName) == 0)) {
194 memcpy(&(pm->ts),ts,sizeof(TTTSet));
195 }
196 if (km!=NULL) {
197 memcpy(&(pm->km),km,sizeof(TKeyMap));
198 }
199 }
200
201 void WINAPI GetDefaultSet(PTTSet ts)
202 {
203 memcpy(ts,&(pm->ts),sizeof(TTTSet));
204 }
205
206
207 /* Key scan code -> Tera Term key code */
208 WORD WINAPI GetKeyCode(PKeyMap KeyMap, WORD Scan)
209 {
210 WORD Key;
211
212 if (KeyMap==NULL) {
213 KeyMap = &(pm->km);
214 }
215 Key = IdKeyMax;
216 while ((Key>0) && (KeyMap->Map[Key-1] != Scan)) {
217 Key--;
218 }
219 return Key;
220 }
221
222 void WINAPI GetKeyStr(HWND HWin, PKeyMap KeyMap, WORD KeyCode,
223 BOOL AppliKeyMode, BOOL AppliCursorMode,
224 BOOL Send8BitMode, PCHAR KeyStr, int destlen,
225 LPINT Len, LPWORD Type)
226 {
227 MSG Msg;
228 char Temp[201];
229
230 if (KeyMap==NULL) {
231 KeyMap = &(pm->km);
232 }
233
234 *Type = IdBinary; // key type
235 *Len = 0;
236 switch (KeyCode) {
237 case IdUp:
238 if (Send8BitMode) {
239 *Len = 2;
240 if (AppliCursorMode)
241 strncpy_s(KeyStr,destlen,"\217A",_TRUNCATE);
242 else
243 strncpy_s(KeyStr,destlen,"\233A",_TRUNCATE);
244 } else {
245 *Len = 3;
246 if (AppliCursorMode)
247 strncpy_s(KeyStr,destlen,"\033OA",_TRUNCATE);
248 else
249 strncpy_s(KeyStr,destlen,"\033[A",_TRUNCATE);
250 }
251 break;
252 case IdDown:
253 if (Send8BitMode) {
254 *Len = 2;
255 if (AppliCursorMode)
256 strncpy_s(KeyStr,destlen,"\217B",_TRUNCATE);
257 else
258 strncpy_s(KeyStr,destlen,"\233B",_TRUNCATE);
259 } else {
260 *Len = 3;
261 if (AppliCursorMode)
262 strncpy_s(KeyStr,destlen,"\033OB",_TRUNCATE);
263 else
264 strncpy_s(KeyStr,destlen,"\033[B",_TRUNCATE);
265 }
266 break;
267 case IdRight:
268 if (Send8BitMode) {
269 *Len = 2;
270 if (AppliCursorMode)
271 strncpy_s(KeyStr,destlen,"\217C",_TRUNCATE);
272 else
273 strncpy_s(KeyStr,destlen,"\233C",_TRUNCATE);
274 } else {
275 *Len = 3;
276 if (AppliCursorMode)
277 strncpy_s(KeyStr,destlen,"\033OC",_TRUNCATE);
278 else
279 strncpy_s(KeyStr,destlen,"\033[C",_TRUNCATE);
280 }
281 break;
282 case IdLeft:
283 if (Send8BitMode) {
284 *Len = 2;
285 if (AppliCursorMode)
286 strncpy_s(KeyStr,destlen,"\217D",_TRUNCATE);
287 else
288 strncpy_s(KeyStr,destlen,"\233D",_TRUNCATE);
289 } else {
290 *Len = 3;
291 if (AppliCursorMode)
292 strncpy_s(KeyStr,destlen,"\033OD",_TRUNCATE);
293 else
294 strncpy_s(KeyStr,destlen,"\033[D",_TRUNCATE);
295 }
296 break;
297 case Id0:
298 if (AppliKeyMode) {
299 if (Send8BitMode) {
300 *Len = 2;
301 strncpy_s(KeyStr,destlen,"\217p",_TRUNCATE);
302 } else {
303 *Len = 3;
304 strncpy_s(KeyStr,destlen,"\033Op",_TRUNCATE);
305 }
306 }
307 else {
308 *Len = 1;
309 KeyStr[0] = '0';
310 }
311 break;
312 case Id1:
313 if (AppliKeyMode) {
314 if (Send8BitMode) {
315 *Len = 2;
316 strncpy_s(KeyStr,destlen,"\217q",_TRUNCATE);
317 } else {
318 *Len = 3;
319 strncpy_s(KeyStr,destlen,"\033Oq",_TRUNCATE);
320 }
321 }
322 else {
323 *Len = 1;
324 KeyStr[0] = '1';
325 }
326 break;
327 case Id2:
328 if (AppliKeyMode) {
329 if (Send8BitMode) {
330 *Len = 2;
331 strncpy_s(KeyStr,destlen,"\217r",_TRUNCATE);
332 } else {
333 *Len = 3;
334 strncpy_s(KeyStr,destlen,"\033Or",_TRUNCATE);
335 }
336 }
337 else {
338 *Len = 1;
339 KeyStr[0] = '2';
340 }
341 break;
342 case Id3:
343 if (AppliKeyMode) {
344 if (Send8BitMode) {
345 *Len = 2;
346 strncpy_s(KeyStr,destlen,"\217s",_TRUNCATE);
347 } else {
348 *Len = 3;
349 strncpy_s(KeyStr,destlen,"\033Os",_TRUNCATE);
350 }
351 }
352 else {
353 *Len = 1;
354 KeyStr[0] = '3';
355 }
356 break;
357 case Id4:
358 if (AppliKeyMode) {
359 if (Send8BitMode) {
360 *Len = 2;
361 strncpy_s(KeyStr,destlen,"\217t",_TRUNCATE);
362 } else {
363 *Len = 3;
364 strncpy_s(KeyStr,destlen,"\033Ot",_TRUNCATE);
365 }
366 }
367 else {
368 *Len = 1;
369 KeyStr[0] = '4';
370 }
371 break;
372 case Id5:
373 if (AppliKeyMode) {
374 if (Send8BitMode) {
375 *Len = 2;
376 strncpy_s(KeyStr,destlen,"\217u",_TRUNCATE);
377 } else {
378 *Len = 3;
379 strncpy_s(KeyStr,destlen,"\033Ou",_TRUNCATE);
380 }
381 }
382 else {
383 *Len = 1;
384 KeyStr[0] = '5';
385 }
386 break;
387 case Id6:
388 if (AppliKeyMode) {
389 if (Send8BitMode) {
390 *Len = 2;
391 strncpy_s(KeyStr,destlen,"\217v",_TRUNCATE);
392 } else {
393 *Len = 3;
394 strncpy_s(KeyStr,destlen,"\033Ov",_TRUNCATE);
395 }
396 }
397 else {
398 *Len = 1;
399 KeyStr[0] = '6';
400 }
401 break;
402 case Id7:
403 if (AppliKeyMode) {
404 if (Send8BitMode) {
405 *Len = 2;
406 strncpy_s(KeyStr,destlen,"\217w",_TRUNCATE);
407 } else {
408 *Len = 3;
409 strncpy_s(KeyStr,destlen,"\033Ow",_TRUNCATE);
410 }
411 }
412 else {
413 *Len = 1;
414 KeyStr[0] = '7';
415 }
416 break;
417 case Id8:
418 if (AppliKeyMode) {
419 if (Send8BitMode) {
420 *Len = 2;
421 strncpy_s(KeyStr,destlen,"\217x",_TRUNCATE);
422 } else {
423 *Len = 3;
424 strncpy_s(KeyStr,destlen,"\033Ox",_TRUNCATE);
425 }
426 }
427 else {
428 *Len = 1;
429 KeyStr[0] = '8';
430 }
431 break;
432 case Id9:
433 if (AppliKeyMode) {
434 if (Send8BitMode) {
435 *Len = 2;
436 strncpy_s(KeyStr,destlen,"\217y",_TRUNCATE);
437 } else {
438 *Len = 3;
439 strncpy_s(KeyStr,destlen,"\033Oy",_TRUNCATE);
440 }
441 }
442 else {
443 *Len = 1;
444 KeyStr[0] = '9';
445 }
446 break;
447 case IdMinus: /* numeric pad - key (DEC) */
448 if (AppliKeyMode) {
449 if (Send8BitMode) {
450 *Len = 2;
451 strncpy_s(KeyStr,destlen,"\217m",_TRUNCATE);
452 } else {
453 *Len = 3;
454 strncpy_s(KeyStr,destlen,"\033Om",_TRUNCATE);
455 }
456 }
457 else {
458 *Len = 1;
459 KeyStr[0] = '-';
460 }
461 break;
462 case IdComma: /* numeric pad , key (DEC) */
463 if (AppliKeyMode) {
464 if (Send8BitMode) {
465 *Len = 2;
466 strncpy_s(KeyStr,destlen,"\217l",_TRUNCATE);
467 } else {
468 *Len = 3;
469 strncpy_s(KeyStr,destlen,"\033Ol",_TRUNCATE);
470 }
471 }
472 else {
473 *Len = 1;
474 KeyStr[0] = ',';
475 }
476 break;
477 case IdPeriod: /* numeric pad . key */
478 if (AppliKeyMode) {
479 if (Send8BitMode) {
480 *Len = 2;
481 strncpy_s(KeyStr,destlen,"\217n",_TRUNCATE);
482 } else {
483 *Len = 3;
484 strncpy_s(KeyStr,destlen,"\033On",_TRUNCATE);
485 }
486 }
487 else {
488 *Len = 1;
489 KeyStr[0] = '.';
490 }
491 break;
492 case IdEnter: /* numeric pad enter key */
493 if (AppliKeyMode) {
494 if (Send8BitMode) {
495 *Len = 2;
496 strncpy_s(KeyStr,destlen,"\217M",_TRUNCATE);
497 } else {
498 *Len = 3;
499 strncpy_s(KeyStr,destlen,"\033OM",_TRUNCATE);
500 }
501 }
502 else {
503 *Type = IdText; // do new-line conversion
504 *Len = 1;
505 KeyStr[0] = 0x0D;
506 }
507 break;
508 case IdSlash: /* numeric pad slash key */
509 if (AppliKeyMode) {
510 if (Send8BitMode) {
511 *Len = 2;
512 strncpy_s(KeyStr,destlen,"\217o",_TRUNCATE);
513 } else {
514 *Len = 3;
515 strncpy_s(KeyStr,destlen,"\033Oo",_TRUNCATE);
516 }
517 }
518 else {
519 *Len = 1;
520 KeyStr[0] = '/';
521 }
522 break;
523 case IdAsterisk: /* numeric pad asterisk key */
524 if (AppliKeyMode) {
525 if (Send8BitMode) {
526 *Len = 2;
527 strncpy_s(KeyStr,destlen,"\217j",_TRUNCATE);
528 } else {
529 *Len = 3;
530 strncpy_s(KeyStr,destlen,"\033Oj",_TRUNCATE);
531 }
532 }
533 else {
534 *Len = 1;
535 KeyStr[0] = '*';
536 }
537 break;
538 case IdPlus: /* numeric pad plus key */
539 if (AppliKeyMode) {
540 if (Send8BitMode) {
541 *Len = 2;
542 strncpy_s(KeyStr,destlen,"\217k",_TRUNCATE);
543 } else {
544 *Len = 3;
545 strncpy_s(KeyStr,destlen,"\033Ok",_TRUNCATE);
546 }
547 }
548 else {
549 *Len = 1;
550 KeyStr[0] = '+';
551 }
552 break;
553 case IdPF1: /* DEC Key: PF1 */
554 if (Send8BitMode) {
555 *Len = 2;
556 strncpy_s(KeyStr,destlen,"\217P",_TRUNCATE);
557 } else {
558 *Len = 3;
559 strncpy_s(KeyStr,destlen,"\033OP",_TRUNCATE);
560 }
561 break;
562 case IdPF2: /* DEC Key: PF2 */
563 if (Send8BitMode) {
564 *Len = 2;
565 strncpy_s(KeyStr,destlen,"\217Q",_TRUNCATE);
566 } else {
567 *Len = 3;
568 strncpy_s(KeyStr,destlen,"\033OQ",_TRUNCATE);
569 }
570 break;
571 case IdPF3: /* DEC Key: PF3 */
572 if (Send8BitMode) {
573 *Len = 2;
574 strncpy_s(KeyStr,destlen,"\217R",_TRUNCATE);
575 } else {
576 *Len = 3;
577 strncpy_s(KeyStr,destlen,"\033OR",_TRUNCATE);
578 }
579 break;
580 case IdPF4: /* DEC Key: PF4 */
581 if (Send8BitMode) {
582 *Len = 2;
583 strncpy_s(KeyStr,destlen,"\217S",_TRUNCATE);
584 } else {
585 *Len = 3;
586 strncpy_s(KeyStr,destlen,"\033OS",_TRUNCATE);
587 }
588 break;
589 case IdFind: /* DEC Key: Find */
590 if (Send8BitMode) {
591 *Len = 3;
592 strncpy_s(KeyStr,destlen,"\2331~",_TRUNCATE);
593 } else {
594 *Len = 4;
595 strncpy_s(KeyStr,destlen,"\033[1~",_TRUNCATE);
596 }
597 break;
598 case IdInsert: /* DEC Key: Insert Here */
599 if (Send8BitMode) {
600 *Len = 3;
601 strncpy_s(KeyStr,destlen,"\2332~",_TRUNCATE);
602 } else {
603 *Len = 4;
604 strncpy_s(KeyStr,destlen,"\033[2~",_TRUNCATE);
605 }
606 break;
607 case IdRemove: /* DEC Key: Remove */
608 if (Send8BitMode) {
609 *Len = 3;
610 strncpy_s(KeyStr,destlen,"\2333~",_TRUNCATE);
611 } else {
612 *Len = 4;
613 strncpy_s(KeyStr,destlen,"\033[3~",_TRUNCATE);
614 }
615 break;
616 case IdSelect: /* DEC Key: Select */
617 if (Send8BitMode) {
618 *Len = 3;
619 strncpy_s(KeyStr,destlen,"\2334~",_TRUNCATE);
620 } else {
621 *Len = 4;
622 strncpy_s(KeyStr,destlen,"\033[4~",_TRUNCATE);
623 }
624 break;
625 case IdPrev: /* DEC Key: Prev */
626 if (Send8BitMode) {
627 *Len = 3;
628 strncpy_s(KeyStr,destlen,"\2335~",_TRUNCATE);
629 } else {
630 *Len = 4;
631 strncpy_s(KeyStr,destlen,"\033[5~",_TRUNCATE);
632 }
633 break;
634 case IdNext: /* DEC Key: Next */
635 if (Send8BitMode) {
636 *Len = 3;
637 strncpy_s(KeyStr,destlen,"\2336~",_TRUNCATE);
638 } else {
639 *Len = 4;
640 strncpy_s(KeyStr,destlen,"\033[6~",_TRUNCATE);
641 }
642 break;
643 case IdF6: /* DEC Key: F6 */
644 if (Send8BitMode) {
645 *Len = 4;
646 strncpy_s(KeyStr,destlen,"\23317~",_TRUNCATE);
647 } else {
648 *Len = 5;
649 strncpy_s(KeyStr,destlen,"\033[17~",_TRUNCATE);
650 }
651 break;
652 case IdF7: /* DEC Key: F7 */
653 if (Send8BitMode) {
654 *Len = 4;
655 strncpy_s(KeyStr,destlen,"\23318~",_TRUNCATE);
656 } else {
657 *Len = 5;
658 strncpy_s(KeyStr,destlen,"\033[18~",_TRUNCATE);
659 }
660 break;
661 case IdF8: /* DEC Key: F8 */
662 if (Send8BitMode) {
663 *Len = 4;
664 strncpy_s(KeyStr,destlen,"\23319~",_TRUNCATE);
665 } else {
666 *Len = 5;
667 strncpy_s(KeyStr,destlen,"\033[19~",_TRUNCATE);
668 }
669 break;
670 case IdF9: /* DEC Key: F9 */
671 if (Send8BitMode) {
672 *Len = 4;
673 strncpy_s(KeyStr,destlen,"\23320~",_TRUNCATE);
674 } else {
675 *Len = 5;
676 strncpy_s(KeyStr,destlen,"\033[20~",_TRUNCATE);
677 }
678 break;
679 case IdF10: /* DEC Key: F10 */
680 if (Send8BitMode) {
681 *Len = 4;
682 strncpy_s(KeyStr,destlen,"\23321~",_TRUNCATE);
683 } else {
684 *Len = 5;
685 strncpy_s(KeyStr,destlen,"\033[21~",_TRUNCATE);
686 }
687 break;
688 case IdF11: /* DEC Key: F11 */
689 if (Send8BitMode) {
690 *Len = 4;
691 strncpy_s(KeyStr,destlen,"\23323~",_TRUNCATE);
692 } else {
693 *Len = 5;
694 strncpy_s(KeyStr,destlen,"\033[23~",_TRUNCATE);
695 }
696 break;
697 case IdF12: /* DEC Key: F12 */
698 if (Send8BitMode) {
699 *Len = 4;
700 strncpy_s(KeyStr,destlen,"\23324~",_TRUNCATE);
701 } else {
702 *Len = 5;
703 strncpy_s(KeyStr,destlen,"\033[24~",_TRUNCATE);
704 }
705 break;
706 case IdF13: /* DEC Key: F13 */
707 if (Send8BitMode) {
708 *Len = 4;
709 strncpy_s(KeyStr,destlen,"\23325~",_TRUNCATE);
710 } else {
711 *Len = 5;
712 strncpy_s(KeyStr,destlen,"\033[25~",_TRUNCATE);
713 }
714 break;
715 case IdF14: /* DEC Key: F14 */
716 if (Send8BitMode) {
717 *Len = 4;
718 strncpy_s(KeyStr,destlen,"\23326~",_TRUNCATE);
719 } else {
720 *Len = 5;
721 strncpy_s(KeyStr,destlen,"\033[26~",_TRUNCATE);
722 }
723 break;
724 case IdHelp: /* DEC Key: Help */
725 if (Send8BitMode) {
726 *Len = 4;
727 strncpy_s(KeyStr,destlen,"\23328~",_TRUNCATE);
728 } else {
729 *Len = 5;
730 strncpy_s(KeyStr,destlen,"\033[28~",_TRUNCATE);
731 }
732 break;
733 case IdDo: /* DEC Key: Do */
734 if (Send8BitMode) {
735 *Len = 4;
736 strncpy_s(KeyStr,destlen,"\23329~",_TRUNCATE);
737 } else {
738 *Len = 5;
739 strncpy_s(KeyStr,destlen,"\033[29~",_TRUNCATE);
740 }
741 break;
742 case IdF17: /* DEC Key: F17 */
743 if (Send8BitMode) {
744 *Len = 4;
745 strncpy_s(KeyStr,destlen,"\23331~",_TRUNCATE);
746 } else {
747 *Len = 5;
748 strncpy_s(KeyStr,destlen,"\033[31~",_TRUNCATE);
749 }
750 break;
751 case IdF18: /* DEC Key: F18 */
752 if (Send8BitMode) {
753 *Len = 4;
754 strncpy_s(KeyStr,destlen,"\23332~",_TRUNCATE);
755 } else {
756 *Len = 5;
757 strncpy_s(KeyStr,destlen,"\033[32~",_TRUNCATE);
758 }
759 break;
760 case IdF19: /* DEC Key: F19 */
761 if (Send8BitMode) {
762 *Len = 4;
763 strncpy_s(KeyStr,destlen,"\23333~",_TRUNCATE);
764 } else {
765 *Len = 5;
766 strncpy_s(KeyStr,destlen,"\033[33~",_TRUNCATE);
767 }
768 break;
769 case IdF20: /* DEC Key: F20 */
770 if (Send8BitMode) {
771 *Len = 4;
772 strncpy_s(KeyStr,destlen,"\23334~",_TRUNCATE);
773 } else {
774 *Len = 5;
775 strncpy_s(KeyStr,destlen,"\033[34~",_TRUNCATE);
776 }
777 break;
778 case IdXF1: /* XTERM F1 */
779 if (Send8BitMode) {
780 *Len = 4;
781 strncpy_s(KeyStr,destlen,"\23311~",_TRUNCATE);
782 } else {
783 *Len = 5;
784 strncpy_s(KeyStr,destlen,"\033[11~",_TRUNCATE);
785 }
786 break;
787 case IdXF2: /* XTERM F2 */
788 if (Send8BitMode) {
789 *Len = 4;
790 strncpy_s(KeyStr,destlen,"\23312~",_TRUNCATE);
791 } else {
792 *Len = 5;
793 strncpy_s(KeyStr,destlen,"\033[12~",_TRUNCATE);
794 }
795 break;
796 case IdXF3: /* XTERM F3 */
797 if (Send8BitMode) {
798 *Len = 4;
799 strncpy_s(KeyStr,destlen,"\23313~",_TRUNCATE);
800 } else {
801 *Len = 5;
802 strncpy_s(KeyStr,destlen,"\033[13~",_TRUNCATE);
803 }
804 break;
805 case IdXF4: /* XTERM F4 */
806 if (Send8BitMode) {
807 *Len = 4;
808 strncpy_s(KeyStr,destlen,"\23314~",_TRUNCATE);
809 } else {
810 *Len = 5;
811 strncpy_s(KeyStr,destlen,"\033[14~",_TRUNCATE);
812 }
813 break;
814 case IdXF5: /* XTERM F5 */
815 if (Send8BitMode) {
816 *Len = 4;
817 strncpy_s(KeyStr,destlen,"\23315~",_TRUNCATE);
818 } else {
819 *Len = 5;
820 strncpy_s(KeyStr,destlen,"\033[15~",_TRUNCATE);
821 }
822 break;
823 case IdXBackTab: /* XTERM Back Tab */
824 if (Send8BitMode) {
825 *Len = 2;
826 strncpy_s(KeyStr,destlen,"\233Z",_TRUNCATE);
827 } else {
828 *Len = 3;
829 strncpy_s(KeyStr,destlen,"\033[Z",_TRUNCATE);
830 }
831 break;
832 case IdHold:
833 case IdPrint:
834 case IdBreak:
835 case IdCmdEditCopy:
836 case IdCmdEditPaste:
837 case IdCmdEditPasteCR:
838 case IdCmdEditCLS:
839 case IdCmdEditCLB:
840 case IdCmdCtrlOpenTEK:
841 case IdCmdCtrlCloseTEK:
842 case IdCmdLineUp:
843 case IdCmdLineDown:
844 case IdCmdPageUp:
845 case IdCmdPageDown:
846 case IdCmdBuffTop:
847 case IdCmdBuffBottom:
848 case IdCmdNextWin:
849 case IdCmdPrevWin:
850 case IdCmdNextSWin:
851 case IdCmdPrevSWin:
852 case IdCmdLocalEcho:
853 case IdCmdScrollLock:
854 PostMessage(HWin,WM_USER_ACCELCOMMAND,KeyCode,0);
855 break;
856 default:
857 if ((KeyCode >= IdUser1) && (KeyCode <= IdKeyMax)) {
858 *Type = (WORD)(*KeyMap).UserKeyType[KeyCode-IdUser1]; // key type
859 *Len = KeyMap->UserKeyLen[KeyCode-IdUser1];
860 memcpy(Temp,
861 &KeyMap->UserKeyStr[KeyMap->UserKeyPtr[KeyCode-IdUser1]],
862 *Len);
863 Temp[*Len] = 0;
864 if ((*Type==IdBinary) || (*Type==IdText))
865 *Len = Hex2Str(Temp,KeyStr,destlen);
866 else
867 strncpy_s(KeyStr,destlen,Temp,_TRUNCATE);
868 }
869 else
870 return;
871 }
872 /* remove WM_CHAR message for used keycode */
873 PeekMessage(&Msg,HWin, WM_CHAR, WM_CHAR,PM_REMOVE);
874 }
875
876 void WINAPI SetCOMFlag(int Com)
877 {
878 pm->ComFlag[(Com-1)/CHAR_BIT] |= 1 << ((Com-1)%CHAR_BIT);
879 }
880
881 void WINAPI ClearCOMFlag(int Com)
882 {
883 pm->ComFlag[(Com-1)/CHAR_BIT] &= ~(1 << ((Com-1)%CHAR_BIT));
884 }
885
886 int WINAPI CheckCOMFlag(int Com)
887 {
888 return ((pm->ComFlag[(Com-1)/CHAR_BIT] & 1 << (Com-1)%CHAR_BIT) > 0);
889 }
890
891 int WINAPI RegWin(HWND HWinVT, HWND HWinTEK)
892 {
893 int i, j;
894
895 if (pm->NWin>=MAXNWIN)
896 return 0;
897 if (HWinVT==NULL)
898 return 0;
899 if (HWinTEK!=NULL) {
900 i = 0;
901 while ((i<pm->NWin) && (pm->WinList[i]!=HWinVT))
902 i++;
903 if (i>=pm->NWin)
904 return 0;
905 for (j=pm->NWin-1 ; j>i ; j--)
906 pm->WinList[j+1] = pm->WinList[j];
907 pm->WinList[i+1] = HWinTEK;
908 pm->NWin++;
909 return 0;
910 }
911 pm->WinList[pm->NWin++] = HWinVT;
912 memset(&pm->WinPrevRect[pm->NWin - 1], 0, sizeof(pm->WinPrevRect[pm->NWin - 1])); // RECT clear
913 if (pm->NWin==1) {
914 return 1;
915 }
916 else {
917 return (int)(SendMessage(pm->WinList[pm->NWin-2],
918 WM_USER_GETSERIALNO,0,0)+1);
919 }
920 }
921
922 void WINAPI UnregWin(HWND HWin)
923 {
924 int i, j;
925
926 i = 0;
927 while ((i<pm->NWin) && (pm->WinList[i]!=HWin)) {
928 i++;
929 }
930 if (pm->WinList[i]!=HWin) {
931 return;
932 }
933 for (j=i ; j<pm->NWin-1 ; j++) {
934 pm->WinList[j] = pm->WinList[j+1];
935 pm->WinPrevRect[j] = pm->WinPrevRect[j+1]; // RECT shift
936 }
937 if (pm->NWin>0) {
938 pm->NWin--;
939 }
940 }
941
942 char GetWindowTypeChar(HWND Hw, HWND HWin)
943 {
944 #if 0
945 if (HWin == Hw)
946 return '*';
947 else if (!IsWindowVisible(Hw))
948 #else
949 if (!IsWindowVisible(Hw))
950 #endif
951 return '#';
952 else if (IsIconic(Hw))
953 return '-';
954 else if (IsZoomed(Hw))
955 return '@';
956 else
957 return '+';
958 }
959
960 void WINAPI SetWinMenu(HMENU menu, PCHAR buf, int buflen, PCHAR langFile, int VTFlag)
961 {
962 int i;
963 char Temp[MAXPATHLEN];
964 HWND Hw;
965 wchar_t uimsg[MAX_UIMSG];
966
967 // delete all items in Window menu
968 i = GetMenuItemCount(menu);
969 if (i>0)
970 do {
971 i--;
972 RemoveMenu(menu,i,MF_BYPOSITION);
973 } while (i>0);
974
975 i = 0;
976 while (i<pm->NWin) {
977 Hw = pm->WinList[i]; // get window handle
978 if ((GetClassName(Hw,Temp,sizeof(Temp))>0) &&
979 ((strcmp(Temp,VTCLASSNAME)==0) ||
980 (strcmp(Temp,TEKCLASSNAME)==0))) {
981 Temp[0] = '&';
982 Temp[1] = (char)(0x31 + i);
983 Temp[2] = ' ';
984 Temp[3] = GetWindowTypeChar(Hw, NULL);
985 Temp[4] = ' ';
986 GetWindowText(Hw,&Temp[5],sizeof(Temp)-6);
987 AppendMenu(menu,MF_ENABLED | MF_STRING,ID_WINDOW_1+i,Temp);
988 i++;
989 if (i>8) {
990 i = pm->NWin;
991 }
992 }
993 else {
994 UnregWin(Hw);
995 }
996 }
997 if (VTFlag == 1) {
998 static const DlgTextInfo MenuTextInfo[] = {
999 { ID_WINDOW_WINDOW, "MENU_WINDOW_WINDOW" },
1000 { ID_WINDOW_MINIMIZEALL, "MENU_WINDOW_MINIMIZEALL" },
1001 { ID_WINDOW_RESTOREALL, "MENU_WINDOW_RESTOREALL" },
1002 { ID_WINDOW_CASCADEALL, "MENU_WINDOW_CASCADE" },
1003 { ID_WINDOW_STACKED, "MENU_WINDOW_STACKED" },
1004 { ID_WINDOW_SIDEBYSIDE, "MENU_WINDOW_SIDEBYSIDE" },
1005 };
1006
1007 AppendMenu(menu, MF_SEPARATOR, 0, NULL);
1008 AppendMenu(menu, MF_ENABLED | MF_STRING, ID_WINDOW_WINDOW, "&Window");
1009 AppendMenu(menu, MF_ENABLED | MF_STRING, ID_WINDOW_MINIMIZEALL, "&Minimize All");
1010 AppendMenu(menu, MF_ENABLED | MF_STRING, ID_WINDOW_RESTOREALL, "&Restore All");
1011 AppendMenu(menu, MF_ENABLED | MF_STRING, ID_WINDOW_CASCADEALL, "&Cascade");
1012 AppendMenu(menu, MF_ENABLED | MF_STRING, ID_WINDOW_STACKED, "&Stacked");
1013 AppendMenu(menu, MF_ENABLED | MF_STRING, ID_WINDOW_SIDEBYSIDE, "Side &by Side");
1014
1015 SetI18nMenuStrs("Tera Term", menu, MenuTextInfo, _countof(MenuTextInfo), langFile);
1016
1017 if (pm->WinUndoFlag) {
1018 if (pm->WinUndoStyle == WIN_CASCADE)
1019 get_lang_msgW("MENU_WINDOW_CASCADE_UNDO", uimsg, _countof(uimsg), L"&Undo - Cascade", langFile);
1020 else if (pm->WinUndoStyle == WIN_STACKED)
1021 get_lang_msgW("MENU_WINDOW_STACKED_UNDO", uimsg, _countof(uimsg), L"&Undo - Stacked", langFile);
1022 else
1023 get_lang_msgW("MENU_WINDOW_SIDEBYSIDE_UNDO", uimsg, _countof(uimsg), L"&Undo - Side by Side", langFile);
1024 _AppendMenuW(menu, MF_ENABLED | MF_STRING, ID_WINDOW_UNDO, uimsg); // TODO UNICODE
1025 }
1026
1027 }
1028 else {
1029 get_lang_msgW("MENU_WINDOW_WINDOW", uimsg, _countof(uimsg), L"&Window", langFile);
1030 _AppendMenuW(menu,MF_ENABLED | MF_STRING,ID_TEKWINDOW_WINDOW, uimsg);
1031 }
1032 }
1033
1034 void WINAPI SetWinList(HWND HWin, HWND HDlg, int IList)
1035 {
1036 int i;
1037 char Temp[MAXPATHLEN];
1038 HWND Hw;
1039
1040 for (i=0; i<pm->NWin; i++) {
1041 Hw = pm->WinList[i]; // get window handle
1042 if ((GetClassName(Hw,Temp,sizeof(Temp))>0) &&
1043 ((strcmp(Temp,VTCLASSNAME)==0) ||
1044 (strcmp(Temp,TEKCLASSNAME)==0))) {
1045 Temp[0] = GetWindowTypeChar(Hw, HWin);
1046 Temp[1] = ' ';
1047 GetWindowText(Hw,&Temp[2],sizeof(Temp)-3);
1048 SendDlgItemMessage(HDlg, IList, LB_ADDSTRING,
1049 0, (LPARAM)Temp);
1050 if (Hw==HWin) {
1051 SendDlgItemMessage(HDlg, IList, LB_SETCURSEL, i,0);
1052 }
1053 }
1054 else {
1055 UnregWin(Hw);
1056 }
1057 }
1058 }
1059
1060 void WINAPI SelectWin(int WinId)
1061 {
1062 if ((WinId>=0) && (WinId<pm->NWin)) {
1063 /* �E�B���h�E�����������������������������������A���������������������������A
1064 * SW_SHOWNORMAL ���� SW_SHOW �����X�����B
1065 * (2009.11.8 yutaka)
1066 * �E�B���h�E�����������������������������T�C�Y������(SW_RESTORE)�����������B
1067 * (2009.11.9 maya)
1068 */
1069 if (IsIconic(pm->WinList[WinId])) {
1070 ShowWindow(pm->WinList[WinId],SW_RESTORE);
1071 }
1072 else {
1073 ShowWindow(pm->WinList[WinId],SW_SHOW);
1074 }
1075 SetForegroundWindow(pm->WinList[WinId]);
1076 }
1077 }
1078
1079 void WINAPI SelectNextWin(HWND HWin, int Next, BOOL SkipIconic)
1080 {
1081 int i;
1082
1083 i = 0;
1084 while ((i < pm->NWin) && (pm->WinList[i]!=HWin)) {
1085 i++;
1086 }
1087 if (pm->WinList[i]!=HWin) {
1088 return;
1089 }
1090
1091 do {
1092 i += Next;
1093 if (i >= pm->NWin) {
1094 i = 0;
1095 }
1096 else if (i < 0) {
1097 i = pm->NWin-1;
1098 }
1099
1100 if (pm->WinList[i] == HWin) {
1101 break;
1102 }
1103 } while ((SkipIconic && IsIconic(pm->WinList[i])) || !IsWindowVisible(pm->WinList[i]));
1104
1105 SelectWin(i);
1106 }
1107
1108 void WINAPI ShowAllWin(int stat) {
1109 int i;
1110
1111 for (i=0; i < pm->NWin; i++) {
1112 ShowWindow(pm->WinList[i], stat);
1113 }
1114 }
1115
1116 void WINAPI UndoAllWin(void) {
1117 int i;
1118 WINDOWPLACEMENT rc0;
1119 RECT rc;
1120 int stat = SW_RESTORE;
1121 int multi_mon = 0;
1122
1123 if (HasMultiMonitorSupport()) {
1124 multi_mon = 1;
1125 }
1126
1127 // ���x�A�����������t���O���������B
1128 pm->WinUndoFlag = FALSE;
1129
1130 memset(&rc0, 0, sizeof(rc0));
1131
1132 for (i=0; i < pm->NWin; i++) {
1133 // �����w�����A�O�����������c���������������A�E�B���h�E�����������������B
1134 if (stat == SW_RESTORE && memcmp(&pm->WinPrevRect[i], &rc0, sizeof(rc0)) != 0) {
1135 rc = pm->WinPrevRect[i].rcNormalPosition;
1136
1137 // NT4.0, 95 ���}���`���j�^API��������
1138 if (multi_mon) {
1139 // �������j�^������������
1140 HMONITOR hMonitor;
1141 MONITORINFO mi;
1142 hMonitor = pMonitorFromRect(&rc, MONITOR_DEFAULTTONEAREST);
1143 mi.cbSize = sizeof(MONITORINFO);
1144 pGetMonitorInfoA(hMonitor, &mi);
1145
1146 // ���u�����i�����O���������x���������������������������j
1147 if (rc.right > mi.rcMonitor.right) {
1148 rc.left -= rc.right - mi.rcMonitor.right;
1149 rc.right = mi.rcMonitor.right;
1150 }
1151 if (rc.left < mi.rcMonitor.left) {
1152 rc.right += mi.rcMonitor.left - rc.left;
1153 rc.left = mi.rcMonitor.left;
1154 }
1155 if (rc.bottom > mi.rcMonitor.bottom) {
1156 rc.top -= rc.bottom - mi.rcMonitor.bottom;
1157 rc.bottom = mi.rcMonitor.bottom;
1158 }
1159 if (rc.top < mi.rcMonitor.top) {
1160 rc.bottom += mi.rcMonitor.top - rc.top;
1161 rc.top = mi.rcMonitor.top;
1162 }
1163 }
1164
1165 // �E�B���h�E���u����
1166 SetWindowPos(
1167 pm->WinList[i], NULL,
1168 rc.left,
1169 rc.top,
1170 rc.right - rc.left,
1171 rc.bottom - rc.top,
1172 SWP_NOZORDER);
1173
1174 // �E�B���h�E����������
1175 ShowWindow(pm->WinList[i], pm->WinPrevRect[i].showCmd);
1176
1177 } else {
1178 ShowWindow(pm->WinList[i], stat);
1179 }
1180 }
1181 }
1182
1183 void WINAPI OpenHelp(UINT Command, DWORD Data, char *UILanguageFile)
1184 {
1185 char HomeDir[MAX_PATH];
1186 char Temp[MAX_PATH];
1187 HWND HWin;
1188 wchar_t HelpFN[MAX_PATH];
1189 wchar_t uimsg[MAX_UIMSG];
1190 wchar_t *HomeDirW;
1191
1192 /* Get home directory */
1193 if (GetModuleFileNameA(NULL,Temp,_countof(Temp)) == 0) {
1194 return;
1195 }
1196 ExtractDirName(Temp, HomeDir);
1197 HomeDirW = ToWcharA(HomeDir);
1198 get_lang_msgW("HELPFILE", uimsg, _countof(uimsg), L"teraterm.chm", UILanguageFile);
1199 _snwprintf_s(HelpFN, _countof(HelpFN), _TRUNCATE, L"%s\\%s", HomeDirW, uimsg);
1200 free(HomeDirW);
1201
1202 // �w���v���I�[�i�[�������f�X�N�g�b�v������ (2007.5.12 maya)
1203 HWin = GetDesktopWindow();
1204 if (_HtmlHelpW(HWin, HelpFN, Command, Data) == NULL) {
1205 // �w���v���J����������
1206 static const TTMessageBoxInfoW info = {
1207 "Tera Term",
1208 NULL, L"Tera Term: HTML help",
1209 "MSG_OPENHELP_ERROR", L"Can't open HTML help file(%s)." };
1210 TTMessageBoxW(HWin, &info, MB_OK | MB_ICONERROR, UILanguageFile, HelpFN);
1211 return;
1212 }
1213 }
1214
1215 HWND WINAPI GetNthWin(int n)
1216 {
1217 if (n<pm->NWin) {
1218 return pm->WinList[n];
1219 }
1220 else {
1221 return NULL;
1222 }
1223 }
1224
1225 int WINAPI GetRegisteredWindowCount(void)
1226 {
1227 return (pm->NWin);
1228 }
1229
1230 // �L�����E�B���h�E���T���A�������u���L�������������B
1231 static void get_valid_window_and_memorize_rect(HWND myhwnd, HWND hwnd[], int *num, int style)
1232 {
1233 int i, n;
1234 WINDOWPLACEMENT wndPlace;
1235
1236 // ��������(Undo)���j���[�����x�����\���������B
1237 if (pm->WinUndoFlag == FALSE) {
1238 pm->WinUndoFlag = TRUE;
1239 } else {
1240 // ���������j���[���\�������������A�������O�������X�^�C�����I�����������A
1241 // ���j���[�������B
1242 // Windows8�����A�������A�����������X�^�C�����I�����������j���[�����������������A
1243 // Tera Term�������j���[���\�������������A�������������B
1244 if (pm->WinUndoStyle == style)
1245 pm->WinUndoFlag = FALSE;
1246 }
1247 pm->WinUndoStyle = style;
1248
1249 n = 0;
1250 for (i = 0 ; i < pm->NWin ; i++) {
1251 // �������u���o���������B
1252 wndPlace.length = sizeof(WINDOWPLACEMENT);
1253 GetWindowPlacement(pm->WinList[i], &wndPlace);
1254 pm->WinPrevRect[i] = wndPlace;
1255
1256 // �������g�������������B
1257 if (pm->WinList[i] == myhwnd) {
1258 hwnd[n] = hwnd[0];
1259 hwnd[0] = myhwnd;
1260 } else {
1261 hwnd[n] = pm->WinList[i];
1262 }
1263 n++;
1264 }
1265 *num = n;
1266 }
1267
1268 // �E�B���h�E�����E���������\������(Show Windows Side by Side)
1269 void WINAPI ShowAllWinSidebySide(HWND myhwnd)
1270 {
1271 int n;
1272 HWND hwnd[MAXNWIN];
1273
1274 get_valid_window_and_memorize_rect(myhwnd, hwnd, &n, WIN_SIDEBYSIDE);
1275 TileWindows(NULL, MDITILE_VERTICAL, NULL, n, hwnd);
1276 }
1277
1278 // �E�B���h�E���������������\������(Show Windows Stacked)
1279 void WINAPI ShowAllWinStacked(HWND myhwnd)
1280 {
1281 int n;
1282 HWND hwnd[MAXNWIN];
1283
1284 get_valid_window_and_memorize_rect(myhwnd, hwnd, &n, WIN_STACKED);
1285 TileWindows(NULL, MDITILE_HORIZONTAL, NULL, n, hwnd);
1286 }
1287
1288 // �E�B���h�E���d�����\������(Cascade)
1289 void WINAPI ShowAllWinCascade(HWND myhwnd)
1290 {
1291 int n;
1292 HWND hwnd[MAXNWIN];
1293
1294 get_valid_window_and_memorize_rect(myhwnd, hwnd, &n, WIN_CASCADE);
1295 CascadeWindows(NULL, MDITILE_SKIPDISABLED, NULL, n, hwnd);
1296 }
1297
1298 // �STera Term���I���w�����o���B
1299 void WINAPI BroadcastClosingMessage(HWND myhwnd)
1300 {
1301 int i, max;
1302 HWND hwnd[MAXNWIN];
1303
1304 // Tera Term���I�����������A���L���������������������A
1305 // ���������o�b�t�@���R�s�[���������B
1306 max = pm->NWin;
1307 for (i = 0 ; i < pm->NWin ; i++) {
1308 hwnd[i] = pm->WinList[i];
1309 }
1310
1311 for (i = 0 ; i < max ; i++) {
1312 // �������g�������������B
1313 if (hwnd[i] == myhwnd)
1314 continue;
1315
1316 PostMessage(hwnd[i], WM_USER_NONCONFIRM_CLOSE, 0, 0);
1317 }
1318 PostMessage(myhwnd, WM_USER_NONCONFIRM_CLOSE, 0, 0);
1319 }
1320
1321
1322 int WINAPI CommReadRawByte(PComVar cv, LPBYTE b)
1323 {
1324 if ( ! cv->Ready ) {
1325 return 0;
1326 }
1327
1328 if ( cv->InBuffCount>0 ) {
1329 *b = cv->InBuff[cv->InPtr];
1330 cv->InPtr++;
1331 cv->InBuffCount--;
1332 if ( cv->InBuffCount==0 ) {
1333 cv->InPtr = 0;
1334 }
1335 return 1;
1336 }
1337 else {
1338 cv->InPtr = 0;
1339 return 0;
1340 }
1341 }
1342
1343 static void LogBinSkip(PComVar cv, int add)
1344 {
1345 if (cv->LogBinSkip != NULL) {
1346 cv->LogBinSkip(add);
1347 }
1348 }
1349
1350 void WINAPI CommInsert1Byte(PComVar cv, BYTE b)
1351 {
1352 if ( ! cv->Ready ) {
1353 return;
1354 }
1355
1356 if (cv->InPtr == 0) {
1357 memmove(&(cv->InBuff[1]),&(cv->InBuff[0]),cv->InBuffCount);
1358 }
1359 else {
1360 cv->InPtr--;
1361 }
1362 cv->InBuff[cv->InPtr] = b;
1363 cv->InBuffCount++;
1364
1365 LogBinSkip(cv, 1);
1366 }
1367
1368 static void Log1Bin(PComVar cv, BYTE b)
1369 {
1370 if (cv->Log1Bin != NULL) {
1371 cv->Log1Bin(b);
1372 }
1373 }
1374
1375 int WINAPI CommRead1Byte(PComVar cv, LPBYTE b)
1376 {
1377 int c;
1378
1379 if ( ! cv->Ready ) {
1380 return 0;
1381 }
1382
1383 if ( cv->TelMode ) {
1384 c = 0;
1385 }
1386 else {
1387 c = CommReadRawByte(cv,b);
1388 }
1389
1390 if ((c==1) && cv->TelCRFlag) {
1391 cv->TelCRFlag = FALSE;
1392 if (*b==0) {
1393 c = 0;
1394 }
1395 }
1396
1397 if ( c==1 ) {
1398 if ( cv->IACFlag ) {
1399 cv->IACFlag = FALSE;
1400 if ( *b != 0xFF ) {
1401 cv->TelMode = TRUE;
1402 CommInsert1Byte(cv,*b);
1403 LogBinSkip(cv, -1);
1404 c = 0;
1405 }
1406 }
1407 else if ((cv->PortType==IdTCPIP) && (*b==0xFF)) {
1408 if (!cv->TelFlag && cv->TelAutoDetect) { /* TTPLUG */
1409 cv->TelFlag = TRUE;
1410 }
1411 if (cv->TelFlag) {
1412 cv->IACFlag = TRUE;
1413 c = 0;
1414 }
1415 }
1416 else if (cv->TelFlag && ! cv->TelBinRecv && (*b==0x0D)) {
1417 cv->TelCRFlag = TRUE;
1418 }
1419 }
1420
1421 if (c == 1) {
1422 Log1Bin(cv, *b);
1423 }
1424
1425 return c;
1426 }
1427
1428 int WINAPI CommRawOut(PComVar cv, /*const*/ PCHAR B, int C)
1429 {
1430 int a;
1431
1432 if ( ! cv->Ready ) {
1433 return C;
1434 }
1435
1436 if (C > OutBuffSize - cv->OutBuffCount) {
1437 a = OutBuffSize - cv->OutBuffCount;
1438 }
1439 else {
1440 a = C;
1441 }
1442 if ( cv->OutPtr > 0 ) {
1443 memmove(&(cv->OutBuff[0]),&(cv->OutBuff[cv->OutPtr]),cv->OutBuffCount);
1444 cv->OutPtr = 0;
1445 }
1446 memcpy(&(cv->OutBuff[cv->OutBuffCount]),B,a);
1447 cv->OutBuffCount = cv->OutBuffCount + a;
1448 return a;
1449 }
1450
1451 int WINAPI CommBinaryOut(PComVar cv, PCHAR B, int C)
1452 {
1453 int a, i, Len;
1454 char d[3];
1455
1456 if ( ! cv->Ready ) {
1457 return C;
1458 }
1459
1460 i = 0;
1461 a = 1;
1462 while ((a>0) && (i<C)) {
1463 Len = 0;
1464
1465 d[Len] = B[i];
1466 Len++;
1467
1468 if ( cv->TelFlag && (B[i]=='\x0d') && ! cv->TelBinSend ) {
1469 d[Len++] = '\x00';
1470 }
1471 else if ( cv->TelFlag && (B[i]=='\xff') ) {
1472 d[Len++] = '\xff';
1473 }
1474
1475 if ( OutBuffSize - cv->OutBuffCount - Len >= 0 ) {
1476 CommRawOut(cv, d, Len);
1477 a = 1;
1478 }
1479 else {
1480 a = 0;
1481 }
1482
1483 i += a;
1484 }
1485 return i;
1486 }
1487
1488 /**
1489 * �f�[�^(������)���o���o�b�t�@����������
1490 *
1491 * �w���f�[�^��������������������������������������
1492 * CommRawOut() ��������������������������
1493 *
1494 * @retval TRUE �o��������
1495 * @retval FALSE �o��������������(buffer full)
1496 */
1497 static BOOL WriteOutBuff(PComVar cv, const char *TempStr, int TempLen)
1498 {
1499 BOOL output;
1500
1501 if (TempLen == 0) {
1502 // ����0������������������������
1503 return TRUE;
1504 }
1505
1506 output = FALSE;
1507 if (cv->TelLineMode) {
1508 const BOOL Full = OutBuffSize - cv->LineModeBuffCount - TempLen < 0;
1509 if (!Full) {
1510 output = TRUE;
1511 memcpy(&(cv->LineModeBuff[cv->LineModeBuffCount]), TempStr, TempLen);
1512 cv->LineModeBuffCount += TempLen;
1513 if (cv->Flush) {
1514 cv->FlushLen = cv->LineModeBuffCount;
1515 }
1516 }
1517 if (cv->FlushLen > 0) {
1518 const int OutLen = CommRawOut(cv, cv->LineModeBuff, cv->FlushLen);
1519 cv->FlushLen -= OutLen;
1520 cv->LineModeBuffCount -= OutLen;
1521 memmove(cv->LineModeBuff, &(cv->LineModeBuff[OutLen]), cv->LineModeBuffCount);
1522 }
1523 cv->Flush = FALSE;
1524 }
1525 else {
1526 const BOOL Full = OutBuffSize-cv->OutBuffCount-TempLen < 0;
1527 if (! Full) {
1528 output = TRUE;
1529 CommRawOut(cv, (char *)TempStr, TempLen);
1530 }
1531 }
1532 return output;
1533 }
1534
1535 /**
1536 * �f�[�^(������)�������o�b�t�@����������
1537 * �����o�b�t�@�������� -> �G�R�[������
1538 *
1539 * @retval TRUE �o��������
1540 * @retval FALSE �o��������������(buffer full)
1541 */
1542 static BOOL WriteInBuff(PComVar cv, const char *TempStr, int TempLen)
1543 {
1544 BOOL Full;
1545
1546 if (TempLen == 0) {
1547 return TRUE;
1548 }
1549
1550 Full = InBuffSize-cv->InBuffCount-TempLen < 0;
1551 if (! Full) {
1552 memcpy(&(cv->InBuff[cv->InBuffCount]),TempStr,TempLen);
1553 cv->InBuffCount = cv->InBuffCount + TempLen;
1554 return TRUE;
1555 }
1556 return FALSE;
1557 }
1558
1559 /**
1560 * �����o�b�t�@�����������������������l����
1561 */
1562 static void PackInBuff(PComVar cv)
1563 {
1564 if ( (cv->InPtr>0) && (cv->InBuffCount>0) ) {
1565 memmove(cv->InBuff,&(cv->InBuff[cv->InPtr]),cv->InBuffCount);
1566 cv->InPtr = 0;
1567 }
1568 }
1569
1570 int WINAPI CommBinaryBuffOut(PComVar cv, PCHAR B, int C)
1571 {
1572 int a, i, Len;
1573 char d[3];
1574
1575 if ( ! cv->Ready ) {
1576 return C;
1577 }
1578
1579 i = 0;
1580 a = 1;
1581 while ((a>0) && (i<C)) {
1582 Len = 0;
1583
1584 d[Len] = B[i];
1585 Len++;
1586
1587 if (B[i] == CR) {
1588 if ( cv->TelFlag && ! cv->TelBinSend ) {
1589 d[Len++] = '\x00';
1590 }
1591 if (cv->TelLineMode) {
1592 cv->Flush = TRUE;
1593 }
1594 }
1595 else if ( cv->TelFlag && (B[i]=='\xff') ) {
1596 d[Len++] = '\xff';
1597 }
1598
1599 if (WriteOutBuff(cv, d, Len)) {
1600 a = 1;
1601 i++;
1602 } else {
1603 a = 0;
1604 }
1605 }
1606 return i;
1607 }
1608
1609 // �����R�[�h(CodePage)��UTF-8���o������
1610 static int OutputTextUTF8(WORD K, char *TempStr, PComVar cv)
1611 {
1612 int CodePage = *cv->CodePage;
1613 unsigned int code;
1614 int outlen;
1615
1616 code = MBCP_UTF32(K, CodePage);
1617 if (code == 0) {
1618 // �������s
1619 code = 0xfffd; // U+FFFD: Replacement Character
1620 }
1621 outlen = UTF32ToUTF8(code, TempStr, 4);
1622 return outlen;
1623 }
1624
1625 static int __isleadbyte_l(int d, PComVar cv)
1626 {
1627 int CodePage = *cv->CodePage;
1628 return IsDBCSLeadByteEx(CodePage, d);
1629 }
1630
1631 //
1632 // MBCS�����e�������R�[�h�����������o�������B
1633 //
1634 static int TextOutMBCS(PComVar cv, PCHAR B, int C)
1635 {
1636 int i, TempLen;
1637 WORD K;
1638 char TempStr[12];
1639 BYTE d;
1640 BOOL Full;
1641 int SendCodeNew; // ���M�R�[�h
1642 BOOL KanjiFlagNew; // TRUE=����������������������������
1643
1644 Full = FALSE;
1645 i = 0;
1646 while (! Full && (i < C)) {
1647 TempLen = 0;
1648 d = (BYTE)B[i];
1649 SendCodeNew = cv->SendCode;
1650 KanjiFlagNew = FALSE;
1651
1652 if (cv->SendKanjiFlag) {
1653 SendCodeNew = IdKanji;
1654
1655 K = (cv->SendKanjiFirst << 8) + d;
1656
1657 // UTF-8�����������s���B1�`3�o�C�g���������������������B
1658 if (cv->KanjiCodeSend == IdUTF8 || cv->Language == IdUtf8) {
1659 TempLen += OutputTextUTF8(K, TempStr, cv);
1660 }
1661 else {
1662 switch (cv->Language) {
1663 case IdJapanese:
1664 switch (cv->KanjiCodeSend) {
1665 case IdEUC:
1666 K = SJIS2EUC(K);
1667 break;
1668 case IdJIS:
1669 K = SJIS2JIS(K);
1670 if ((cv->SendCode==IdKatakana) &&
1671 (cv->JIS7KatakanaSend==1)) {
1672 TempStr[TempLen++] = SI;
1673 }
1674 break;
1675 case IdSJIS:
1676 /* nothing to do */
1677 break;
1678 }
1679 break;
1680 case IdKorean:
1681 break;
1682 }
1683 TempStr[TempLen++] = HIBYTE(K);
1684 TempStr[TempLen++] = LOBYTE(K);
1685 }
1686 }
1687 else if (__isleadbyte_l(d, cv)) {
1688 KanjiFlagNew = TRUE;
1689 cv->SendKanjiFirst = d;
1690 SendCodeNew = IdKanji;
1691
1692 if (cv->Language == IdJapanese) {
1693 if ((cv->SendCode!=IdKanji) && (cv->KanjiCodeSend==IdJIS)) {
1694 TempStr[0] = 0x1B;
1695 TempStr[1] = '$';
1696 if (cv->KanjiIn == IdKanjiInB) {
1697 TempStr[2] = 'B';
1698 }
1699 else {
1700 TempStr[2] = '@';
1701 }
1702 TempLen = 3;
1703 }
1704 }
1705 }
1706 else {
1707 if (cv->Language == IdJapanese) {
1708 if ((cv->SendCode==IdKanji) && (cv->KanjiCodeSend==IdJIS)) {
1709 TempStr[0] = 0x1B;
1710 TempStr[1] = '(';
1711 switch (cv->KanjiOut) {
1712 case IdKanjiOutJ:
1713 TempStr[2] = 'J';
1714 break;
1715 case IdKanjiOutH:
1716 TempStr[2] = 'H';
1717 break;
1718 default:
1719 TempStr[2] = 'B';
1720 }
1721 TempLen = 3;
1722 }
1723
1724 if ((0xa0<d) && (d<0xe0)) {
1725 SendCodeNew = IdKatakana;
1726 if ((cv->SendCode!=IdKatakana) &&
1727 (cv->KanjiCodeSend==IdJIS) &&
1728 (cv->JIS7KatakanaSend==1)) {
1729 TempStr[TempLen++] = SO;
1730 }
1731 }
1732 else {
1733 SendCodeNew = IdASCII;
1734 if ((cv->SendCode==IdKatakana) &&
1735 (cv->KanjiCodeSend==IdJIS) &&
1736 (cv->JIS7KatakanaSend==1)) {
1737 TempStr[TempLen++] = SI;
1738 }
1739 }
1740 }
1741
1742 if (d==CR) {
1743 TempStr[TempLen++] = 0x0d;
1744 if (cv->CRSend==IdCRLF) {
1745 TempStr[TempLen++] = 0x0a;
1746 }
1747 else if ((cv->CRSend==IdCR) &&
1748 cv->TelFlag && ! cv->TelBinSend) {
1749 TempStr[TempLen++] = 0;
1750 }
1751 else if (cv->CRSend == IdLF) {
1752 TempStr[TempLen-1] = 0x0a;
1753 }
1754 if (cv->TelLineMode) {
1755 cv->Flush = TRUE;
1756 }
1757 }
1758 else if (d==BS) {
1759 if (cv->TelLineMode) {
1760 if (cv->FlushLen < cv->LineModeBuffCount) {
1761 cv->LineModeBuffCount--;
1762 }
1763 }
1764 else {
1765 TempStr[TempLen++] = d;
1766 }
1767 }
1768 else if (d==0x15) { // Ctrl-U
1769 if (cv->TelLineMode) {
1770 cv->LineModeBuffCount = cv->FlushLen;
1771 }
1772 else {
1773 TempStr[TempLen++] = d;
1774 }
1775 }
1776 else if ((d>=0x80) && (cv->KanjiCodeSend==IdUTF8 || cv->Language==IdUtf8)) {
1777 TempLen += OutputTextUTF8((WORD)d, TempStr, cv);
1778 }
1779 else if ((d>=0xa1) && (d<=0xe0) && (cv->Language == IdJapanese)) {
1780 /* Katakana */
1781 if (cv->KanjiCodeSend==IdEUC) {
1782 TempStr[TempLen++] = (char)SS2;
1783 }
1784 if ((cv->KanjiCodeSend==IdJIS) &&
1785 (cv->JIS7KatakanaSend==1)) {
1786 TempStr[TempLen++] = d & 0x7f;
1787 }
1788 else {
1789 TempStr[TempLen++] = d;
1790 }
1791 }
1792 else {
1793 TempStr[TempLen++] = d;
1794 if (cv->TelFlag && (d==0xff)) {
1795 TempStr[TempLen++] = (char)0xff;
1796 }
1797 }
1798 } // if (cv->SendKanjiFlag) else if ... else ... end
1799
1800 if (WriteOutBuff(cv, TempStr, TempLen)) {
1801 i++; // 1������������
1802 // ��������������������
1803 cv->SendCode = SendCodeNew;
1804 cv->SendKanjiFlag = KanjiFlagNew;
1805 } else {
1806 Full = TRUE;
1807 }
1808
1809 } // end of "while {}"
1810
1811 return i;
1812 }
1813
1814 int WINAPI CommTextOut(PComVar cv, PCHAR B, int C)
1815 {
1816 int i, TempLen;
1817 char TempStr[12];
1818 BYTE d;
1819 BOOL Full;
1820
1821 if (! cv->Ready ) {
1822 return C;
1823 }
1824
1825 switch (cv->Language) {
1826 case IdUtf8:
1827 case IdJapanese:
1828 case IdKorean:
1829 return TextOutMBCS(cv, B, C);
1830 break;
1831 }
1832
1833 Full = FALSE;
1834 i = 0;
1835 while (! Full && (i < C)) {
1836 TempLen = 0;
1837 d = (BYTE)B[i];
1838
1839 switch (d) {
1840 case CR:
1841 TempStr[TempLen] = 0x0d;
1842 TempLen++;
1843 if (cv->CRSend==IdCRLF) {
1844 TempStr[TempLen++] = 0x0a;
1845 }
1846 else if (cv->CRSend==IdCR && cv->TelFlag && ! cv->TelBinSend) {
1847 TempStr[TempLen++] = 0;
1848 }
1849 else if (cv->CRSend == IdLF) {
1850 TempStr[TempLen-1] = 0x0a;
1851 }
1852 if (cv->TelLineMode) {
1853 cv->Flush = TRUE;
1854 }
1855 break;
1856
1857 case BS:
1858 if (cv->TelLineMode) {
1859 if (cv->FlushLen < cv->LineModeBuffCount) {
1860 cv->LineModeBuffCount--;
1861 }
1862 }
1863 else {
1864 TempStr[TempLen++] = d;
1865 }
1866 break;
1867
1868 case 0x15: // Ctrl-U
1869 if (cv->TelLineMode) {
1870 cv->LineModeBuffCount = cv->FlushLen;
1871 }
1872 else {
1873 TempStr[TempLen++] = d;
1874 }
1875 break;
1876
1877 default:
1878 if ((cv->Language==IdRussian) && (d>=128)) {
1879 d = RussConv(cv->RussClient, cv->RussHost, d);
1880 }
1881 TempStr[TempLen++] = d;
1882 if (cv->TelFlag && (d==0xff)) {
1883 TempStr[TempLen++] = (char)0xff;
1884 }
1885 }
1886
1887 if (WriteOutBuff(cv, TempStr, TempLen)) {
1888 i++; // 1������������
1889 } else {
1890 Full = TRUE;
1891 }
1892
1893 } // end of while {}
1894
1895 return i;
1896 }
1897
1898 /**
1899 * @retval true ���{�������p�J�^�J�i
1900 * @retval false ������
1901 */
1902 static BOOL IsHalfWidthKatakana(unsigned int u32)
1903 {
1904 // Halfwidth CJK punctuation (U+FF61�`FF64)
1905 // Halfwidth Katakana variants (U+FF65�`FF9F)
1906 return (0xff61 <= u32 && u32 <= 0xff9f);
1907 }
1908
1909 /**
1910 * �o���p�A TODO echo�p������
1911 * @param cv
1912 * @param u32 ��������
1913 * @param check_only TRUE���������s�����A
1914 * @param TempStr �o��������
1915 * @param StrLen TempStr�����o��������
1916 * @retval �������s����
1917 */
1918 static BOOL OutControl(PComVar cv, unsigned int u32, BOOL check_only, char *TempStr, size_t *StrLen)
1919 {
1920 const wchar_t d = u32;
1921 size_t TempLen = 0;
1922 BOOL retval = FALSE;
1923 if (check_only == TRUE) {
1924 /* �`�F�b�N���� */
1925 if (d == CR || d == BS || d == 0x15/*ctrl-u*/) {
1926 return TRUE;
1927 } else {
1928 return FALSE;
1929 }
1930 }
1931 if (d==CR) {
1932 TempStr[TempLen++] = 0x0d;
1933 if (cv->CRSend==IdCRLF) {
1934 TempStr[TempLen++] = 0x0a;
1935 }
1936 else if ((cv->CRSend ==IdCR) &&
1937 cv->TelFlag && ! cv->TelBinSend) {
1938 TempStr[TempLen++] = 0;
1939 }
1940 else if (cv->CRSend == IdLF) {
1941 TempStr[TempLen-1] = 0x0a;
1942 }
1943 if (cv->TelLineMode) {
1944 cv->Flush = TRUE;
1945 }
1946 retval = TRUE;
1947 }
1948 else if (d== BS) {
1949 if (cv->TelLineMode) {
1950 if (cv->FlushLen < cv->LineModeBuffCount) {
1951 cv->LineModeBuffCount--;
1952 }
1953 }
1954 else {
1955 TempStr[TempLen++] = BS;
1956 }
1957 retval = TRUE;
1958 }
1959 else if (d==0x15) { // ctrl-u
1960 if (cv->TelLineMode) {
1961 cv->LineModeBuffCount = cv->FlushLen;
1962 }
1963 else {
1964 TempStr[TempLen++] = 0x15;
1965 }
1966 retval = TRUE;
1967 }
1968 *StrLen = TempLen;
1969 return retval;
1970 }
1971 static BOOL ControlEcho(PComVar cv, unsigned int u32, BOOL check_only, char *TempStr, size_t *StrLen)
1972 {
1973 const wchar_t d = u32;
1974 size_t TempLen = 0;
1975 BOOL retval = FALSE;
1976 if (check_only == TRUE) {
1977 /* �`�F�b�N���� */
1978 if (d == CR || (d == 0x15/*ctrl-u*/ && cv->TelLineMode)) {
1979 return TRUE;
1980 } else {
1981 return FALSE;
1982 }
1983 }
1984 if (d==CR) {
1985 TempStr[TempLen++] = 0x0d;
1986 if (cv->CRSend==IdCRLF) {
1987 TempStr[TempLen++] = 0x0a;
1988 }
1989 else if ((cv->CRSend ==IdCR) && cv->TelFlag && ! cv->TelBinSend) {
1990 TempStr[TempLen++] = 0;
1991 }
1992 else if (cv->CRSend == IdLF) {
1993 TempStr[TempLen-1] = 0x0a;
1994 }
1995 retval = TRUE;
1996 }
1997 else if (d==0x15/*ctrl-u*/ && cv->TelLineMode) {
1998 // Move to top of line (CHA "\033[G") and erase line (EL "\033[K")
1999 memcpy(TempStr, "\033[G\033[K", 6);
2000 TempLen += 6;
2001 retval = TRUE;
2002 }
2003 *StrLen = TempLen;
2004 return retval;
2005 }
2006
2007 /**
2008 * �o���p����������������
2009 *
2010 * @retval ��������������
2011 */
2012 typedef struct {
2013 int KanjiCode; // [in]�o�������R�[�h(sjis,jis����)
2014 BOOL (*ControlOut)(PComVar cv, unsigned int u32, BOOL check_only, char *TempStr, size_t *StrLen);
2015 // state�����������K�v�����������R�[�h���g�p
2016 BOOL JIS7Katakana; // [in](Kanji JIS)kana
2017 int SendCode; // [in,out](Kanji JIS)���O�����M�R�[�h Ascii/Kana/Kanji
2018 BOOL KanjiFlag; // [in,out](MBCS)���O��1byte��������������?(2byte������������?)
2019 BYTE KanjiFirst; // [in,out](MBCS)���O��1byte
2020 } OutputCharState;
2021
2022 /**
2023 * unicode(UTF-16)����unicode(UTF-32)��1���������o����
2024 * �o���f�[�^(TempStr)����������
2025 */
2026 static size_t MakeOutputString(PComVar cv, OutputCharState *states,
2027 const wchar_t *B, int C,
2028 char *TempStr, int *TempLen_)
2029 {
2030 BOOL (*ControlOut)(PComVar cv, unsigned int u32, BOOL check_only, char *TempStr, size_t *StrLen)
2031 = states->ControlOut;
2032 //
2033 int TempLen = 0;
2034 size_t TempLen2;
2035 size_t output_char_count; // ��������������
2036
2037 // UTF-32 ��1���������o��
2038 unsigned int u32;
2039 size_t u16_len = UTF16ToUTF32(B, C, &u32);
2040 if (u16_len == 0) {
2041 // �f�R�[�h��������? ����������������?
2042 assert(FALSE);
2043 u32 = '?';
2044 u16_len = 1;
2045 }
2046 output_char_count = u16_len;
2047
2048 // �e���V�t�g����������������
2049 if (u32 < 0x100 || ControlOut(cv, u32, TRUE, NULL, NULL)) {
2050 if (cv->Language == IdJapanese && states->KanjiCode == IdJIS) {
2051 // �����������A���{��,JIS��������
2052 if (cv->SendCode == IdKanji) {
2053 // �����������������A����OUT
2054 TempStr[TempLen++] = 0x1B;
2055 TempStr[TempLen++] = '(';
2056 switch (cv->KanjiOut) {
2057 case IdKanjiOutJ:
2058 TempStr[TempLen++] = 'J';
2059 break;
2060 case IdKanjiOutH:
2061 TempStr[TempLen++] = 'H';
2062 break;
2063 default:
2064 TempStr[TempLen++] = 'B';
2065 }
2066 }
2067
2068 if (states->JIS7Katakana == 1) {
2069 if (cv->SendCode == IdKatakana) {
2070 TempStr[TempLen++] = SO;
2071 }
2072 }
2073
2074 states->SendCode = IdASCII;
2075 }
2076 }
2077
2078 // 1������������
2079 if (ControlOut(cv, u32, FALSE, TempStr, &TempLen2)) {
2080 // ��������������������
2081 TempLen += TempLen2;
2082 output_char_count = 1;
2083 } else if (cv->Language == IdUtf8 ||
2084 (cv->Language == IdJapanese && states->KanjiCode == IdUTF8) ||
2085 (cv->Language == IdKorean && states->KanjiCode == IdUTF8))
2086 {
2087 // UTF-8 ���o��
2088 size_t utf8_len = sizeof(TempStr);
2089 utf8_len = UTF32ToUTF8(u32, TempStr, utf8_len);
2090 TempLen += utf8_len;
2091 } else if (cv->Language == IdJapanese && *cv->CodePage == 932) {
2092 // ���{��
2093 // ���� CP932(SJIS) ���������������o��
2094 char mb_char[2];
2095 size_t mb_len = sizeof(mb_char);
2096 mb_len = UTF32ToMBCP(u32, 932, mb_char, mb_len);
2097 if (mb_len == 0) {
2098 // SJIS��������������
2099 TempStr[TempLen++] = '?';
2100 } else {
2101 switch (states->KanjiCode) {
2102 case IdEUC:
2103 // TODO ���p�J�i
2104 if (mb_len == 1) {
2105 TempStr[TempLen++] = mb_char[0];
2106 } else {
2107 WORD K;
2108 K = (((WORD)(unsigned char)mb_char[0]) << 8) +
2109 (WORD)(unsigned char)mb_char[1];
2110 K = SJIS2EUC(K);
2111 TempStr[TempLen++] = HIBYTE(K);
2112 TempStr[TempLen++] = LOBYTE(K);
2113 }
2114 break;
2115 case IdJIS:
2116 if (u32 < 0x100) {
2117 // ASCII
2118 TempStr[TempLen++] = mb_char[0];
2119 states->SendCode = IdASCII;
2120 } else if (IsHalfWidthKatakana(u32)) {
2121 // ���p�J�^�J�i
2122 if (states->JIS7Katakana==1) {
2123 if (cv->SendCode != IdKatakana) {
2124 TempStr[TempLen++] = SI;
2125 }
2126 TempStr[TempLen++] = mb_char[0] & 0x7f;
2127 } else {
2128 TempStr[TempLen++] = mb_char[0];
2129 }
2130 states->SendCode = IdKatakana;
2131 } else {
2132 // ����
2133 WORD K;
2134 K = (((WORD)(unsigned char)mb_char[0]) << 8) +
2135 (WORD)(unsigned char)mb_char[1];
2136 K = SJIS2JIS(K);
2137 if (states->SendCode != IdKanji) {
2138 // ����IN
2139 TempStr[TempLen++] = 0x1B;
2140 TempStr[TempLen++] = '$';
2141 if (cv->KanjiIn == IdKanjiInB) {
2142 TempStr[TempLen++] = 'B';
2143 }
2144 else {
2145 TempStr[TempLen++] = '@';
2146 }
2147 states->SendCode = IdKanji;
2148 }
2149 TempStr[TempLen++] = HIBYTE(K);
2150 TempStr[TempLen++] = LOBYTE(K);
2151 }
2152 break;
2153 case IdSJIS:
2154 if (mb_len == 1) {
2155 TempStr[TempLen++] = mb_char[0];
2156 } else {
2157 TempStr[TempLen++] = mb_char[0];
2158 TempStr[TempLen++] = mb_char[1];
2159 }
2160 break;
2161 default:
2162 assert(FALSE);
2163 break;
2164 }
2165 }
2166 } else if (cv->Language == IdRussian) {
2167 /* ����CP1251�����������o�� */
2168 char mb_char[2];
2169 size_t mb_len = sizeof(mb_char);
2170 BYTE b;
2171 mb_len = UTF32ToMBCP(u32, 1251, mb_char, mb_len);
2172 if (mb_len != 1) {
2173 b = '?';
2174 } else {
2175 b = RussConv(IdWindows, cv->RussHost, mb_char[0]);
2176 }
2177 TempStr[TempLen++] = b;
2178 } else if (cv->Language == IdKorean && *cv->CodePage == 51949) {
2179 /* CP51949�����������o�� */
2180 char mb_char[2];
2181 size_t mb_len = sizeof(mb_char);
2182 mb_len = UTF32ToMBCP(u32, 51949, mb_char, mb_len);
2183 if (mb_len == 0) {
2184 TempStr[TempLen++] = '?';
2185 }
2186 else if (mb_len == 1) {
2187 TempStr[TempLen++] = mb_char[0];
2188 } else {
2189 TempStr[TempLen++] = mb_char[0];
2190 TempStr[TempLen++] = mb_char[1];
2191 }
2192 } else if (cv->Language == IdEnglish) {
2193 TempStr[TempLen++] = u32;
2194 } else {
2195 // CodePage������
2196 char mb_char[2];
2197 size_t mb_len = sizeof(mb_char);
2198 mb_len = UTF32ToMBCP(u32, *cv->CodePage, mb_char, mb_len);
2199 if (mb_len == 0) {
2200 TempStr[TempLen++] = '?';
2201 }
2202 else if (mb_len == 1) {
2203 TempStr[TempLen++] = mb_char[0];
2204 } else {
2205 TempStr[TempLen++] = mb_char[0];
2206 TempStr[TempLen++] = mb_char[1];
2207 }
2208 }
2209
2210 *TempLen_ = TempLen;
2211 return output_char_count;
2212 }
2213
2214
2215 /**
2216 * CommTextOut() �� wchar_t ��
2217 *
2218 * @retval �o��������(wchar_t�P��)
2219 */
2220 int WINAPI CommTextOutW(PComVar cv, const wchar_t *B, int C)
2221 {
2222 char TempStr[12];
2223 BOOL Full = FALSE;
2224 int i = 0;
2225 while (! Full && (i < C)) {
2226 // �o���p�f�[�^������
2227 int TempLen = 0;
2228 size_t output_char_count; // ��������������
2229 OutputCharState state;
2230 state.KanjiCode = cv->KanjiCodeSend;
2231 state.ControlOut = OutControl;
2232 state.SendCode = cv->SendCode;
2233 state.JIS7Katakana = cv->JIS7KatakanaSend;
2234 output_char_count = MakeOutputString(cv, &state, &B[i], C-i, TempStr, &TempLen);
2235
2236 // �f�[�^���o���o�b�t�@��
2237 if (WriteOutBuff(cv, TempStr, TempLen)) {
2238 i += output_char_count; // output_char_count ������ ��������
2239 // ��������������������
2240 cv->SendCode = state.SendCode;
2241 } else {
2242 Full = TRUE;
2243 }
2244 } // end of "while {}"
2245 _CrtCheckMemory();
2246 return i;
2247 }
2248
2249 /**
2250 * CommTextEcho() �� wchar_t ��
2251 *
2252 * @retval �o��������(wchar_t�P��)
2253 */
2254 int WINAPI CommTextEchoW(PComVar cv, const wchar_t *B, int C)
2255 {
2256 char TempStr[12];
2257 BOOL Full = FALSE;
2258 int i = 0;
2259 while (! Full && (i < C)) {
2260 // �o���p�f�[�^������
2261 int TempLen = 0;
2262 size_t output_char_count; // ��������������
2263 OutputCharState state;
2264 state.KanjiCode = cv->KanjiCodeEcho;
2265 state.ControlOut = ControlEcho;
2266 state.SendCode = cv->EchoCode;
2267 state.JIS7Katakana = cv->JIS7KatakanaEcho;
2268 output_char_count = MakeOutputString(cv, &state, &B[i], C-i, TempStr, &TempLen);
2269
2270 // �f�[�^���o���o�b�t�@��
2271 if (WriteInBuff(cv, TempStr, TempLen)) {
2272 i += output_char_count; // output_char_count ������ ��������
2273 // ��������������������
2274 cv->EchoCode = state.SendCode;
2275 } else {
2276 Full = TRUE;
2277 }
2278 } // end of "while {}"
2279 _CrtCheckMemory();
2280 return i;
2281 }
2282
2283 int WINAPI CommBinaryEcho(PComVar cv, PCHAR B, int C)
2284 {
2285 int a, i, Len;
2286 char d[3];
2287
2288 if ( ! cv->Ready )
2289 return C;
2290
2291 PackInBuff(cv);
2292
2293 i = 0;
2294 a = 1;
2295 while ((a>0) && (i<C)) {
2296 Len = 0;
2297
2298 d[Len] = B[i];
2299 Len++;
2300
2301 if ( cv->TelFlag && (B[i]=='\x0d') &&
2302 ! cv->TelBinSend ) {
2303 d[Len] = 0x00;
2304 Len++;
2305 }
2306
2307 if ( cv->TelFlag && (B[i]=='\xff') ) {
2308 d[Len] = '\xff';
2309 Len++;
2310 }
2311
2312 if (WriteInBuff(cv, d, Len)) {
2313 a = 1;
2314 i++;
2315 } else {
2316 a = 0;
2317 }
2318 }
2319 return i;
2320 }
2321
2322 static int WINAPI TextEchoMBCS(PComVar cv, PCHAR B, int C)
2323 {
2324 int i, TempLen;
2325 WORD K;
2326 char TempStr[12];
2327 int EchoCodeNew;
2328 BYTE d;
2329 BOOL Full, KanjiFlagNew;
2330
2331 Full = FALSE;
2332 i = 0;
2333 while (! Full && (i < C)) {
2334 TempLen = 0;
2335 d = (BYTE)B[i];
2336 EchoCodeNew = cv->EchoCode;
2337 KanjiFlagNew = FALSE;
2338
2339 if (cv->EchoKanjiFlag) {
2340 EchoCodeNew = IdKanji;
2341
2342 K = (cv->EchoKanjiFirst << 8) + d;
2343
2344 // UTF-8�����������s���B1�`3�o�C�g���������������������B
2345 if (cv->KanjiCodeEcho == IdUTF8 || cv->Language==IdUtf8) {
2346 TempLen += OutputTextUTF8(K, TempStr, cv);
2347 }
2348 else {
2349 switch (cv->Language) {
2350 case IdJapanese:
2351 switch (cv->KanjiCodeEcho) {
2352 case IdEUC:
2353 K = SJIS2EUC(K);
2354 break;
2355 case IdJIS:
2356 K = SJIS2JIS(K);
2357 if ((cv->EchoCode==IdKatakana) &&
2358 (cv->JIS7KatakanaEcho==1)) {
2359 TempStr[TempLen++] = SI;
2360 }
2361 break;
2362 case IdSJIS:
2363 /* nothing to do */
2364 break;
2365 }
2366 break;
2367 case IdKorean:
2368 break;
2369 }
2370 TempStr[TempLen++] = HIBYTE(K);
2371 TempStr[TempLen++] = LOBYTE(K);
2372 }
2373 }
2374 else if (__isleadbyte_l(d, cv)) {
2375 KanjiFlagNew = TRUE;
2376 cv->EchoKanjiFirst = d;
2377 EchoCodeNew = IdKanji;
2378
2379 if (cv->Language == IdJapanese) {
2380 if ((cv->EchoCode!=IdKanji) && (cv->KanjiCodeEcho==IdJIS)) {
2381 TempStr[0] = 0x1B;
2382 TempStr[1] = '$';
2383 if (cv->KanjiIn == IdKanjiInB) {
2384 TempStr[2] = 'B';
2385 }
2386 else {
2387 TempStr[2] = '@';
2388 }
2389 TempLen = 3;
2390 }
2391 }
2392 }
2393 else {
2394 if (cv->Language == IdJapanese) {
2395 if ((cv->EchoCode==IdKanji) && (cv->KanjiCodeEcho==IdJIS)) {
2396 TempStr[0] = 0x1B;
2397 TempStr[1] = '(';
2398 switch (cv->KanjiOut) {
2399 case IdKanjiOutJ:
2400 TempStr[2] = 'J';
2401 break;
2402 case IdKanjiOutH:
2403 TempStr[2] = 'H';
2404 break;
2405 default:
2406 TempStr[2] = 'B';
2407 }
2408 TempLen = 3;
2409 }
2410
2411 if ((0xa0<d) && (d<0xe0)) {
2412 EchoCodeNew = IdKatakana;
2413 if ((cv->EchoCode!=IdKatakana) &&
2414 (cv->KanjiCodeEcho==IdJIS) &&
2415 (cv->JIS7KatakanaEcho==1)) {
2416 TempStr[TempLen++] = SO;
2417 }
2418 }
2419 else {
2420 EchoCodeNew = IdASCII;
2421 if ((cv->EchoCode==IdKatakana) &&
2422 (cv->KanjiCodeEcho==IdJIS) &&
2423 (cv->JIS7KatakanaEcho==1)) {
2424 TempStr[TempLen++] = SI;
2425 }
2426 }
2427 }
2428
2429 if (d==CR) {
2430 TempStr[TempLen++] = 0x0d;
2431 if (cv->CRSend==IdCRLF) {
2432 TempStr[TempLen++] = 0x0a;
2433 }
2434 else if ((cv->CRSend==IdCR) &&
2435 cv->TelFlag && ! cv->TelBinSend) {
2436 TempStr[TempLen++] = 0;
2437 }
2438 else if (cv->CRSend == IdLF) {
2439 TempStr[TempLen-1] = 0x0a;
2440 }
2441 }
2442 else if (d==0x15) { // Ctrl-U
2443 if (cv->TelLineMode) {
2444 // Move to top of line (CHA "\033[G") and erase line (EL "\033[K")
2445 strncpy_s(TempStr, sizeof(TempStr), "\033[G\033[K", _TRUNCATE);
2446 TempLen += 6;
2447 }
2448 else {
2449 TempStr[TempLen++] = d;
2450 }
2451 }
2452 else if ((d>=0x80) && (cv->KanjiCodeEcho==IdUTF8 || cv->Language==IdUtf8)) {
2453 TempLen += OutputTextUTF8((WORD)d, TempStr, cv);
2454 }
2455 else if ((d>=0xa1) && (d<=0xe0) && (cv->Language == IdJapanese)) {
2456 /* Katakana */
2457 if (cv->KanjiCodeEcho==IdEUC) {
2458 TempStr[TempLen++] = (char)SS2;
2459 }
2460 if ((cv->KanjiCodeEcho==IdJIS) &&
2461 (cv->JIS7KatakanaEcho==1)) {
2462 TempStr[TempLen++] = d & 0x7f;
2463 }
2464 else {
2465 TempStr[TempLen++] = d;
2466 }
2467 }
2468 else {
2469 TempStr[TempLen++] = d;
2470 if (cv->TelFlag && (d==0xff)) {
2471 TempStr[TempLen++] = (char)0xff;
2472 }
2473 }
2474 } // if (cv->EchoKanjiFlag) else if ... else ... end
2475
2476 if (WriteInBuff(cv, TempStr, TempLen)) {
2477 i++;
2478 cv->EchoCode = EchoCodeNew;
2479 cv->EchoKanjiFlag = KanjiFlagNew;
2480 } else {
2481 Full = FALSE;
2482 }
2483
2484 } // end of "while {}"
2485
2486 return i;
2487 }
2488
2489 int WINAPI CommTextEcho(PComVar cv, PCHAR B, int C)
2490 {
2491 int i, TempLen;
2492 char TempStr[11];
2493 BYTE d;
2494 BOOL Full;
2495
2496 if ( ! cv->Ready ) {
2497 return C;
2498 }
2499
2500 PackInBuff(cv);
2501
2502 switch (cv->Language) {
2503 case IdUtf8:
2504 case IdJapanese:
2505 case IdKorean:
2506 return TextEchoMBCS(cv,B,C);
2507 break;
2508 }
2509
2510 Full = FALSE;
2511 i = 0;
2512 while (! Full && (i < C)) {
2513 TempLen = 0;
2514 d = (BYTE)B[i];
2515
2516 switch (d) {
2517 case CR:
2518 TempStr[TempLen] = 0x0d;
2519 TempLen++;
2520 if (cv->CRSend==IdCRLF) {
2521 TempStr[TempLen++] = 0x0a;
2522 }
2523 else if (cv->CRSend==IdCR && cv->TelFlag && ! cv->TelBinSend) {
2524 TempStr[TempLen++] = 0;
2525 }
2526 else if (cv->CRSend == IdLF) {
2527 TempStr[TempLen-1] = 0x0a;
2528 }
2529 break;
2530
2531 case 0x15: // Ctrl-U
2532 if (cv->TelLineMode) {
2533 // Move to top of line (CHA "\033[G") and erase line (EL "\033[K")
2534 strncpy_s(TempStr, sizeof(TempStr), "\033[G\033[K", _TRUNCATE);
2535 TempLen += 6;
2536 }
2537 else {
2538 TempStr[TempLen++] = d;
2539 }
2540 break;
2541
2542 default:
2543 if ((cv->Language==IdRussian) && (d>=128)) {
2544 d = RussConv(cv->RussClient,cv->RussHost,d);
2545 }
2546 TempStr[TempLen++] = d;
2547 if (cv->TelFlag && (d==0xff)) {
2548 TempStr[TempLen++] = (char)0xff;
2549 }
2550 }
2551
2552 if(WriteInBuff(cv, TempStr,TempLen)) {
2553 i++;
2554 } else {
2555 Full = TRUE;
2556 }
2557 } // end of while {}
2558
2559 return i;
2560 }
2561
2562 /*
2563 * @return �G���[���L������ FALSE
2564 * @param[in] BOOL first_instance
2565 */
2566 static BOOL OpenSharedMemory(BOOL *first_instance_)
2567 {
2568 int i;
2569 HMap = NULL;
2570 pm = NULL;
2571 for (i = 0; i < 100; i++) {
2572 char tmp[32];
2573 HANDLE hMap;
2574 BOOL first_instance;
2575 TMap *map;
2576 _snprintf_s(tmp, sizeof(tmp), _TRUNCATE, i == 0 ? "%s" : "%s_%d", TT_FILEMAPNAME, i);
2577 hMap = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE,
2578 0, sizeof(TMap), tmp);
2579 if (hMap == NULL) {
2580 return FALSE;
2581 }
2582
2583 first_instance = (GetLastError() != ERROR_ALREADY_EXISTS);
2584
2585 map = (TMap *)MapViewOfFile(hMap,FILE_MAP_WRITE,0,0,0);
2586 if (map == NULL) {
2587 return FALSE;
2588 }
2589
2590 if (first_instance ||
2591 (map->size_tmap == sizeof(TMap) &&
2592 map->size_tttset == sizeof(TTTSet)))
2593 {
2594 map->size_tmap = sizeof(TMap);
2595 map->size_tttset = sizeof(TTTSet);
2596 HMap = hMap;
2597 pm = map;
2598 *first_instance_ = first_instance;
2599 return TRUE;
2600 }
2601
2602 // next try
2603 UnmapViewOfFile(map);
2604 CloseHandle(hMap);
2605 }
2606 return FALSE;
2607 }
2608
2609 BOOL WINAPI DllMain(HANDLE hInstance,
2610 ULONG ul_reason_for_call,
2611 LPVOID lpReserved)
2612 {
2613 switch( ul_reason_for_call ) {
2614 case DLL_THREAD_ATTACH:
2615 /* do thread initialization */
2616 break;
2617 case DLL_THREAD_DETACH:
2618 /* do thread cleanup */
2619 break;
2620 case DLL_PROCESS_ATTACH:
2621 /* do process initialization */
2622 hInst = hInstance;
2623 if (OpenSharedMemory(&FirstInstance) == FALSE) {
2624 // dll���[�h���s�Ateraterm���N��������
2625 return FALSE;
2626 }
2627 WinCompatInit();
2628 break;
2629 case DLL_PROCESS_DETACH:
2630 /* do process cleanup */
2631 UnmapViewOfFile(pm);
2632 CloseHandle(HMap);
2633 break;
2634 }
2635 return TRUE;
2636 }

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