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

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