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 10130 - (show annotations) (download) (as text)
Tue Aug 9 01:08:44 2022 UTC (20 months ago) by zmatsuo
File MIME type: text/x-csrc
File size: 29315 byte(s)
ttpcmn.dll 内の関数の一部分を ttermpro.exe へ移動

- 文字列などヒープ領域を使用する箇所
  - ttcmn_static.c,h へまとめたて、ttermpro.exeへ移動
- この移動で、ttpcmn.dllとtermpro.exeでモジュールをまたいだヒープの操作はなくなった

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

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