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

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