Develop and Download Open Source Software

Browse Subversion Repository

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

Parent Directory Parent Directory | Revision Log Revision Log


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

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