/*
 * synergy -- mouse and keyboard sharing utility
 * Copyright (C) 2004 Chris Schoeneman
 * Copyright (C) 2006 Knut St. Osmundsen
 *
 * This package is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * found in the file COPYING that should have accompanied this file.
 *
 * This package is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#include "CPMUtil.h"
#include "CStringUtil.h"
#include <stdio.h>
#include <process.h>

//
// CPMUtil
//

CString
CPMUtil::getString(HMODULE hmod, ULONG id)
{
	char szBuf[1024];

	// load string
	LONG cch = WinLoadString(WinQueryAnchorBlock(HWND_DESKTOP), hmod, id, sizeof(szBuf), (PSZ)szBuf);
	if(cch < 0) {
		szBuf[cch] = '\0';
		char *psz = szBuf;
		return psz;
	}
	return "";
}

CString
CPMUtil::getErrorString(HMODULE hmod, ULONG error, ULONG id)
{
#if 1
	char szMsg[80];
	snprintf(szMsg, sizeof(szMsg), "sys error %#lx (%d)\n", error, error);
	char *pszMsg = szMsg;
	return CString(pszMsg);

#else
	char* buffer;
	if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
								FORMAT_MESSAGE_IGNORE_INSERTS |
								FORMAT_MESSAGE_FROM_SYSTEM,
								0,
								error,
								MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
								(LPTSTR)&buffer,
								0,
								NULL) == 0) {
		CString errorString = CStringUtil::print("%d", error);
		return CStringUtil::format(getString(hinstance, id).c_str(),
							errorString.c_str());
	}
	else {
		CString result(buffer);
		LocalFree(buffer);
		return result;
	}
#endif
}

HAB CPMUtil::getHAB(void)
{
    return WinQueryAnchorBlock(HWND_DESKTOP);
}

HMQ CPMUtil::getHMQ(HAB hab /* = NULLHANDLE */)
{
    if (hab == NULLHANDLE) {
        hab = getHAB();
    }
    return WinQueueFromID(hab, getpid(), _gettid());
}


/** dynamic resolver */
USHORT APIENTRY WinTranslateChar2(USHORT  usCodePage,
                                  PUSHORT pusCharInOut,
                                  PULONG  pulDeadKeyInfo,
                                  WINTCOP enmOperation,
                                  PUSHORT pfShiftState)
{
    static USHORT (* APIENTRY pfnWinTranslateChar2)(USHORT, PUSHORT, PULONG, WINTCOP, PUSHORT) = NULL;
    if (!pfnWinTranslateChar2) {
        /* resolve it */
        HMODULE hmod;
        if (    DosLoadModule(NULL, 0, (PCSZ)"PMWIN", &hmod) != NO_ERROR
            ||  DosQueryProcAddr(hmod, 1070, NULL, (PPFN)&pfnWinTranslateChar2) != NO_ERROR) {
            asm("int3");
            *pusCharInOut = 0;
            return 0;
        }
        DosFreeModule(hmod);
    }
    return pfnWinTranslateChar2(usCodePage, pusCharInOut, pulDeadKeyInfo, enmOperation, pfShiftState);
}

