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 10617 - (show annotations) (download) (as text)
Fri Mar 3 15:15:04 2023 UTC (12 months ago) by zmatsuo
File MIME type: text/x-csrc
File size: 29474 byte(s)
lngファイル名変数を ANSI版から Unicode 版へ切り替え

- get_lang_msgW() -> GetI18nStrWW()
- SetDlgTexts() -> SetDlgTextsW()
- SetWinMenu() を SetWinMenuW() に置き換え
  - ttpcmn/ttcmn.c, def
1 /*
2 * Copyright (C) 1994-1998 T. Teranishi
3 * (C) 2004- 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 /* TTCMN.DLL, main */
31 #include <string.h>
32 #include <stdio.h>
33 #include <windows.h>
34 #include <setupapi.h>
35 #include <htmlhelp.h>
36 #include <assert.h>
37 #define _CRTDBG_MAP_ALLOC
38 #include <stdlib.h>
39 #include <crtdbg.h>
40
41 #define DllExport __declspec(dllexport)
42 #include "language.h"
43 #undef DllExport
44
45 #include "teraterm.h"
46 #include "tttypes.h"
47 #include "ttlib.h"
48 #include "codeconv.h"
49 #include "compat_win.h"
50 #include "win32helper.h"
51 #include "../teraterm/unicode.h"
52
53 #include "ttcmn_shared_memory.h"
54 #include "ttcommon.h"
55 #include "ttcmn_i.h"
56
57 static PMap pm;
58
59 #define VTCLASSNAME "VTWin32"
60 #define TEKCLASSNAME "TEKWin32"
61
62 enum window_style {
63 WIN_CASCADE,
64 WIN_STACKED,
65 WIN_SIDEBYSIDE,
66 };
67
68 void WINAPI SetCOMFlag(int Com)
69 {
70 if (Com <= 0 || MAXCOMPORT <= Com) return;
71 pm->ComFlag[(Com-1)/CHAR_BIT] |= 1 << ((Com-1)%CHAR_BIT);
72 }
73
74 void WINAPI ClearCOMFlag(int Com)
75 {
76 if (Com <= 0 || MAXCOMPORT <= Com) return;
77 pm->ComFlag[(Com-1)/CHAR_BIT] &= ~(1 << ((Com-1)%CHAR_BIT));
78 }
79
80 int WINAPI CheckCOMFlag(int Com)
81 {
82 if (Com <= 0) return 0;
83 if (Com > MAXCOMPORT) return 1;
84 return ((pm->ComFlag[(Com-1)/CHAR_BIT] & 1 << (Com-1)%CHAR_BIT) > 0);
85 }
86
87 int WINAPI RegWin(HWND HWinVT, HWND HWinTEK)
88 {
89 int i, j;
90
91 if (pm->NWin>=MAXNWIN)
92 return 0;
93 if (HWinVT==NULL)
94 return 0;
95 if (HWinTEK!=NULL) {
96 i = 0;
97 while ((i<pm->NWin) && (pm->WinList[i]!=HWinVT))
98 i++;
99 if (i>=pm->NWin)
100 return 0;
101 for (j=pm->NWin-1 ; j>i ; j--)
102 pm->WinList[j+1] = pm->WinList[j];
103 pm->WinList[i+1] = HWinTEK;
104 pm->NWin++;
105 return 0;
106 }
107 pm->WinList[pm->NWin++] = HWinVT;
108 memset(&pm->WinPrevRect[pm->NWin - 1], 0, sizeof(pm->WinPrevRect[pm->NWin - 1])); // RECT clear
109 if (pm->NWin==1) {
110 return 1;
111 }
112 else {
113 return (int)(SendMessage(pm->WinList[pm->NWin-2],
114 WM_USER_GETSERIALNO,0,0)+1);
115 }
116 }
117
118 void WINAPI UnregWin(HWND HWin)
119 {
120 int i, j;
121
122 i = 0;
123 while ((i<pm->NWin) && (pm->WinList[i]!=HWin)) {
124 i++;
125 }
126 if (pm->WinList[i]!=HWin) {
127 return;
128 }
129 for (j=i ; j<pm->NWin-1 ; j++) {
130 pm->WinList[j] = pm->WinList[j+1];
131 pm->WinPrevRect[j] = pm->WinPrevRect[j+1]; // RECT shift
132 }
133 if (pm->NWin>0) {
134 pm->NWin--;
135 }
136 }
137
138 static char GetWindowTypeChar(HWND Hw, HWND HWin)
139 {
140 #if 0
141 if (HWin == Hw)
142 return '*';
143 else if (!IsWindowVisible(Hw))
144 #else
145 if (!IsWindowVisible(Hw))
146 #endif
147 return '#';
148 else if (IsIconic(Hw))
149 return '-';
150 else if (IsZoomed(Hw))
151 return '@';
152 else
153 return '+';
154 }
155
156 void WINAPI SetWinMenuW(HMENU menu, const wchar_t *langFile, int VTFlag)
157 {
158 int i;
159 char Temp[MAXPATHLEN];
160 HWND Hw;
161
162 // delete all items in Window menu
163 i = GetMenuItemCount(menu);
164 if (i>0)
165 do {
166 i--;
167 RemoveMenu(menu,i,MF_BYPOSITION);
168 } while (i>0);
169
170 i = 0;
171 while (i<pm->NWin) {
172 Hw = pm->WinList[i]; // get window handle
173 if ((GetClassNameA(Hw,Temp,sizeof(Temp))>0) &&
174 ((strcmp(Temp,VTCLASSNAME)==0) ||
175 (strcmp(Temp,TEKCLASSNAME)==0))) {
176 Temp[0] = '&';
177 Temp[1] = (char)(0x31 + i);
178 Temp[2] = ' ';
179 Temp[3] = GetWindowTypeChar(Hw, NULL);
180 Temp[4] = ' ';
181 GetWindowTextA(Hw,&Temp[5],sizeof(Temp)-6);
182 AppendMenuA(menu,MF_ENABLED | MF_STRING,ID_WINDOW_1+i,Temp);
183 i++;
184 if (i>8) {
185 i = pm->NWin;
186 }
187 }
188 else {
189 UnregWin(Hw);
190 }
191 }
192 if (VTFlag == 1) {
193 static const DlgTextInfo MenuTextInfo[] = {
194 { ID_WINDOW_WINDOW, "MENU_WINDOW_WINDOW" },
195 { ID_WINDOW_MINIMIZEALL, "MENU_WINDOW_MINIMIZEALL" },
196 { ID_WINDOW_RESTOREALL, "MENU_WINDOW_RESTOREALL" },
197 { ID_WINDOW_CASCADEALL, "MENU_WINDOW_CASCADE" },
198 { ID_WINDOW_STACKED, "MENU_WINDOW_STACKED" },
199 { ID_WINDOW_SIDEBYSIDE, "MENU_WINDOW_SIDEBYSIDE" },
200 };
201
202 AppendMenuA(menu, MF_SEPARATOR, 0, NULL);
203 AppendMenuA(menu, MF_ENABLED | MF_STRING, ID_WINDOW_WINDOW, "&Window");
204 AppendMenuA(menu, MF_ENABLED | MF_STRING, ID_WINDOW_MINIMIZEALL, "&Minimize All");
205 AppendMenuA(menu, MF_ENABLED | MF_STRING, ID_WINDOW_RESTOREALL, "&Restore All");
206 AppendMenuA(menu, MF_ENABLED | MF_STRING, ID_WINDOW_CASCADEALL, "&Cascade");
207 AppendMenuA(menu, MF_ENABLED | MF_STRING, ID_WINDOW_STACKED, "&Stacked");
208 AppendMenuA(menu, MF_ENABLED | MF_STRING, ID_WINDOW_SIDEBYSIDE, "Side &by Side");
209
210 SetI18nMenuStrsW(menu, "Tera Term", MenuTextInfo, _countof(MenuTextInfo), langFile);
211
212 if (pm->WinUndoFlag) {
213 wchar_t *uimsg;
214 if (pm->WinUndoStyle == WIN_CASCADE)
215 GetI18nStrWW("Tera Term", "MENU_WINDOW_CASCADE_UNDO", L"&Undo - Cascade", langFile, &uimsg);
216 else if (pm->WinUndoStyle == WIN_STACKED)
217 GetI18nStrWW("Tera Term", "MENU_WINDOW_STACKED_UNDO", L"&Undo - Stacked", langFile, &uimsg);
218 else
219 GetI18nStrWW("Tera Term", "MENU_WINDOW_SIDEBYSIDE_UNDO", L"&Undo - Side by Side", langFile, &uimsg);
220 AppendMenuW(menu, MF_ENABLED | MF_STRING, ID_WINDOW_UNDO, uimsg);
221 free(uimsg);
222 }
223
224 }
225 else {
226 wchar_t *uimsg;
227 GetI18nStrWW("Tera Term", "MENU_WINDOW_WINDOW", L"&Window", langFile, &uimsg);
228 AppendMenuW(menu,MF_ENABLED | MF_STRING,ID_TEKWINDOW_WINDOW, uimsg);
229 free(uimsg);
230 }
231 }
232
233 void WINAPI SetWinList(HWND HWin, HWND HDlg, int IList)
234 {
235 int i;
236 char Temp[MAXPATHLEN];
237 HWND Hw;
238
239 for (i=0; i<pm->NWin; i++) {
240 Hw = pm->WinList[i]; // get window handle
241 if ((GetClassName(Hw,Temp,sizeof(Temp))>0) &&
242 ((strcmp(Temp,VTCLASSNAME)==0) ||
243 (strcmp(Temp,TEKCLASSNAME)==0))) {
244 Temp[0] = GetWindowTypeChar(Hw, HWin);
245 Temp[1] = ' ';
246 GetWindowText(Hw,&Temp[2],sizeof(Temp)-3);
247 SendDlgItemMessage(HDlg, IList, LB_ADDSTRING,
248 0, (LPARAM)Temp);
249 if (Hw==HWin) {
250 SendDlgItemMessage(HDlg, IList, LB_SETCURSEL, i,0);
251 }
252 }
253 else {
254 UnregWin(Hw);
255 }
256 }
257 }
258
259 void WINAPI SelectWin(int WinId)
260 {
261 if ((WinId>=0) && (WinId<pm->NWin)) {
262 /* �E�B���h�E�����������������������������������A���������������������������A
263 * SW_SHOWNORMAL ���� SW_SHOW �����X�����B
264 * (2009.11.8 yutaka)
265 * �E�B���h�E�����������������������������T�C�Y������(SW_RESTORE)�����������B
266 * (2009.11.9 maya)
267 */
268 if (IsIconic(pm->WinList[WinId])) {
269 ShowWindow(pm->WinList[WinId],SW_RESTORE);
270 }
271 else {
272 ShowWindow(pm->WinList[WinId],SW_SHOW);
273 }
274 SetForegroundWindow(pm->WinList[WinId]);
275 }
276 }
277
278 void WINAPI SelectNextWin(HWND HWin, int Next, BOOL SkipIconic)
279 {
280 int i;
281
282 i = 0;
283 while ((i < pm->NWin) && (pm->WinList[i]!=HWin)) {
284 i++;
285 }
286 if (pm->WinList[i]!=HWin) {
287 return;
288 }
289
290 do {
291 i += Next;
292 if (i >= pm->NWin) {
293 i = 0;
294 }
295 else if (i < 0) {
296 i = pm->NWin-1;
297 }
298
299 if (pm->WinList[i] == HWin) {
300 break;
301 }
302 } while ((SkipIconic && IsIconic(pm->WinList[i])) || !IsWindowVisible(pm->WinList[i]));
303
304 SelectWin(i);
305 }
306
307 void WINAPI ShowAllWin(int stat) {
308 int i;
309
310 for (i=0; i < pm->NWin; i++) {
311 ShowWindow(pm->WinList[i], stat);
312 }
313 }
314
315 void WINAPI UndoAllWin(void) {
316 int i;
317 WINDOWPLACEMENT rc0;
318 RECT rc;
319 int stat = SW_RESTORE;
320 int multi_mon = 0;
321
322 if (HasMultiMonitorSupport()) {
323 multi_mon = 1;
324 }
325
326 // ���x�A�����������t���O���������B
327 pm->WinUndoFlag = FALSE;
328
329 memset(&rc0, 0, sizeof(rc0));
330
331 for (i=0; i < pm->NWin; i++) {
332 // �����w�����A�O�����������c���������������A�E�B���h�E�����������������B
333 if (stat == SW_RESTORE && memcmp(&pm->WinPrevRect[i], &rc0, sizeof(rc0)) != 0) {
334 rc = pm->WinPrevRect[i].rcNormalPosition;
335
336 // NT4.0, 95 ���}���`���j�^API��������
337 if (multi_mon) {
338 // �������j�^������������
339 HMONITOR hMonitor;
340 MONITORINFO mi;
341 hMonitor = pMonitorFromRect(&rc, MONITOR_DEFAULTTONEAREST);
342 mi.cbSize = sizeof(MONITORINFO);
343 pGetMonitorInfoA(hMonitor, &mi);
344
345 // ���u�����i�����O���������x���������������������������j
346 if (rc.right > mi.rcMonitor.right) {
347 rc.left -= rc.right - mi.rcMonitor.right;
348 rc.right = mi.rcMonitor.right;
349 }
350 if (rc.left < mi.rcMonitor.left) {
351 rc.right += mi.rcMonitor.left - rc.left;
352 rc.left = mi.rcMonitor.left;
353 }
354 if (rc.bottom > mi.rcMonitor.bottom) {
355 rc.top -= rc.bottom - mi.rcMonitor.bottom;
356 rc.bottom = mi.rcMonitor.bottom;
357 }
358 if (rc.top < mi.rcMonitor.top) {
359 rc.bottom += mi.rcMonitor.top - rc.top;
360 rc.top = mi.rcMonitor.top;
361 }
362 }
363
364 // �E�B���h�E���u����
365 SetWindowPos(
366 pm->WinList[i], NULL,
367 rc.left,
368 rc.top,
369 rc.right - rc.left,
370 rc.bottom - rc.top,
371 SWP_NOZORDER);
372
373 // �E�B���h�E����������
374 ShowWindow(pm->WinList[i], pm->WinPrevRect[i].showCmd);
375
376 } else {
377 ShowWindow(pm->WinList[i], stat);
378 }
379 }
380 }
381
382 HWND WINAPI GetNthWin(int n)
383 {
384 if (n<pm->NWin) {
385 return pm->WinList[n];
386 }
387 else {
388 return NULL;
389 }
390 }
391
392 int WINAPI GetRegisteredWindowCount(void)
393 {
394 return (pm->NWin);
395 }
396
397 // �L�����E�B���h�E���T���A�������u���L�������������B
398 static void get_valid_window_and_memorize_rect(HWND myhwnd, HWND hwnd[], int *num, int style)
399 {
400 int i, n;
401 WINDOWPLACEMENT wndPlace;
402
403 // ��������(Undo)���j���[�����x�����\���������B
404 if (pm->WinUndoFlag == FALSE) {
405 pm->WinUndoFlag = TRUE;
406 } else {
407 // ���������j���[���\�������������A�������O�������X�^�C�����I�����������A
408 // ���j���[�������B
409 // Windows8�����A�������A�����������X�^�C�����I�����������j���[�����������������A
410 // Tera Term�������j���[���\�������������A�������������B
411 if (pm->WinUndoStyle == style)
412 pm->WinUndoFlag = FALSE;
413 }
414 pm->WinUndoStyle = style;
415
416 n = 0;
417 for (i = 0 ; i < pm->NWin ; i++) {
418 // �������u���o���������B
419 wndPlace.length = sizeof(WINDOWPLACEMENT);
420 GetWindowPlacement(pm->WinList[i], &wndPlace);
421 pm->WinPrevRect[i] = wndPlace;
422
423 // �������g�������������B
424 if (pm->WinList[i] == myhwnd) {
425 hwnd[n] = hwnd[0];
426 hwnd[0] = myhwnd;
427 } else {
428 hwnd[n] = pm->WinList[i];
429 }
430 n++;
431 }
432 *num = n;
433 }
434
435 // �E�B���h�E�����E���������\������(Show Windows Side by Side)
436 void WINAPI ShowAllWinSidebySide(HWND myhwnd)
437 {
438 int n;
439 HWND hwnd[MAXNWIN];
440
441 get_valid_window_and_memorize_rect(myhwnd, hwnd, &n, WIN_SIDEBYSIDE);
442 TileWindows(NULL, MDITILE_VERTICAL, NULL, n, hwnd);
443 }
444
445 // �E�B���h�E���������������\������(Show Windows Stacked)
446 void WINAPI ShowAllWinStacked(HWND myhwnd)
447 {
448 int n;
449 HWND hwnd[MAXNWIN];
450
451 get_valid_window_and_memorize_rect(myhwnd, hwnd, &n, WIN_STACKED);
452 TileWindows(NULL, MDITILE_HORIZONTAL, NULL, n, hwnd);
453 }
454
455 // �E�B���h�E���d�����\������(Cascade)
456 void WINAPI ShowAllWinCascade(HWND myhwnd)
457 {
458 int n;
459 HWND hwnd[MAXNWIN];
460
461 get_valid_window_and_memorize_rect(myhwnd, hwnd, &n, WIN_CASCADE);
462 CascadeWindows(NULL, MDITILE_SKIPDISABLED, NULL, n, hwnd);
463 }
464
465 // �STera Term���I���w�����o���B
466 void WINAPI BroadcastClosingMessage(HWND myhwnd)
467 {
468 int i, max;
469 HWND hwnd[MAXNWIN];
470
471 // Tera Term���I�����������A���L���������������������A
472 // ���������o�b�t�@���R�s�[���������B
473 max = pm->NWin;
474 for (i = 0 ; i < pm->NWin ; i++) {
475 hwnd[i] = pm->WinList[i];
476 }
477
478 for (i = 0 ; i < max ; i++) {
479 // �������g�������������B
480 if (hwnd[i] == myhwnd)
481 continue;
482
483 PostMessage(hwnd[i], WM_USER_NONCONFIRM_CLOSE, 0, 0);
484 }
485 PostMessage(myhwnd, WM_USER_NONCONFIRM_CLOSE, 0, 0);
486 }
487
488
489 int WINAPI CommReadRawByte(PComVar cv, LPBYTE b)
490 {
491 if ( ! cv->Ready ) {
492 return 0;
493 }
494
495 if ( cv->InBuffCount>0 ) {
496 *b = cv->InBuff[cv->InPtr];
497 cv->InPtr++;
498 cv->InBuffCount--;
499 if ( cv->InBuffCount==0 ) {
500 cv->InPtr = 0;
501 }
502 return 1;
503 }
504 else {
505 cv->InPtr = 0;
506 return 0;
507 }
508 }
509
510 static void LogBinSkip(PComVar cv, int add)
511 {
512 if (cv->LogBinSkip != NULL) {
513 cv->LogBinSkip(add);
514 }
515 }
516
517 void WINAPI CommInsert1Byte(PComVar cv, BYTE b)
518 {
519 if ( ! cv->Ready ) {
520 return;
521 }
522
523 if (cv->InPtr == 0) {
524 memmove(&(cv->InBuff[1]),&(cv->InBuff[0]),cv->InBuffCount);
525 }
526 else {
527 cv->InPtr--;
528 }
529 cv->InBuff[cv->InPtr] = b;
530 cv->InBuffCount++;
531
532 LogBinSkip(cv, 1);
533 }
534
535 static void Log1Bin(PComVar cv, BYTE b)
536 {
537 if (cv->Log1Bin != NULL) {
538 cv->Log1Bin(b);
539 }
540 }
541
542 int WINAPI CommRead1Byte(PComVar cv, LPBYTE b)
543 {
544 int c;
545
546 if ( ! cv->Ready ) {
547 return 0;
548 }
549
550 if ( cv->TelMode ) {
551 c = 0;
552 }
553 else {
554 c = CommReadRawByte(cv,b);
555 }
556
557 if ((c==1) && cv->TelCRFlag) {
558 cv->TelCRFlag = FALSE;
559 if (*b==0) {
560 c = 0;
561 }
562 }
563
564 if ( c==1 ) {
565 if ( cv->IACFlag ) {
566 cv->IACFlag = FALSE;
567 if ( *b != 0xFF ) {
568 cv->TelMode = TRUE;
569 CommInsert1Byte(cv,*b);
570 LogBinSkip(cv, -1);
571 c = 0;
572 }
573 }
574 else if ((cv->PortType==IdTCPIP) && (*b==0xFF)) {
575 if (!cv->TelFlag && cv->TelAutoDetect) { /* TTPLUG */
576 cv->TelFlag = TRUE;
577 }
578 if (cv->TelFlag) {
579 cv->IACFlag = TRUE;
580 c = 0;
581 }
582 }
583 else if (cv->TelFlag && ! cv->TelBinRecv && (*b==0x0D)) {
584 cv->TelCRFlag = TRUE;
585 }
586 }
587
588 if (c == 1) {
589 Log1Bin(cv, *b);
590 }
591
592 return c;
593 }
594
595 int WINAPI CommRawOut(PComVar cv, /*const*/ PCHAR B, int C)
596 {
597 int a;
598
599 if ( ! cv->Ready ) {
600 return C;
601 }
602
603 if (C > OutBuffSize - cv->OutBuffCount) {
604 a = OutBuffSize - cv->OutBuffCount;
605 }
606 else {
607 a = C;
608 }
609 if ( cv->OutPtr > 0 ) {
610 memmove(&(cv->OutBuff[0]),&(cv->OutBuff[cv->OutPtr]),cv->OutBuffCount);
611 cv->OutPtr = 0;
612 }
613 memcpy(&(cv->OutBuff[cv->OutBuffCount]),B,a);
614 cv->OutBuffCount = cv->OutBuffCount + a;
615 return a;
616 }
617
618 int WINAPI CommBinaryOut(PComVar cv, PCHAR B, int C)
619 {
620 int a, i, Len;
621 char d[3];
622
623 if ( ! cv->Ready ) {
624 return C;
625 }
626
627 i = 0;
628 a = 1;
629 while ((a>0) && (i<C)) {
630 Len = 0;
631
632 d[Len] = B[i];
633 Len++;
634
635 if ( cv->TelFlag && (B[i]=='\x0d') && ! cv->TelBinSend ) {
636 d[Len++] = '\x00';
637 }
638 else if ( cv->TelFlag && (B[i]=='\xff') ) {
639 d[Len++] = '\xff';
640 }
641
642 if ( OutBuffSize - cv->OutBuffCount - Len >= 0 ) {
643 CommRawOut(cv, d, Len);
644 a = 1;
645 }
646 else {
647 a = 0;
648 }
649
650 i += a;
651 }
652 return i;
653 }
654
655 /**
656 * �f�[�^(������)���o���o�b�t�@����������
657 *
658 * �w���f�[�^��������������������������������������
659 * CommRawOut() ��������������������������
660 *
661 * @retval TRUE �o��������
662 * @retval FALSE �o��������������(buffer full)
663 */
664 static BOOL WriteOutBuff(PComVar cv, const char *TempStr, int TempLen)
665 {
666 BOOL output;
667
668 if (TempLen == 0) {
669 // ����0������������������������
670 return TRUE;
671 }
672
673 output = FALSE;
674 if (cv->TelLineMode) {
675 const BOOL Full = OutBuffSize - cv->LineModeBuffCount - TempLen < 0;
676 if (!Full) {
677 output = TRUE;
678 memcpy(&(cv->LineModeBuff[cv->LineModeBuffCount]), TempStr, TempLen);
679 cv->LineModeBuffCount += TempLen;
680 if (cv->Flush) {
681 cv->FlushLen = cv->LineModeBuffCount;
682 }
683 }
684 if (cv->FlushLen > 0) {
685 const int OutLen = CommRawOut(cv, cv->LineModeBuff, cv->FlushLen);
686 cv->FlushLen -= OutLen;
687 cv->LineModeBuffCount -= OutLen;
688 memmove(cv->LineModeBuff, &(cv->LineModeBuff[OutLen]), cv->LineModeBuffCount);
689 }
690 cv->Flush = FALSE;
691 }
692 else {
693 const BOOL Full = OutBuffSize-cv->OutBuffCount-TempLen < 0;
694 if (! Full) {
695 output = TRUE;
696 CommRawOut(cv, (char *)TempStr, TempLen);
697 }
698 }
699 return output;
700 }
701
702 /**
703 * �f�[�^(������)�������o�b�t�@����������
704 * �����o�b�t�@�������� -> �G�R�[������
705 *
706 * @retval TRUE �o��������
707 * @retval FALSE �o��������������(buffer full)
708 */
709 static BOOL WriteInBuff(PComVar cv, const char *TempStr, int TempLen)
710 {
711 BOOL Full;
712
713 if (TempLen == 0) {
714 return TRUE;
715 }
716
717 Full = InBuffSize-cv->InBuffCount-TempLen < 0;
718 if (! Full) {
719 memcpy(&(cv->InBuff[cv->InBuffCount]),TempStr,TempLen);
720 cv->InBuffCount = cv->InBuffCount + TempLen;
721 return TRUE;
722 }
723 return FALSE;
724 }
725
726 /**
727 * �����o�b�t�@�����������������������l����
728 */
729 static void PackInBuff(PComVar cv)
730 {
731 if ( (cv->InPtr>0) && (cv->InBuffCount>0) ) {
732 memmove(cv->InBuff,&(cv->InBuff[cv->InPtr]),cv->InBuffCount);
733 cv->InPtr = 0;
734 }
735 }
736
737 int WINAPI CommBinaryBuffOut(PComVar cv, PCHAR B, int C)
738 {
739 int a, i, Len;
740 char d[3];
741
742 if ( ! cv->Ready ) {
743 return C;
744 }
745
746 i = 0;
747 a = 1;
748 while ((a>0) && (i<C)) {
749 Len = 0;
750
751 d[Len] = B[i];
752 Len++;
753
754 if (B[i] == CR) {
755 if ( cv->TelFlag && ! cv->TelBinSend ) {
756 d[Len++] = '\x00';
757 }
758 if (cv->TelLineMode) {
759 cv->Flush = TRUE;
760 }
761 }
762 else if ( cv->TelFlag && (B[i]=='\xff') ) {
763 d[Len++] = '\xff';
764 }
765
766 if (WriteOutBuff(cv, d, Len)) {
767 a = 1;
768 i++;
769 } else {
770 a = 0;
771 }
772 }
773 return i;
774 }
775
776 /**
777 * @retval true ���{�������p�J�^�J�i
778 * @retval false ������
779 */
780 static BOOL IsHalfWidthKatakana(unsigned int u32)
781 {
782 // Halfwidth CJK punctuation (U+FF61�`FF64)
783 // Halfwidth Katakana variants (U+FF65�`FF9F)
784 return (0xff61 <= u32 && u32 <= 0xff9f);
785 }
786
787 /**
788 * �o���p�A TODO echo�p������
789 * @param cv
790 * @param u32 ��������
791 * @param check_only TRUE���������s�����A
792 * @param TempStr �o��������
793 * @param StrLen TempStr�����o��������
794 * @retval �������s����
795 */
796 static BOOL OutControl(PComVar cv, unsigned int u32, BOOL check_only, char *TempStr, size_t *StrLen)
797 {
798 const wchar_t d = u32;
799 size_t TempLen = 0;
800 BOOL retval = FALSE;
801 if (check_only == TRUE) {
802 /* �`�F�b�N���� */
803 if (d == CR || d == BS || d == 0x15/*ctrl-u*/) {
804 return TRUE;
805 } else {
806 return FALSE;
807 }
808 }
809 if (d==CR) {
810 TempStr[TempLen++] = 0x0d;
811 if (cv->CRSend==IdCRLF) {
812 TempStr[TempLen++] = 0x0a;
813 }
814 else if ((cv->CRSend ==IdCR) &&
815 cv->TelFlag && ! cv->TelBinSend) {
816 TempStr[TempLen++] = 0;
817 }
818 else if (cv->CRSend == IdLF) {
819 TempStr[TempLen-1] = 0x0a;
820 }
821 if (cv->TelLineMode) {
822 cv->Flush = TRUE;
823 }
824 retval = TRUE;
825 }
826 else if (d== BS) {
827 if (cv->TelLineMode) {
828 if (cv->FlushLen < cv->LineModeBuffCount) {
829 cv->LineModeBuffCount--;
830 }
831 }
832 else {
833 TempStr[TempLen++] = BS;
834 }
835 retval = TRUE;
836 }
837 else if (d==0x15) { // ctrl-u
838 if (cv->TelLineMode) {
839 cv->LineModeBuffCount = cv->FlushLen;
840 }
841 else {
842 TempStr[TempLen++] = 0x15;
843 }
844 retval = TRUE;
845 }
846 *StrLen = TempLen;
847 return retval;
848 }
849 static BOOL ControlEcho(PComVar cv, unsigned int u32, BOOL check_only, char *TempStr, size_t *StrLen)
850 {
851 const wchar_t d = u32;
852 size_t TempLen = 0;
853 BOOL retval = FALSE;
854 if (check_only == TRUE) {
855 /* �`�F�b�N���� */
856 if (d == CR || (d == 0x15/*ctrl-u*/ && cv->TelLineMode)) {
857 return TRUE;
858 } else {
859 return FALSE;
860 }
861 }
862 if (d==CR) {
863 TempStr[TempLen++] = 0x0d;
864 if (cv->CRSend==IdCRLF) {
865 TempStr[TempLen++] = 0x0a;
866 }
867 else if ((cv->CRSend ==IdCR) && cv->TelFlag && ! cv->TelBinSend) {
868 TempStr[TempLen++] = 0;
869 }
870 else if (cv->CRSend == IdLF) {
871 TempStr[TempLen-1] = 0x0a;
872 }
873 retval = TRUE;
874 }
875 else if (d==0x15/*ctrl-u*/ && cv->TelLineMode) {
876 // Move to top of line (CHA "\033[G") and erase line (EL "\033[K")
877 memcpy(TempStr, "\033[G\033[K", 6);
878 TempLen += 6;
879 retval = TRUE;
880 }
881 *StrLen = TempLen;
882 return retval;
883 }
884
885 /**
886 * �o���p����������������
887 *
888 * @retval ��������������
889 */
890 typedef struct {
891 int KanjiCode; // [in]�o�������R�[�h(sjis,jis����)
892 BOOL (*ControlOut)(PComVar cv, unsigned int u32, BOOL check_only, char *TempStr, size_t *StrLen);
893 // state�����������K�v�����������R�[�h���g�p
894 BOOL JIS7Katakana; // [in](Kanji JIS)kana
895 int SendCode; // [in,out](Kanji JIS)���O�����M�R�[�h Ascii/Kana/Kanji
896 BOOL KanjiFlag; // [in,out](MBCS)���O��1byte��������������?(2byte������������?)
897 BYTE KanjiFirst; // [in,out](MBCS)���O��1byte
898 } OutputCharState;
899
900 /**
901 * unicode(UTF-16)����unicode(UTF-32)��1���������o����
902 * �o���f�[�^(TempStr)����������
903 */
904 static size_t MakeOutputString(PComVar cv, OutputCharState *states,
905 const wchar_t *B, int C,
906 char *TempStr, int *TempLen_)
907 {
908 BOOL (*ControlOut)(PComVar cv, unsigned int u32, BOOL check_only, char *TempStr, size_t *StrLen)
909 = states->ControlOut;
910 //
911 int TempLen = 0;
912 size_t TempLen2;
913 size_t output_char_count; // ��������������
914
915 // UTF-32 ��1���������o��
916 unsigned int u32;
917 size_t u16_len = UTF16ToUTF32(B, C, &u32);
918 if (u16_len == 0) {
919 // �f�R�[�h��������? ����������������?
920 assert(FALSE);
921 u32 = '?';
922 u16_len = 1;
923 }
924 output_char_count = u16_len;
925
926 // �e���V�t�g����������������
927 if (u32 < 0x100 || ControlOut(cv, u32, TRUE, NULL, NULL)) {
928 if (cv->Language == IdJapanese && states->KanjiCode == IdJIS) {
929 // �����������A���{��,JIS��������
930 if (cv->SendCode == IdKanji) {
931 // �����������������A����OUT
932 TempStr[TempLen++] = 0x1B;
933 TempStr[TempLen++] = '(';
934 switch (cv->KanjiOut) {
935 case IdKanjiOutJ:
936 TempStr[TempLen++] = 'J';
937 break;
938 case IdKanjiOutH:
939 TempStr[TempLen++] = 'H';
940 break;
941 default:
942 TempStr[TempLen++] = 'B';
943 }
944 }
945
946 if (states->JIS7Katakana == 1) {
947 if (cv->SendCode == IdKatakana) {
948 TempStr[TempLen++] = SO;
949 }
950 }
951
952 states->SendCode = IdASCII;
953 }
954 }
955
956 // 1������������
957 if (ControlOut(cv, u32, FALSE, TempStr, &TempLen2)) {
958 // ��������������������
959 TempLen += TempLen2;
960 output_char_count = 1;
961 } else if (cv->Language == IdUtf8 ||
962 (cv->Language == IdJapanese && states->KanjiCode == IdUTF8) ||
963 (cv->Language == IdKorean && states->KanjiCode == IdUTF8) ||
964 (cv->Language == IdChinese && states->KanjiCode == IdUTF8))
965 {
966 // UTF-8 ���o��
967 size_t utf8_len = sizeof(TempStr);
968 utf8_len = UTF32ToUTF8(u32, TempStr, utf8_len);
969 TempLen += utf8_len;
970 } else if (cv->Language == IdJapanese) {
971 // ���{��
972 // ���� CP932(SJIS) ���������������o��
973 char mb_char[2];
974 size_t mb_len = sizeof(mb_char);
975 mb_len = UTF32ToMBCP(u32, 932, mb_char, mb_len);
976 if (mb_len == 0) {
977 // SJIS��������������
978 TempStr[TempLen++] = '?';
979 } else {
980 switch (states->KanjiCode) {
981 case IdEUC:
982 // TODO ���p�J�i
983 if (mb_len == 1) {
984 TempStr[TempLen++] = mb_char[0];
985 } else {
986 WORD K;
987 K = (((WORD)(unsigned char)mb_char[0]) << 8) +
988 (WORD)(unsigned char)mb_char[1];
989 K = SJIS2EUC(K);
990 TempStr[TempLen++] = HIBYTE(K);
991 TempStr[TempLen++] = LOBYTE(K);
992 }
993 break;
994 case IdJIS:
995 if (u32 < 0x100) {
996 // ASCII
997 TempStr[TempLen++] = mb_char[0];
998 states->SendCode = IdASCII;
999 } else if (IsHalfWidthKatakana(u32)) {
1000 // ���p�J�^�J�i
1001 if (states->JIS7Katakana==1) {
1002 if (cv->SendCode != IdKatakana) {
1003 TempStr[TempLen++] = SI;
1004 }
1005 TempStr[TempLen++] = mb_char[0] & 0x7f;
1006 } else {
1007 TempStr[TempLen++] = mb_char[0];
1008 }
1009 states->SendCode = IdKatakana;
1010 } else {
1011 // ����
1012 WORD K;
1013 K = (((WORD)(unsigned char)mb_char[0]) << 8) +
1014 (WORD)(unsigned char)mb_char[1];
1015 K = SJIS2JIS(K);
1016 if (states->SendCode != IdKanji) {
1017 // ����IN
1018 TempStr[TempLen++] = 0x1B;
1019 TempStr[TempLen++] = '$';
1020 if (cv->KanjiIn == IdKanjiInB) {
1021 TempStr[TempLen++] = 'B';
1022 }
1023 else {
1024 TempStr[TempLen++] = '@';
1025 }
1026 states->SendCode = IdKanji;
1027 }
1028 TempStr[TempLen++] = HIBYTE(K);
1029 TempStr[TempLen++] = LOBYTE(K);
1030 }
1031 break;
1032 case IdSJIS:
1033 if (mb_len == 1) {
1034 TempStr[TempLen++] = mb_char[0];
1035 } else {
1036 TempStr[TempLen++] = mb_char[0];
1037 TempStr[TempLen++] = mb_char[1];
1038 }
1039 break;
1040 default:
1041 assert(FALSE);
1042 break;
1043 }
1044 }
1045 } else if (cv->Language == IdRussian) {
1046 /* ����CP1251�����������o�� */
1047 char mb_char[2];
1048 size_t mb_len = sizeof(mb_char);
1049 BYTE b;
1050 mb_len = UTF32ToMBCP(u32, 1251, mb_char, mb_len);
1051 if (mb_len != 1) {
1052 b = '?';
1053 } else {
1054 b = RussConv(IdWindows, states->KanjiCode, mb_char[0]);
1055 }
1056 TempStr[TempLen++] = b;
1057 } else if (cv->Language == IdKorean || cv->Language == IdChinese) {
1058 int code_page;
1059 char mb_char[2];
1060 size_t mb_len;
1061 if (cv->Language == IdKorean) {
1062 code_page = 51949;
1063 } else if (cv->Language == IdChinese) {
1064 switch (states->KanjiCode) {
1065 case IdCnGB2312:
1066 code_page = 936;
1067 break;
1068 case IdCnBig5:
1069 code_page = 950;
1070 break;
1071 default:
1072 assert(FALSE);
1073 code_page = 936;
1074 break;
1075 }
1076 } else {
1077 assert(FALSE);
1078 code_page = 0;
1079 }
1080 /* code_page �����������o�� */
1081 mb_len = sizeof(mb_char);
1082 mb_len = UTF32ToMBCP(u32, code_page, mb_char, mb_len);
1083 if (mb_len == 0) {
1084 TempStr[TempLen++] = '?';
1085 }
1086 else if (mb_len == 1) {
1087 TempStr[TempLen++] = mb_char[0];
1088 } else {
1089 TempStr[TempLen++] = mb_char[0];
1090 TempStr[TempLen++] = mb_char[1];
1091 }
1092 } else if (cv->Language == IdEnglish) {
1093 char byte;
1094 int part = KanjiCodeToISO8859Part(states->KanjiCode);
1095 int r = UnicodeToISO8859(part, u32, &byte);
1096 if (r == 0) {
1097 // �����������������R�[�h������
1098 byte = '?';
1099 }
1100 TempStr[TempLen++] = byte;
1101 } else {
1102 assert(FALSE);
1103 }
1104
1105 *TempLen_ = TempLen;
1106 return output_char_count;
1107 }
1108
1109
1110 /**
1111 * CommTextOut() �� wchar_t ��
1112 *
1113 * @retval �o��������(wchar_t�P��)
1114 */
1115 int WINAPI CommTextOutW(PComVar cv, const wchar_t *B, int C)
1116 {
1117 char TempStr[12];
1118 BOOL Full = FALSE;
1119 int i = 0;
1120 while (! Full && (i < C)) {
1121 // �o���p�f�[�^������
1122 int TempLen = 0;
1123 size_t output_char_count; // ��������������
1124 OutputCharState state;
1125 state.KanjiCode = cv->KanjiCodeSend;
1126 state.ControlOut = OutControl;
1127 state.SendCode = cv->SendCode;
1128 state.JIS7Katakana = cv->JIS7KatakanaSend;
1129 output_char_count = MakeOutputString(cv, &state, &B[i], C-i, TempStr, &TempLen);
1130
1131 // �f�[�^���o���o�b�t�@��
1132 if (WriteOutBuff(cv, TempStr, TempLen)) {
1133 i += output_char_count; // output_char_count ������ ��������
1134 // ��������������������
1135 cv->SendCode = state.SendCode;
1136 } else {
1137 Full = TRUE;
1138 }
1139 } // end of "while {}"
1140 _CrtCheckMemory();
1141 return i;
1142 }
1143
1144 /**
1145 * CommTextEcho() �� wchar_t ��
1146 *
1147 * @retval �o��������(wchar_t�P��)
1148 */
1149 int WINAPI CommTextEchoW(PComVar cv, const wchar_t *B, int C)
1150 {
1151 char TempStr[12];
1152 BOOL Full = FALSE;
1153 int i = 0;
1154 while (! Full && (i < C)) {
1155 // �o���p�f�[�^������
1156 int TempLen = 0;
1157 size_t output_char_count; // ��������������
1158 OutputCharState state;
1159 state.KanjiCode = cv->KanjiCodeEcho;
1160 state.ControlOut = ControlEcho;
1161 state.SendCode = cv->EchoCode;
1162 state.JIS7Katakana = cv->JIS7KatakanaEcho;
1163 output_char_count = MakeOutputString(cv, &state, &B[i], C-i, TempStr, &TempLen);
1164
1165 // �f�[�^���o���o�b�t�@��
1166 if (WriteInBuff(cv, TempStr, TempLen)) {
1167 i += output_char_count; // output_char_count ������ ��������
1168 // ��������������������
1169 cv->EchoCode = state.SendCode;
1170 } else {
1171 Full = TRUE;
1172 }
1173 } // end of "while {}"
1174 _CrtCheckMemory();
1175 return i;
1176 }
1177
1178 int WINAPI CommBinaryEcho(PComVar cv, PCHAR B, int C)
1179 {
1180 int a, i, Len;
1181 char d[3];
1182
1183 if ( ! cv->Ready )
1184 return C;
1185
1186 PackInBuff(cv);
1187
1188 i = 0;
1189 a = 1;
1190 while ((a>0) && (i<C)) {
1191 Len = 0;
1192
1193 d[Len] = B[i];
1194 Len++;
1195
1196 if ( cv->TelFlag && (B[i]=='\x0d') &&
1197 ! cv->TelBinSend ) {
1198 d[Len] = 0x00;
1199 Len++;
1200 }
1201
1202 if ( cv->TelFlag && (B[i]=='\xff') ) {
1203 d[Len] = '\xff';
1204 Len++;
1205 }
1206
1207 if (WriteInBuff(cv, d, Len)) {
1208 a = 1;
1209 i++;
1210 } else {
1211 a = 0;
1212 }
1213 }
1214 return i;
1215 }
1216
1217 /**
1218 * ���L�����������|�C���^���Z�b�g
1219 */
1220 DllExport void WINAPI SetPMPtr(PMap pm_)
1221 {
1222 pm = pm_;
1223 }
1224
1225 BOOL WINAPI DllMain(HANDLE hInstance,
1226 ULONG ul_reason_for_call,
1227 LPVOID lpReserved)
1228 {
1229 switch( ul_reason_for_call ) {
1230 case DLL_THREAD_ATTACH:
1231 /* do thread initialization */
1232 break;
1233 case DLL_THREAD_DETACH:
1234 /* do thread cleanup */
1235 break;
1236 case DLL_PROCESS_ATTACH:
1237 /* do process initialization */
1238 #ifdef _DEBUG
1239 _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
1240 #endif
1241 WinCompatInit();
1242 break;
1243 case DLL_PROCESS_DETACH:
1244 /* do process cleanup */
1245 // TODO ttermpro.exe���s��
1246 // CloseSharedMemory(pm, HMap);
1247 break;
1248 }
1249 return TRUE;
1250 }

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