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 9129 - (show annotations) (download) (as text)
Sat Jan 16 05:21:37 2021 UTC (3 years, 2 months ago) by zmatsuo
File MIME type: text/x-csrc
File size: 67927 byte(s)
VS2005 による Windows 95 のサポート方法を変更

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

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