1 /* $Id: winmain.c,v 1.6 2000/11/16 14:21:32 amura Exp $ */
2 /*  OS dependent code used by Ng for WinCE.
3  *    Copyright (C) 1998 Eiichiro Ito
4  *  Modified for Ng for Win32
5  *    Copyright (C) 1999,2000 Toru Imai
6  *
7  *  This program is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License as published by
9  *  ree Software Foundation; either version 2 of the License, or
10  *  (at your option) any later version.
11  *
12  *  This program is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *  GNU General Public License for more details.
16  *
17  *  You should have received a copy of the GNU General Public License
18  *  along with this program; if not, write to the Free Software
19  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20  */
21 /*
22  * NG : NG program main routine
23  *
24  * 1998/11/14:Eiichiroh Itoh
25  *
26  */
27 
28 /*
29  * $Log: winmain.c,v $
30  * Revision 1.6  2000/11/16 14:21:32  amura
31  * merge Ng for win32 0.5
32  *
33  * Revision 1.5  2000/10/23 16:52:52  amura
34  * add GPL copyright to header
35  *
36  * Revision 1.4  2000/09/01 19:41:21  amura
37  * fix for suppress buffer overrun
38  *
39  * Revision 1.3  2000/07/22 20:46:33  amura
40  * support "Drag&Drop"
41  *
42  * Revision 1.2  2000/07/18 12:42:34  amura
43  * support IME convertion on the spot
44  *
45  * Revision 1.1.1.1  2000/06/27 01:48:00  amura
46  * import to CVS
47  *
48  */
49 
50 #include	<windows.h>
51 #include	<windowsx.h>
52 #include	<commdlg.h>
53 #include	<commctrl.h>
54 #include "config.h"
55 #include "def.h"
56 #include	"ttyctrl.h"
57 #include	"resource.h"
58 #include	"winmain.h"
59 #include	"tools.h"
60 
61 #ifdef KANJI
62 #ifdef USE_KCTRL
63 #include "kctrl.h"
64 #include "cefep.h"
65 #define VALID_KCTRL_VERSION 13
66 #else /* not USE_KCTRL */
67 #include	<imm.h>
68 #endif /* USE_KCTRL */
69 #endif /* KANJI */
70 
71 #if defined(WIN32_PLATFORM_PSPC) && 300 <= _WIN32_WCE
72 #define USE_SHMENU /* Define a macro to indicate using PocketPC menu */
73 #define POCKETPC_MENU_HEIGHT 26 /* Height of Menubar */
74 #else
75 #define POCKETPC_MENU_HEIGHT 0
76 #endif
77 
78 /* #define MG_FOR_PPC
79    This should be defined in the Makefile or dsp file */
80 
81 #if defined(MG_FOR_PPC) || defined(__PsPC__) || 300 <= _WIN32_WCE
82 #include <aygshell.h>
83 #endif
84 
85 #ifdef COMMANDBANDS
86 #if 200 <= _WIN32_WCE
87 #define USE_COMMANDBANDS
88 /* #define USE_BEGINTHREAD */
89 /* instead of CreateThread.  Though I do not care... */
90 #endif
91 #endif
92 
93 #if !defined(MG_FOR_PPC) && !defined(_WIN32_WCE_EMULATION)
94 #ifndef USE_KCTRL
95 #define MG_IME_CONTROL
96 #endif /* USE_KCTRL */
97 #endif /* !defined(MG_FOR_PPC) && !defined(_WIN32_WCE_EMULATION) */
98 
99 #define		EXCEPTION_QUIT			(1)
100 #define		IDM_START				(1001)
101 #define		IDM_EXIT				(1002)
102 #define		IDC_TTY					(2001)
103 
104 #ifdef KANJI
105 #define MGTITLE TEXT("Ng")
106 #define MGCLASS TEXT("NG")
107 #else
108 #define MGTITLE TEXT("Mg")
109 #define MGCLASS TEXT("MG")
110 #endif
111 
112 HINSTANCE	g_hInst ;
113 HWND		g_hwndMain ;
114 HWND		g_hwndTty ;
115 HANDLE		g_hevtGetChar = 0 ;
116 HANDLE		g_hThread = 0 ;
117 BOOL		g_bExit = FALSE ;
118 TCHAR		g_szTitleName[ MAX_PATH ] = MGTITLE;
119 TCHAR		g_szClassName[] = MGCLASS;
120 DWORD		g_dwAppVersion = 12 ;
121 TCHAR		MessageBuf[ MAX_PATH ] = TEXT("") ;
122 CHAR		g_szArgBuf[ 256 ] ;
123 int		g_dwArgc ;
124 LPSTR		g_szArgv[ 128 ] ;
125 #if defined(COMMANDBANDS) && defined(USE_COMMANDBANDS)
126 HIMAGELIST	g_himlrebar; /* Image list for rebar bands */
127 #endif
128 #ifdef CTRLMAP
129 DWORD g_ctrlmap;
130 #endif
131 DWORD g_beepsound, g_keyboardlocale;
132 TCHAR g_beepfile[128];
133 #if defined(KANJI) && defined(USE_KCTRL)
134 DWORD		g_dwDllVersion = 0 ;
135 #endif
136 
137 #if (defined(COMMANDBANDS) && !defined(USE_SHMENU)) || !defined(_WIN32_WCE)
138 #define USE_REGINFO
139 #endif
140 
141 #ifdef USE_REGINFO
142 /* Settings stored in registry */
143 struct reginfo {
144 #if defined(COMMANDBANDS) && !defined(USE_SHMENU)
145   BOOL showbands;
146 #endif /* COMMANDBANDS */
147 #ifndef _WIN32_WCE
148   BOOL maximized;
149   RECT rect; /* rect for the window */
150 #else /* if _WIN32_WCE */
151 #if defined(COMMANDBANDS) && defined(USE_COMMANDBANDS) \
152     && !defined(USE_SHMENU)
153   COMMANDBANDSRESTOREINFO cbinfo[2]; /* Info for Bands */
154 #endif
155 #endif /* _WIN32_WCE */
156   BOOL valid; /* tell if stored info is valid */
157 };
158 
159 static struct reginfo g_reginfo;
160 #endif /* USE_REGINFO */
161 
162 static	BOOL	init_application( void ) ;
163 static	BOOL	init_instance( int nCmdShow ) ;
164 LRESULT CALLBACK	MainWndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam ) ;
165 static	void	cmdline2args( LPSTR cmdline, int *argc, char **argv ) ;
166 static	void	ThreadMain( void ) ;
167 
168 #ifdef CTRLMAP
169 #define VK_EISU 0xf0
170 #define VK_SOMETHING 0xe5
171 
172 static BOOL
controlkey_swap(MSG * msg)173 controlkey_swap(MSG *msg)
174 {
175   if (msg->message == WM_KEYDOWN || msg->message == WM_KEYUP) {
176     if ((int)msg->wParam == VK_EISU) {
177       if (msg->message == WM_KEYDOWN && !(msg->lParam & (1 << 30))) {
178 	/* key was up before this message */
179 	keybd_event(VK_CONTROL, 0, 0, 0);
180       }
181       else if (msg->message == WM_KEYUP && (msg->lParam & (1 << 30))) {
182 	/* key was down before this message */
183 	keybd_event(VK_CONTROL, 0, KEYEVENTF_KEYUP, 0);
184       }
185       return TRUE;
186     }
187     if ((int)msg->wParam == VK_SOMETHING) { /* What's this? */
188       /* Although I don't know the reason and details, some specific
189 	 virtual code is generated according to a key press of
190 	 Japanese mode-related keys such as EISU, HIRAGANA, HANKAKU
191 	 and so on.  Curiously, the virtual code is only generated for
192 	 depressing while Japanese input mode is open.  The following
193 	 program detects the virtual code and treats as control key in
194 	 case EISU is depressed. */
195 
196       SHORT eisu_down;
197 
198       eisu_down = GetAsyncKeyState(VK_EISU);
199       if (eisu_down) {
200 	if (msg->message == WM_KEYDOWN && !(msg->lParam & (1 << 30))) {
201 	  /* key was up before this message */
202 	  keybd_event(VK_CONTROL, 0, 0, 0);
203 	}
204 	return TRUE;
205       }
206     }
207   }
208   return FALSE;
209 }
210 #endif /* CTRLMAP */
211 
212 int WINAPI
213 #ifdef	_WIN32_WCE
WinMain(HINSTANCE hThisInst,HINSTANCE hPrevInst,LPTSTR lpszArgs,int nWinMode)214 WinMain( HINSTANCE hThisInst, HINSTANCE hPrevInst,
215 		 LPTSTR lpszArgs, int nWinMode )
216 #else	/* _WIN32_WCE */
217 WinMain( HINSTANCE hThisInst, HINSTANCE hPrevInst,
218 		 LPSTR lpszArgs, int nWinMode )
219 #endif	/* _WIN32_WCE */
220 {
221 	MSG			msg ;
222 
223 	g_hInst = hThisInst ;
224 #if defined(KANJI) && defined(USE_KCTRL)
225 	g_dwDllVersion = GetKVersion() ;
226 	if ( g_dwDllVersion < VALID_KCTRL_VERSION ) {
227 		wsprintf( MessageBuf,
228 				  TEXT("Obsolete KCTRL.DLL used\r\nPlease use Ver%d.%02d or later"),
229 				  VALID_KCTRL_VERSION / 100, VALID_KCTRL_VERSION % 100 ) ;
230 		MessageBox( NULL, MessageBuf, g_szTitleName, MB_OK|MB_ICONASTERISK ) ;
231 		return FALSE ;
232 	}
233 	if ( !InitFep() ) {
234 		MessageBox( NULL, TEXT("Can't initialize FEP."), g_szTitleName, MB_OK|MB_ICONASTERISK ) ;
235 		return FALSE ;
236 	}
237 	if ( !InitKanjiControls() ) {
238 		wsprintf( MessageBuf,
239 				  TEXT("KCTRL.DLL Initialize error\r\nError=%x"),
240 				  GetLastError() ) ;
241 		MessageBox( NULL, MessageBuf, g_szTitleName, MB_OK|MB_ICONASTERISK ) ;
242 		return FALSE ;
243 	}
244 #endif
245 	/* define a TTY Window */
246 	if ( !TtyViewRegisterClass( g_hInst ) ) {
247 		goto ExitMain ;
248 	}
249 	/* create an event for keyboard input notification */
250 	g_hevtGetChar = CreateEvent( NULL, FALSE, FALSE, NULL ) ;
251 	if ( g_hevtGetChar == NULL ) {
252 		goto ExitMain ;
253 	}
254 	/* define a window class */
255 	if ( !init_application() ) {
256 		goto ExitMain ;
257 	}
258 	/* create a window */
259 	if ( !init_instance( nWinMode ) ) {
260 		goto ExitMain ;
261 	}
262 
263 	{
264 	  DWORD foo;
265 	/* read configuration for Ng for Win32 */
266 #ifdef CTRLMAP
267 	  g_ctrlmap = RegQueryDWord(HKEY_CURRENT_USER, NGREGKEY,
268 				    NGCTRLKEYMAPVAL) ? TRUE : FALSE;
269 #endif
270 	  g_beepsound = RegQueryDWord(HKEY_CURRENT_USER, NGREGKEY,
271 				      NGBEEPSOUNDVAL);
272 	  g_keyboardlocale = RegQueryDWord(HKEY_CURRENT_USER, NGREGKEY,
273 					   NGKEYBOARDLOCALEVAL);
274 	  if (g_keyboardlocale == 0) {
275 #ifndef JAPANESE_KEYBOARD
276 	    g_keyboardlocale = NGKEYBOARD_US;
277 #else
278 	    g_keyboardlocale = NGKEYBOARD_JP;
279 #endif
280 	  }
281 	  SendMessage(g_hwndTty, TTYM_SETKEYBOARDLOCALE,
282 		      (WPARAM)g_keyboardlocale, 0);
283 
284 	  foo = sizeof(g_beepfile);
285 	  RegQueryString(HKEY_CURRENT_USER, NGREGKEY, NGBEEPFILEVAL,
286 			 g_beepfile, &foo);
287 	}
288 
289 	/* create a command line processing routine */
290 #ifdef	_WIN32_WCE
291 	unicode2sjis( lpszArgs, g_szArgBuf, sizeof g_szArgBuf ) ;
292 #else	/* _WIN32_WCE */
293 	strncpy(g_szArgBuf, lpszArgs, sizeof g_szArgBuf);
294 	g_szArgBuf[(sizeof g_szArgBuf)-1] = '\0';
295 #endif	/* _WIN32_WCE */
296 	cmdline2args( g_szArgBuf, &g_dwArgc, g_szArgv ) ;
297 	/* event loop */
298 	while ( GetMessage( &msg, NULL, 0, 0 ) ) {
299 #ifdef CTRLMAP
300 	  if (!g_ctrlmap || !controlkey_swap(&msg)) {
301 	    /* call controlkey_swap() if g_ctrlmap is TRUE */
302 	    TranslateMessage(&msg);
303 	    DispatchMessage(&msg);
304 	  }
305 #else
306 	  TranslateMessage(&msg);
307 	  DispatchMessage(&msg);
308 #endif
309 	}
310 
311 ExitMain:
312 	if ( g_hevtGetChar ) {
313 		/* close the event for keyboard input notification */
314 		CloseHandle( g_hevtGetChar ) ;
315 	}
316 #if defined(KANJI) && defined(USE_KCTRL)
317 	ReleaseKanjiControls() ;
318 #endif
319 	return TRUE ;
320 }
321 
322 /*
323  * register the main window class
324  */
325 static	BOOL
init_application(void)326 init_application( void )
327 {
328 	WNDCLASS	wcl ;
329 	wcl.style         = 0 ;
330 	wcl.lpfnWndProc   = MainWndProc ;
331 	wcl.cbClsExtra    = 0 ;
332 	wcl.cbWndExtra    = 0 ;
333 	wcl.hInstance     = g_hInst ;
334 #ifdef _WIN32_WCE
335 	wcl.hIcon         = NULL ;
336 	wcl.hCursor       = NULL ;
337 #else
338 	wcl.hIcon         = LoadIcon (g_hInst,
339 				      (LPCTSTR)MAKEINTRESOURCE(IDI_APPICON));
340 	wcl.hCursor       = LoadCursor(NULL, IDC_ARROW);
341 #endif
342 	wcl.hbrBackground = (HBRUSH) GetStockObject( WHITE_BRUSH ) ;
343 	wcl.lpszMenuName  = 0 ;
344 	wcl.lpszClassName = g_szClassName ;
345 	if ( !RegisterClass( &wcl ) ) {
346 		return FALSE ;
347 	}
348 
349 	/* initialize common controls */
350 #if 200 <= _WIN32_WCE
351 	{
352 	  INITCOMMONCONTROLSEX icex;
353 
354 	  icex.dwSize = sizeof(icex);
355 	  icex.dwICC = ICC_BAR_CLASSES | ICC_COOL_CLASSES;
356 	  InitCommonControlsEx(&icex);
357 	}
358 #else
359 	InitCommonControls();
360 #endif
361 	return TRUE ;
362 }
363 
364 #define RegQueryBinary(r, k, v, d, s) RegQueryString(r, k, v, (LPTSTR)d, s)
365 
366 #ifdef COMMANDBANDS
367 static HWND g_hwndCB;
368 #endif
369 
370 /*
371  * create a main window
372  */
373 static	BOOL
init_instance(int nCmdShow)374 init_instance( int nCmdShow )
375 {
376 	RECT	rect ;
377         HMENU hMenu = NULL;
378 	int x, y, cx, cy;
379 #ifdef USE_REGINFO
380 	DWORD foo;
381 #endif
382 
383 #ifndef _WIN32_WCE
384 	hMenu = LoadMenu(g_hInst, MAKEINTRESOURCE(IDR_MAINMENU));
385 #endif /* _WIN32_WCE */
386 
387 #ifdef USE_REGINFO /* get window position from registry */
388 	foo = sizeof(g_reginfo);
389         if (RegQueryBinary(HKEY_CURRENT_USER, NGREGKEY, NGPREVPOSVAL,
390 			   &g_reginfo, &foo) == ERROR_SUCCESS) {
391 #ifndef _WIN32_WCE
392 #define MG_MIN_HEIGHT 120
393 #define MG_MIN_WIDTH 160
394 	  if (g_reginfo.rect.bottom - g_reginfo.rect.top < MG_MIN_HEIGHT) {
395 	    g_reginfo.rect.bottom = g_reginfo.rect.top + MG_MIN_HEIGHT;
396 	  }
397 	  if (g_reginfo.rect.right - g_reginfo.rect.left < MG_MIN_WIDTH) {
398 	    g_reginfo.rect.right = g_reginfo.rect.left + MG_MIN_WIDTH;
399 	  }
400 #endif /* _WIN32_WCE */
401 	}
402 	else {
403 	  g_reginfo.valid = FALSE;
404 #ifndef _WIN32_WCE
405 	  g_reginfo.rect.top = 0;
406 	  g_reginfo.rect.bottom = 296;
407 	  g_reginfo.rect.left = 0;
408 	  g_reginfo.rect.right = 500;
409 #endif /* _WIN32_WCE */
410 	}
411 
412 #if defined(COMMANDBANDS) && !defined(USE_SHMENU)
413 	if (!g_reginfo.valid) {
414 	  g_reginfo.showbands = TRUE;
415 	}
416 #endif /* defined(COMMANDBANDS) && !defined(USE_SHMENU) */
417 #endif /* USE_REGINFO */
418 
419 	x = y = cx = cy = CW_USEDEFAULT;
420 #if defined(WIN32_PLATFORM_PSPC) && 300 <= _WIN32_WCE
421 	{
422 	  SIPINFO si;
423 
424 	  memset(&si, 0, sizeof(SIPINFO));
425 	  si.cbSize = sizeof(si);
426 	  if (SHSipInfo(SPI_GETSIPINFO, 0, &si, 0)) {
427 	    if (si.fdwFlags & SIPF_ON) {
428 	      x = si.rcVisibleDesktop.left;
429 	      y = si.rcVisibleDesktop.top;
430 	      cx = si.rcVisibleDesktop.right - si.rcVisibleDesktop.left;
431 	      cy = si.rcVisibleDesktop.bottom - si.rcVisibleDesktop.top
432 		+ POCKETPC_MENU_HEIGHT;
433 	    }
434 	  }
435   	}
436 #endif
437 
438 	/* create a main window */
439 	g_hwndMain = CreateWindowEx( 0, g_szClassName,
440 					g_szTitleName,
441 #ifdef	_WIN32_WCE
442 				        x, y, cx, cy,
443 #else	/* _WIN32_WCE */
444                                         WS_OVERLAPPEDWINDOW | WS_VISIBLE,
445 				        g_reginfo.rect.left,
446 				        g_reginfo.rect.top,
447 				        g_reginfo.rect.right -
448 				          g_reginfo.rect.left,
449 				        g_reginfo.rect.bottom -
450 				          g_reginfo.rect.top,
451 #endif	/* _WIN32_WCE */
452 					NULL, hMenu, g_hInst, NULL ) ;
453 	if ( !g_hwndMain ) {
454 		return FALSE;
455 	}
456 	GetClientRect( g_hwndMain, &rect ) ;
457 
458 #ifdef COMMANDBANDS
459 	{
460 	  int nCommandHeight = 0;
461 
462 #ifdef _WIN32_WCE
463 #ifndef USE_SHMENU
464 #ifdef USE_COMMANDBANDS
465 	  CommandBands_Show(g_hwndCB, g_reginfo.showbands);
466 	  if (g_reginfo.showbands) {
467 	    nCommandHeight = CommandBands_Height(g_hwndCB);
468 	  }
469 #else
470 	  CommandBar_Show(g_hwndCB, g_reginfo.showbands);
471 	  if (g_reginfo.showbands) {
472 	    nCommandHeight = CommandBar_Height(g_hwndCB);
473 	  }
474 #endif /* USE_COMMANDBANDS */
475 #else /* if USE_SHMENU */
476 	  nCommandHeight = 0;
477 #endif /* USE_SHMENU */
478 #endif /* _WIN32_WCE */
479 	  rect.top += nCommandHeight;
480 	}
481 #endif /* COMMANDBANDS */
482 
483 	/* create a TTY window */
484 	g_hwndTty = CreateWindowEx( 0, CTRL_TTYVIEW,
485 					TEXT(""),
486 					WS_VISIBLE|WS_CHILD,
487 					rect.left, rect.top,
488 				        rect.right - rect.left,
489 				        rect.bottom - rect.top,
490 					g_hwndMain, (HMENU) IDC_TTY, g_hInst, NULL ) ;
491 	if ( !g_hwndTty ) {
492 		return FALSE;
493 	}
494 	/* configure the event for keyboard input notification */
495 	SendMessage( g_hwndTty, TTYM_SETEVENT, (WPARAM) g_hevtGetChar, 0 ) ;
496 
497 	/* show the main window */
498 	ShowWindow( g_hwndMain, nCmdShow ) ;
499 	UpdateWindow( g_hwndMain ) ;
500 	SetFocus( g_hwndTty ) ;
501 
502 	/* send a message to commence a thread */
503 	PostMessage( g_hwndMain, WM_COMMAND, IDM_START, 0 ) ;
504 	return TRUE ;
505 }
506 
507 #ifdef COMMANDBANDS
508 
509 #if defined(USE_COMMANDBANDS) && !defined(USE_SHMENU)
510 #define RB_ICON_CX 11
511 #define RB_ICON_CY 15
512 
513 /* Initialize the images for rebar bands */
514 static HIMAGELIST
InitRebarImageLists(HWND hwnd)515 InitRebarImageLists(HWND hwnd)
516 {
517   HBITMAP hbmp;
518   HIMAGELIST res;
519 
520   /* Create the image list for the item pictures */
521   res = ImageList_Create(RB_ICON_CX, RB_ICON_CY, ILC_COLOR | ILC_MASK, 2, 0);
522     /* Create two.  No more will be added.  */
523 
524   if (res) {
525     /* Add the bitmaps to the list */
526     hbmp = LoadBitmap(g_hInst, MAKEINTRESOURCE(IDB_REBAR));
527     if (hbmp) {
528       if (ImageList_AddMasked(res, hbmp, RGB(255, 0, 0)) != -1) {
529 	/* Fail if not all the images were added */
530 	if (3 <= ImageList_GetImageCount(res)) {
531 	  /* All is fine.  But this specific condition does not check
532 	     anything. */
533 	}
534       }
535       /* Clean up the GDI objects */
536       DeleteObject(hbmp);
537     }
538     else {
539       ImageList_Destroy(res);
540       res = (HIMAGELIST)NULL;
541     }
542   }
543   return res;
544 }
545 #endif /* defined(USE_COMMANDBANDS) && !defined(USE_SHMENU) */
546 
547 #ifndef USE_SHMENU
548 /* It is very strange for me to define this by myself... */
549 #define NUM_STD_BITMAPS   15
550 
551 #define TBSTATE_DISABLED 0
552 
553 #define BTNID(x) ((x) - IDBN_MARK + NUM_STD_BITMAPS)
554 
555 /* Tool buttons */
556 static TBBUTTON MGButton[] = {
557 #ifndef USE_COMMANDBANDS
558   /* For a space */
559   {0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0, 0,  0},
560 #endif
561   {BTNID(IDBN_MARK), IDC_MARK, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, -1},
562   {0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0, 0,  0},
563   {STD_CUT, IDC_CUT, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, -1},
564   {STD_COPY, IDC_COPY, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, -1},
565   {STD_PASTE, IDC_PASTE, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, -1},
566   {0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0, 0,  0},
567   {BTNID(IDBN_PRIOR), IDC_PRIOR, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, -1},
568   {BTNID(IDBN_NEXT), IDC_NEXT, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, -1},
569 };
570 
571 /* Tool tips */
572 static int MGTips[] = {
573   IDS_MARK,
574   IDS_CUT,
575   IDS_COPY,
576   IDS_PASTE,
577   IDS_PRIOR,
578   IDS_NEXT,
579 };
580 
581 #define NUM_TIPS (sizeof(MGTips) / sizeof(int))
582 
583 #define MAX_TIP_STRING 32 /* Max string length for tool tips */
584 
585 static LPTSTR *g_tooltips;
586 
587 /* Create resource from Tool tip strings */
588 static LPTSTR *
LoadToolTips(int * tips)589 LoadToolTips(int *tips)
590 {
591   int *p, *ep;
592   LPTSTR *res, *ps;
593   TCHAR buf[MAX_TIP_STRING];
594 
595   res = LocalAlloc(LPTR, sizeof(LPTSTR) * NUM_TIPS);
596   if (res) {
597     for (p = MGTips, ep = p + NUM_TIPS, ps = res ; p < ep ; p++, ps++) {
598       LoadString(g_hInst, *p, buf, MAX_TIP_STRING);
599       *ps = LocalAlloc(LPTR, sizeof(TCHAR) * (lstrlen(buf) + 1));
600       if (*ps) {
601 	lstrcpy(*ps, buf);
602       }
603       else {
604 	LPTSTR *q;
605 
606 	for (q = res ; q < ps ; q++) {
607 	  LocalFree(*q);
608 	}
609 	LocalFree(res);
610 	return NULL;
611       }
612     }
613   }
614   g_tooltips = res;
615   return res;
616 }
617 
618 /* Destroy Tool tip strings  */
619 static void
FreeToolTips(void)620 FreeToolTips(void)
621 {
622   if (g_tooltips) {
623     LPTSTR *p, *ep;
624 
625     for (p = g_tooltips, ep = p + NUM_TIPS ; p < ep ; p++) {
626       LocalFree(*p);
627     }
628     LocalFree(g_tooltips);
629     g_tooltips = NULL;
630   }
631 }
632 
633 /* Create tool buttons */
634 static void
CreateToolButtons(HWND hwnd)635 CreateToolButtons(HWND hwnd)
636 {
637 #ifdef _WIN32_WCE
638   /* Are there any macro for "16"? */
639   CommandBar_AddBitmap(hwnd, HINST_COMMCTRL, IDB_STD_SMALL_COLOR,
640 		       NUM_STD_BITMAPS, 16, 16);
641   CommandBar_AddBitmap(hwnd, g_hInst, IDB_BUTTONS, 3, 16, 16);
642   CommandBar_AddButtons(hwnd, sizeof(MGButton)/sizeof(TBBUTTON), MGButton);
643 
644   if (LoadToolTips(MGTips)) {
645     CommandBar_AddToolTips(hwnd, NUM_TIPS, g_tooltips);
646   }
647 #endif /* _WIN32_WCE */
648 }
649 
650 #endif /* !USE_SHMENU */
651 
652 #define IDD_REBAR    901 /* ID used at message processing */
653 #define SF_RBMENU    902
654 #define SF_RBBUTTON  903
655 
656 #endif /* COMMANDBANDS */
657 
658 void
MainWMCreate(HWND hWnd)659 MainWMCreate( HWND hWnd )
660 {
661 	HICON	hIcon ;
662 
663 	hIcon = (HICON) LoadImage( g_hInst, MAKEINTRESOURCE(IDI_APPICON),
664 							  IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR ) ;
665 	if ( hIcon ) {
666 		SendMessage( hWnd, WM_SETICON, FALSE, (LPARAM)hIcon ) ;
667 	}
668 
669 #ifdef _WIN32_WCE
670 #ifdef COMMANDBANDS
671 #ifndef USE_SHMENU
672 #ifndef USE_COMMANDBANDS
673   g_hwndCB = CommandBar_Create(g_hInst, hWnd, 1);
674   CommandBar_InsertMenubar(g_hwndCB, g_hInst, IDR_MAINMENU, 0);
675   CreateToolButtons(g_hwndCB);
676 #ifndef MG_FOR_PPC
677     /* add [X] Button */
678   CommandBar_AddAdornments(g_hwndCB, 0, 0);
679 #endif
680 #else /* if USE_COMMANDBANDS */
681   {
682     HWND hwnd2;
683     REBARBANDINFO arbbi[2];
684 
685     /* Initialize images for Rebar bands */
686     g_himlrebar = InitRebarImageLists(hWnd);
687 
688     g_hwndCB = CommandBands_Create(g_hInst, hWnd, IDD_REBAR,
689 				 RBS_VARHEIGHT | RBS_BANDBORDERS |
690 				 RBS_SMARTLABELS, g_himlrebar);
691 
692     arbbi[0].cbSize = sizeof(REBARBANDINFO);
693     arbbi[0].fMask = RBBIM_STYLE | RBBIM_SIZE | RBBIM_IMAGE | RBBIM_ID;
694     arbbi[0].wID = SF_RBMENU;
695     arbbi[0].iImage = 0;
696     arbbi[0].fStyle = RBBS_NOGRIPPER;
697     arbbi[0].cx = 62;
698 
699     arbbi[1].cbSize = sizeof(REBARBANDINFO);
700     arbbi[1].fMask = RBBIM_STYLE | RBBIM_SIZE | RBBIM_IMAGE | RBBIM_ID;
701     arbbi[1].wID = SF_RBBUTTON;
702     arbbi[1].iImage = 1;
703     arbbi[1].fStyle = 0;
704     arbbi[1].cx = 300;
705 
706     if (g_reginfo.valid) { /* if valid info stored in registry */
707       arbbi[0].fStyle = g_reginfo.cbinfo[0].fStyle;
708       arbbi[1].fStyle = g_reginfo.cbinfo[1].fStyle;
709       arbbi[0].cx = g_reginfo.cbinfo[0].cxRestored;
710       arbbi[1].cx = g_reginfo.cbinfo[1].cxRestored;
711     }
712 
713     CommandBands_AddBands(g_hwndCB, g_hInst, 2, arbbi);
714 
715     /* Add Menu */
716     hwnd2 = CommandBands_GetCommandBar(g_hwndCB, 0);
717     CommandBar_InsertMenubar(hwnd2, g_hInst, IDR_MAINMENU, 0);
718 
719     /* Add Buttons */
720     hwnd2 = CommandBands_GetCommandBar(g_hwndCB, 1);
721     CreateToolButtons(hwnd2);
722 
723 #ifndef MG_FOR_PPC
724     /* add [X] Button */
725     CommandBands_AddAdornments(g_hwndCB, g_hInst, 0, 0);
726 #endif
727 
728     if (g_reginfo.valid) { /* if valid info stored in registry */
729       if (g_reginfo.cbinfo[0].fMaximized) {
730 	SendMessage(g_hwndCB, RB_MAXIMIZEBAND, (WPARAM)0, (LPARAM)0);
731       }
732       if (g_reginfo.cbinfo[1].fMaximized) {
733 	SendMessage(g_hwndCB, RB_MAXIMIZEBAND, (WPARAM)1, (LPARAM)0);
734       }
735     }
736   }
737 #endif /* USE_COMMANDBANDS */
738 #else /* USE_SHMENU */
739   {
740     SHMENUBARINFO mbi;
741     RECT rc;
742 
743     memset(&mbi, 0, sizeof(SHMENUBARINFO));
744     mbi.cbSize = sizeof(SHMENUBARINFO);
745     mbi.hwndParent = hWnd;
746     mbi.dwFlags = 0;
747     mbi.nToolBarId = IDR_PPCMENU;
748     mbi.hInstRes = g_hInst;
749     mbi.nBmpId = IDB_BUTTONS;
750     mbi.cBmpImages = 3;
751 
752     if (SHCreateMenuBar(&mbi)) {
753       g_hwndCB = mbi.hwndMB;
754     }
755     else {
756       g_hwndCB = (HWND)NULL;
757     }
758 
759     GetWindowRect(hWnd, &rc);
760     rc.bottom -= POCKETPC_MENU_HEIGHT;
761     if (g_hwndCB) {
762       MoveWindow(hWnd, rc.left, rc.top,
763 		 rc.right - rc.left, rc.bottom - rc.top, FALSE);
764     }
765   }
766 #endif /* USE_SHMENU */
767 #endif /* COMMANDBANDS */
768 #endif /* _WIN32_WCE */
769 }
770 
771 #ifdef SPI_GETSIPINFO
772 static void
AdjustAgainstSIP(HWND hWnd,UINT param)773 AdjustAgainstSIP(HWND hWnd, UINT param)
774 {
775   SIPINFO sipinf;
776   BOOL sipres;
777 
778   sipinf.cbSize = sizeof(sipinf);
779   sipinf.dwImDataSize = 0;
780   sipinf.pvImData = NULL;
781 
782 #if _WIN32_WCE >= 210
783   sipres = SipGetInfo(&sipinf);
784 #else
785   sipres = SHSipInfo(SPI_GETSIPINFO, param, &sipinf, 0);
786 #endif
787 
788   if (sipres) {
789     RECT winrect;
790 
791     GetWindowRect(hWnd, &winrect);
792     if (!EqualRect(&winrect, &sipinf.rcVisibleDesktop)) {
793       int shmenuheight = 0;
794 
795 #ifdef USE_SHMENU
796       if (!(sipinf.fdwFlags & SIPF_ON)) {
797 	shmenuheight = POCKETPC_MENU_HEIGHT;
798       }
799 #endif /* USE_SHMENU */
800 
801       MoveWindow(hWnd,
802 		 sipinf.rcVisibleDesktop.left,
803 		 sipinf.rcVisibleDesktop.top,
804 		 sipinf.rcVisibleDesktop.right -
805 		 sipinf.rcVisibleDesktop.left,
806 		 sipinf.rcVisibleDesktop.bottom -
807 		 sipinf.rcVisibleDesktop.top - shmenuheight, FALSE);
808     }
809   }
810 }
811 #endif /* SPI_GETSIPINFO */
812 
813 static void
AdjustPane(HWND hwnd)814 AdjustPane(HWND hwnd)
815 {
816   RECT rect;
817 #ifdef _WIN32_WCE
818 #ifdef COMMANDBANDS
819   int nCommandHeight;
820 #endif /* COMMANDBANDS */
821 #endif /* _WIN32_WCE */
822 
823   GetClientRect(g_hwndMain, &rect);
824 
825 #ifdef _WIN32_WCE
826 #ifdef COMMANDBANDS
827 #ifndef USE_SHMENU
828 #ifndef USE_COMMANDBANDS
829   if (CommandBar_IsVisible(g_hwndCB)) {
830     nCommandHeight = CommandBar_Height(g_hwndCB);
831   }
832 #else /* if USE_COMMANDBANDS */
833   if (CommandBands_IsVisible(g_hwndCB)) {
834     nCommandHeight = CommandBands_Height(g_hwndCB);
835   }
836   else {
837     nCommandHeight = 0;
838   }
839 #endif /* USE_COMMANDBANDS */
840 #else /* if USE_SHMENU */
841   nCommandHeight = 0;
842 #endif /* USE_SHMENU */
843   rect.top += nCommandHeight;
844 #endif /* COMMANDBANDS */
845 #endif /* _WIN32_WCE */
846 
847   MoveWindow(g_hwndTty, rect.left, rect.top,
848 	     rect.right - rect.left,
849 	     rect.bottom - rect.top, TRUE);
850 }
851 
852 int ConfigStartupFilePath(int, int);
853 
854 /*
855  * WinProc for main window
856  */
857 LRESULT CALLBACK
MainWndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)858 MainWndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
859 {
860 #ifdef SPI_GETSIPINFO
861 	static BOOL SIPChanged = FALSE;
862 #endif
863 	DWORD	threadID ;
864 
865 	switch ( message ) {
866 	case WM_CREATE:
867 		MainWMCreate( hWnd ) ;
868 		break ;
869 	case WM_CLOSE:
870 		SendMessage(g_hwndTty, TTYM_COMMAND,
871 			    (WPARAM)IDC_CLOSE, (LPARAM)NULL);
872 		break ;
873 	case WM_DESTROY:
874 #ifdef CTRLMAP
875 		if (g_ctrlmap) {
876 		  /* send ctrl key `up' event in order to prevent
877 		     ctrl key to be kept in a state of `depressed' */
878 		  keybd_event(VK_CONTROL, 0, KEYEVENTF_KEYUP, 0);
879 		}
880 #endif
881 #if defined(COMMANDBANDS) && !defined(USE_SHMENU)
882 #ifdef _WIN32_WCE
883 #ifdef USE_COMMANDBANDS
884 		g_reginfo.cbinfo[0].cbSize = sizeof(COMMANDBANDSRESTOREINFO);
885 		CommandBands_GetRestoreInformation(g_hwndCB,
886 	     SendMessage(g_hwndCB, RB_IDTOINDEX, (WPARAM)SF_RBMENU, (LPARAM)0),
887 			g_reginfo.cbinfo);
888 		CommandBands_GetRestoreInformation(g_hwndCB,
889 	     SendMessage(g_hwndCB, RB_IDTOINDEX, (WPARAM)SF_RBBUTTON,
890 			(LPARAM)0), g_reginfo.cbinfo + 1);
891 		/* Is "Destroy" necessary?
892 		   No.  Because there are no CommandBands_Destroy()!? */
893 #else /* if !USE_COMMANDBANDS */
894 		   CommandBar_Destroy(g_hwndCB);
895 #endif /* !USE_COMMANDBANDS */
896 #endif /* _WIN32_WCE */
897 		/* Free Tool Tip strings */
898 		FreeToolTips();
899 #endif /* COMMANDBANDS && !USE_SHMENU */
900 
901 #ifndef _WIN32_WCE
902 		if (!g_reginfo.maximized)
903 			GetWindowRect(g_hwndMain, &g_reginfo.rect);
904 #endif /* _WIN32_WCE */
905 #ifdef USE_REGINFO
906 		/* Store settings to registry db */
907 		g_reginfo.valid = TRUE;
908 		RegSetBinary(HKEY_CURRENT_USER, NGREGKEY, NGPREVPOSVAL,
909 			     (LPBYTE)&g_reginfo, sizeof(g_reginfo));
910 #endif
911 
912 #ifdef _WIN32_WCE
913 #if defined(COMMANDBANDS) && defined(USE_COMMANDBANDS) \
914 		&& !defined(USE_SHMENU)
915 		if (g_himlrebar) { /* Destroy Image List */
916 			ImageList_Destroy(g_himlrebar);
917 			g_himlrebar = NULL;
918 		}
919 #endif
920 #else /* not _WIN32_WCE */
921 		/* Destroy Menu */
922 		if (GetMenu(hWnd)) {
923 			DestroyMenu(GetMenu(hWnd));
924 		}
925 #endif
926 		g_bExit = TRUE ;
927 		Sleep( 1000 ) ;
928 		PostQuitMessage( 0 ) ;
929 		break ;
930 	case WM_SETFOCUS:
931 #ifdef SPI_GETSIPINFO
932 		AdjustAgainstSIP(hWnd, 0);
933 		SIPChanged = FALSE;
934 #endif
935 		SetFocus( g_hwndTty ) ;
936 		break ;
937 
938 #if !defined(_WIN32_WCE) || 200 <= _WIN32_WCE
939 	case WM_SIZE:
940 		switch (wParam) {
941 		case SIZE_MAXIMIZED:
942 		case SIZE_RESTORED:
943 		  AdjustPane(g_hwndMain);
944 #ifndef _WIN32_WCE
945 		  /* the following processing is intended to save the
946                      previous window position */
947 		  g_reginfo.maximized = (wParam == SIZE_MAXIMIZED);
948 #endif
949 		  break;
950 
951 		default:
952 		  break;
953 		}
954 		return 0;
955 #endif
956 
957 	case WM_COMMAND:
958 		switch ( GET_WM_COMMAND_ID( wParam, lParam ) ) {
959 		case IDM_START:
960 			g_hThread = CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE) ThreadMain, 0, 0, &threadID ) ;
961 			if ( g_hThread != NULL ) {
962 				CloseHandle( g_hThread ) ;
963 				break ;
964 			}
965 			//
966 		case IDM_EXIT:
967 			DestroyWindow(hWnd);
968 			break ;
969 
970 		case IDC_OPTION:
971 			ConfigStartupFilePath(0, 0);
972 			break;
973 
974 	        default:
975 			SendMessage(g_hwndTty, TTYM_COMMAND, wParam, lParam);
976 			break;
977   		}
978 		break ;
979 
980 #ifdef SPI_GETSIPINFO
981 	case WM_SETTINGCHANGE:
982 		switch (wParam) {
983 		case SPI_SETSIPINFO:
984 		case SPI_SETCURRENTIM:
985 			if (GetActiveWindow())
986 				AdjustAgainstSIP(hWnd, (UINT)lParam);
987 			else
988 				SIPChanged = TRUE;
989 	 		break;
990 #endif
991 
992 	case WM_NOTIFY:
993 		switch(((LPNMHDR)lParam)->code) {
994 #ifdef RBN_HEIGHTCHANGE
995 		/* The height of Rebar has changed */
996 		case RBN_HEIGHTCHANGE:
997 			AdjustPane(hWnd);
998 			break;
999 #endif
1000 		}
1001 		break;
1002 	default:
1003 		return DefWindowProc( hWnd, message, wParam, lParam ) ;
1004 	}
1005 	return 0 ;
1006 }
1007 
1008 int
1009 Kbhit( void )
1010 {
1011 	return SendMessage( g_hwndTty, TTYM_KBHIT, 0, 0 ) ? 1 : 0 ;
1012 }
1013 
1014 int
1015 KbhitSleep( DWORD sec )
1016 {
1017 	WaitForSingleObject( g_hevtGetChar, sec * 1000 ) ;
1018 	if ( g_bExit ) {
1019 		ExitThread( 0 ) ;
1020 		return FALSE ;
1021 	}
1022 	return Kbhit() ;
1023 }
1024 
1025 int
1026 GetChar( void )
1027 {
1028 	int		c ;
1029 
1030 	while ( 1 ) {
1031 	        while (1) {
1032 		  extern VOID MouseEvent pro((int, int, int));
1033 		  c = SendMessage(g_hwndTty, TTYM_GETWINDOWEVENT, 0, 0);
1034 		  if (c < 0) {
1035 		    break;
1036 		  }
1037 		  else {
1038 		    switch (c & TTY_WM_MASK) {
1039 		    case TTY_WM_MOUSE:
1040 		      MouseEvent(0, (c >> 4) & 0x3fff, (c >> 18) & 0x3fff);
1041 		      break;
1042 
1043 #if !defined(_WIN32_WCE) || 200 <= _WIN32_WCE
1044 		    case TTY_WM_RESIZE:
1045 		      {
1046 			extern int refresh pro((int, int));
1047 			refresh(FFRAND, 0); /* Very easy way... */
1048 		      }
1049 		      break;
1050 #endif
1051 
1052 #ifdef	DROPFILES	/* 00.07.07  by sahf */
1053 		    case TTY_WM_DROPFILES:
1054 		      {
1055 			HLOCAL hMemory;
1056 			extern VOID DropEvent pro((const char *, int));
1057 			/* hMemory got filename buffer address... */
1058 			c = SendMessage( g_hwndTty, TTYM_DROPFILES, 0, (LPARAM)&hMemory );
1059 			if ( c == -1 ) {
1060 			  break ;
1061 			}
1062 			DropEvent((const char *)hMemory, c);
1063 			LocalFree(hMemory);	/* allocated in ttyctrl.cpp */
1064 		      }
1065 		    break;
1066 #endif	/* DROPFILES */
1067 		    }
1068 		  }
1069 		}
1070 		c = SendMessage( g_hwndTty, TTYM_GETCHAR, 0, 0 ) ;
1071 		if ( c != -1 ) {
1072 			break ;
1073 		}
1074 		WaitForSingleObject( g_hevtGetChar, INFINITE ) ;
1075 		if ( g_bExit ) {
1076 			ExitThread( 0 ) ;
1077 			break ;
1078 		}
1079 	}
1080 	ResetEvent( g_hevtGetChar ) ;
1081 	return c ;
1082 }
1083 
1084 void
1085 GotoXY( int x, int y )
1086 {
1087 	SendMessage( g_hwndTty, TTYM_GOTOXY, MAKEWPARAM( y, x ), 0 ) ;
1088 }
1089 
1090 void
1091 EraseEOL( void )
1092 {
1093 	SendMessage( g_hwndTty, TTYM_ERASEEOL, 0, 0 ) ;
1094 }
1095 
1096 void
1097 EraseEOP( void )
1098 {
1099 	SendMessage( g_hwndTty, TTYM_ERASEEOP, 0, 0 ) ;
1100 }
1101 
1102 void
1103 PutChar( char c )
1104 {
1105 	SendMessage( g_hwndTty, TTYM_PUTCHAR, (WPARAM) c, 0 ) ;
1106 }
1107 
1108 void
1109 PutKChar( char c1, char c2 )
1110 {
1111   SendMessage(g_hwndTty, TTYM_PUTKCHAR, MAKEWPARAM(c2, c1), 0);
1112 }
1113 
1114 void
1115 PutLine( int y, unsigned char *sjis, short color )
1116 {
1117 	SendMessage( g_hwndTty, TTYM_PUTLINE, MAKEWPARAM( color, y ), (LPARAM) sjis ) ;
1118 }
1119 
1120 void
1121 Flush( void )
1122 {
1123 	SendMessage( g_hwndTty, TTYM_FLUSH, 0, 0 ) ;
1124 }
1125 
1126 void
1127 GetWH( int *w, int *h )
1128 {
1129 	DWORD	ret ;
1130 
1131 	ret = SendMessage( g_hwndTty, TTYM_GETWH, 0, 0 ) ;
1132 	*w = HIWORD( ret ) ;
1133 	*h = LOWORD( ret ) ;
1134 }
1135 
1136 void
1137 Exit( int code )
1138 {
1139 	RaiseException( EXCEPTION_QUIT, 0, 0, 0 ) ;
1140 }
1141 
1142 void
1143 MessageOut( LPCSTR buf )
1144 {
1145 	sjis2unicode( buf, MessageBuf, sizeof MessageBuf ) ;
1146 	MessageBox( g_hwndMain, MessageBuf, MGTITLE, MB_OK ) ;
1147 }
1148 
1149 /*
1150  * Command line related procedure
1151  */
1152 static void
1153 cmdline2args( LPSTR cmdline, int *argc, char **argv )
1154 {
1155 	CHAR	c ;
1156 	BOOL	f_skip = TRUE, f_quote = FALSE ;
1157 
1158 	argv[ 0 ] = "" ;
1159 	*argc = 1 ;
1160 	while ( c = *cmdline ) {
1161 		if ( f_skip ) {
1162 			if ( !(c == ' ' || c == '\t') ) {
1163 				if ( c == '"' ) {
1164 					f_quote = TRUE ;
1165 					cmdline ++ ;
1166 				}
1167 				argv[ (*argc) ++ ] = cmdline ;
1168 				f_skip = FALSE ;
1169 			}
1170 		} else {
1171 			if ( f_quote ) {
1172 				if ( c == '"' ) {
1173 					f_quote = FALSE ;
1174 					*cmdline = 0 ;
1175 					f_skip = TRUE ;
1176 				}
1177 			} else if ( (c == ' ' || c == '\t') ) {
1178 				*cmdline = 0 ;
1179 				f_skip = TRUE ;
1180 			}
1181 		}
1182 		cmdline ++ ;
1183 	}
1184 }
1185 
1186 /*
1187  * main routine for a thread
1188  */
1189 static void
1190 ThreadMain( void )
1191 {
1192 	__try {
1193 		Main( g_dwArgc, g_szArgv ) ;
1194 	} __except ( GetExceptionCode() == EXCEPTION_QUIT ) {
1195 		// do nothing
1196 	}
1197 	SendMessage( g_hwndMain, WM_COMMAND, IDM_EXIT, 0 ) ;
1198 	ExitThread( 0 ) ;
1199 }
1200 
1201 #ifdef FEPCTRL
1202 #define fep_init() /* nothing to do */
1203 #define fep_term() /* nothing to do */
1204 
1205 static int fepctrl = FALSE;		/* FEP control enable flag	*/
1206 static int fepmode = TRUE;		/* now FEP mode			*/
1207 
1208 static BOOL g_ime_prevopened;
1209 
1210 fepmode_on()
1211 {
1212 #ifndef USE_KCTRL
1213 	if (fepctrl && !fepmode) {
1214 		HIMC hIMC = ImmGetContext(g_hwndTty);
1215 		if (hIMC) {
1216 			ImmSetOpenStatus(hIMC, g_ime_prevopened);
1217 			ImmReleaseContext(g_hwndTty, hIMC);
1218 		}
1219 		fepmode = TRUE;
1220 	}
1221 #endif
1222 	return 0;
1223 }
1224 
1225 /* The following fepmode_off() provides a doubled fepmode_off()
1226    feature.  That is, the second call for the fepmode_off() is
1227    expected to change the previous fep mode as off, without doing any
1228    actual fep control since the fep mode has been already turned off
1229    by the first call of the function.  So, the succeeding fepmode_on()
1230    will not turn on the fep mode even if the previous fep mode was on
1231    before the first call of fepmode_off().
1232 
1233    By Tillanosoft, Mar 21, 1999 */
1234 fepmode_off()
1235 {
1236 #ifndef USE_KCTRL
1237 	if (fepctrl) {
1238 		if (fepmode) {
1239 			HIMC hIMC = ImmGetContext(g_hwndTty);
1240 			if (hIMC) {
1241 				g_ime_prevopened = ImmGetOpenStatus(hIMC);
1242 				if (g_ime_prevopened)
1243 					ImmSetOpenStatus(hIMC, FALSE);
1244 				ImmReleaseContext(g_hwndTty, hIMC);
1245 			}
1246 			fepmode = FALSE;
1247 		}
1248 		else {
1249 		    g_ime_prevopened = FALSE;
1250 		}
1251 	}
1252 #endif
1253 	return 0;
1254 }
1255 
1256 fepmode_set(f, n)
1257 {
1258 	register int s;
1259 	char buf[NFILEN];
1260 	/* extern int ereply(); *//* declared in def.h */
1261 
1262 	if (f & FFARG) {
1263 		n = (n > 0);
1264 	}
1265 	else {
1266 		if ((s = ereply("FEP Control: ", buf, NFILEN)) != TRUE)
1267 			return (s);
1268 		if (ISDIGIT(buf[0]) || buf[0] == '-')
1269 			n = (atoi(buf) > 0);
1270 		else if (buf[0] == 't' || buf[0] == 'T')
1271 			n = TRUE;
1272 		else /* if (buf[0] == 'n' || buf[0] == 'N') */
1273 			n = FALSE;
1274 	}
1275 
1276 	if (!fepctrl && n) {
1277 		fepmode = TRUE;
1278 	}
1279 	else if (fepctrl && !n) {
1280 		/* nothing to do */
1281 	}
1282 	fepctrl = n;
1283 
1284 	return TRUE;
1285 }
1286 
1287 fepmode_chg(f, n)
1288 {
1289 	fepctrl = !fepctrl;
1290 	if (fepctrl) {
1291 		fepmode = TRUE;
1292 	}
1293 	return TRUE;
1294 }
1295 
1296 int
1297 fepmode_toggle( int f, int n )
1298 {
1299 #ifdef USE_KCTRL
1300 	Fep_Execute( g_hwndMain ) ;
1301 	return TRUE ;
1302 #else /* if !USE_KCTRL */
1303 	HIMC hIMC = ImmGetContext(g_hwndTty);
1304 	if (hIMC) {
1305 		BOOL ime_open = ImmGetOpenStatus(hIMC);
1306 		g_ime_prevopened = !ime_open;
1307 		ImmSetOpenStatus(hIMC, !ime_open);
1308 		ImmReleaseContext(g_hwndTty, hIMC);
1309 	}
1310 	return TRUE;
1311 #endif
1312 }
1313 #endif /* FEPCTRL */
1314 
1315 #ifdef KANJI
1316 #define	etos(c1, c2)	\
1317 {\
1318 	c1 &= 0x7f;\
1319 	c2 &= 0x7f;\
1320 	if(c1 >= 0x5f)\
1321 		c1 += 0x80;\
1322 	if((c1 % 2) == 0) {\
1323 		c1 = (c1 - 0x30) / 2 + 0x88;\
1324 		c2 += 0x7e;\
1325 	} else {\
1326 		if(c2 >= 0x60)\
1327 			c2 += 0x01;\
1328 		c1 = (c1 - 0x31) / 2 + 0x89;\
1329 		c2 += 0x1f;\
1330 	}\
1331 	c1 &= 0xff;\
1332 	c2 &= 0xff;\
1333 }
1334 #endif
1335 
1336 void
1337 #ifdef HANKANA  /* 92.11.21  by S.Sasaki */
1338 putline( int row, int column, unsigned char *s, unsigned char *t, short color )
1339 #else
1340 putline(int row, int column, unsigned char *s, short color)
1341 #endif
1342 {
1343 #ifdef KANJI
1344         int c1 = 0, c2;
1345 #ifdef HANKANA
1346 	unsigned char *ccp1;
1347 #endif
1348 #endif
1349 	int c;
1350 	unsigned char	sjis[ 256 ], *dst, *cp1, *cp2;
1351 
1352 	dst = sjis ;
1353 	cp1 = &s[0] ;
1354 	cp2 = &s[ncol] ;
1355 #ifdef HANKANA
1356 	ccp1 = &t[0] ;
1357 #endif
1358 	while ( cp1 != cp2 ) {
1359 		c = *cp1 ++ ;
1360 #ifdef KANJI
1361 #ifdef HANKANA
1362 		c2 = *ccp1 ++ ;
1363 #endif
1364 		if ( c1 ) {
1365 			etos( c1, c ) ;
1366 			*dst++ = c1 ;
1367 			*dst++ = c ;
1368 			c1 = 0 ;
1369 #ifdef HANKANA
1370 		} else if ( (c & 0xFF) == 0x8E && c2 != 0 ) {
1371 			*dst++ = c2 ;
1372 #endif
1373 		} else if ( ISKANJI( c ) ) {
1374 			c1 = c ;
1375 		} else
1376 #endif
1377 			*dst++ = c ;
1378 	}
1379 	*dst = 0 ;
1380 	PutLine(row, sjis, (short)(color == CMODE ? 1 : 0));
1381 }
1382 
1383 #if defined(COMMANDBANDS) && !defined(USE_SHMENU)
1384 static BOOL CALLBACK
1385 ViewProc(HWND hDlg, UINT message, UINT wParam, LONG lParam)
1386 {
1387   switch (message) {
1388   case WM_INITDIALOG:
1389     Button_SetCheck(GetDlgItem(hDlg, IDC_SHOWMENUBAR), g_reginfo.showbands);
1390     return 1;
1391 
1392   case WM_COMMAND:
1393 #if 0
1394     switch (LOWORD(wParam)) {
1395     case IDC_SHOWMENUBAR:
1396       break;
1397     }
1398 #endif
1399     return 0;
1400 
1401   case WM_NOTIFY:
1402     switch (((LPNMHDR)lParam)->code) {
1403     case PSN_SETACTIVE: /* Visit this page */
1404       SetWindowLong(hDlg, DWL_MSGRESULT, 0);
1405       return TRUE;
1406 
1407     case PSN_APPLY:
1408       {
1409 	BOOL newvalue;
1410 	newvalue = Button_GetCheck(GetDlgItem(hDlg, IDC_SHOWMENUBAR));
1411 	if (g_reginfo.showbands != newvalue) {
1412 	  g_reginfo.showbands = newvalue;
1413 #ifdef _WIN32_WCE
1414 #ifdef USE_COMMANDBANDS
1415 	  CommandBands_Show(g_hwndCB, newvalue);
1416 #else
1417 	  CommandBar_Show(g_hwndCB, newvalue);
1418 #endif
1419 	  AdjustPane(g_hwndMain);
1420 #endif
1421 	}
1422       }
1423       SetWindowLong(hDlg, DWL_MSGRESULT, PSNRET_NOERROR);
1424       return TRUE;
1425 
1426     case PSN_KILLACTIVE: /* Go away from this page */
1427       SetWindowLong(hDlg, DWL_MSGRESULT, FALSE);
1428       return(TRUE);
1429 
1430     case PSN_RESET: /* CANCEL Button */
1431       return TRUE;
1432     }
1433 
1434   default:
1435     return 0;
1436   }
1437 }
1438 #endif /* defined(COMMANDBANDS) && !defined(USE_SHMENU) */
1439 
1440 #ifndef NO_STARTUP
1441 /* Dialog Proc to change the startup file path */
1442 
1443 #define MAXFILENAMESIZE 160
1444 #define INIFILEFILTER TEXT("INI file (*.ini)\0*.ini\0All files (*.*)\0*.*\0")
1445 
1446 static OPENFILENAME templateofn = {
1447     sizeof(OPENFILENAME), NULL, 0, INIFILEFILTER, NULL, 0, 0,
1448     NULL, 0, NULL, 0, NULL, TEXT("INI File"),
1449     OFN_HIDEREADONLY, 0, 0, NULL, 0, NULL, NULL};
1450 
1451 static BOOL CALLBACK
1452 StartFileProc(HWND hDlg, UINT message, UINT wParam, LONG lParam)
1453 {
1454   TCHAR	unicode[MAX_PATH];
1455   DWORD foo = sizeof(unicode);
1456 
1457   switch (message) {
1458   case WM_INITDIALOG:
1459     if (RegQueryString(HKEY_CURRENT_USER, NGREGKEY, NGSTARTUPFILEVAL,
1460 		       unicode, &foo) == ERROR_SUCCESS) {
1461       SetDlgItemText(hDlg, IDC_STARTUPFILE, unicode);
1462     }
1463     return 1;
1464 
1465   case WM_COMMAND:
1466     switch (LOWORD(wParam)) {
1467     case IDC_FILEOPENDLG:
1468       {
1469 	OPENFILENAME ofn;
1470 	TCHAR filename[MAXFILENAMESIZE];
1471 	int stat;
1472 
1473 	ofn = templateofn;
1474 	ofn.lpstrFile = filename;
1475 	ofn.nMaxFile = MAXFILENAMESIZE;
1476 	ofn.lpstrFile[0] = (TCHAR)0;
1477 	stat = GetOpenFileName(&ofn);
1478 	if (stat) {
1479 	  SetDlgItemText(hDlg, IDC_STARTUPFILE, ofn.lpstrFile);
1480 	}
1481       }
1482       break;
1483 
1484 #ifndef _WIN32_WCE
1485     case IDC_STARTUPFILE:
1486       switch (HIWORD(wParam)) {
1487       case EN_CHANGE:
1488 	SendMessage(GetParent(hDlg), PSM_CHANGED, (WPARAM)(HWND)hDlg, 0L);
1489 	break;
1490       }
1491       break;
1492 #endif
1493     }
1494     return 0;
1495 
1496   case WM_NOTIFY:
1497     switch (((LPNMHDR)lParam)->code) {
1498     case PSN_SETACTIVE: /* Visit this page */
1499       SetWindowLong(hDlg, DWL_MSGRESULT, 0);
1500       return TRUE;
1501 
1502     case PSN_APPLY:
1503       GetDlgItemText(hDlg, IDC_STARTUPFILE, unicode, foo / sizeof(TCHAR));
1504       RegSetString(HKEY_CURRENT_USER, NGREGKEY, NGSTARTUPFILEVAL, unicode);
1505       SetWindowLong(hDlg, DWL_MSGRESULT, PSNRET_NOERROR);
1506       return TRUE;
1507 
1508     case PSN_KILLACTIVE: /* Go away from this page */
1509       SetWindowLong(hDlg, DWL_MSGRESULT, FALSE);
1510       return(TRUE);
1511 
1512     case PSN_RESET: /* CANCEL Button */
1513       return TRUE;
1514     }
1515 
1516   default:
1517     return 0;
1518   }
1519 }
1520 #endif
1521 
1522 #if defined(CTRLMAP) || defined(JAPANESE_KEYBOARD)
1523 static BOOL CALLBACK
1524 KeyMapProc(HWND hDlg, UINT message, UINT wParam, LONG lParam)
1525 {
1526   DWORD val;
1527 
1528   switch (message) {
1529   case WM_INITDIALOG:
1530 #ifdef CTRLMAP
1531     val = RegQueryDWord(HKEY_CURRENT_USER, NGREGKEY,
1532 			NGCTRLKEYMAPVAL) ? TRUE : FALSE;
1533     Button_SetCheck(GetDlgItem(hDlg, IDC_CONTROLMAP), val);
1534 #else /* if !CTRLMAP */
1535     EnableWindow(GetDlgItem(hDlg, IDC_CONTROLMAP), FALSE);
1536 #endif /* !CTRLMAP */
1537 
1538 #ifdef JAPANESE_KEYBOARD
1539     val = RegQueryDWord(HKEY_CURRENT_USER, NGREGKEY, NGKEYBOARDLOCALEVAL);
1540     switch (val) {
1541     case NGKEYBOARD_US:
1542       val = BST_UNCHECKED;
1543       break;
1544     case NGKEYBOARD_JP:
1545       val = BST_CHECKED;
1546       break;
1547     default:
1548     case 0:
1549       val = BST_CHECKED;
1550       break;
1551     }
1552     Button_SetCheck(GetDlgItem(hDlg, IDC_KEYBOARDLOCALE), val);
1553 #else /* if !JAPANESE_KEYBOARD */
1554     EnableWindow(GetDlgItem(hDlg, IDC_KEYBOARDLOCALE), FALSE);
1555 #endif /* !JAPANESE_KEYBOARD */
1556     return 1;
1557 
1558   case WM_COMMAND:
1559     switch (LOWORD(wParam)) {
1560 #if 0 /* Did not work as I supposed. */
1561     case IDC_ALT:
1562       alt = !alt;
1563       Button_SetState(GetDlgItem(hDlg, IDC_ALT), alt);
1564       if (alt) {
1565 	keybd_event(VK_MENU, 0, 0, 0);
1566       }
1567       else {
1568 	keybd_event(VK_MENU, 0, KEYEVENTF_KEYUP, 0);
1569       }
1570       break;
1571 #endif
1572 #if defined(CTRLMAP) && !defined(_WIN32_WCE)
1573     case IDC_CONTROLMAP:
1574       SendMessage(GetParent(hDlg), PSM_CHANGED, (WPARAM)(HWND)hDlg, 0L);
1575       break;
1576 #endif
1577     }
1578     return 0;
1579 
1580   case WM_NOTIFY:
1581     switch (((LPNMHDR)lParam)->code) {
1582     case PSN_SETACTIVE: /* Visit this page */
1583       SetWindowLong(hDlg, DWL_MSGRESULT, 0);
1584       return TRUE;
1585 
1586     case PSN_APPLY:
1587 #ifdef CTRLMAP
1588       val = Button_GetCheck(GetDlgItem(hDlg, IDC_CONTROLMAP));
1589       RegSetDWord(HKEY_CURRENT_USER, NGREGKEY, NGCTRLKEYMAPVAL, val);
1590       g_ctrlmap = val;
1591 #endif
1592 #ifdef JAPANESE_KEYBOARD
1593       val = Button_GetCheck(GetDlgItem(hDlg, IDC_KEYBOARDLOCALE)) ?
1594 	NGKEYBOARD_JP : NGKEYBOARD_US;
1595       RegSetDWord(HKEY_CURRENT_USER, NGREGKEY, NGKEYBOARDLOCALEVAL, val);
1596       g_keyboardlocale = val;
1597       SendMessage(g_hwndTty, TTYM_SETKEYBOARDLOCALE, (WPARAM)val, 0);
1598 #endif
1599       SetWindowLong(hDlg, DWL_MSGRESULT, PSNRET_NOERROR);
1600       return TRUE;
1601 
1602     case PSN_KILLACTIVE: /* Go away from this page */
1603       SetWindowLong(hDlg, DWL_MSGRESULT, FALSE);
1604       return(TRUE);
1605 
1606     case PSN_RESET: /* CANCEL Button */
1607       return TRUE;
1608     }
1609 
1610   default:
1611     return 0;
1612   }
1613 }
1614 #endif
1615 
1616 struct _beepsounds {
1617   UINT title;
1618   UINT val;
1619 } beepsounds[] = {
1620   {IDS_OK, MB_OK},
1621   {IDS_ICONASTERISK, MB_ICONASTERISK},
1622   {IDS_ICONEXCLAMATION, MB_ICONEXCLAMATION},
1623   {IDS_ICONHAND, MB_ICONHAND},
1624   {IDS_ICONQUESTION, MB_ICONQUESTION}
1625 };
1626 
1627 #define NUMBEEPSOUNDS (sizeof(beepsounds) / sizeof(struct _beepsounds))
1628 
1629 #define WAVFILEFILTER TEXT("Wave file (*.wav)\0*.wav\0All files (*.*)\0*.*\0")
1630 
1631 static OPENFILENAME templatewaveofn = {
1632     sizeof(OPENFILENAME), NULL, 0, WAVFILEFILTER, NULL, 0, 0,
1633     NULL, 0, NULL, 0, TEXT("\\Windows"), TEXT("Wave File"),
1634     OFN_HIDEREADONLY, 0, 0, NULL, 0, NULL, NULL};
1635 
1636 static void
1637 SetBeepRadio(HWND hDlg, BOOL messagebeep)
1638 {
1639   EnableWindow(GetDlgItem(hDlg, IDC_MESSAGECOMBO), messagebeep);
1640   EnableWindow(GetDlgItem(hDlg, IDC_SOUNDFILE), !messagebeep);
1641   EnableWindow(GetDlgItem(hDlg, IDC_SOUNDBUTTON), !messagebeep);
1642 }
1643 
1644 static void
1645 SetBeepButtons(HWND hDlg, DWORD dobeep)
1646 {
1647   EnableWindow(GetDlgItem(hDlg, IDC_PLAY), dobeep);
1648   EnableWindow(GetDlgItem(hDlg, IDC_MESSAGEBEEP), dobeep);
1649   EnableWindow(GetDlgItem(hDlg, IDC_MESSAGECOMBO), dobeep);
1650 
1651 #ifdef TARGET_WCEVER_IS_100
1652   EnableWindow(GetDlgItem(hDlg, IDC_PLAYSOUND), FALSE);
1653   EnableWindow(GetDlgItem(hDlg, IDC_SOUNDFILE), FALSE);
1654   EnableWindow(GetDlgItem(hDlg, IDC_SOUNDBUTTON), FALSE);
1655 #else
1656   EnableWindow(GetDlgItem(hDlg, IDC_PLAYSOUND), dobeep);
1657   EnableWindow(GetDlgItem(hDlg, IDC_SOUNDFILE), dobeep);
1658   EnableWindow(GetDlgItem(hDlg, IDC_SOUNDBUTTON), dobeep);
1659 #endif
1660   if (dobeep) {
1661     /* dobeep == 1 means to use sndPlaySound(), not to use MessageBeep() */
1662     Button_SetCheck(GetDlgItem(hDlg, IDC_MESSAGEBEEP), dobeep != 1);
1663     Button_SetCheck(GetDlgItem(hDlg, IDC_PLAYSOUND), dobeep == 1);
1664     SetBeepRadio(hDlg, dobeep != 1);
1665   }
1666 }
1667 
1668 static void
1669 BeepGetButtons(HWND hDlg, DWORD *beep, LPTSTR beepfile, int len)
1670 {
1671   DWORD val;
1672 
1673   val = Button_GetCheck(GetDlgItem(hDlg, IDC_BEEP));
1674   if (val) {
1675     if (Button_GetCheck(GetDlgItem(hDlg, IDC_PLAYSOUND))) {
1676       *beep = 1;
1677     }
1678     else {
1679       DWORD sel;
1680       sel = SendMessage(GetDlgItem(hDlg, IDC_MESSAGECOMBO),
1681 			CB_GETCURSEL, (WPARAM)0, (LPARAM)0);
1682       if (sel != CB_ERR) {
1683 	*beep = beepsounds[sel].val + NG_WAVE_OFFSET;
1684       }
1685     }
1686   }
1687   else {
1688     *beep = 0;
1689   }
1690   GetDlgItemText(hDlg, IDC_SOUNDFILE, beepfile, len);
1691 }
1692 
1693 static BOOL CALLBACK
1694 BeepProc(HWND hDlg, UINT message, UINT wParam, LONG lParam)
1695 {
1696   DWORD val;
1697   HWND hcb;
1698   struct _beepsounds *pb, *epb;
1699   TCHAR buf[128];
1700   UINT cursound, nth = 0;
1701 
1702   switch (message) {
1703   case WM_INITDIALOG:
1704     /* initialize the combo box */
1705     cursound = g_beepsound - NG_WAVE_OFFSET;
1706     hcb = GetDlgItem(hDlg, IDC_MESSAGECOMBO);
1707     SendMessage(hcb, CB_RESETCONTENT, 0, 0);
1708     for (pb = beepsounds, epb = pb + NUMBEEPSOUNDS ; pb < epb ; pb++) {
1709       if (cursound == pb->val) {
1710 	nth = pb - beepsounds;
1711       }
1712       LoadString(g_hInst, pb->title, buf, sizeof(buf) / sizeof(TCHAR));
1713       SendMessage(hcb, CB_ADDSTRING, 0, (LONG)buf);
1714     }
1715     SendMessage(hcb, CB_SETCURSEL, (WPARAM)nth, (LPARAM)0);
1716 
1717     /* initialize the edit box */
1718     if (g_beepfile[0]) {
1719       SetDlgItemText(hDlg, IDC_SOUNDFILE, g_beepfile);
1720     }
1721 
1722     /* set the current configuration for beep sounds */
1723     Button_SetCheck(GetDlgItem(hDlg, IDC_BEEP), g_beepsound);
1724     SetBeepButtons(hDlg, g_beepsound);
1725     return 1;
1726 
1727   case WM_COMMAND:
1728     switch (LOWORD(wParam)) {
1729     case IDC_MESSAGEBEEP:
1730     case IDC_PLAYSOUND:
1731       SetBeepRadio(hDlg, LOWORD(wParam) == IDC_MESSAGEBEEP);
1732 #ifndef _WIN32_WCE
1733       SendMessage(GetParent(hDlg), PSM_CHANGED, (WPARAM)(HWND)hDlg, 0L);
1734 #endif
1735       break;
1736 
1737     case IDC_BEEP:
1738       val = Button_GetCheck(GetDlgItem(hDlg, IDC_BEEP));
1739       if (val) {
1740 	val = Button_GetCheck(GetDlgItem(hDlg, IDC_PLAYSOUND)) ? 1 : 2;
1741       }
1742       SetBeepButtons(hDlg, val);
1743 #ifndef _WIN32_WCE
1744       SendMessage(GetParent(hDlg), PSM_CHANGED, (WPARAM)(HWND)hDlg, 0L);
1745 #endif
1746       break;
1747 
1748     case IDC_SOUNDBUTTON:
1749       {
1750 	OPENFILENAME ofn;
1751 	TCHAR filename[MAXFILENAMESIZE];
1752 	int stat;
1753 
1754 	ofn = templatewaveofn;
1755 	ofn.lpstrFile = filename;
1756 	ofn.nMaxFile = MAXFILENAMESIZE;
1757 	ofn.lpstrFile[0] = (TCHAR)0;
1758 #ifndef _WIN32_WCE
1759 #define MEDIA_FOLDER TEXT("\\Media")
1760 #define MEDIA_FOLDER_LEN (sizeof(MEDIA_FOLDER) / sizeof(TCHAR))
1761 	{
1762 	  TCHAR initialdir[MAX_PATH];
1763 	  int len = GetWindowsDirectory(initialdir, MAX_PATH);
1764 	  if (0 < len) {
1765 	    if (len < MAX_PATH - MEDIA_FOLDER_LEN) {
1766 	      lstrcat(initialdir, MEDIA_FOLDER);
1767 	    }
1768 	    ofn.lpstrInitialDir = initialdir;
1769 	  }
1770 	}
1771 #endif
1772 	stat = GetOpenFileName(&ofn);
1773 	if (stat) {
1774 	  SetDlgItemText(hDlg, IDC_SOUNDFILE, ofn.lpstrFile);
1775 #ifndef _WIN32_WCE
1776 	  SendMessage(GetParent(hDlg), PSM_CHANGED, (WPARAM)(HWND)hDlg, 0L);
1777 #endif
1778 	}
1779       }
1780       break;
1781 
1782     case IDC_PLAY:
1783       val = g_beepsound;
1784       lstrcpy(buf, g_beepfile);
1785       BeepGetButtons(hDlg, &g_beepsound,
1786 		     g_beepfile, sizeof(g_beepfile) / sizeof(TCHAR));
1787       ttbeep();
1788       g_beepsound = val;
1789       lstrcpy(g_beepfile, buf);
1790       break;
1791 
1792 #ifndef _WIN32_WCE
1793     case IDC_MESSAGECOMBO:
1794       SendMessage(GetParent(hDlg), PSM_CHANGED, (WPARAM)(HWND)hDlg, 0L);
1795       break;
1796 
1797     case IDC_SOUNDFILE:
1798       switch (HIWORD(wParam)) {
1799       case EN_CHANGE:
1800 	SendMessage(GetParent(hDlg), PSM_CHANGED, (WPARAM)(HWND)hDlg, 0L);
1801 	break;
1802       }
1803       break;
1804 #endif
1805     }
1806     return 0;
1807 
1808   case WM_NOTIFY:
1809     switch (((LPNMHDR)lParam)->code) {
1810     case PSN_SETACTIVE: /* Visit this page */
1811       SetWindowLong(hDlg, DWL_MSGRESULT, 0);
1812       return TRUE;
1813 
1814     case PSN_APPLY:
1815       BeepGetButtons(hDlg, &g_beepsound,
1816 		     g_beepfile, sizeof(g_beepfile) / sizeof(TCHAR));
1817       RegSetDWord(HKEY_CURRENT_USER, NGREGKEY, NGBEEPSOUNDVAL, g_beepsound);
1818       RegSetString(HKEY_CURRENT_USER, NGREGKEY, NGBEEPFILEVAL, g_beepfile);
1819       SetWindowLong(hDlg, DWL_MSGRESULT, PSNRET_NOERROR);
1820       return TRUE;
1821 
1822     case PSN_KILLACTIVE: /* Go away from this page */
1823       SetWindowLong(hDlg, DWL_MSGRESULT, FALSE);
1824       return(TRUE);
1825 
1826     case PSN_RESET: /* CANCEL Button */
1827       return TRUE;
1828     }
1829 
1830   default:
1831     return 0;
1832   }
1833 }
1834 
1835 #ifndef USE_KCTRL /* font configuration is not made functional for KCTRL */
1836 #define CONFIG_FONT
1837 #endif
1838 
1839 #ifdef CONFIG_FONT
1840 
1841 #ifdef KANJI
1842 #define REQUIRED_CHARSET SHIFTJIS_CHARSET
1843 #ifndef _WIN32_WCE
1844 #define REQUIRED_PITCH FIXED_PITCH
1845 #endif
1846 #else /* !KANJI */
1847 #define REQUIRED_PITCH FIXED_PITCH
1848 #endif /* !KANJI */
1849 
1850 static int CALLBACK
1851 SetFontNames(CONST LOGFONT *lpelf, CONST TEXTMETRIC *lpntm,
1852 	     DWORD FontType, LPARAM lParam)
1853 {
1854   HWND hDlg = (HWND)lParam, hcb = GetDlgItem(hDlg, IDC_FONTNAME);
1855 
1856   if ((lpelf->lfPitchAndFamily &
1857        (FF_ROMAN | FF_SWISS | FF_MODERN | FF_SCRIPT | FF_DECORATIVE)) ==
1858       FF_MODERN
1859 #ifdef REQUIRED_CHARSET
1860       && lpelf->lfCharSet == REQUIRED_CHARSET
1861 #endif
1862 #ifdef REQUIRED_PITCH
1863       && (lpelf->lfPitchAndFamily & REQUIRED_PITCH)
1864 #endif
1865       ) {
1866     SendMessage(hcb, CB_ADDSTRING, 0, (LONG)lpelf->lfFaceName);
1867   }
1868   return 1;
1869 }
1870 
1871 static LPTSTR fontpoints[] = {
1872   TEXT("8"),
1873   TEXT("9"),
1874   TEXT("10"),
1875   TEXT("11"),
1876   TEXT("12"),
1877   TEXT("14"),
1878   TEXT("16"),
1879   TEXT("18"),
1880   TEXT("20"),
1881   TEXT("22"),
1882   TEXT("24"),
1883   TEXT("28"),
1884   TEXT("32")
1885 };
1886 
1887 #define NUMPOINTS (sizeof(fontpoints) / sizeof(int))
1888 
1889 #define MAX_LINESPACE 32
1890 
1891 static void
1892 SetFontEntries(HWND hDlg)
1893 {
1894   HDC hdc;
1895   HWND hSpin;
1896   LPTSTR *p, *ep;
1897   TCHAR fontname[LF_FACESIZE];
1898   DWORD val;
1899 
1900   hdc = GetDC(g_hwndTty);
1901   SendMessage(GetDlgItem(hDlg, IDC_FONTNAME), CB_RESETCONTENT, 0, 0);
1902   EnumFontFamilies(hdc, NULL, SetFontNames, (LPARAM)hDlg);
1903   ReleaseDC(g_hwndTty, hdc);
1904 
1905   SendMessage(GetDlgItem(hDlg, IDC_POINT), CB_RESETCONTENT, 0, 0);
1906   for (p = fontpoints, ep = p + NUMPOINTS ; p < ep ; p++) {
1907     SendMessage(GetDlgItem(hDlg, IDC_POINT), CB_ADDSTRING, 0, (LONG)*p);
1908   }
1909 
1910   /* Do something for spin (up-down) control */
1911   hSpin = GetDlgItem(hDlg, IDC_SPIN);
1912   SendMessage(hSpin, UDM_SETRANGE, (WPARAM)0,
1913 	      (LPARAM)MAKELONG((short)MAX_LINESPACE, (short)0));
1914   SendMessage(hSpin, UDM_SETPOS, (WPARAM)0,
1915 	      (LPARAM)MAKELONG((short)0, 0)); /* line space after (short) */
1916 
1917   /* set the current configurations */
1918   val = sizeof(fontname);
1919   if (RegQueryString(HKEY_CURRENT_USER, NGREGKEY, NGFONTNAMEVAL,
1920 		     fontname, &val) == ERROR_SUCCESS) {
1921     SendMessage(GetDlgItem(hDlg, IDC_FONTNAME), CB_SELECTSTRING,
1922 		(WPARAM)-1, (LPARAM)fontname);
1923     val = RegQueryDWord(HKEY_CURRENT_USER, NGREGKEY, NGFONTSIZEVAL);
1924     if (val > 0) {
1925       SetDlgItemInt(hDlg, IDC_POINT, val, FALSE);
1926       val = RegQueryDWord(HKEY_CURRENT_USER, NGREGKEY, NGLINESPACEVAL);
1927       SetDlgItemInt(hDlg, IDC_LINESPACE, val, FALSE);
1928       Button_SetCheck(GetDlgItem(hDlg, IDC_SPECIFY), TRUE);
1929       return;
1930     }
1931   }
1932   Button_SetCheck(GetDlgItem(hDlg, IDC_NOSPECIFY), TRUE);
1933 }
1934 
1935 static void
1936 ApplyFontEntries(HWND hDlg)
1937 {
1938   DWORD point, linespace;
1939   TCHAR fontname[LF_FACESIZE];
1940 
1941   if (Button_GetCheck(GetDlgItem(hDlg, IDC_SPECIFY))) {
1942     point = GetDlgItemInt(hDlg, IDC_POINT, NULL, FALSE);
1943     linespace = GetDlgItemInt(hDlg, IDC_LINESPACE, NULL, FALSE);
1944     GetDlgItemText(hDlg, IDC_FONTNAME, fontname, LF_FACESIZE);
1945 
1946     RegSetString(HKEY_CURRENT_USER, NGREGKEY, NGFONTNAMEVAL, fontname);
1947     RegSetDWord(HKEY_CURRENT_USER, NGREGKEY, NGFONTSIZEVAL, point);
1948     RegSetDWord(HKEY_CURRENT_USER, NGREGKEY, NGLINESPACEVAL, linespace);
1949   }
1950   else {
1951     RegRemoveValue(HKEY_CURRENT_USER, NGREGKEY, NGFONTNAMEVAL);
1952     RegRemoveValue(HKEY_CURRENT_USER, NGREGKEY, NGFONTSIZEVAL);
1953     RegRemoveValue(HKEY_CURRENT_USER, NGREGKEY, NGLINESPACEVAL);
1954   }
1955 
1956   /* To force the screen to be refreshed. */
1957   nrow = 4; /* This number (4) of rows may not be used... */
1958 
1959   /* Then, notify the change to TTYCTRL */
1960   SendMessage(g_hwndTty, TTYM_FONTCHANGED, (WPARAM)0, (LPARAM)0);
1961 }
1962 
1963 static BOOL CALLBACK
1964 FontProc(HWND hDlg, UINT message, UINT wParam, LONG lParam)
1965 {
1966   switch (message) {
1967   case WM_INITDIALOG:
1968     SetFontEntries(hDlg);
1969     return 1;
1970 
1971   case WM_COMMAND:
1972     switch (LOWORD(wParam)) {
1973 #ifndef _WIN32_WCE
1974     case IDC_NOSPECIFY:
1975     case IDC_SPECIFY:
1976     case IDC_FONTNAME:
1977     case IDC_POINT:
1978     case IDC_LINESPACE:
1979       SendMessage(GetParent(hDlg), PSM_CHANGED, (WPARAM)(HWND)hDlg, 0L);
1980       break;
1981 #endif
1982     default:
1983       break;
1984     }
1985     return 0;
1986 
1987   case WM_NOTIFY:
1988     switch (((LPNMHDR)lParam)->code) {
1989     case PSN_SETACTIVE: /* Visit this page */
1990       SetWindowLong(hDlg, DWL_MSGRESULT, 0);
1991       return TRUE;
1992 
1993     case PSN_APPLY:
1994       ApplyFontEntries(hDlg);
1995       SetWindowLong(hDlg, DWL_MSGRESULT, PSNRET_NOERROR);
1996       return TRUE;
1997 
1998     case PSN_KILLACTIVE: /* Go away from this page */
1999       SetWindowLong(hDlg, DWL_MSGRESULT, FALSE);
2000       return(TRUE);
2001 
2002     case PSN_RESET: /* CANCEL Button */
2003       return TRUE;
2004     }
2005 
2006   default:
2007     return 0;
2008   }
2009 }
2010 
2011 #endif /* CONFIG_FONT */
2012 
2013 #define MAX_PAGES 5
2014 
2015 /*
2016    Add one property sheet page.
2017  */
2018 
2019 static void
2020 AddPage(LPPROPSHEETHEADER ppsh, UINT id, DLGPROC pfn)
2021 {
2022   if (ppsh->nPages < MAX_PAGES) {
2023     PROPSHEETPAGE psp;
2024 
2025     psp.dwSize = sizeof(psp);
2026     psp.dwFlags = PSP_DEFAULT;
2027     psp.hInstance = ppsh->hInstance;
2028 #ifdef __BORLANDC__
2029     psp.DUMMYUNIONNAME.pszTemplate = MAKEINTRESOURCE(id);
2030 #else
2031     psp.pszTemplate = MAKEINTRESOURCE(id);
2032 #endif
2033     psp.pfnDlgProc = pfn;
2034     psp.lParam = 0;
2035 
2036 #ifdef __BORLANDC__
2037     ppsh->DUMMYUNIONNAME3.phpage[ppsh->nPages] = CreatePropertySheetPage(&psp);
2038     if (ppsh->DUMMYUNIONNAME3.phpage[ppsh->nPages]) {
2039 #else
2040     ppsh->phpage[ppsh->nPages] = CreatePropertySheetPage(&psp);
2041     if (ppsh->phpage[ppsh->nPages]) {
2042 #endif
2043       ppsh->nPages++;
2044     }
2045   }
2046 }
2047 
2048 /*
2049  CreatePropertySheet creates a property sheet.
2050  */
2051 
2052 static void
2053 CreatePropertySheet(HINSTANCE hInstance, HWND hwnd)
2054 {
2055   PROPSHEETHEADER psh;
2056   HPROPSHEETPAGE rPages[MAX_PAGES];
2057 
2058   psh.hwndParent = hwnd;
2059   psh.dwSize = sizeof(psh);
2060   psh.dwFlags = 0;
2061   psh.hInstance = hInstance;
2062 #ifdef __BORLANDC__
2063   psh.DUMMYUNIONNAME.hIcon = NULL;
2064 #else
2065   psh.hIcon = NULL;
2066 #endif
2067   psh.pszCaption = MAKEINTRESOURCE(IDS_CONFIGNAME);
2068   psh.nPages = 0;
2069 #ifdef __BORLANDC__
2070   psh.DUMMYUNIONNAME2.nStartPage = 0;
2071   psh.DUMMYUNIONNAME3.phpage = rPages;
2072 #else
2073   psh.nStartPage = 0;
2074   psh.phpage = rPages;
2075 #endif
2076   psh.pfnCallback = NULL;
2077 
2078 #if defined(_WIN32_WCE) && defined(COMMANDBANDS) && !defined(USE_SHMENU)
2079   AddPage(&psh, IDD_VIEW, ViewProc);
2080 #endif
2081 #ifndef NO_STARTUP
2082   AddPage(&psh, IDD_STARTUPFILE, StartFileProc);
2083 #endif
2084 #if defined(CTRLMAP) || defined(JAPANESE_KEYBOARD)
2085   AddPage(&psh, IDD_KEY, KeyMapProc);
2086 #endif
2087   AddPage(&psh, IDD_BEEP, BeepProc);
2088 #ifdef CONFIG_FONT
2089   AddPage(&psh, IDD_FONT, FontProc);
2090 #endif
2091 
2092   PropertySheet(&psh);
2093 }
2094 
2095 
2096 /* change the path to store the path into the registry database of Win32 */
2097 
2098 int
2099 ConfigStartupFilePath(int f, int n)
2100 {
2101   CreatePropertySheet(g_hInst, g_hwndTty);
2102   return TRUE;
2103 }
2104 
2105