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 8860 - (show annotations) (download) (as text)
Sat Jul 25 16:00:24 2020 UTC (3 years, 8 months ago) by zmatsuo
File MIME type: text/x-csrc
File size: 68598 byte(s)
マクロ(ttmacro)用送信バッファの分離

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

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