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

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