/*
 * Windows 16-bit hook functions
 *
 * Copyright 1994, 1995, 2002 Alexandre Julliard
 * Copyright 1996 Andrew Lewycky
 *
 * Based on investigations by Alex Korobka
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include <stdarg.h>

#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "wownt32.h"
#include "wine/winuser16.h"
#include "win.h"
#include "user_private.h"
#include "winproc.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(hook);


static LRESULT CALLBACK call_WH_MSGFILTER( INT code, WPARAM wp, LPARAM lp );
static LRESULT CALLBACK call_WH_KEYBOARD( INT code, WPARAM wp, LPARAM lp );
static LRESULT CALLBACK call_WH_GETMESSAGE( INT code, WPARAM wp, LPARAM lp );
static LRESULT CALLBACK call_WH_CALLWNDPROC( INT code, WPARAM wp, LPARAM lp );
static LRESULT CALLBACK call_WH_CBT( INT code, WPARAM wp, LPARAM lp );
static LRESULT CALLBACK call_WH_MOUSE( INT code, WPARAM wp, LPARAM lp );
static LRESULT CALLBACK call_WH_SHELL( INT code, WPARAM wp, LPARAM lp );

#define WH_MAXHOOK16 WH_SHELL  /* Win16 only supports up to WH_SHELL */
#define NB_HOOKS16 (WH_MAXHOOK16 - WH_MINHOOK + 1)

static const HOOKPROC hook_procs[NB_HOOKS16] =
{
    call_WH_MSGFILTER,   /* WH_MSGFILTER	*/
    NULL,                /* WH_JOURNALRECORD */
    NULL,                /* WH_JOURNALPLAYBACK */
    call_WH_KEYBOARD,    /* WH_KEYBOARD */
    call_WH_GETMESSAGE,  /* WH_GETMESSAGE */
    call_WH_CALLWNDPROC, /* WH_CALLWNDPROC */
    call_WH_CBT,         /* WH_CBT */
    NULL,                /* WH_SYSMSGFILTER */
    call_WH_MOUSE,       /* WH_MOUSE */
    NULL,                /* WH_HARDWARE */
    NULL,                /* WH_DEBUG */
    call_WH_SHELL        /* WH_SHELL */
};


/* this structure is stored in the thread queue */
struct hook16_queue_info
{
    INT        id;                /* id of current hook */
    HHOOK      hook[NB_HOOKS16];  /* Win32 hook handles */
    HOOKPROC16 proc[NB_HOOKS16];  /* 16-bit hook procedures */
};



/***********************************************************************
 *           map_msg_16_to_32
 */
inline static void map_msg_16_to_32( const MSG16 *msg16, MSG *msg32 )
{
    msg32->hwnd    = WIN_Handle32(msg16->hwnd);
    msg32->message = msg16->message;
    msg32->wParam  = msg16->wParam;
    msg32->lParam  = msg16->lParam;
    msg32->time    = msg16->time;
    msg32->pt.x    = msg16->pt.x;
    msg32->pt.y    = msg16->pt.y;
}


/***********************************************************************
 *           map_msg_32_to_16
 */
inline static void map_msg_32_to_16( const MSG *msg32, MSG16 *msg16 )
{
    msg16->hwnd    = HWND_16(msg32->hwnd);
    msg16->message = msg32->message;
    msg16->wParam  = msg32->wParam;
    msg16->lParam  = msg32->lParam;
    msg16->time    = msg32->time;
    msg16->pt.x    = msg32->pt.x;
    msg16->pt.y    = msg32->pt.y;
}


/***********************************************************************
 *           call_hook_16
 */
