/*
 * synergy -- mouse and keyboard sharing utility
 * Copyright (C) 2002 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.
 */

#ifndef CSYNERGYHOOK_H
#define CSYNERGYHOOK_H

#include "BasicTypes.h"
#define INCL_BASE
#define INCL_ERRORS
#define INCL_PM
#include <os2.h>

#if defined(SYNRGYHK_EXPORTS)
# define CSYNERGYHOOK_API extern "C" __declspec(dllexport)
#else
# define CSYNERGYHOOK_API extern "C" __declspec(dllimport)
#endif

/** @name The messages posted from the input hook on the synergy message queue.
 * @{
 */
#define SYNERGY_PM_MSG_MARK             WM_USER + 20    // mark id; <unused>
#define SYNERGY_PM_MSG_KEY              WM_USER + 21    // vk code; key data
/**
 * mp1.s1: msg
 * mp1.s2: 0 reserved.
 * mp2.s1: mouse x
 * mp2.s2: mouse y
 */
#define SYNERGY_PM_MSG_MOUSE_BUTTON     WM_USER + 22
/** WM_MOUSEMOVE mp1 and mp2. */
#define SYNERGY_PM_MSG_MOUSE_MOVE       WM_USER + 23

#define SYNERGY_PM_MSG_POST_WARP        WM_USER + 24    // <unused>; <unused>
#define SYNERGY_PM_MSG_PRE_WARP         WM_USER + 25    // x; y
#define SYNERGY_PM_MSG_DEBUG            WM_USER + 27    // data, data

#define SYNERGY_PM_MSG_FIRST            SYNERGY_PM_MSG_MARK     /**< The first message. */
#define SYNERGY_PM_MSG_LAST             SYNERGY_PM_MSG_DEBUG    /**< The last message. */
#define SYNERGY_PM_MSG_INPUT_FIRST      SYNERGY_PM_MSG_KEY      /**< The first input message. */
#define SYNERGY_PM_MSG_INPUT_LAST       SYNERGY_PM_MSG_PRE_WARP /**< The last input message. */
/** @} */

#define SYNERGY_PM_HOOK_FAKE_INPUT_MP1_FIXED    MPFROM2SHORT(KC_VIRTUALKEY | KC_SCANCODE, 0)
#define SYNERGY_PM_HOOK_FAKE_INPUT_MP2_SET      MPFROM2SHORT(0x8f70, 0x708f)
#define SYNERGY_PM_HOOK_FAKE_INPUT_MP2_CLEAR    MPFROM2SHORT(0x9f70, 0x708f)

enum EHookResult {
    kHOOK_FAILED,
    kHOOK_OKAY,
    kHOOK_OKAY_LL
};

enum EHookMode {
    kHOOK_DISABLE,
    kHOOK_WATCH_JUMP_ZONE,
    kHOOK_RELAY_EVENTS
};

typedef bool            (*InitFunc)(HMQ hmq, int tid, int pid);
typedef bool            (*CleanupFunc)(HAB hab);
typedef EHookResult     (*InstallFunc)(HAB hab);
typedef bool            (*UninstallFunc)(HAB hab);
typedef void            (*SetSidesFunc)(UInt32);
typedef void            (*SetZoneFunc)(SInt32, SInt32, SInt32, SInt32, SInt32);
typedef void            (*SetModeFunc)(int);
typedef const char *    (*FakeMsgFunc)(HAB hab, const QMSG *pQmsg);

CSYNERGYHOOK_API bool   init(HMQ hmq, int tid, int pid);
CSYNERGYHOOK_API bool   cleanup(HAB hab);
CSYNERGYHOOK_API EHookResult install(HAB hab);
CSYNERGYHOOK_API bool   uninstall(HAB hab);
CSYNERGYHOOK_API void   setSides(UInt32 sides);
CSYNERGYHOOK_API void   setZone(SInt32 x, SInt32 y, SInt32 cx, SInt32 cy, SInt32 jumpZoneSize);
CSYNERGYHOOK_API const char * fakeMsg(HAB hab, const QMSG *pQmsg);



//
// Various OS/2 stuff from the DDK.
//

/*
 * video/rel/.../pmwinp.mac and pmwinx.h in the ddk.
 */
