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 8616 - (show annotations) (download) (as text)
Mon Mar 23 15:54:26 2020 UTC (4 years ago) by zmatsuo
File MIME type: text/x-csrc
File size: 67980 byte(s)
TTMessageBoxW() を追加、一部利用するよう修正

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

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