static LRESULT call_hook_16( INT id, INT code, WPARAM wp, LPARAM lp )
{
    struct hook16_queue_info *info = get_user_thread_info()->hook16_info;
    WORD args[4];
    DWORD ret;
    INT prev_id = info->id;
    info->id = id;

    args[3] = code;
    args[2] = wp;
    args[1] = HIWORD(lp);
    args[0] = LOWORD(lp);
    WOWCallback16Ex( (DWORD)info->proc[id - WH_MINHOOK], WCB16_PASCAL, sizeof(args), args, &ret );

    info->id = prev_id;

    /* Grrr. While the hook procedure is supposed to have an LRESULT return
       value even in Win16, it seems that for those hook types where the
       return value is interpreted as BOOL, Windows doesn't actually check
       the HIWORD ...  Some buggy Win16 programs, notably WINFILE, rely on
       that, because they neglect to clear DX ... */
    if (id != WH_JOURNALPLAYBACK) ret = LOWORD( ret );
    return ret;
}


/***********************************************************************
 *		call_WH_MSGFILTER
 */
static LRESULT CALLBACK call_WH_MSGFILTER( INT code, WPARAM wp, LPARAM lp )
{
    MSG *msg32 = (MSG *)lp;
    MSG16 msg16;
    LRESULT ret;

    map_msg_32_to_16( msg32, &msg16 );
    lp = MapLS( &msg16 );
    ret = call_hook_16( WH_MSGFILTER, code, wp, lp );
    UnMapLS( lp );
    return ret;
}


/***********************************************************************
 *		call_WH_KEYBOARD
 */
static LRESULT CALLBACK call_WH_KEYBOARD( INT code, WPARAM wp, LPARAM lp )
{
    return call_hook_16( WH_KEYBOARD, code, wp, lp );
}


/***********************************************************************
 *		call_WH_GETMESSAGE
 */
static LRESULT CALLBACK call_WH_GETMESSAGE( INT code, WPARAM wp, LPARAM lp )
{
    MSG *msg32 = (MSG *)lp;
    MSG16 msg16;
    LRESULT ret;

    map_msg_32_to_16( msg32, &msg16 );

    lp = MapLS( &msg16 );
    ret = call_hook_16( WH_GETMESSAGE, code, wp, lp );
    UnMapLS( lp );

    map_msg_16_to_32( &msg16, msg32 );
    return ret;
}


/***********************************************************************
 *		call_WH_CALLWNDPROC
 */
static LRESULT CALLBACK call_WH_CALLWNDPROC( INT code, WPARAM wp, LPARAM lp )
{
    CWPSTRUCT *cwp32 = (CWPSTRUCT *)lp;
    CWPSTRUCT16 cwp16;
    MSGPARAM16 mp16;
    LRESULT ret;

    cwp16.hwnd   = HWND_16(cwp32->hwnd);
    cwp16.lParam = cwp32->lParam;

    WINPROC_MapMsg32ATo16( cwp32->hwnd, cwp32->message, cwp32->wParam,
                           &cwp16.message, &cwp16.wParam, &cwp16.lParam );

    lp = MapLS( &cwp16 );
    ret = call_hook_16( WH_CALLWNDPROC, code, wp, lp );
    UnMapLS( lp );

    mp16.wParam  = cwp16.wParam;
    mp16.lParam  = cwp16.lParam;
    mp16.lResult = 0;
    WINPROC_UnmapMsg32ATo16( cwp32->hwnd, cwp32->message, cwp32->wParam, cwp32->lParam, &mp16 );
    return ret;
}


/***********************************************************************
 *		call_WH_CBT
 */
