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 5301 - (hide annotations) (download) (as text)
Sun Jun 2 14:35:35 2013 UTC (10 years, 10 months ago) by yutakapon
File MIME type: text/x-csrc
File size: 53924 byte(s)
ウィンドウの「左右に並べて」、「上下に並べて」表示処理をAPIを使わずに、
自前で行うようにした。
これにより、Top Mostなウィンドウも並び替え対象となる。

「重ねて」表示の方は未。

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