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

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