static LRESULT CALLBACK call_WH_CBT( INT code, WPARAM wp, LPARAM lp )
{
    LRESULT ret = 0;

    switch (code)
    {
    case HCBT_CREATEWND:
        {
            CBT_CREATEWNDA *cbtcw32 = (CBT_CREATEWNDA *)lp;
            CBT_CREATEWND16 cbtcw16;
            CREATESTRUCT16 cs16;

            cs16.lpCreateParams = (SEGPTR)cbtcw32->lpcs->lpCreateParams;
            cs16.hInstance      = HINSTANCE_16(cbtcw32->lpcs->hInstance);
            cs16.hMenu          = HMENU_16(cbtcw32->lpcs->hMenu);
            cs16.hwndParent     = HWND_16(cbtcw32->lpcs->hwndParent);
            cs16.cy             = cbtcw32->lpcs->cy;
            cs16.cx             = cbtcw32->lpcs->cx;
            cs16.y              = cbtcw32->lpcs->y;
            cs16.x              = cbtcw32->lpcs->x;
            cs16.style          = cbtcw32->lpcs->style;
            cs16.lpszName       = MapLS( cbtcw32->lpcs->lpszName );
            cs16.lpszClass      = MapLS( cbtcw32->lpcs->lpszClass );
            cs16.dwExStyle      = cbtcw32->lpcs->dwExStyle;

            cbtcw16.lpcs = (CREATESTRUCT16 *)MapLS( &cs16 );
            cbtcw16.hwndInsertAfter = HWND_16( cbtcw32->hwndInsertAfter );

            lp = MapLS( &cbtcw16 );
            ret = call_hook_16( WH_CBT, code, wp, lp );
            UnMapLS( cs16.lpszName );
            UnMapLS( cs16.lpszClass );

            cbtcw32->hwndInsertAfter = WIN_Handle32( cbtcw16.hwndInsertAfter );
            UnMapLS( (SEGPTR)cbtcw16.lpcs );
            UnMapLS( lp );
            break;
        }

    case HCBT_ACTIVATE:
        {
            CBTACTIVATESTRUCT *cas32 = (CBTACTIVATESTRUCT *)lp;
            CBTACTIVATESTRUCT16 cas16;

            cas16.fMouse     = cas32->fMouse;
            cas16.hWndActive = HWND_16( cas32->hWndActive );

            lp = MapLS( &cas16 );
            ret = call_hook_16( WH_CBT, code, wp, lp );
            UnMapLS( lp );
            break;
        }
    case HCBT_CLICKSKIPPED:
        {
            MOUSEHOOKSTRUCT *ms32 = (MOUSEHOOKSTRUCT *)lp;
            MOUSEHOOKSTRUCT16 ms16;

            ms16.pt.x         = ms32->pt.x;
            ms16.pt.y         = ms32->pt.y;
            ms16.hwnd         = HWND_16( ms32->hwnd );
            ms16.wHitTestCode = ms32->wHitTestCode;
            ms16.dwExtraInfo  = ms32->dwExtraInfo;

            lp = MapLS( &ms16 );
            ret = call_hook_16( WH_CBT, code, wp, lp );
            UnMapLS( lp );
            break;
        }
    case HCBT_MOVESIZE:
        {
            RECT *rect32 = (RECT *)lp;
            RECT16 rect16;

            rect16.left   = rect32->left;
            rect16.top    = rect32->top;
            rect16.right  = rect32->right;
            rect16.bottom = rect32->bottom;
            lp = MapLS( &rect16 );
            ret = call_hook_16( WH_CBT, code, wp, lp );
            UnMapLS( lp );
            break;
        }
    }
    return ret;
}


/***********************************************************************
 *		call_WH_MOUSE
 */
static LRESULT CALLBACK call_WH_MOUSE( INT code, WPARAM wp, LPARAM lp )
{
    MOUSEHOOKSTRUCT *ms32 = (MOUSEHOOKSTRUCT *)lp;
    MOUSEHOOKSTRUCT16 ms16;
    LRESULT ret;

    ms16.pt.x         = ms32->pt.x;
    ms16.pt.y         = ms32->pt.y;
    ms16.hwnd         = HWND_16( ms32->hwnd );
    ms16.wHitTestCode = ms32->wHitTestCode;
    ms16.dwExtraInfo  = ms32->dwExtraInfo;

    lp = MapLS( &ms16 );
    ret = call_hook_16( WH_MOUSE, code, wp, lp );
    UnMapLS( lp );
    return ret;
}


/***********************************************************************
 *		call_WH_SHELL
 */
