/*
 * WindowsNT support (minimum function for jelvis)
 *   Written by Tomonori.Watanabe (GCD02235@niftyserve.or.jp)
 *                                (tom_w@st.rim.or.jp)
 *
 * This version is freely redistributable.
 */
/*
 * add function for jvim
 *   add by K.Tsuchida (kenichi-tsu@aix.or.jp/gdh01571@niftyserve.or.jp)
 */
/*
 * General purpose Japanese FEP control routines for MS-DOS.
 * Original is Written by Junn Ohta (ohta@src.ricoh.co.jp, msa02563)
 *
 *	int fep_init(void)
 *		checks FEP and turn it off, returns FEP type.
 *	void fep_term(void)
 *		restore the status of FEP saved by fep_init().
 *	void fep_on(void)
 *		restore the status of FEP saved by fep_off().
 *	void fep_off(void)
 *		save the status of FEP and turn it off.
 *	void fep_force_on(void)
 *		turn FEP on by its default "on" status.
 *	void fep_force_off(void)
 *		don't save the status of FEP and turn it off.
 *	int fep_get_mode(void)
 *		return the current status of FEP (0 = off).
 *
 */
#include <windows.h>
#include <winnls32.h>
#include <ime.h>
#include "fepctrl.h"
static HGLOBAL		imeheap = NULL;
static long			imeParam;
static IMESTRUCT	*ime;
static HWND			console;
static DWORD		fep_initial_state;
static DWORD		fep_state;
static BOOL			ime_initial_state;
static BOOL			ime_state;
static DWORD		fep_err;
int fep_init()
{
	ime = NULL;
	console = GetForegroundWindow();
	if (!IsWindow(console)) {
		fep_err = GetLastError();
		return (FEP_NONE);
	}
	if ((imeheap = GlobalAlloc(GHND|GMEM_SHARE, ((sizeof(IMESTRUCT)+32)&~31))) == NULL)
		return (FEP_NONE);
	if ((ime = (IMESTRUCT *)GlobalLock(imeheap)) == NULL) {
		GlobalFree(imeheap);
		return (FEP_NONE);
	}
	ime_initial_state = WINNLSEnableIME(NULL, TRUE);
	imeParam = (long)imeheap;
	ime->fnc = IME_GETOPEN;
	GlobalUnlock(imeheap);
	fep_initial_state = SendIMEMessageEx(console, imeParam);
	fep_state = fep_initial_state;
	fep_force_off();
	return (FEP_MSKANJI);
}
void fep_term()
{
	if ((ime = (IMESTRUCT *)GlobalLock(imeheap)) != NULL) {
		ime->fnc = IME_SETOPEN;
		ime->wParam = fep_initial_state;
		GlobalUnlock(imeheap);
		SendIMEMessageEx(console, imeParam);
		GlobalFree(imeheap);
		WINNLSEnableIME(NULL, ime_initial_state);
	}
}
void fep_on()
{
	if (imeheap != NULL && (ime = (IMESTRUCT *)GlobalLock(imeheap)) != NULL) {
		ime->fnc = IME_SETOPEN;
		ime->wParam = fep_state;
		GlobalUnlock(imeheap);
		SendIMEMessageEx(console, imeParam);
	}
}
void fep_off()
{
	if (imeheap != NULL && (ime = (IMESTRUCT *)GlobalLock(imeheap)) != NULL) {
		ime->fnc = IME_GETOPEN;
		GlobalUnlock(imeheap);
		fep_state = SendIMEMessageEx(console, imeParam);
	}
	fep_force_off();
}
void fep_force_off()
{
	if (imeheap != NULL && (ime = (IMESTRUCT *)GlobalLock(imeheap)) != NULL) {
		ime->fnc = IME_SETOPEN;
		ime->wParam = FALSE;
		GlobalUnlock(imeheap);
		SendIMEMessageEx(console, imeParam);
	}
}
void fep_force_on()
{
	if (imeheap != NULL && (ime = (IMESTRUCT *)GlobalLock(imeheap)) != NULL) {
		ime->fnc = IME_SETOPEN;
		ime->wParam = TRUE;
		GlobalUnlock(imeheap);
		SendIMEMessageEx(console, imeParam);
	}
}
int fep_get_mode()
{
	if (imeheap != NULL && (ime = (IMESTRUCT *)GlobalLock(imeheap)) != NULL) {
		ime->fnc = IME_GETOPEN;
		GlobalUnlock(imeheap);
		return(SendIMEMessageEx(console, imeParam));
	}
	return(0);
}
/*
 *	WINDOWS-NT IME display sync routine
 *			use desktop IME status line.
 */
void fep_disp_sync(con)
HANDLE	con;
{
	CONSOLE_SCREEN_BUFFER_INFO	pcinf;
	static int					oldX  = 0;
	static int					oldY  = 0;
	static int					fontX = 0;
	static int					fontY = 0;
	if (imeheap == NULL)
		return;
	if (fontX == 0) {
		RECT	rect;
		if (GetClientRect(console, &rect) != TRUE) {
			return;
		}
		if (GetConsoleScreenBufferInfo(con, &pcinf) != TRUE) {
			return;
		}
		fontX = rect.right / pcinf.dwSize.X;
		fontY = rect.bottom / pcinf.dwSize.Y;
	}
	if (WINNLSGetEnableStatus(NULL) == TRUE) {
		(void) GetConsoleScreenBufferInfo(con, &pcinf);
		if ((pcinf.dwCursorPosition.Y != oldY)
				|| (pcinf.dwCursorPosition.X != oldX)) {
			if ((ime = (IMESTRUCT *)GlobalLock(imeheap)) != NULL) {
				ime->fnc = IME_SETCONVERSIONWINDOW;
				ime->wParam = MCW_WINDOW;
				ime->lParam1= 
						((pcinf.dwCursorPosition.Y * fontY) << 16)
						+ pcinf.dwCursorPosition.X * fontX;
				GlobalUnlock(imeheap);
				SendIMEMessageEx(console, imeParam);
				oldY = pcinf.dwCursorPosition.Y;
				oldX = pcinf.dwCursorPosition.X;
			}
		}
	}
}
syntax highlighted by Code2HTML, v. 0.9.1