Develop and Download Open Source Software

Browse Subversion Repository

Annotation of /trunk/teraterm/ttpcmn/ttcmn.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 6076 - (hide annotations) (download) (as text)
Thu Nov 5 11:44:40 2015 UTC (8 years, 5 months ago) by salarm
File MIME type: text/x-csrc
File size: 54960 byte(s)
USBシリアルに接続中にUSBシリアルケーブルを抜き差しするとCOMに接続できなくなる不具合修正
・COMポートが消えた時に自動的に切断してCOMポートが復活した時に再接続するようにした
※WindowsXP以降でのみ動作

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