static LRESULT CALLBACK call_WH_SHELL( INT code, WPARAM wp, LPARAM lp )
{
    return call_hook_16( WH_SHELL, code, wp, lp );
}


/***********************************************************************
 *		SetWindowsHook (USER.121)
 */
FARPROC16 WINAPI SetWindowsHook16( INT16 id, HOOKPROC16 proc )
{
    HINSTANCE16 hInst = FarGetOwner16( HIWORD(proc) );

    /* WH_MSGFILTER is the only task-specific hook for SetWindowsHook() */
    HTASK16 hTask = (id == WH_MSGFILTER) ? GetCurrentTask() : 0;

    return (FARPROC16)SetWindowsHookEx16( id, proc, hInst, hTask );
}


/***********************************************************************
 *		SetWindowsHookEx (USER.291)
 */
HHOOK WINAPI SetWindowsHookEx16( INT16 id, HOOKPROC16 proc, HINSTANCE16 hInst, HTASK16 hTask )
{
    struct user_thread_info *thread_info = get_user_thread_info();
    struct hook16_queue_info *info;
    HHOOK hook;
    int index = id - WH_MINHOOK;

    if (id < WH_MINHOOK || id > WH_MAXHOOK16) return 0;
    if (!hook_procs[index])
    {
        FIXME( "hook type %d broken in Win16\n", id );
        return 0;
    }
    if (!hTask) FIXME( "System-global hooks (%d) broken in Win16\n", id );
    else if (hTask != GetCurrentTask())
    {
        FIXME( "setting hook (%d) on other task not supported\n", id );
        return 0;
    }

    if (!(info = thread_info->hook16_info))
    {
        if (!(info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*info) ))) return 0;
        thread_info->hook16_info = info;
    }
    if (info->hook[index])
    {
        FIXME( "Multiple hooks (%d) for the same task not supported yet\n", id );
        return 0;
    }
    if (!(hook = SetWindowsHookExA( id, hook_procs[index], 0, GetCurrentThreadId() ))) return 0;
    info->hook[index] = hook;
    info->proc[index] = proc;
    return hook;
}


/***********************************************************************
 *		UnhookWindowsHook (USER.234)
 */
BOOL16 WINAPI UnhookWindowsHook16( INT16 id, HOOKPROC16 proc )
{
    struct hook16_queue_info *info;
    int index = id - WH_MINHOOK;

    if (id < WH_MINHOOK || id > WH_MAXHOOK16) return FALSE;
    if (!(info = get_user_thread_info()->hook16_info)) return FALSE;
    if (info->proc[index] != proc) return FALSE;
    if (!UnhookWindowsHookEx( info->hook[index] )) return FALSE;
    info->hook[index] = 0;
    info->proc[index] = 0;
    return TRUE;
}


/***********************************************************************
 *		UnhookWindowsHookEx (USER.292)
 */
BOOL16 WINAPI UnhookWindowsHookEx16( HHOOK hhook )
{
    struct hook16_queue_info *info;
    int index;

    if (!(info = get_user_thread_info()->hook16_info)) return FALSE;
    for (index = 0; index < NB_HOOKS16; index++)
    {
        if (info->hook[index] == hhook)
        {
            info->hook[index] = 0;
            info->proc[index] = 0;
            return UnhookWindowsHookEx( hhook );
        }
    }
    return FALSE;
}


/***********************************************************************
 *		CallMsgFilter32 (USER.823)
 */