typedef struct _KBDEVENT {    /* kevt */
    BYTE monFlags;          /* Open, Close and Flush monitor flags */
    BYTE scancode;          /* Original scan code (actually high byte of
                               monitor flags */
    BYTE xlatedchar;        /* Output of interrupt level character translation
                               table */

    BYTE xlatedscan;        /* Translated scan code.  Different only for
                               the enhanced keyboard */

    USHORT shiftDBCS;         /* DBCS shift state and status */
    USHORT shiftstate;        /* Current state of shift keys */
    ULONG time;             /* millisecond counter time stamp */
    USHORT ddFlags;           /* Keyboard device driver flags */
} KBDEVENT;
typedef KBDEVENT *PKBDEVENT;
// guess MON_* are for the monFlags field.
#define MON_OPEN	EQU	0001H
#define MON_CLOSE	EQU	0002H
#define MON_FLUSH	EQU	0004H
// guess KSS_* is for the shiftstate field.
#define KSS_SYSREQ	EQU	8000H
#define KSS_CAPSLOCK	EQU	4000H
#define KSS_NUMLOCK	EQU	2000H
#define KSS_SCROLLLOCK	EQU	1000H
#define KSS_RIGHTALT	EQU	0800H
#define KSS_RIGHTCTRL	EQU	0400H
#define KSS_LEFTALT	EQU	0200H
#define KSS_LEFTCTRL	EQU	0100H
#define KSS_INSERTON	EQU	0080H
#define KSS_CAPSLOCKON	EQU	0040H
#define KSS_NUMLOCKON	EQU	0020H
#define KSS_SCROLLLOCKON	EQU	0010H
#define KSS_EITHERALT	EQU	0008H
#define KSS_EITHERCTRL	EQU	0004H
#define KSS_LEFTSHIFT	EQU	0002H
#define KSS_RIGHTSHIFT	EQU	0001H
#define KSS_EITHERSHIFT	EQU	0003H
/* Valid values for ddFlags field */
#define KDD_MONFLAG1    0x8000 // bird: conflicts with KDD_KC_LONEKEY - relevant for VIOCHAR?
#define KDD_MONFLAG2	0x4000 // bird: conflicts with KDD_KC_PREVDOWN - relevant for VIOCHAR?
#define KDD_RESERVED	0x3C00
#define KDD_ACCENTED	0x0200
#define KDD_MULTIMAKE	0x0100
#define KDD_SECONDARY	0x0080
#define KDD_BREAK	0x0040
#define KDD_EXTENDEDKEY	0x0020
#define KDD_ACTIONFIELD	0x001F
#define KDD_KC_LONEKEY	0x8000
#define KDD_KC_PREVDOWN	0x4000
#define KDD_KC_KEYUP	0x2000
#define KDD_KC_ALT	0x1000
#define KDD_KC_CTRL	0x0800
#define KDD_KC_SHIFT	0x0400
#define KDD_KC_FLAGS	0x0FC00
/* Valid values for KDD_ACTIONFIELD portion of ddFlags field */
#define KDD_PUTINKIB	0x0000
#define KDD_ACK	0x0001
#define KDD_PREFIXKEY	0x0002
#define KDD_OVERRUN	0x0003
#define KDD_RESEND	0x0004
#define KDD_REBOOTKEY	0x0005
#define KDD_DUMPKEY	0x0006
#define KDD_SHIFTKEY	0x0007
#define KDD_PAUSEKEY	0x0008
#define KDD_PSEUDOPAUSE	0x0009
#define KDD_WAKEUPKEY	0x000A
#define KDD_BADACCENT	0x000B
#define KDD_HOTKEY	0x000C
#define KDD_ACCENTKEY	0x0010
#define KDD_BREAKKEY	0x0011
#define KDD_PSEUDOBREAK	0x0012
#define KDD_PRTSCKEY	0x0013
#define KDD_PRTECHOKEY	0x0014
#define KDD_PSEUDOPRECH	0x0015
#define KDD_STATUSCHG	0x0016
#define KDD_WRITTENKEY	0x0017
#define KDD_UNDEFINED	0x001F

/// PMWIN.174
// This needs to be used when pushing stuff to VIO programs. (pmvnc does anyway)
extern "C" KBDEVENT KbdPacket[2];

#endif
