/*
 * DOS interrupt 33h handler
 */

#include <stdlib.h>
#include <string.h>

#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
#include "miscemu.h"
#include "callback.h"
#include "dosexe.h"
#include "vga.h"
#include "debugtools.h"

DEFAULT_DEBUG_CHANNEL(int);

static struct
{
  DWORD x, y, but;
  FARPROC16 callback;
  WORD callmask;
} mouse_info;

/**********************************************************************
 *	    INT_Int33Handler
 *
 * Handler for int 33h (MS MOUSE).
 */
void WINAPI INT_Int33Handler( CONTEXT86 *context )
{
  switch (LOWORD(context->Eax)) {
  case 0x00:
    TRACE("Reset mouse driver and request status\n");
    AX_reg(context) = 0xFFFF; /* installed */
    BX_reg(context) = 3;      /* # of buttons */
    memset( &mouse_info, 0, sizeof(mouse_info) );
    break;
  case 0x01:
    FIXME("Show mouse cursor\n");
    break;
  case 0x02:
    FIXME("Hide mouse cursor\n");
    break;
  case 0x03:
    TRACE("Return mouse position and button status\n");
    BX_reg(context) = mouse_info.but;
    CX_reg(context) = mouse_info.x;
    DX_reg(context) = mouse_info.y;
    break;
  case 0x04:
    FIXME("Position mouse cursor\n");
    break;
  case 0x07:
    FIXME("Define horizontal mouse cursor range\n");
    break;
  case 0x08:
    FIXME("Define vertical mouse cursor range\n");
    break;
  case 0x09:
    FIXME("Define graphics mouse cursor\n");
    break;
  case 0x0A:
    FIXME("Define text mouse cursor\n");
    break;
  case 0x0C:
    TRACE("Define mouse interrupt subroutine\n");
    mouse_info.callmask = CX_reg(context);
    mouse_info.callback = (FARPROC16)MAKESEGPTR(context->SegEs, LOWORD(context->Edx));
    break;
  case 0x10:
    FIXME("Define screen region for update\n");
    break;
  default:
    INT_BARF(context,0x33);
  }
}

typedef struct {
  FARPROC16 proc;
  WORD mask,but,x,y,mx,my;
} MCALLDATA;

static void MouseRelay(CONTEXT86 *context,void *mdata)
{
  MCALLDATA *data = (MCALLDATA *)mdata;
  CONTEXT86 ctx = *context;

  ctx.Eax   = data->mask;
  ctx.Ebx   = data->but;
  ctx.Ecx   = data->x;
  ctx.Edx   = data->y;
  ctx.Esi   = data->mx;
  ctx.Edi   = data->my;
  ctx.SegCs = SELECTOROF(data->proc);
  ctx.Eip   = OFFSETOF(data->proc);
  free(data);
  DPMI_CallRMProc(&ctx, NULL, 0, 0);
}

void WINAPI INT_Int33Message(UINT message,WPARAM wParam,LPARAM lParam)
{
  WORD mask = 0;
  unsigned Height, Width, SX=1, SY=1;

  if (!VGA_GetMode(&Height,&Width,NULL)) {
    /* may need to do some coordinate scaling */
    SX = 640/Width;
    if (!SX) SX=1;
  }
  mouse_info.x = LOWORD(lParam) * SX;
  mouse_info.y = HIWORD(lParam) * SY;
  switch (message) {
  case WM_MOUSEMOVE:
    mask |= 0x01;
    break;
  case WM_LBUTTONDOWN:
  case WM_LBUTTONDBLCLK:
    mouse_info.but |= 0x01;
    mask |= 0x02;
    break;
  case WM_LBUTTONUP:
    mouse_info.but &= ~0x01;
    mask |= 0x04;
    break;
  case WM_RBUTTONDOWN:
  case WM_RBUTTONDBLCLK:
    mouse_info.but |= 0x02;
    mask |= 0x08;
    break;
  case WM_RBUTTONUP:
    mouse_info.but &= ~0x02;
    mask |= 0x10;
    break;
  case WM_MBUTTONDOWN:
  case WM_MBUTTONDBLCLK:
    mouse_info.but |= 0x04;
    mask |= 0x20;
    break;
  case WM_MBUTTONUP:
    mouse_info.but &= ~0x04;
    mask |= 0x40;
    break;
  }

  if ((mask & mouse_info.callmask) && mouse_info.callback) {
    MCALLDATA *data = calloc(1,sizeof(MCALLDATA));
    data->proc = mouse_info.callback;
    data->mask = mask & mouse_info.callmask;
    data->but = mouse_info.but;
    data->x = mouse_info.x;
    data->y = mouse_info.y;
    Dosvm.QueueEvent(-1, DOS_PRIORITY_MOUSE, MouseRelay, data);
  }
}