BOOL16 WINAPI CallMsgFilter32_16( MSG32_16 *lpmsg16_32, INT16 code, BOOL16 wHaveParamHigh )
{
    MSG msg32;
    BOOL16 ret;

    if (GetSysModalWindow16()) return FALSE;
    msg32.hwnd      = WIN_Handle32( lpmsg16_32->msg.hwnd );
    msg32.message   = lpmsg16_32->msg.message;
    msg32.lParam    = lpmsg16_32->msg.lParam;
    msg32.time      = lpmsg16_32->msg.time;
    msg32.pt.x      = lpmsg16_32->msg.pt.x;
    msg32.pt.y      = lpmsg16_32->msg.pt.y;
    if (wHaveParamHigh) msg32.wParam = MAKELONG(lpmsg16_32->msg.wParam, lpmsg16_32->wParamHigh);
    else msg32.wParam = lpmsg16_32->msg.wParam;

    ret = (BOOL16)CallMsgFilterA(&msg32, code);

    lpmsg16_32->msg.hwnd    = HWND_16( msg32.hwnd );
    lpmsg16_32->msg.message = msg32.message;
    lpmsg16_32->msg.wParam  = LOWORD(msg32.wParam);
    lpmsg16_32->msg.lParam  = msg32.lParam;
    lpmsg16_32->msg.time    = msg32.time;
    lpmsg16_32->msg.pt.x    = msg32.pt.x;
    lpmsg16_32->msg.pt.y    = msg32.pt.y;
    if (wHaveParamHigh) lpmsg16_32->wParamHigh = HIWORD(msg32.wParam);
    return ret;
}


/***********************************************************************
 *		CallMsgFilter (USER.123)
 */
BOOL16 WINAPI CallMsgFilter16( MSG16 *msg, INT16 code )
{
    return CallMsgFilter32_16( (MSG32_16 *)msg, code, FALSE );
}


/***********************************************************************
 *		CallNextHookEx (USER.293)
 */
