/*
 * Windows hook functions
 *
 * Copyright 1994 Alexandre Julliard
 */

/* Warning!
 * HHOOK is not a real handle, but a 32-bit pointer to a HOOKDATA structure.
 * This is for compatibility with Windows 3.0 where HHOOK was a HOOKPROC.
 */

#include "hook.h"
#include "user.h"
#include "stddebug.h"
#include "debug.h"

HHOOK systemHooks[LAST_HOOK-FIRST_HOOK+1] = { 0, };

  /* Task-specific hooks should probably be in the task structure */
HHOOK taskHooks[LAST_HOOK-FIRST_HOOK+1] = { 0, };



/***********************************************************************
 *           SetWindowsHook   (USER.121)
 */
FARPROC SetWindowsHook( short id, HOOKPROC proc )
{
  HHOOK hhook = SetWindowsHookEx( id, proc, 0, 0 );
  HOOKDATA *data = PTR_SEG_TO_LIN(hhook);
  if (data != NULL)  {
    data = PTR_SEG_TO_LIN(data->next);
    if (data != NULL)  {
      return data->proc;
    }
  }
  return 0;
}


/***********************************************************************
 *           UnhookWindowsHook   (USER.234)
 */
BOOL UnhookWindowsHook( short id, FARPROC hproc )
{
  HHOOK *prevHook,hhook;
  
  prevHook = &TASK_HOOK(id);
  while (*prevHook)  {
    HOOKDATA *data = (HOOKDATA *)PTR_SEG_TO_LIN(*prevHook);

    if (data->proc == hproc) {
      hhook = *prevHook;
      *prevHook = data->next;
      USER_HEAP_FREE(LOWORD(hhook));
      return TRUE;
    }
  }
  prevHook = &SYSTEM_HOOK(id);
  while (*prevHook) {
    HOOKDATA *data = (HOOKDATA *)PTR_SEG_TO_LIN(*prevHook);
    if (data->proc == hproc) {
      hhook = *prevHook;
      *prevHook = data->next;
      USER_HEAP_FREE(LOWORD(hhook));
      return TRUE;
    }
  }
  return FALSE;
}


/***********************************************************************
 *           DefHookProc   (USER.235)
 */
DWORD DefHookProc( short code, WORD wParam, DWORD lParam, HHOOK *hhook )
{
    return CallNextHookEx( *hhook, code, wParam, lParam );
}


/***********************************************************************
 *           CallMsgFilter   (USER.123)
 */
BOOL CallMsgFilter( SEGPTR msg, short code )
{
    if (CALL_SYSTEM_HOOK( WH_SYSMSGFILTER, code, 0, (LPARAM)msg )) return TRUE;
    else return CALL_TASK_HOOK( WH_MSGFILTER, code, 0, (LPARAM)msg );
}


/***********************************************************************
 *           SetWindowsHookEx   (USER.291)
 */
HHOOK SetWindowsHookEx( short id, HOOKPROC proc, HINSTANCE hinst, HTASK htask )
{
    HOOKDATA *data;
    HANDLE handle;
    HHOOK *prevHook;

    if ((id < FIRST_HOOK) || (id > LAST_HOOK)) return 0;
    if (id != WH_GETMESSAGE && id != WH_CALLWNDPROC) {
	fprintf( stdnimp, "Unimplemented hook set: %d!\n", id );
    }
    if (htask)  /* Task-specific hook */
    {
	if ((id == WH_JOURNALRECORD) || (id == WH_JOURNALPLAYBACK) ||
	    (id == WH_SYSMSGFILTER)) return 0;
	prevHook = &TASK_HOOK( id );
    }
    else  /* System-wide hook */
    {
	prevHook = &SYSTEM_HOOK( id );
    }
    
    handle = (HANDLE) USER_HEAP_ALLOC( sizeof(*data) );
    if (!handle) return 0;
    data   = (HOOKDATA *) USER_HEAP_LIN_ADDR( handle );

    data->next  = *prevHook;
    data->proc  = proc;
    data->id    = id;
    data->htask = htask;
    *prevHook   = USER_HEAP_SEG_ADDR(handle);
    return *prevHook;
}


/***********************************************************************
 *           UnhookWindowHookEx   (USER.292)
 */
BOOL UnhookWindowsHookEx( HHOOK hhook )
{
    HOOKDATA *data = (HOOKDATA *)PTR_SEG_TO_LIN(hhook);
    HHOOK *prevHook;

    if (!data) return FALSE;
    prevHook = data->htask ? &TASK_HOOK(data->id) : &SYSTEM_HOOK(data->id);
    while (*prevHook && (*prevHook != hhook)) {    
	prevHook = &((HOOKDATA *)*prevHook)->next;
    }
    if (!*prevHook) return FALSE;
    *prevHook = data->next;
    USER_HEAP_FREE( hhook & 0xffff );
    return TRUE;
}


/***********************************************************************
 *           CallNextHookEx   (USER.293)
 */
DWORD CallNextHookEx( HHOOK hhook, short code, WPARAM wParam, LPARAM lParam )
{
    HOOKDATA *data = (HOOKDATA *)PTR_SEG_TO_LIN(hhook);
    if (!data->next) return 0;
    else return INTERNAL_CALL_HOOK( data->next, code, wParam, lParam );
}
