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 9048 - (show annotations) (download) (as text)
Wed Dec 16 12:24:13 2020 UTC (3 years, 3 months ago) by nmaya
File MIME type: text/x-csrc
File size: 67985 byte(s)
ソースファイルの著作権表記の "最後の発行の年" を削除

ticket #40996
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 #ifndef _WIN32_IE
31 #define _WIN32_IE 0x501
32 #endif
33
34 /* TTCMN.DLL, main */
35 #include <direct.h>
36 #include <string.h>
37 #include <stdio.h>
38 #include <windows.h>
39 #include <tchar.h>
40 #include <setupapi.h>
41 #include <locale.h>
42 #include <htmlhelp.h>
43 #include <assert.h>
44 #include <crtdbg.h>
45
46 #define DllExport __declspec(dllexport)
47 #include "language.h"
48 #undef DllExport
49
50 #include "teraterm.h"
51 #include "tttypes.h"
52 #include "ttlib.h"
53 #include "compat_w95.h"
54 #include "tt_res.h"
55 #include "codeconv.h"
56 #include "compat_win.h"
57
58 #define DllExport __declspec(dllexport)
59 #include "ttcommon.h"
60 #include "layer_for_unicode.h"
61
62 /* shared memory */
63 typedef struct {
64 size_t size_tmap; /* sizeof TMap */
65 size_t size_tttset; /* sizeof TTTSet */
66 /* Setup information from "teraterm.ini" */
67 TTTSet ts;
68 /* Key code map from "keyboard.def" */
69 TKeyMap km;
70 // Window list
71 int NWin;
72 HWND WinList[MAXNWIN];
73 /* COM port use flag
74 * bit 8 7 6 5 4 3 2 1
75 * char[0] : COM 8 7 6 5 4 3 2 1
76 * char[1] : COM16 15 14 13 12 11 10 9 ...
77 */
78 unsigned char ComFlag[(MAXCOMPORT-1)/CHAR_BIT+1];
79 /* Previous window rect (Tera Term 4.78 or later) */
80 WINDOWPLACEMENT WinPrevRect[MAXNWIN];
81 BOOL WinUndoFlag;
82 int WinUndoStyle;
83 } TMap;
84 typedef TMap *PMap;
85
86 // TMap ���i�[�����t�@�C���}�b�s���O�I�u�W�F�N�g(���L������)�����O
87 // TMap(�����������o)���X�V�������o�[�W�������������N���������������K�v��������
88 // �A�������o�[�W�����������g�����������X�������A���������������X�����K�v������
89 #define TT_FILEMAPNAME "ttset_memfilemap_" TT_VERSION_STR("_")
90
91 /* first instance flag */
92 static BOOL FirstInstance = TRUE;
93
94 static HINSTANCE hInst;
95
96 static PMap pm;
97
98 static HANDLE HMap = NULL;
99 #define VTCLASSNAME _T("VTWin32")
100 #define TEKCLASSNAME _T("TEKWin32")
101
102 enum window_style {
103 WIN_CASCADE,
104 WIN_STACKED,
105 WIN_SIDEBYSIDE,
106 };
107
108
109 void WINAPI CopyShmemToTTSet(PTTSet ts)
110 {
111 // ���������������L�����������R�s�[����
112 memcpy(ts, &pm->ts, sizeof(TTTSet));
113 }
114
115 void WINAPI CopyTTSetToShmem(PTTSet ts)
116 {
117 // ���������������L���������R�s�[����
118 memcpy(&pm->ts, ts, sizeof(TTTSet));
119 }
120
121
122 BOOL WINAPI StartTeraTerm(PTTSet ts)
123 {
124 if (FirstInstance) {
125 // init window list
126 pm->NWin = 0;
127 }
128 else {
129 /* only the first instance uses saved position */
130 pm->ts.VTPos.x = CW_USEDEFAULT;
131 pm->ts.VTPos.y = CW_USEDEFAULT;
132 pm->ts.TEKPos.x = CW_USEDEFAULT;
133 pm->ts.TEKPos.y = CW_USEDEFAULT;
134 }
135
136 memcpy(ts,&(pm->ts),sizeof(TTTSet));
137
138 // if (FirstInstance) { �������������� (2008.3.13 maya)
139 // �N���������A���L�������� HomeDir �� SetupFName ����������
140 /* Get home directory */
141 GetHomeDir(hInst, ts->HomeDir, sizeof(ts->HomeDir));
142 _chdir(ts->HomeDir);
143 GetDefaultSetupFName(ts->HomeDir, ts->SetupFName, sizeof(ts->SetupFName));
144
145 strncpy_s(ts->KeyCnfFN, sizeof(ts->KeyCnfFN), ts->HomeDir, _TRUNCATE);
146 AppendSlash(ts->KeyCnfFN, sizeof(ts->KeyCnfFN));
147 strncat_s(ts->KeyCnfFN, sizeof(ts->KeyCnfFN), "KEYBOARD.CNF", _TRUNCATE);
148
149 if (FirstInstance) {
150 FirstInstance = FALSE;
151 return TRUE;
152 }
153 else {
154 return FALSE;
155 }
156 }
157
158 // �����t�@�C�����f�B�X�N���������ATera Term�{�������N�������B
159 // (2012.4.30 yutaka)
160 void WINAPI RestartTeraTerm(HWND hwnd, PTTSet ts)
161 {
162 char path[1024];
163 STARTUPINFO si;
164 PROCESS_INFORMATION pi;
165 int ret;
166
167 static const TTMessageBoxInfoW info = {
168 "Tera Term",
169 NULL, L"Tera Term: Configuration Warning",
170 "MSG_TT_TAKE_EFFECT",
171 L"This option takes effect the next time a session is started.\n"
172 L"Are you sure that you want to relaunch Tera Term?"
173 };
174 ret = TTMessageBoxW(hwnd, &info, MB_YESNO | MB_ICONEXCLAMATION | MB_DEFBUTTON2, ts->UILanguageFile);
175 if (ret != IDYES)
176 return;
177
178 SendMessage(hwnd, WM_COMMAND, ID_SETUP_SAVE, 0);
179 // ID_FILE_EXIT ���b�Z�[�W�����A�v�������������������������AWM_QUIT ���|�X�g�����B
180 //PostMessage(hwnd, WM_COMMAND, ID_FILE_EXIT, 0);
181 PostQuitMessage(0);
182
183 // ���v���Z�X�����N���B
184 if (GetModuleFileName(NULL, path, sizeof(path)) == 0) {
185 return;
186 }
187 memset(&si, 0, sizeof(si));
188 GetStartupInfo(&si);
189 memset(&pi, 0, sizeof(pi));
190 if (CreateProcess(NULL, path, NULL, NULL, FALSE, 0,
191 NULL, NULL, &si, &pi) == 0) {
192 }
193 }
194
195 void WINAPI ChangeDefaultSet(PTTSet ts, PKeyMap km)
196 {
197 if ((ts!=NULL) &&
198 (_stricmp(ts->SetupFName, pm->ts.SetupFName) == 0)) {
199 memcpy(&(pm->ts),ts,sizeof(TTTSet));
200 }
201 if (km!=NULL) {
202 memcpy(&(pm->km),km,sizeof(TKeyMap));
203 }
204 }
205
206 void WINAPI GetDefaultSet(PTTSet ts)
207 {
208 memcpy(ts,&(pm->ts),sizeof(TTTSet));
209 }
210
211
212 /* Key scan code -> Tera Term key code */
213 WORD WINAPI GetKeyCode(PKeyMap KeyMap, WORD Scan)
214 {
215 WORD Key;
216
217 if (KeyMap==NULL) {
218 KeyMap = &(pm->km);
219 }
220 Key = IdKeyMax;
221 while ((Key>0) && (KeyMap->Map[Key-1] != Scan)) {
222 Key--;
223 }
224 return Key;
225 }
226
227 void WINAPI GetKeyStr(HWND HWin, PKeyMap KeyMap, WORD KeyCode,
228 BOOL AppliKeyMode, BOOL AppliCursorMode,
229 BOOL Send8BitMode, PCHAR KeyStr, int destlen,
230 LPINT Len, LPWORD Type)
231 {
232 MSG Msg;
233 char Temp[201];
234
235 if (KeyMap==NULL) {
236 KeyMap = &(pm->km);
237 }
238
239 *Type = IdBinary; // key type
240 *Len = 0;
241 switch (KeyCode) {
242 case IdUp:
243 if (Send8BitMode) {
244 *Len = 2;
245 if (AppliCursorMode)
246 strncpy_s(KeyStr,destlen,"\217A",_TRUNCATE);
247 else
248 strncpy_s(KeyStr,destlen,"\233A",_TRUNCATE);
249 } else {
250 *Len = 3;
251 if (AppliCursorMode)
252 strncpy_s(KeyStr,destlen,"\033OA",_TRUNCATE);
253 else
254 strncpy_s(KeyStr,destlen,"\033[A",_TRUNCATE);
255 }
256 break;
257 case IdDown:
258 if (Send8BitMode) {
259 *Len = 2;
260 if (AppliCursorMode)
261 strncpy_s(KeyStr,destlen,"\217B",_TRUNCATE);
262 else
263 strncpy_s(KeyStr,destlen,"\233B",_TRUNCATE);
264 } else {
265 *Len = 3;
266 if (AppliCursorMode)
267 strncpy_s(KeyStr,destlen,"\033OB",_TRUNCATE);
268 else
269 strncpy_s(KeyStr,destlen,"\033[B",_TRUNCATE);
270 }
271 break;
272 case IdRight:
273 if (Send8BitMode) {
274 *Len = 2;
275 if (AppliCursorMode)
276 strncpy_s(KeyStr,destlen,"\217C",_TRUNCATE);
277 else
278 strncpy_s(KeyStr,destlen,"\233C",_TRUNCATE);
279 } else {
280 *Len = 3;
281 if (AppliCursorMode)
282 strncpy_s(KeyStr,destlen,"\033OC",_TRUNCATE);
283 else
284 strncpy_s(KeyStr,destlen,"\033[C",_TRUNCATE);
285 }
286 break;
287 case IdLeft:
288 if (Send8BitMode) {
289 *Len = 2;
290 if (AppliCursorMode)
291 strncpy_s(KeyStr,destlen,"\217D",_TRUNCATE);
292 else
293 strncpy_s(KeyStr,destlen,"\233D",_TRUNCATE);
294 } else {
295 *Len = 3;
296 if (AppliCursorMode)
297 strncpy_s(KeyStr,destlen,"\033OD",_TRUNCATE);
298 else
299 strncpy_s(KeyStr,destlen,"\033[D",_TRUNCATE);
300 }
301 break;
302 case Id0:
303 if (AppliKeyMode) {
304 if (Send8BitMode) {
305 *Len = 2;
306 strncpy_s(KeyStr,destlen,"\217p",_TRUNCATE);
307 } else {
308 *Len = 3;
309 strncpy_s(KeyStr,destlen,"\033Op",_TRUNCATE);
310 }
311 }
312 else {
313 *Len = 1;
314 KeyStr[0] = '0';
315 }
316 break;
317 case Id1:
318 if (AppliKeyMode) {
319 if (Send8BitMode) {
320 *Len = 2;
321 strncpy_s(KeyStr,destlen,"\217q",_TRUNCATE);
322 } else {
323 *Len = 3;
324 strncpy_s(KeyStr,destlen,"\033Oq",_TRUNCATE);
325 }
326 }
327 else {
328 *Len = 1;
329 KeyStr[0] = '1';
330 }
331 break;
332 case Id2:
333 if (AppliKeyMode) {
334 if (Send8BitMode) {
335 *Len = 2;
336 strncpy_s(KeyStr,destlen,"\217r",_TRUNCATE);
337 } else {
338 *Len = 3;
339 strncpy_s(KeyStr,destlen,"\033Or",_TRUNCATE);
340 }
341 }
342 else {
343 *Len = 1;
344 KeyStr[0] = '2';
345 }
346 break;
347 case Id3:
348 if (AppliKeyMode) {
349 if (Send8BitMode) {
350 *Len = 2;
351 strncpy_s(KeyStr,destlen,"\217s",_TRUNCATE);
352 } else {
353 *Len = 3;
354 strncpy_s(KeyStr,destlen,"\033Os",_TRUNCATE);
355 }
356 }
357 else {
358 *Len = 1;
359 KeyStr[0] = '3';
360 }
361 break;
362 case Id4:
363 if (AppliKeyMode) {
364 if (Send8BitMode) {
365 *Len = 2;
366 strncpy_s(KeyStr,destlen,"\217t",_TRUNCATE);
367 } else {
368 *Len = 3;
369 strncpy_s(KeyStr,destlen,"\033Ot",_TRUNCATE);
370 }
371 }
372 else {
373 *Len = 1;
374 KeyStr[0] = '4';
375 }
376 break;
377 case Id5:
378 if (AppliKeyMode) {
379 if (Send8BitMode) {
380 *Len = 2;
381 strncpy_s(KeyStr,destlen,"\217u",_TRUNCATE);
382 } else {
383 *Len = 3;
384 strncpy_s(KeyStr,destlen,"\033Ou",_TRUNCATE);
385 }
386 }
387 else {
388 *Len = 1;
389 KeyStr[0] = '5';
390 }
391 break;
392 case Id6:
393 if (AppliKeyMode) {
394 if (Send8BitMode) {
395 *Len = 2;
396 strncpy_s(KeyStr,destlen,"\217v",_TRUNCATE);
397 } else {
398 *Len = 3;
399 strncpy_s(KeyStr,destlen,"\033Ov",_TRUNCATE);
400 }
401 }
402 else {
403 *Len = 1;
404 KeyStr[0] = '6';
405 }
406 break;
407 case Id7:
408 if (AppliKeyMode) {
409 if (Send8BitMode) {
410 *Len = 2;
411 strncpy_s(KeyStr,destlen,"\217w",_TRUNCATE);
412 } else {
413 *Len = 3;
414 strncpy_s(KeyStr,destlen,"\033Ow",_TRUNCATE);
415 }
416 }
417 else {
418 *Len = 1;
419 KeyStr[0] = '7';
420 }
421 break;
422 case Id8:
423 if (AppliKeyMode) {
424 if (Send8BitMode) {
425 *Len = 2;
426 strncpy_s(KeyStr,destlen,"\217x",_TRUNCATE);
427 } else {
428 *Len = 3;
429 strncpy_s(KeyStr,destlen,"\033Ox",_TRUNCATE);
430 }
431 }
432 else {
433 *Len = 1;
434 KeyStr[0] = '8';
435 }
436 break;
437 case Id9:
438 if (AppliKeyMode) {
439 if (Send8BitMode) {
440 *Len = 2;
441 strncpy_s(KeyStr,destlen,"\217y",_TRUNCATE);
442 } else {
443 *Len = 3;
444 strncpy_s(KeyStr,destlen,"\033Oy",_TRUNCATE);
445 }
446 }
447 else {
448 *Len = 1;
449 KeyStr[0] = '9';
450 }
451 break;
452 case IdMinus: /* numeric pad - key (DEC) */
453 if (AppliKeyMode) {
454 if (Send8BitMode) {
455 *Len = 2;
456 strncpy_s(KeyStr,destlen,"\217m",_TRUNCATE);
457 } else {
458 *Len = 3;
459 strncpy_s(KeyStr,destlen,"\033Om",_TRUNCATE);
460 }
461 }
462 else {
463 *Len = 1;
464 KeyStr[0] = '-';
465 }
466 break;
467 case IdComma: /* numeric pad , key (DEC) */
468 if (AppliKeyMode) {
469 if (Send8BitMode) {
470 *Len = 2;
471 strncpy_s(KeyStr,destlen,"\217l",_TRUNCATE);
472 } else {
473 *Len = 3;
474 strncpy_s(KeyStr,destlen,"\033Ol",_TRUNCATE);
475 }
476 }
477 else {
478 *Len = 1;
479 KeyStr[0] = ',';
480 }
481 break;
482 case IdPeriod: /* numeric pad . key */
483 if (AppliKeyMode) {
484 if (Send8BitMode) {
485 *Len = 2;
486 strncpy_s(KeyStr,destlen,"\217n",_TRUNCATE);
487 } else {
488 *Len = 3;
489 strncpy_s(KeyStr,destlen,"\033On",_TRUNCATE);
490 }
491 }
492 else {
493 *Len = 1;
494 KeyStr[0] = '.';
495 }
496 break;
497 case IdEnter: /* numeric pad enter key */
498 if (AppliKeyMode) {
499 if (Send8BitMode) {
500 *Len = 2;
501 strncpy_s(KeyStr,destlen,"\217M",_TRUNCATE);
502 } else {
503 *Len = 3;
504 strncpy_s(KeyStr,destlen,"\033OM",_TRUNCATE);
505 }
506 }
507 else {
508 *Type = IdText; // do new-line conversion
509 *Len = 1;
510 KeyStr[0] = 0x0D;
511 }
512 break;
513 case IdSlash: /* numeric pad slash key */
514 if (AppliKeyMode) {
515 if (Send8BitMode) {
516 *Len = 2;
517 strncpy_s(KeyStr,destlen,"\217o",_TRUNCATE);
518 } else {
519 *Len = 3;
520 strncpy_s(KeyStr,destlen,"\033Oo",_TRUNCATE);
521 }
522 }
523 else {
524 *Len = 1;
525 KeyStr[0] = '/';
526 }
527 break;
528 case IdAsterisk: /* numeric pad asterisk key */
529 if (AppliKeyMode) {
530 if (Send8BitMode) {
531 *Len = 2;
532 strncpy_s(KeyStr,destlen,"\217j",_TRUNCATE);
533 } else {
534 *Len = 3;
535 strncpy_s(KeyStr,destlen,"\033Oj",_TRUNCATE);
536 }
537 }
538 else {
539 *Len = 1;
540 KeyStr[0] = '*';
541 }
542 break;
543 case IdPlus: /* numeric pad plus key */
544 if (AppliKeyMode) {
545 if (Send8BitMode) {
546 *Len = 2;
547 strncpy_s(KeyStr,destlen,"\217k",_TRUNCATE);
548 } else {
549 *Len = 3;
550 strncpy_s(KeyStr,destlen,"\033Ok",_TRUNCATE);
551 }
552 }
553 else {
554 *Len = 1;
555 KeyStr[0] = '+';
556 }
557 break;
558 case IdPF1: /* DEC Key: PF1 */
559 if (Send8BitMode) {
560 *Len = 2;
561 strncpy_s(KeyStr,destlen,"\217P",_TRUNCATE);
562 } else {
563 *Len = 3;
564 strncpy_s(KeyStr,destlen,"\033OP",_TRUNCATE);
565 }
566 break;
567 case IdPF2: /* DEC Key: PF2 */
568 if (Send8BitMode) {
569 *Len = 2;
570 strncpy_s(KeyStr,destlen,"\217Q",_TRUNCATE);
571 } else {
572 *Len = 3;
573 strncpy_s(KeyStr,destlen,"\033OQ",_TRUNCATE);
574 }
575 break;
576 case IdPF3: /* DEC Key: PF3 */
577 if (Send8BitMode) {
578 *Len = 2;
579 strncpy_s(KeyStr,destlen,"\217R",_TRUNCATE);
580 } else {
581 *Len = 3;
582 strncpy_s(KeyStr,destlen,"\033OR",_TRUNCATE);
583 }
584 break;
585 case IdPF4: /* DEC Key: PF4 */
586 if (Send8BitMode) {
587 *Len = 2;
588 strncpy_s(KeyStr,destlen,"\217S",_TRUNCATE);
589 } else {
590 *Len = 3;
591 strncpy_s(KeyStr,destlen,"\033OS",_TRUNCATE);
592 }
593 break;
594 case IdFind: /* DEC Key: Find */
595 if (Send8BitMode) {
596 *Len = 3;
597 strncpy_s(KeyStr,destlen,"\2331~",_TRUNCATE);
598 } else {
599 *Len = 4;
600 strncpy_s(KeyStr,destlen,"\033[1~",_TRUNCATE);
601 }
602 break;
603 case IdInsert: /* DEC Key: Insert Here */
604 if (Send8BitMode) {
605 *Len = 3;
606 strncpy_s(KeyStr,destlen,"\2332~",_TRUNCATE);
607 } else {
608 *Len = 4;
609 strncpy_s(KeyStr,destlen,"\033[2~",_TRUNCATE);
610 }
611 break;
612 case IdRemove: /* DEC Key: Remove */
613 if (Send8BitMode) {
614 *Len = 3;
615 strncpy_s(KeyStr,destlen,"\2333~",_TRUNCATE);
616 } else {
617 *Len = 4;
618 strncpy_s(KeyStr,destlen,"\033[3~",_TRUNCATE);
619 }
620 break;
621 case IdSelect: /* DEC Key: Select */
622 if (Send8BitMode) {
623 *Len = 3;
624 strncpy_s(KeyStr,destlen,"\2334~",_TRUNCATE);
625 } else {
626 *Len = 4;
627 strncpy_s(KeyStr,destlen,"\033[4~",_TRUNCATE);
628 }
629 break;
630 case IdPrev: /* DEC Key: Prev */
631 if (Send8BitMode) {
632 *Len = 3;
633 strncpy_s(KeyStr,destlen,"\2335~",_TRUNCATE);
634 } else {
635 *Len = 4;
636 strncpy_s(KeyStr,destlen,"\033[5~",_TRUNCATE);
637 }
638 break;
639 case IdNext: /* DEC Key: Next */
640 if (Send8BitMode) {
641 *Len = 3;
642 strncpy_s(KeyStr,destlen,"\2336~",_TRUNCATE);
643 } else {
644 *Len = 4;
645 strncpy_s(KeyStr,destlen,"\033[6~",_TRUNCATE);
646 }
647 break;
648 case IdF6: /* DEC Key: F6 */
649 if (Send8BitMode) {
650 *Len = 4;
651 strncpy_s(KeyStr,destlen,"\23317~",_TRUNCATE);
652 } else {
653 *Len = 5;
654 strncpy_s(KeyStr,destlen,"\033[17~",_TRUNCATE);
655 }
656 break;
657 case IdF7: /* DEC Key: F7 */
658 if (Send8BitMode) {
659 *Len = 4;
660 strncpy_s(KeyStr,destlen,"\23318~",_TRUNCATE);
661 } else {
662 *Len = 5;
663 strncpy_s(KeyStr,destlen,"\033[18~",_TRUNCATE);
664 }
665 break;
666 case IdF8: /* DEC Key: F8 */
667 if (Send8BitMode) {
668 *Len = 4;
669 strncpy_s(KeyStr,destlen,"\23319~",_TRUNCATE);
670 } else {
671 *Len = 5;
672 strncpy_s(KeyStr,destlen,"\033[19~",_TRUNCATE);
673 }
674 break;
675 case IdF9: /* DEC Key: F9 */
676 if (Send8BitMode) {
677 *Len = 4;
678 strncpy_s(KeyStr,destlen,"\23320~",_TRUNCATE);
679 } else {
680 *Len = 5;
681 strncpy_s(KeyStr,destlen,"\033[20~",_TRUNCATE);
682 }
683 break;
684 case IdF10: /* DEC Key: F10 */
685 if (Send8BitMode) {
686 *Len = 4;
687 strncpy_s(KeyStr,destlen,"\23321~",_TRUNCATE);
688 } else {
689 *Len = 5;
690 strncpy_s(KeyStr,destlen,"\033[21~",_TRUNCATE);
691 }
692 break;
693 case IdF11: /* DEC Key: F11 */
694 if (Send8BitMode) {
695 *Len = 4;
696 strncpy_s(KeyStr,destlen,"\23323~",_TRUNCATE);
697 } else {
698 *Len = 5;
699 strncpy_s(KeyStr,destlen,"\033[23~",_TRUNCATE);
700 }
701 break;
702 case IdF12: /* DEC Key: F12 */
703 if (Send8BitMode) {
704 *Len = 4;
705 strncpy_s(KeyStr,destlen,"\23324~",_TRUNCATE);
706 } else {
707 *Len = 5;
708 strncpy_s(KeyStr,destlen,"\033[24~",_TRUNCATE);
709 }
710 break;
711 case IdF13: /* DEC Key: F13 */
712 if (Send8BitMode) {
713 *Len = 4;
714 strncpy_s(KeyStr,destlen,"\23325~",_TRUNCATE);
715 } else {
716 *Len = 5;
717 strncpy_s(KeyStr,destlen,"\033[25~",_TRUNCATE);
718 }
719 break;
720 case IdF14: /* DEC Key: F14 */
721 if (Send8BitMode) {
722 *Len = 4;
723 strncpy_s(KeyStr,destlen,"\23326~",_TRUNCATE);
724 } else {
725 *Len = 5;
726 strncpy_s(KeyStr,destlen,"\033[26~",_TRUNCATE);
727 }
728 break;
729 case IdHelp: /* DEC Key: Help */
730 if (Send8BitMode) {
731 *Len = 4;
732 strncpy_s(KeyStr,destlen,"\23328~",_TRUNCATE);
733 } else {
734 *Len = 5;
735 strncpy_s(KeyStr,destlen,"\033[28~",_TRUNCATE);
736 }
737 break;
738 case IdDo: /* DEC Key: Do */
739 if (Send8BitMode) {
740 *Len = 4;
741 strncpy_s(KeyStr,destlen,"\23329~",_TRUNCATE);
742 } else {
743 *Len = 5;
744 strncpy_s(KeyStr,destlen,"\033[29~",_TRUNCATE);
745 }
746 break;
747 case IdF17: /* DEC Key: F17 */
748 if (Send8BitMode) {
749 *Len = 4;
750 strncpy_s(KeyStr,destlen,"\23331~",_TRUNCATE);
751 } else {
752 *Len = 5;
753 strncpy_s(KeyStr,destlen,"\033[31~",_TRUNCATE);
754 }
755 break;
756 case IdF18: /* DEC Key: F18 */
757 if (Send8BitMode) {
758 *Len = 4;
759 strncpy_s(KeyStr,destlen,"\23332~",_TRUNCATE);
760 } else {
761 *Len = 5;
762 strncpy_s(KeyStr,destlen,"\033[32~",_TRUNCATE);
763 }
764 break;
765 case IdF19: /* DEC Key: F19 */
766 if (Send8BitMode) {
767 *Len = 4;
768 strncpy_s(KeyStr,destlen,"\23333~",_TRUNCATE);
769 } else {
770 *Len = 5;
771 strncpy_s(KeyStr,destlen,"\033[33~",_TRUNCATE);
772 }
773 break;
774 case IdF20: /* DEC Key: F20 */
775 if (Send8BitMode) {
776 *Len = 4;
777 strncpy_s(KeyStr,destlen,"\23334~",_TRUNCATE);
778 } else {
779 *Len = 5;
780 strncpy_s(KeyStr,destlen,"\033[34~",_TRUNCATE);
781 }
782 break;
783 case IdXF1: /* XTERM F1 */
784 if (Send8BitMode) {
785 *Len = 4;
786 strncpy_s(KeyStr,destlen,"\23311~",_TRUNCATE);
787 } else {
788 *Len = 5;
789 strncpy_s(KeyStr,destlen,"\033[11~",_TRUNCATE);
790 }
791 break;
792 case IdXF2: /* XTERM F2 */
793 if (Send8BitMode) {
794 *Len = 4;
795 strncpy_s(KeyStr,destlen,"\23312~",_TRUNCATE);
796 } else {
797 *Len = 5;
798 strncpy_s(KeyStr,destlen,"\033[12~",_TRUNCATE);
799 }
800 break;
801 case IdXF3: /* XTERM F3 */
802 if (Send8BitMode) {
803 *Len = 4;
804 strncpy_s(KeyStr,destlen,"\23313~",_TRUNCATE);
805 } else {
806 *Len = 5;
807 strncpy_s(KeyStr,destlen,"\033[13~",_TRUNCATE);
808 }
809 break;
810 case IdXF4: /* XTERM F4 */
811 if (Send8BitMode) {
812 *Len = 4;
813 strncpy_s(KeyStr,destlen,"\23314~",_TRUNCATE);
814 } else {
815 *Len = 5;
816 strncpy_s(KeyStr,destlen,"\033[14~",_TRUNCATE);
817 }
818 break;
819 case IdXF5: /* XTERM F5 */
820 if (Send8BitMode) {
821 *Len = 4;
822 strncpy_s(KeyStr,destlen,"\23315~",_TRUNCATE);
823 } else {
824 *Len = 5;
825 strncpy_s(KeyStr,destlen,"\033[15~",_TRUNCATE);
826 }
827 break;
828 case IdXBackTab: /* XTERM Back Tab */
829 if (Send8BitMode) {
830 *Len = 2;
831 strncpy_s(KeyStr,destlen,"\233Z",_TRUNCATE);
832 } else {
833 *Len = 3;
834 strncpy_s(KeyStr,destlen,"\033[Z",_TRUNCATE);
835 }
836 break;
837 case IdHold:
838 case IdPrint:
839 case IdBreak:
840 case IdCmdEditCopy:
841 case IdCmdEditPaste:
842 case IdCmdEditPasteCR:
843 case IdCmdEditCLS:
844 case IdCmdEditCLB:
845 case IdCmdCtrlOpenTEK:
846 case IdCmdCtrlCloseTEK:
847 case IdCmdLineUp:
848 case IdCmdLineDown:
849 case IdCmdPageUp:
850 case IdCmdPageDown:
851 case IdCmdBuffTop:
852 case IdCmdBuffBottom:
853 case IdCmdNextWin:
854 case IdCmdPrevWin:
855 case IdCmdNextSWin:
856 case IdCmdPrevSWin:
857 case IdCmdLocalEcho:
858 case IdCmdScrollLock:
859 PostMessage(HWin,WM_USER_ACCELCOMMAND,KeyCode,0);
860 break;
861 default:
862 if ((KeyCode >= IdUser1) && (KeyCode <= IdKeyMax)) {
863 *Type = (WORD)(*KeyMap).UserKeyType[KeyCode-IdUser1]; // key type
864 *Len = KeyMap->UserKeyLen[KeyCode-IdUser1];
865 memcpy(Temp,
866 &KeyMap->UserKeyStr[KeyMap->UserKeyPtr[KeyCode-IdUser1]],
867 *Len);
868 Temp[*Len] = 0;
869 if ((*Type==IdBinary) || (*Type==IdText))
870 *Len = Hex2Str(Temp,KeyStr,destlen);
871 else
872 strncpy_s(KeyStr,destlen,Temp,_TRUNCATE);
873 }
874 else
875 return;
876 }
877 /* remove WM_CHAR message for used keycode */
878 PeekMessage(&Msg,HWin, WM_CHAR, WM_CHAR,PM_REMOVE);
879 }
880
881 void WINAPI SetCOMFlag(int Com)
882 {
883 pm->ComFlag[(Com-1)/CHAR_BIT] |= 1 << ((Com-1)%CHAR_BIT);
884 }
885
886 void WINAPI ClearCOMFlag(int Com)
887 {
888 pm->ComFlag[(Com-1)/CHAR_BIT] &= ~(1 << ((Com-1)%CHAR_BIT));
889 }
890
891 int WINAPI CheckCOMFlag(int Com)
892 {
893 return ((pm->ComFlag[(Com-1)/CHAR_BIT] & 1 << (Com-1)%CHAR_BIT) > 0);
894 }
895
896 int WINAPI RegWin(HWND HWinVT, HWND HWinTEK)
897 {
898 int i, j;
899
900 if (pm->NWin>=MAXNWIN)
901 return 0;
902 if (HWinVT==NULL)
903 return 0;
904 if (HWinTEK!=NULL) {
905 i = 0;
906 while ((i<pm->NWin) && (pm->WinList[i]!=HWinVT))
907 i++;
908 if (i>=pm->NWin)
909 return 0;
910 for (j=pm->NWin-1 ; j>i ; j--)
911 pm->WinList[j+1] = pm->WinList[j];
912 pm->WinList[i+1] = HWinTEK;
913 pm->NWin++;
914 return 0;
915 }
916 pm->WinList[pm->NWin++] = HWinVT;
917 memset(&pm->WinPrevRect[pm->NWin - 1], 0, sizeof(pm->WinPrevRect[pm->NWin - 1])); // RECT clear
918 if (pm->NWin==1) {
919 return 1;
920 }
921 else {
922 return (int)(SendMessage(pm->WinList[pm->NWin-2],
923 WM_USER_GETSERIALNO,0,0)+1);
924 }
925 }
926
927 void WINAPI UnregWin(HWND HWin)
928 {
929 int i, j;
930
931 i = 0;
932 while ((i<pm->NWin) && (pm->WinList[i]!=HWin)) {
933 i++;
934 }
935 if (pm->WinList[i]!=HWin) {
936 return;
937 }
938 for (j=i ; j<pm->NWin-1 ; j++) {
939 pm->WinList[j] = pm->WinList[j+1];
940 pm->WinPrevRect[j] = pm->WinPrevRect[j+1]; // RECT shift
941 }
942 if (pm->NWin>0) {
943 pm->NWin--;
944 }
945 }
946
947 char GetWindowTypeChar(HWND Hw, HWND HWin)
948 {
949 #if 0
950 if (HWin == Hw)
951 return '*';
952 else if (!IsWindowVisible(Hw))
953 #else
954 if (!IsWindowVisible(Hw))
955 #endif
956 return '#';
957 else if (IsIconic(Hw))
958 return '-';
959 else if (IsZoomed(Hw))
960 return '@';
961 else
962 return '+';
963 }
964
965 void WINAPI SetWinMenu(HMENU menu, PCHAR buf, int buflen, PCHAR langFile, int VTFlag)
966 {
967 int i;
968 char Temp[MAXPATHLEN];
969 HWND Hw;
970 wchar_t uimsg[MAX_UIMSG];
971
972 // delete all items in Window menu
973 i = GetMenuItemCount(menu);
974 if (i>0)
975 do {
976 i--;
977 RemoveMenu(menu,i,MF_BYPOSITION);
978 } while (i>0);
979
980 i = 0;
981 while (i<pm->NWin) {
982 Hw = pm->WinList[i]; // get window handle
983 if ((GetClassName(Hw,Temp,sizeof(Temp))>0) &&
984 ((strcmp(Temp,VTCLASSNAME)==0) ||
985 (strcmp(Temp,TEKCLASSNAME)==0))) {
986 Temp[0] = '&';
987 Temp[1] = (char)(0x31 + i);
988 Temp[2] = ' ';
989 Temp[3] = GetWindowTypeChar(Hw, NULL);
990 Temp[4] = ' ';
991 GetWindowText(Hw,&Temp[5],sizeof(Temp)-6);
992 AppendMenu(menu,MF_ENABLED | MF_STRING,ID_WINDOW_1+i,Temp);
993 i++;
994 if (i>8) {
995 i = pm->NWin;
996 }
997 }
998 else {
999 UnregWin(Hw);
1000 }
1001 }
1002 if (VTFlag == 1) {
1003 static const DlgTextInfo MenuTextInfo[] = {
1004 { ID_WINDOW_WINDOW, "MENU_WINDOW_WINDOW" },
1005 { ID_WINDOW_MINIMIZEALL, "MENU_WINDOW_MINIMIZEALL" },
1006 { ID_WINDOW_RESTOREALL, "MENU_WINDOW_RESTOREALL" },
1007 { ID_WINDOW_CASCADEALL, "MENU_WINDOW_CASCADE" },
1008 { ID_WINDOW_STACKED, "MENU_WINDOW_STACKED" },
1009 { ID_WINDOW_SIDEBYSIDE, "MENU_WINDOW_SIDEBYSIDE" },
1010 };
1011
1012 AppendMenu(menu, MF_SEPARATOR, 0, NULL);
1013 AppendMenu(menu, MF_ENABLED | MF_STRING, ID_WINDOW_WINDOW, "&Window");
1014 AppendMenu(menu, MF_ENABLED | MF_STRING, ID_WINDOW_MINIMIZEALL, "&Minimize All");
1015 AppendMenu(menu, MF_ENABLED | MF_STRING, ID_WINDOW_RESTOREALL, "&Restore All");
1016 AppendMenu(menu, MF_ENABLED | MF_STRING, ID_WINDOW_CASCADEALL, "&Cascade");
1017 AppendMenu(menu, MF_ENABLED | MF_STRING, ID_WINDOW_STACKED, "&Stacked");
1018 AppendMenu(menu, MF_ENABLED | MF_STRING, ID_WINDOW_SIDEBYSIDE, "Side &by Side");
1019
1020 SetI18nMenuStrs("Tera Term", menu, MenuTextInfo, _countof(MenuTextInfo), langFile);
1021
1022 if (pm->WinUndoFlag) {
1023 if (pm->WinUndoStyle == WIN_CASCADE)
1024 get_lang_msgW("MENU_WINDOW_CASCADE_UNDO", uimsg, _countof(uimsg), L"&Undo - Cascade", langFile);
1025 else if (pm->WinUndoStyle == WIN_STACKED)
1026 get_lang_msgW("MENU_WINDOW_STACKED_UNDO", uimsg, _countof(uimsg), L"&Undo - Stacked", langFile);
1027 else
1028 get_lang_msgW("MENU_WINDOW_SIDEBYSIDE_UNDO", uimsg, _countof(uimsg), L"&Undo - Side by Side", langFile);
1029 _AppendMenuW(menu, MF_ENABLED | MF_STRING, ID_WINDOW_UNDO, uimsg); // TODO UNICODE
1030 }
1031
1032 }
1033 else {
1034 get_lang_msgW("MENU_WINDOW_WINDOW", uimsg, _countof(uimsg), L"&Window", langFile);
1035 _AppendMenuW(menu,MF_ENABLED | MF_STRING,ID_TEKWINDOW_WINDOW, uimsg);
1036 }
1037 }
1038
1039 void WINAPI SetWinList(HWND HWin, HWND HDlg, int IList)
1040 {
1041 int i;
1042 char Temp[MAXPATHLEN];
1043 HWND Hw;
1044
1045 for (i=0; i<pm->NWin; i++) {
1046 Hw = pm->WinList[i]; // get window handle
1047 if ((GetClassName(Hw,Temp,sizeof(Temp))>0) &&
1048 ((strcmp(Temp,VTCLASSNAME)==0) ||
1049 (strcmp(Temp,TEKCLASSNAME)==0))) {
1050 Temp[0] = GetWindowTypeChar(Hw, HWin);
1051 Temp[1] = ' ';
1052 GetWindowText(Hw,&Temp[2],sizeof(Temp)-3);
1053 SendDlgItemMessage(HDlg, IList, LB_ADDSTRING,
1054 0, (LPARAM)Temp);
1055 if (Hw==HWin) {
1056 SendDlgItemMessage(HDlg, IList, LB_SETCURSEL, i,0);
1057 }
1058 }
1059 else {
1060 UnregWin(Hw);
1061 }
1062 }
1063 }
1064
1065 void WINAPI SelectWin(int WinId)
1066 {
1067 if ((WinId>=0) && (WinId<pm->NWin)) {
1068 /* �E�B���h�E�����������������������������������A���������������������������A
1069 * SW_SHOWNORMAL ���� SW_SHOW �����X�����B
1070 * (2009.11.8 yutaka)
1071 * �E�B���h�E�����������������������������T�C�Y������(SW_RESTORE)�����������B
1072 * (2009.11.9 maya)
1073 */
1074 if (IsIconic(pm->WinList[WinId])) {
1075 ShowWindow(pm->WinList[WinId],SW_RESTORE);
1076 }
1077 else {
1078 ShowWindow(pm->WinList[WinId],SW_SHOW);
1079 }
1080 SetForegroundWindow(pm->WinList[WinId]);
1081 }
1082 }
1083
1084 void WINAPI SelectNextWin(HWND HWin, int Next, BOOL SkipIconic)
1085 {
1086 int i;
1087
1088 i = 0;
1089 while ((i < pm->NWin) && (pm->WinList[i]!=HWin)) {
1090 i++;
1091 }
1092 if (pm->WinList[i]!=HWin) {
1093 return;
1094 }
1095
1096 do {
1097 i += Next;
1098 if (i >= pm->NWin) {
1099 i = 0;
1100 }
1101 else if (i < 0) {
1102 i = pm->NWin-1;
1103 }
1104
1105 if (pm->WinList[i] == HWin) {
1106 break;
1107 }
1108 } while ((SkipIconic && IsIconic(pm->WinList[i])) || !IsWindowVisible(pm->WinList[i]));
1109
1110 SelectWin(i);
1111 }
1112
1113 void WINAPI ShowAllWin(int stat) {
1114 int i;
1115
1116 for (i=0; i < pm->NWin; i++) {
1117 ShowWindow(pm->WinList[i], stat);
1118 }
1119 }
1120
1121 void WINAPI UndoAllWin(void) {
1122 int i;
1123 WINDOWPLACEMENT rc0;
1124 RECT rc;
1125 int stat = SW_RESTORE;
1126 int multi_mon = 0;
1127
1128 if (HasMultiMonitorSupport()) {
1129 multi_mon = 1;
1130 }
1131
1132 // ���x�A�����������t���O���������B
1133 pm->WinUndoFlag = FALSE;
1134
1135 memset(&rc0, 0, sizeof(rc0));
1136
1137 for (i=0; i < pm->NWin; i++) {
1138 // �����w�����A�O�����������c���������������A�E�B���h�E�����������������B
1139 if (stat == SW_RESTORE && memcmp(&pm->WinPrevRect[i], &rc0, sizeof(rc0)) != 0) {
1140 rc = pm->WinPrevRect[i].rcNormalPosition;
1141
1142 // NT4.0, 95 ���}���`���j�^API��������
1143 if (multi_mon) {
1144 // �������j�^������������
1145 HMONITOR hMonitor;
1146 MONITORINFO mi;
1147 hMonitor = pMonitorFromRect(&rc, MONITOR_DEFAULTTONEAREST);
1148 mi.cbSize = sizeof(MONITORINFO);
1149 pGetMonitorInfoA(hMonitor, &mi);
1150
1151 // ���u�����i�����O���������x���������������������������j
1152 if (rc.right > mi.rcMonitor.right) {
1153 rc.left -= rc.right - mi.rcMonitor.right;
1154 rc.right = mi.rcMonitor.right;
1155 }
1156 if (rc.left < mi.rcMonitor.left) {
1157 rc.right += mi.rcMonitor.left - rc.left;
1158 rc.left = mi.rcMonitor.left;
1159 }
1160 if (rc.bottom > mi.rcMonitor.bottom) {
1161 rc.top -= rc.bottom - mi.rcMonitor.bottom;
1162 rc.bottom = mi.rcMonitor.bottom;
1163 }
1164 if (rc.top < mi.rcMonitor.top) {
1165 rc.bottom += mi.rcMonitor.top - rc.top;
1166 rc.top = mi.rcMonitor.top;
1167 }
1168 }
1169
1170 // �E�B���h�E���u����
1171 SetWindowPos(
1172 pm->WinList[i], NULL,
1173 rc.left,
1174 rc.top,
1175 rc.right - rc.left,
1176 rc.bottom - rc.top,
1177 SWP_NOZORDER);
1178
1179 // �E�B���h�E����������
1180 ShowWindow(pm->WinList[i], pm->WinPrevRect[i].showCmd);
1181
1182 } else {
1183 ShowWindow(pm->WinList[i], stat);
1184 }
1185 }
1186 }
1187
1188 void WINAPI OpenHelp(UINT Command, DWORD Data, char *UILanguageFile)
1189 {
1190 char HomeDir[MAX_PATH];
1191 char Temp[MAX_PATH];
1192 HWND HWin;
1193 wchar_t HelpFN[MAX_PATH];
1194 wchar_t uimsg[MAX_UIMSG];
1195 wchar_t *HomeDirW;
1196
1197 /* Get home directory */
1198 if (GetModuleFileNameA(NULL,Temp,_countof(Temp)) == 0) {
1199 return;
1200 }
1201 ExtractDirName(Temp, HomeDir);
1202 HomeDirW = ToWcharA(HomeDir);
1203 get_lang_msgW("HELPFILE", uimsg, _countof(uimsg), L"teraterm.chm", UILanguageFile);
1204 _snwprintf_s(HelpFN, _countof(HelpFN), _TRUNCATE, L"%s\\%s", HomeDirW, uimsg);
1205 free(HomeDirW);
1206
1207 // �w���v���I�[�i�[�������f�X�N�g�b�v������ (2007.5.12 maya)
1208 HWin = GetDesktopWindow();
1209 if (_HtmlHelpW(HWin, HelpFN, Command, Data) == NULL) {
1210 // �w���v���J����������
1211 static const TTMessageBoxInfoW info = {
1212 "Tera Term",
1213 NULL, L"Tera Term: HTML help",
1214 "MSG_OPENHELP_ERROR", L"Can't open HTML help file(%s)." };
1215 TTMessageBoxW(HWin, &info, MB_OK | MB_ICONERROR, UILanguageFile, HelpFN);
1216 return;
1217 }
1218 }
1219
1220 HWND WINAPI GetNthWin(int n)
1221 {
1222 if (n<pm->NWin) {
1223 return pm->WinList[n];
1224 }
1225 else {
1226 return NULL;
1227 }
1228 }
1229
1230 int WINAPI GetRegisteredWindowCount(void)
1231 {
1232 return (pm->NWin);
1233 }
1234
1235 // �L�����E�B���h�E���T���A�������u���L�������������B
1236 static void get_valid_window_and_memorize_rect(HWND myhwnd, HWND hwnd[], int *num, int style)
1237 {
1238 int i, n;
1239 WINDOWPLACEMENT wndPlace;
1240
1241 // ��������(Undo)���j���[�����x�����\���������B
1242 if (pm->WinUndoFlag == FALSE) {
1243 pm->WinUndoFlag = TRUE;
1244 } else {
1245 // ���������j���[���\�������������A�������O�������X�^�C�����I�����������A
1246 // ���j���[�������B
1247 // Windows8�����A�������A�����������X�^�C�����I�����������j���[�����������������A
1248 // Tera Term�������j���[���\�������������A�������������B
1249 if (pm->WinUndoStyle == style)
1250 pm->WinUndoFlag = FALSE;
1251 }
1252 pm->WinUndoStyle = style;
1253
1254 n = 0;
1255 for (i = 0 ; i < pm->NWin ; i++) {
1256 // �������u���o���������B
1257 wndPlace.length = sizeof(WINDOWPLACEMENT);
1258 GetWindowPlacement(pm->WinList[i], &wndPlace);
1259 pm->WinPrevRect[i] = wndPlace;
1260
1261 // �������g�������������B
1262 if (pm->WinList[i] == myhwnd) {
1263 hwnd[n] = hwnd[0];
1264 hwnd[0] = myhwnd;
1265 } else {
1266 hwnd[n] = pm->WinList[i];
1267 }
1268 n++;
1269 }
1270 *num = n;
1271 }
1272
1273 // �E�B���h�E�����E���������\������(Show Windows Side by Side)
1274 void WINAPI ShowAllWinSidebySide(HWND myhwnd)
1275 {
1276 int n;
1277 HWND hwnd[MAXNWIN];
1278
1279 get_valid_window_and_memorize_rect(myhwnd, hwnd, &n, WIN_SIDEBYSIDE);
1280 TileWindows(NULL, MDITILE_VERTICAL, NULL, n, hwnd);
1281 }
1282
1283 // �E�B���h�E���������������\������(Show Windows Stacked)
1284 void WINAPI ShowAllWinStacked(HWND myhwnd)
1285 {
1286 int n;
1287 HWND hwnd[MAXNWIN];
1288
1289 get_valid_window_and_memorize_rect(myhwnd, hwnd, &n, WIN_STACKED);
1290 TileWindows(NULL, MDITILE_HORIZONTAL, NULL, n, hwnd);
1291 }
1292
1293 // �E�B���h�E���d�����\������(Cascade)
1294 void WINAPI ShowAllWinCascade(HWND myhwnd)
1295 {
1296 int n;
1297 HWND hwnd[MAXNWIN];
1298
1299 get_valid_window_and_memorize_rect(myhwnd, hwnd, &n, WIN_CASCADE);
1300 CascadeWindows(NULL, MDITILE_SKIPDISABLED, NULL, n, hwnd);
1301 }
1302
1303 // �STera Term���I���w�����o���B
1304 void WINAPI BroadcastClosingMessage(HWND myhwnd)
1305 {
1306 int i, max;
1307 HWND hwnd[MAXNWIN];
1308
1309 // Tera Term���I�����������A���L���������������������A
1310 // ���������o�b�t�@���R�s�[���������B
1311 max = pm->NWin;
1312 for (i = 0 ; i < pm->NWin ; i++) {
1313 hwnd[i] = pm->WinList[i];
1314 }
1315
1316 for (i = 0 ; i < max ; i++) {
1317 // �������g�������������B
1318 if (hwnd[i] == myhwnd)
1319 continue;
1320
1321 PostMessage(hwnd[i], WM_USER_NONCONFIRM_CLOSE, 0, 0);
1322 }
1323 PostMessage(myhwnd, WM_USER_NONCONFIRM_CLOSE, 0, 0);
1324 }
1325
1326
1327 int WINAPI CommReadRawByte(PComVar cv, LPBYTE b)
1328 {
1329 if ( ! cv->Ready ) {
1330 return 0;
1331 }
1332
1333 if ( cv->InBuffCount>0 ) {
1334 *b = cv->InBuff[cv->InPtr];
1335 cv->InPtr++;
1336 cv->InBuffCount--;
1337 if ( cv->InBuffCount==0 ) {
1338 cv->InPtr = 0;
1339 }
1340 return 1;
1341 }
1342 else {
1343 cv->InPtr = 0;
1344 return 0;
1345 }
1346 }
1347
1348 static void LogBinSkip(PComVar cv, int add)
1349 {
1350 if (cv->LogBinSkip != NULL) {
1351 cv->LogBinSkip(add);
1352 }
1353 }
1354
1355 void WINAPI CommInsert1Byte(PComVar cv, BYTE b)
1356 {
1357 if ( ! cv->Ready ) {
1358 return;
1359 }
1360
1361 if (cv->InPtr == 0) {
1362 memmove(&(cv->InBuff[1]),&(cv->InBuff[0]),cv->InBuffCount);
1363 }
1364 else {
1365 cv->InPtr--;
1366 }
1367 cv->InBuff[cv->InPtr] = b;
1368 cv->InBuffCount++;
1369
1370 LogBinSkip(cv, 1);
1371 }
1372
1373 static void Log1Bin(PComVar cv, BYTE b)
1374 {
1375 if (cv->Log1Bin != NULL) {
1376 cv->Log1Bin(b);
1377 }
1378 }
1379
1380 int WINAPI CommRead1Byte(PComVar cv, LPBYTE b)
1381 {
1382 int c;
1383
1384 if ( ! cv->Ready ) {
1385 return 0;
1386 }
1387
1388 if ( cv->TelMode ) {
1389 c = 0;
1390 }
1391 else {
1392 c = CommReadRawByte(cv,b);
1393 }
1394
1395 if ((c==1) && cv->TelCRFlag) {
1396 cv->TelCRFlag = FALSE;
1397 if (*b==0) {
1398 c = 0;
1399 }
1400 }
1401
1402 if ( c==1 ) {
1403 if ( cv->IACFlag ) {
1404 cv->IACFlag = FALSE;
1405 if ( *b != 0xFF ) {
1406 cv->TelMode = TRUE;
1407 CommInsert1Byte(cv,*b);
1408 LogBinSkip(cv, -1);
1409 c = 0;
1410 }
1411 }
1412 else if ((cv->PortType==IdTCPIP) && (*b==0xFF)) {
1413 if (!cv->TelFlag && cv->TelAutoDetect) { /* TTPLUG */
1414 cv->TelFlag = TRUE;
1415 }
1416 if (cv->TelFlag) {
1417 cv->IACFlag = TRUE;
1418 c = 0;
1419 }
1420 }
1421 else if (cv->TelFlag && ! cv->TelBinRecv && (*b==0x0D)) {
1422 cv->TelCRFlag = TRUE;
1423 }
1424 }
1425
1426 if (c == 1) {
1427 Log1Bin(cv, *b);
1428 }
1429
1430 return c;
1431 }
1432
1433 int WINAPI CommRawOut(PComVar cv, /*const*/ PCHAR B, int C)
1434 {
1435 int a;
1436
1437 if ( ! cv->Ready ) {
1438 return C;
1439 }
1440
1441 if (C > OutBuffSize - cv->OutBuffCount) {
1442 a = OutBuffSize - cv->OutBuffCount;
1443 }
1444 else {
1445 a = C;
1446 }
1447 if ( cv->OutPtr > 0 ) {
1448 memmove(&(cv->OutBuff[0]),&(cv->OutBuff[cv->OutPtr]),cv->OutBuffCount);
1449 cv->OutPtr = 0;
1450 }
1451 memcpy(&(cv->OutBuff[cv->OutBuffCount]),B,a);
1452 cv->OutBuffCount = cv->OutBuffCount + a;
1453 return a;
1454 }
1455
1456 int WINAPI CommBinaryOut(PComVar cv, PCHAR B, int C)
1457 {
1458 int a, i, Len;
1459 char d[3];
1460
1461 if ( ! cv->Ready ) {
1462 return C;
1463 }
1464
1465 i = 0;
1466 a = 1;
1467 while ((a>0) && (i<C)) {
1468 Len = 0;
1469
1470 d[Len] = B[i];
1471 Len++;
1472
1473 if ( cv->TelFlag && (B[i]=='\x0d') && ! cv->TelBinSend ) {
1474 d[Len++] = '\x00';
1475 }
1476 else if ( cv->TelFlag && (B[i]=='\xff') ) {
1477 d[Len++] = '\xff';
1478 }
1479
1480 if ( OutBuffSize - cv->OutBuffCount - Len >= 0 ) {
1481 CommRawOut(cv, d, Len);
1482 a = 1;
1483 }
1484 else {
1485 a = 0;
1486 }
1487
1488 i += a;
1489 }
1490 return i;
1491 }
1492
1493 /**
1494 * �f�[�^(������)���o���o�b�t�@����������
1495 *
1496 * �w���f�[�^��������������������������������������
1497 * CommRawOut() ��������������������������
1498 *
1499 * @retval TRUE �o��������
1500 * @retval FALSE �o��������������(buffer full)
1501 */
1502 static BOOL WriteOutBuff(PComVar cv, const char *TempStr, int TempLen)
1503 {
1504 BOOL output;
1505
1506 if (TempLen == 0) {
1507 // ����0������������������������
1508 return TRUE;
1509 }
1510
1511 output = FALSE;
1512 if (cv->TelLineMode) {
1513 const BOOL Full = OutBuffSize - cv->LineModeBuffCount - TempLen < 0;
1514 if (!Full) {
1515 output = TRUE;
1516 memcpy(&(cv->LineModeBuff[cv->LineModeBuffCount]), TempStr, TempLen);
1517 cv->LineModeBuffCount += TempLen;
1518 if (cv->Flush) {
1519 cv->FlushLen = cv->LineModeBuffCount;
1520 }
1521 }
1522 if (cv->FlushLen > 0) {
1523 const int OutLen = CommRawOut(cv, cv->LineModeBuff, cv->FlushLen);
1524 cv->FlushLen -= OutLen;
1525 cv->LineModeBuffCount -= OutLen;
1526 memmove(cv->LineModeBuff, &(cv->LineModeBuff[OutLen]), cv->LineModeBuffCount);
1527 }
1528 cv->Flush = FALSE;
1529 }
1530 else {
1531 const BOOL Full = OutBuffSize-cv->OutBuffCount-TempLen < 0;
1532 if (! Full) {
1533 output = TRUE;
1534 CommRawOut(cv, (char *)TempStr, TempLen);
1535 }
1536 }
1537 return output;
1538 }
1539
1540 /**
1541 * �f�[�^(������)�������o�b�t�@����������
1542 * �����o�b�t�@�������� -> �G�R�[������
1543 *
1544 * @retval TRUE �o��������
1545 * @retval FALSE �o��������������(buffer full)
1546 */
1547 static BOOL WriteInBuff(PComVar cv, const char *TempStr, int TempLen)
1548 {
1549 BOOL Full;
1550
1551 if (TempLen == 0) {
1552 return TRUE;
1553 }
1554
1555 Full = InBuffSize-cv->InBuffCount-TempLen < 0;
1556 if (! Full) {
1557 memcpy(&(cv->InBuff[cv->InBuffCount]),TempStr,TempLen);
1558 cv->InBuffCount = cv->InBuffCount + TempLen;
1559 return TRUE;
1560 }
1561 return FALSE;
1562 }
1563
1564 /**
1565 * �����o�b�t�@�����������������������l����
1566 */
1567 static void PackInBuff(PComVar cv)
1568 {
1569 if ( (cv->InPtr>0) && (cv->InBuffCount>0) ) {
1570 memmove(cv->InBuff,&(cv->InBuff[cv->InPtr]),cv->InBuffCount);
1571 cv->InPtr = 0;
1572 }
1573 }
1574
1575 int WINAPI CommBinaryBuffOut(PComVar cv, PCHAR B, int C)
1576 {
1577 int a, i, Len;
1578 char d[3];
1579
1580 if ( ! cv->Ready ) {
1581 return C;
1582 }
1583
1584 i = 0;
1585 a = 1;
1586 while ((a>0) && (i<C)) {
1587 Len = 0;
1588
1589 d[Len] = B[i];
1590 Len++;
1591
1592 if (B[i] == CR) {
1593 if ( cv->TelFlag && ! cv->TelBinSend ) {
1594 d[Len++] = '\x00';
1595 }
1596 if (cv->TelLineMode) {
1597 cv->Flush = TRUE;
1598 }
1599 }
1600 else if ( cv->TelFlag && (B[i]=='\xff') ) {
1601 d[Len++] = '\xff';
1602 }
1603
1604 if (WriteOutBuff(cv, d, Len)) {
1605 a = 1;
1606 i++;
1607 } else {
1608 a = 0;
1609 }
1610 }
1611 return i;
1612 }
1613
1614 // �����R�[�h(CodePage)��UTF-8���o������
1615 static int OutputTextUTF8(WORD K, char *TempStr, PComVar cv)
1616 {
1617 int CodePage = *cv->CodePage;
1618 unsigned int code;
1619 int outlen;
1620
1621 code = MBCP_UTF32(K, CodePage);
1622 if (code == 0) {
1623 // �������s
1624 code = 0xfffd; // U+FFFD: Replacement Character
1625 }
1626 outlen = UTF32ToUTF8(code, TempStr, 4);
1627 return outlen;
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->locale)) {
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->locale)) {
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 // listup serial port driver
2562 // cf. http://www.codeproject.com/system/setupdi.asp?df=100&forumid=4368&exp=0&select=479661
2563 // (2007.8.17 yutaka)
2564 static void ListupSerialPort(LPWORD ComPortTable, int comports, char **ComPortDesc, int ComPortMax)
2565 {
2566 GUID ClassGuid[1];
2567 DWORD dwRequiredSize;
2568 BOOL bRet;
2569 HDEVINFO DeviceInfoSet = NULL;
2570 SP_DEVINFO_DATA DeviceInfoData;
2571 DWORD dwMemberIndex = 0;
2572 int i;
2573
2574 DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
2575
2576 // ���O�����������t���[��������
2577 for (i = 0 ; i < ComPortMax ; i++) {
2578 free(ComPortDesc[i]);
2579 ComPortDesc[i] = NULL;
2580 }
2581
2582 // Get ClassGuid from ClassName for PORTS class
2583 bRet =
2584 SetupDiClassGuidsFromName(_T("PORTS"), (LPGUID) & ClassGuid, 1,
2585 &dwRequiredSize);
2586 if (!bRet) {
2587 goto cleanup;
2588 }
2589
2590 // Get class devices
2591 // COM�|�[�g�����������t�����������������A�������������������A���W�X�g�����c��������
2592 // ����FriendlyName���\���������������������������B(2007.11.8 yutaka)
2593 DeviceInfoSet =
2594 SetupDiGetClassDevs(&ClassGuid[0], NULL, NULL, DIGCF_PRESENT | DIGCF_PROFILE);
2595
2596 if (DeviceInfoSet) {
2597 // Enumerate devices
2598 dwMemberIndex = 0;
2599 while (SetupDiEnumDeviceInfo
2600 (DeviceInfoSet, dwMemberIndex++, &DeviceInfoData)) {
2601 TCHAR szFriendlyName[MAX_PATH];
2602 TCHAR szPortName[MAX_PATH];
2603 //TCHAR szMessage[MAX_PATH];
2604 DWORD dwReqSize = 0;
2605 DWORD dwPropType;
2606 DWORD dwType = REG_SZ;
2607 HKEY hKey = NULL;
2608
2609 // Get friendlyname
2610 bRet = SetupDiGetDeviceRegistryProperty(DeviceInfoSet,
2611 &DeviceInfoData,
2612 SPDRP_FRIENDLYNAME,
2613 &dwPropType,
2614 (LPBYTE)
2615 szFriendlyName,
2616 sizeof(szFriendlyName),
2617 &dwReqSize);
2618
2619 // Open device parameters reg key
2620 hKey = SetupDiOpenDevRegKey(DeviceInfoSet,
2621 &DeviceInfoData,
2622 DICS_FLAG_GLOBAL,
2623 0, DIREG_DEV, KEY_READ);
2624 if (hKey) {
2625 // Qurey for portname
2626 long lRet;
2627 dwReqSize = sizeof(szPortName);
2628 lRet = RegQueryValueEx(hKey,
2629 _T("PortName"),
2630 0,
2631 &dwType,
2632 (LPBYTE) & szPortName,
2633 &dwReqSize);
2634
2635 // Close reg key
2636 RegCloseKey(hKey);
2637 }
2638
2639 #if 0
2640 sprintf(szMessage, _T("Name: %s\nPort: %s\n"), szFriendlyName,
2641 szPortName);
2642 printf("%s\n", szMessage);
2643 #endif
2644
2645 if (_strnicmp(szPortName, "COM", 3) == 0) { // COM�|�[�g�h���C�o������
2646 int port = atoi(&szPortName[3]);
2647 int i;
2648
2649 for (i = 0 ; i < comports ; i++) {
2650 if (ComPortTable[i] == port) { // �������m�F
2651 ComPortDesc[i] = _strdup(szFriendlyName);
2652 break;
2653 }
2654 }
2655 }
2656
2657 }
2658 }
2659
2660 cleanup:
2661 // Destroy device info list
2662 SetupDiDestroyDeviceInfoList(DeviceInfoSet);
2663 }
2664
2665
2666 /*
2667 *
2668 * [return]
2669 * 1���� �A�v�����g�p���\��COM�|�[�g������
2670 * 0 �A�v�����g�p���\��COM�|�[�g������
2671 * -1 �����g�p
2672 *
2673 */
2674 int WINAPI DetectComPorts(LPWORD ComPortTable, int ComPortMax, char **ComPortDesc)
2675 {
2676 HMODULE h;
2677 TCHAR devicesBuff[65535];
2678 TCHAR *p;
2679 int comports = 0;
2680 int i, j, min;
2681 WORD s;
2682
2683 if (((h = GetModuleHandle("kernel32.dll")) != NULL) &&
2684 (GetProcAddress(h, "QueryDosDeviceA") != NULL) &&
2685 (QueryDosDevice(NULL, devicesBuff, 65535) != 0)) {
2686 p = devicesBuff;
2687 while (*p != '\0') {
2688 if (strncmp(p, "COM", 3) == 0 && p[3] != '\0') {
2689 ComPortTable[comports++] = atoi(p+3);
2690 if (comports >= ComPortMax)
2691 break;
2692 }
2693 p += (strlen(p)+1);
2694 }
2695
2696 for (i=0; i<comports-1; i++) {
2697 min = i;
2698 for (j=i+1; j<comports; j++) {
2699 if (ComPortTable[min] > ComPortTable[j]) {
2700 min = j;
2701 }
2702 }
2703 if (min != i) {
2704 s = ComPortTable[i];
2705 ComPortTable[i] = ComPortTable[min];
2706 ComPortTable[min] = s;
2707 }
2708 }
2709 }
2710 else {
2711 #if 1
2712 for (i=1; i<=ComPortMax; i++) {
2713 FILE *fp;
2714 char buf[12]; // \\.\COMxxxx + NULL
2715 _snprintf_s(buf, sizeof(buf), _TRUNCATE, "\\\\.\\COM%d", i);
2716 if ((fp = fopen(buf, "r")) != NULL) {
2717 fclose(fp);
2718 ComPortTable[comports++] = i;
2719 }
2720 }
2721 #else
2722 comports = -1;
2723 #endif
2724 }
2725
2726 ListupSerialPort(ComPortTable, comports, ComPortDesc, ComPortMax);
2727
2728 return comports;
2729 }
2730
2731 int WINAPI CheckComPort(WORD ComPort)
2732 {
2733 HMODULE h;
2734 TCHAR devicesBuff[65535];
2735 char com_str[64];
2736 BOOL bRet;
2737 GUID ClassGuid[1];
2738 DWORD dwRequiredSize;
2739 HDEVINFO DeviceInfoSet = NULL;
2740 SP_DEVINFO_DATA DeviceInfoData;
2741 int found = 0;
2742
2743 _snprintf_s(com_str, sizeof(com_str), _TRUNCATE, "COM%d", ComPort);
2744
2745 if (((h = GetModuleHandle("kernel32.dll")) == NULL) | (GetProcAddress(h, "QueryDosDeviceA") == NULL) ) {
2746 /* ERROR */
2747 return -1;
2748 }
2749
2750 if (QueryDosDevice(com_str, devicesBuff, 65535) == 0) {
2751 DWORD err = GetLastError();
2752 if (err == ERROR_FILE_NOT_FOUND) {
2753 /* NOT FOUND */
2754 return 0;
2755 }
2756 /* ERROR */
2757 return -1;
2758 }
2759
2760 /* QueryDosDevice�����f�����m���������������������������`�F�b�N */
2761 bRet = SetupDiClassGuidsFromName(_T("PORTS"), (LPGUID) & ClassGuid, 1, &dwRequiredSize);
2762 if (bRet == FALSE) {
2763 return -1;
2764 }
2765
2766 DeviceInfoSet = SetupDiGetClassDevs(&ClassGuid[0], NULL, NULL, DIGCF_PRESENT | DIGCF_PROFILE);
2767 if (DeviceInfoSet == NULL) {
2768 return -1;
2769 }
2770
2771 if (DeviceInfoSet) {
2772 DWORD dwMemberIndex = 0;
2773 HKEY hKey = NULL;
2774 TCHAR szPortName[MAX_PATH];
2775 DWORD dwReqSize;
2776 DWORD dwType;
2777
2778 DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
2779 while (SetupDiEnumDeviceInfo(DeviceInfoSet, dwMemberIndex, &DeviceInfoData)) {
2780 hKey = SetupDiOpenDevRegKey(DeviceInfoSet, &DeviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ);
2781 if (hKey) {
2782 long lRet;
2783 dwReqSize = sizeof(szPortName);
2784 lRet = RegQueryValueEx(hKey, _T("PortName"), 0, &dwType, (LPBYTE)& szPortName, &dwReqSize);
2785 RegCloseKey(hKey);
2786 if (_stricmp(szPortName, com_str) == 0) {
2787 found = TRUE;
2788 break;
2789 }
2790 }
2791 dwMemberIndex++;
2792 }
2793 }
2794
2795 SetupDiDestroyDeviceInfoList(DeviceInfoSet);
2796
2797 return found;
2798 }
2799
2800 /*
2801 * @return �G���[���L������ FALSE
2802 * @param[in] BOOL first_instance
2803 */
2804 static BOOL OpenSharedMemory(BOOL *first_instance_)
2805 {
2806 int i;
2807 HMap = NULL;
2808 pm = NULL;
2809 for (i = 0; i < 100; i++) {
2810 char tmp[32];
2811 HANDLE hMap;
2812 BOOL first_instance;
2813 TMap *map;
2814 _snprintf_s(tmp, sizeof(tmp), _TRUNCATE, i == 0 ? "%s" : "%s_%d", TT_FILEMAPNAME, i);
2815 hMap = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE,
2816 0, sizeof(TMap), tmp);
2817 if (hMap == NULL) {
2818 return FALSE;
2819 }
2820
2821 first_instance = (GetLastError() != ERROR_ALREADY_EXISTS);
2822
2823 map = (TMap *)MapViewOfFile(hMap,FILE_MAP_WRITE,0,0,0);
2824 if (map == NULL) {
2825 return FALSE;
2826 }
2827
2828 if (first_instance ||
2829 (map->size_tmap == sizeof(TMap) &&
2830 map->size_tttset == sizeof(TTTSet)))
2831 {
2832 map->size_tmap = sizeof(TMap);
2833 map->size_tttset = sizeof(TTTSet);
2834 HMap = hMap;
2835 pm = map;
2836 *first_instance_ = first_instance;
2837 return TRUE;
2838 }
2839
2840 // next try
2841 UnmapViewOfFile(map);
2842 CloseHandle(hMap);
2843 }
2844 return FALSE;
2845 }
2846
2847 BOOL WINAPI DllMain(HANDLE hInstance,
2848 ULONG ul_reason_for_call,
2849 LPVOID lpReserved)
2850 {
2851 switch( ul_reason_for_call ) {
2852 case DLL_THREAD_ATTACH:
2853 /* do thread initialization */
2854 break;
2855 case DLL_THREAD_DETACH:
2856 /* do thread cleanup */
2857 break;
2858 case DLL_PROCESS_ATTACH:
2859 /* do process initialization */
2860 DoCover_IsDebuggerPresent();
2861 hInst = hInstance;
2862 if (OpenSharedMemory(&FirstInstance) == FALSE) {
2863 // dll���[�h���s�Ateraterm���N��������
2864 return FALSE;
2865 }
2866 WinCompatInit();
2867 break;
2868 case DLL_PROCESS_DETACH:
2869 /* do process cleanup */
2870 UnmapViewOfFile(pm);
2871 CloseHandle(HMap);
2872 break;
2873 }
2874 return TRUE;
2875 }

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