LRESULT WINAPI CallNextHookEx16( HHOOK hhook, INT16 code, WPARAM16 wparam, LPARAM lparam )
{
    struct hook16_queue_info *info;
    LRESULT ret = 0;

    if (!(info = get_user_thread_info()->hook16_info)) return 0;

    switch (info->id)
    {
    case WH_MSGFILTER:
    {
        MSG16 *msg16 = MapSL(lparam);
        MSG msg32;

        map_msg_16_to_32( msg16, &msg32 );
        ret = CallNextHookEx( hhook, code, wparam, (LPARAM)&msg32 );
        break;
    }

    case WH_GETMESSAGE:
    {
        MSG16 *msg16 = MapSL(lparam);
        MSG msg32;

        map_msg_16_to_32( msg16, &msg32 );
        ret = CallNextHookEx( hhook, code, wparam, (LPARAM)&msg32 );
        map_msg_32_to_16( &msg32, msg16 );
        break;
    }

    case WH_CALLWNDPROC:
    {
        CWPSTRUCT16 *cwp16 = MapSL(lparam);
        CWPSTRUCT cwp32;

        cwp32.hwnd   = WIN_Handle32(cwp16->hwnd);
        cwp32.lParam = cwp16->lParam;

        WINPROC_MapMsg16To32A( cwp32.hwnd, cwp16->message, cwp16->wParam,
                               &cwp32.message, &cwp32.wParam, &cwp32.lParam );
        ret = CallNextHookEx( hhook, code, wparam, (LPARAM)&cwp32 );
        WINPROC_UnmapMsg16To32A( cwp32.hwnd, cwp32.message, cwp32.wParam, cwp32.lParam, 0 );
        break;
    }

    case WH_CBT:
        switch (code)
        {
        case HCBT_CREATEWND:
            {
                CBT_CREATEWNDA cbtcw32;
                CREATESTRUCTA cs32;
                CBT_CREATEWND16 *cbtcw16 = MapSL(lparam);
                CREATESTRUCT16 *cs16 = MapSL( (SEGPTR)cbtcw16->lpcs );

                cbtcw32.lpcs = &cs32;
                cbtcw32.hwndInsertAfter = WIN_Handle32( cbtcw16->hwndInsertAfter );

                cs32.lpCreateParams = (LPVOID)cs16->lpCreateParams;
                cs32.hInstance      = HINSTANCE_32(cs16->hInstance);
                cs32.hMenu          = HMENU_32(cs16->hMenu);
                cs32.hwndParent     = WIN_Handle32(cs16->hwndParent);
                cs32.cy             = cs16->cy;
                cs32.cx             = cs16->cx;
                cs32.y              = cs16->y;
                cs32.x              = cs16->x;
                cs32.style          = cs16->style;
                cs32.lpszName       = MapSL( cs16->lpszName );
                cs32.lpszClass      = MapSL( cs16->lpszClass );
                cs32.dwExStyle      = cs16->dwExStyle;

                ret = CallNextHookEx( hhook, code, wparam, (LPARAM)&cbtcw32 );
                cbtcw16->hwndInsertAfter = HWND_16( cbtcw32.hwndInsertAfter );
                break;
            }
        case HCBT_ACTIVATE:
            {
                CBTACTIVATESTRUCT16 *cas16 = MapSL(lparam);
                CBTACTIVATESTRUCT cas32;
                cas32.fMouse = cas16->fMouse;
                cas32.hWndActive = WIN_Handle32(cas16->hWndActive);
                ret = CallNextHookEx( hhook, code, wparam, (LPARAM)&cas32 );
                break;
            }
        case HCBT_CLICKSKIPPED:
            {
                MOUSEHOOKSTRUCT16 *ms16 = MapSL(lparam);
                MOUSEHOOKSTRUCT ms32;

                ms32.pt.x = ms16->pt.x;
                ms32.pt.y = ms16->pt.y;
                /* wHitTestCode may be negative, so convince compiler to do
                   correct sign extension. Yay. :| */
                ms32.wHitTestCode = (INT)(INT16)ms16->wHitTestCode;
                ms32.dwExtraInfo = ms16->dwExtraInfo;
                ms32.hwnd = WIN_Handle32( ms16->hwnd );
                ret = CallNextHookEx( hhook, code, wparam, (LPARAM)&ms32 );
                break;
            }
        case HCBT_MOVESIZE:
            {
                RECT16 *rect16 = MapSL(lparam);
                RECT rect32;

                rect32.left   = rect16->left;
                rect32.top    = rect16->top;
                rect32.right  = rect16->right;
                rect32.bottom = rect16->bottom;
                ret = CallNextHookEx( hhook, code, wparam, (LPARAM)&rect32 );
                break;
            }
        }
        break;

    case WH_MOUSE:
    {
        MOUSEHOOKSTRUCT16 *ms16 = MapSL(lparam);
        MOUSEHOOKSTRUCT ms32;

        ms32.pt.x = ms16->pt.x;
        ms32.pt.y = ms16->pt.y;
        /* wHitTestCode may be negative, so convince compiler to do
           correct sign extension. Yay. :| */
        ms32.wHitTestCode = (INT)((INT16)ms16->wHitTestCode);
        ms32.dwExtraInfo = ms16->dwExtraInfo;
        ms32.hwnd = WIN_Handle32(ms16->hwnd);
        ret = CallNextHookEx( hhook, code, wparam, (LPARAM)&ms32 );
        break;
    }

    case WH_SHELL:
    case WH_KEYBOARD:
        ret = CallNextHookEx( hhook, code, wparam, lparam );
        break;

    case WH_HARDWARE:
    case WH_FOREGROUNDIDLE:
    case WH_CALLWNDPROCRET:
    case WH_SYSMSGFILTER:
    case WH_JOURNALRECORD:
    case WH_JOURNALPLAYBACK:
    default:
        FIXME("\t[%i] 16to32 translation unimplemented\n", info->id);
        ret = CallNextHookEx( hhook, code, wparam, lparam );
        break;
    }
    return ret;
}


/***********************************************************************
 *		DefHookProc (USER.235)
 */
LRESULT WINAPI DefHookProc16( INT16 code, WPARAM16 wparam, LPARAM lparam, HHOOK *hhook )
{
    return CallNextHookEx16( *hhook, code, wparam, lparam );
}
