/*
 * WinTab32 library
 *
 * Copyright 2003 CodeWeavers, Aric Stewart
 *
 * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#include <stdarg.h>

#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
#include "winerror.h"
#include "wintab.h"
#include "wintab_internal.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(wintab32);

HWND hwndDefault = NULL;
static const WCHAR
  WC_TABLETCLASSNAME[] = {'W','i','n','e','T','a','b','l','e','t','C','l','a','s','s',0};
CRITICAL_SECTION csTablet;

int (*pLoadTabletInfo)(HWND hwnddefault) = NULL;
int (*pGetCurrentPacket)(LPWTPACKET packet) = NULL;
int (*pAttachEventQueueToTablet)(HWND hOwner) = NULL;
UINT (*pWTInfoW)(UINT wCategory, UINT nIndex, LPVOID lpOutput) = NULL;

static LRESULT WINAPI TABLET_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam,
                                          LPARAM lParam);

static VOID TABLET_Register(void)
{
    WNDCLASSW wndClass;
    ZeroMemory(&wndClass, sizeof(WNDCLASSW));
    wndClass.style = CS_GLOBALCLASS;
    wndClass.lpfnWndProc = TABLET_WindowProc;
    wndClass.cbClsExtra = 0;
    wndClass.cbWndExtra = 0;
    wndClass.hCursor = NULL;
    wndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW +1);
    wndClass.lpszClassName = WC_TABLETCLASSNAME;
    RegisterClassW(&wndClass);
}

static VOID TABLET_Unregister(void)
{
    UnregisterClassW(WC_TABLETCLASSNAME, NULL);
}

BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpReserved)
{
    static const WCHAR name[] = {'T','a','b','l','e','t',0};
    HMODULE hx11drv;

    TRACE("%p, %x, %p\n",hInstDLL,fdwReason,lpReserved);
    switch (fdwReason)
    {
        case DLL_PROCESS_ATTACH:
            TRACE("Initialization\n");
            DisableThreadLibraryCalls(hInstDLL);
            InitializeCriticalSection(&csTablet);
            csTablet.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": csTablet");
            hx11drv = GetModuleHandleA("winex11.drv");
            if (hx11drv)
            {
                pLoadTabletInfo = (void *)GetProcAddress(hx11drv, "LoadTabletInfo");
                pAttachEventQueueToTablet = (void *)GetProcAddress(hx11drv, "AttachEventQueueToTablet");
                pGetCurrentPacket = (void *)GetProcAddress(hx11drv, "GetCurrentPacket");
                pWTInfoW = (void *)GetProcAddress(hx11drv, "WTInfoW");
                TABLET_Register();
                hwndDefault = CreateWindowW(WC_TABLETCLASSNAME, name,
                                WS_POPUPWINDOW,0,0,0,0,0,0,hInstDLL,0);
            }
            else
                return FALSE;
            break;
        case DLL_PROCESS_DETACH:
            TRACE("Detaching\n");
            if (hwndDefault)
            {
                DestroyWindow(hwndDefault);
                hwndDefault = 0;
            }
            TABLET_Unregister();
            csTablet.DebugInfo->Spare[0] = 0;
            DeleteCriticalSection(&csTablet);
            break;
    }
    return TRUE;
}


/*
 * The window proc for the default TABLET window
 */
static LRESULT WINAPI TABLET_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam,
                                          LPARAM lParam)
{
    TRACE("Incoming Message 0x%x  (0x%08x, 0x%08x)\n", uMsg, (UINT)wParam,
           (UINT)lParam);

    switch(uMsg)
    {
        case WM_NCCREATE:
            return TRUE;

        case WT_PACKET:
            {
                WTPACKET packet;
                LPOPENCONTEXT handler;
                pGetCurrentPacket(&packet);
                handler = AddPacketToContextQueue(&packet,(HWND)lParam);
                if (handler && handler->context.lcOptions & CXO_MESSAGES)
                    TABLET_PostTabletMessage(handler, _WT_PACKET(handler->context.lcMsgBase),
                                (WPARAM)packet.pkSerialNumber,
                                (LPARAM)handler->handle, FALSE);
                break;
            }
        case WT_PROXIMITY:
            {
                WTPACKET packet;
                LPOPENCONTEXT handler;
                LPARAM prox;
                pGetCurrentPacket(&packet);
                handler = AddPacketToContextQueue(&packet,(HWND)lParam);
                if (handler)
                {
                    prox = MAKELPARAM( wParam, 1 );
                    TABLET_PostTabletMessage(handler, WT_PROXIMITY,
                                        (WPARAM)handler->handle, (LPARAM)prox,
                                        TRUE);
                }
                break;
            }
    }
    return 0;
}
