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

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