/*
 * Tablet Context
 *
 * Copyright 2002 Patrik Stridvall
 * 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 "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>

#include "windef.h"
#include "winerror.h"
#include "winbase.h"
#include "winuser.h"
#include "winnls.h"

#include "wintab.h"
#include "wintab_internal.h"

#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(wintab32);

/*
 * Documentation found at
 * http://www.csl.sony.co.jp/projects/ar/restricted/wintabl.html
 */

static BOOL gLoaded;
static LPOPENCONTEXT gOpenContexts;
static HCTX gTopContext = (HCTX)0xc00;

static void LOGCONTEXTAtoW(const LOGCONTEXTA *in, LOGCONTEXTW *out)
{
    MultiByteToWideChar(CP_ACP, 0, in->lcName, -1, out->lcName, LCNAMELEN);
    out->lcName[LCNAMELEN - 1] = 0;
    /* we use the fact that the fields after lcName are the same in LOGCONTEXTA and W */
    memcpy(&out->lcOptions, &in->lcOptions, sizeof(LOGCONTEXTA) - FIELD_OFFSET(LOGCONTEXTA, lcOptions));
}

static void LOGCONTEXTWtoA(const LOGCONTEXTW *in, LOGCONTEXTA *out)
{
    WideCharToMultiByte(CP_ACP, 0, in->lcName, LCNAMELEN, out->lcName, LCNAMELEN, NULL, NULL);
    out->lcName[LCNAMELEN - 1] = 0;
    /* we use the fact that the fields after lcName are the same in LOGCONTEXTA and W */
    memcpy(&out->lcOptions, &in->lcOptions, sizeof(LOGCONTEXTW) - FIELD_OFFSET(LOGCONTEXTW, lcOptions));
}

static BOOL is_logcontext_category(UINT wCategory)
{
    return wCategory == WTI_DEFSYSCTX || wCategory == WTI_DEFCONTEXT || wCategory == WTI_DDCTXS;
}

static BOOL is_string_field(UINT wCategory, UINT nIndex)
{
    if (wCategory == WTI_INTERFACE && nIndex == IFC_WINTABID)
        return TRUE;
    if (is_logcontext_category(wCategory) && nIndex == CTX_NAME)
        return TRUE;
    if (wCategory >= WTI_CURSORS && wCategory <= WTI_CURSORS + 9)
        return TRUE;
    if (wCategory == WTI_DEVICES && (nIndex == DVC_NAME || nIndex == DVC_PNPID))
        return TRUE;
    return FALSE;
}

static char* DUMPBITS(int x, char* buf)
{
    strcpy(buf,"{");
   if (x&PK_CONTEXT) strcat(buf,"PK_CONTEXT ");
   if (x&PK_STATUS) strcat(buf, "PK_STATUS ");
   if (x&PK_TIME) strcat(buf, "PK_TIME ");
   if (x&PK_CHANGED) strcat(buf, "PK_CHANGED ");
   if (x&PK_SERIAL_NUMBER) strcat(buf, "PK_SERIAL_NUMBER ");
   if (x&PK_CURSOR) strcat(buf, "PK_CURSOR ");
   if (x&PK_BUTTONS) strcat(buf, "PK_BUTTONS ");
   if (x&PK_X) strcat(buf, "PK_X ");
   if (x&PK_Y) strcat(buf, "PK_Y ");
   if (x&PK_Z) strcat(buf, "PK_Z ");
   if (x&PK_NORMAL_PRESSURE) strcat(buf, "PK_NORMAL_PRESSURE ");
   if (x&PK_TANGENT_PRESSURE) strcat(buf, "PK_TANGENT_PRESSURE ");
   if (x&PK_ORIENTATION) strcat(buf, "PK_ORIENTATION ");
   if (x&PK_ROTATION) strcat(buf, "PK_ROTATION ");
    strcat(buf, "}");
    return buf;
}

static inline void DUMPPACKET(WTPACKET packet)
{
    TRACE("pkContext: %p pkStatus: 0x%x pkTime : 0x%x pkChanged: 0x%x pkSerialNumber: 0x%x pkCursor : %i pkButtons: %x pkX: %i pkY: %i pkZ: %i pkNormalPressure: %i pkTangentPressure: %i pkOrientation: (%i,%i,%i) pkRotation: (%i,%i,%i)\n",
          packet.pkContext,
    (UINT)packet.pkStatus,
    (UINT)packet.pkTime,
    (UINT)packet.pkChanged,
    packet.pkSerialNumber,
    packet.pkCursor,
    (UINT)packet.pkButtons,
    packet.pkX,
    packet.pkY,
    packet.pkZ,
    packet.pkNormalPressure,
    packet.pkTangentPressure,
    packet.pkOrientation.orAzimuth,
        packet.pkOrientation.orAltitude, packet.pkOrientation.orTwist,
    packet.pkRotation.roPitch,
        packet.pkRotation.roRoll, packet.pkRotation.roYaw);
}

static inline void DUMPCONTEXT(LOGCONTEXTW lc)
{
        CHAR mmsg[4000];
        CHAR bits[100];
        CHAR bits1[100];
        CHAR bits2[100];

        sprintf(mmsg,"%s, %x, %x, %x, %x, %x, %x, %x%s, %x%s, %x%s, %x, %x, %i, %i, %i, %i ,%i, %i, %i, %i, %i,%i, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i %i %i",
    wine_dbgstr_w(lc.lcName), lc.lcOptions, lc.lcStatus, lc.lcLocks, lc.lcMsgBase,
lc.lcDevice, lc.lcPktRate, (UINT)lc.lcPktData, DUMPBITS(lc.lcPktData,bits),
(UINT)lc.lcPktMode, DUMPBITS(lc.lcPktMode,bits1), (UINT)lc.lcMoveMask,
DUMPBITS(lc.lcMoveMask,bits2), (INT)lc.lcBtnDnMask, (INT)lc.lcBtnUpMask,
(INT)lc.lcInOrgX, (INT)lc.lcInOrgY, (INT)lc.lcInOrgZ, lc.lcInExtX, lc.lcInExtY,
lc.lcInExtZ, lc.lcOutOrgX, lc.lcOutOrgY, lc.lcOutOrgZ, lc.lcOutExtX,
lc.lcOutExtY, lc.lcOutExtZ, lc.lcSensX, lc.lcSensY, lc.lcSensZ, lc.lcSysMode,
lc.lcSysOrgX, lc.lcSysOrgY, lc.lcSysExtX, lc.lcSysExtY, lc.lcSysSensX,
lc.lcSysSensY);
        TRACE("context: %s\n",mmsg);
}


/* Find an open context given the handle */
static LPOPENCONTEXT TABLET_FindOpenContext(HCTX hCtx)
{
    LPOPENCONTEXT ptr = gOpenContexts;
    while (ptr)
    {
        if (ptr->handle == hCtx) return ptr;
        ptr = ptr->next;
    }
    return NULL;
}

static void LoadTablet(void)
{
    TRACE("Initializing the tablet to hwnd %p\n",hwndDefault);
    gLoaded= TRUE;
    pLoadTabletInfo(hwndDefault);
}

int TABLET_PostTabletMessage(LPOPENCONTEXT newcontext, UINT msg, WPARAM wParam,
                             LPARAM lParam, BOOL send_always)
{
    if ((send_always) || (newcontext->context.lcOptions & CXO_MESSAGES))
    {
        TRACE("Posting message %x to %p\n",msg, newcontext->hwndOwner);
        return PostMessageA(newcontext->hwndOwner, msg, wParam, lParam);
    }
    return 0;
}

static inline DWORD ScaleForContext(DWORD In, DWORD InOrg, DWORD InExt, DWORD
                                    OutOrg, DWORD OutExt)
{
    if (((InExt > 0 )&&(OutExt > 0)) || ((InExt<0) && (OutExt < 0)))
        return ((In - InOrg) * abs(OutExt) / abs(InExt)) + OutOrg;
    else
        return ((abs(InExt) - (In - InOrg))*abs(OutExt) / abs(InExt)) + OutOrg;
}

LPOPENCONTEXT FindOpenContext(HWND hwnd)
{
    LPOPENCONTEXT ptr;

    EnterCriticalSection(&csTablet);
    ptr = gOpenContexts;
    while (ptr)
    {
        TRACE("Trying Context %p (%p %p)\n",ptr->handle,hwnd,ptr->hwndOwner);
        if (ptr->hwndOwner == hwnd) break;
    }
    LeaveCriticalSection(&csTablet);
    return ptr;
}

LPOPENCONTEXT AddPacketToContextQueue(LPWTPACKET packet, HWND hwnd)
{
    LPOPENCONTEXT ptr=NULL;

    EnterCriticalSection(&csTablet);

    ptr = gOpenContexts;
    while (ptr)
    {
        TRACE("Trying Queue %p (%p %p)\n", ptr->handle, hwnd, ptr->hwndOwner);

        if (ptr->hwndOwner == hwnd)
        {
            int tgt;
            if (!ptr->enabled)
            {
                ptr = ptr->next;
                continue;
            }

            tgt = ptr->PacketsQueued;

            packet->pkContext = ptr->handle;

            /* translate packet data to the context */

            /* Scale  as per documentation */
            packet->pkY = ScaleForContext(packet->pkY, ptr->context.lcInOrgY,
                                ptr->context.lcInExtY, ptr->context.lcOutOrgY,
                                ptr->context.lcOutExtY);

            packet->pkX = ScaleForContext(packet->pkX, ptr->context.lcInOrgX,
                                ptr->context.lcInExtX, ptr->context.lcOutOrgX,
                                ptr->context.lcOutExtX);

            /* flip the Y axis */
            if (ptr->context.lcOutExtY > 0)
                packet->pkY = ptr->context.lcOutExtY - packet->pkY;

            DUMPPACKET(*packet);

            if (tgt == ptr->QueueSize)
            {
                TRACE("Queue Overflow %p\n",ptr->handle);
                ptr->PacketQueue[tgt-1].pkStatus |= TPS_QUEUE_ERR;
            }
            else
            {
                TRACE("Placed in queue %p index %i\n",ptr->handle,tgt);
                memcpy(&ptr->PacketQueue[tgt], packet, sizeof
                        (WTPACKET));
                ptr->PacketsQueued++;

                if (ptr->ActiveCursor != packet->pkCursor)
                {
                    ptr->ActiveCursor = packet->pkCursor;
                    if (ptr->context.lcOptions & CXO_CSRMESSAGES)
                        TABLET_PostTabletMessage(ptr, _WT_CSRCHANGE(ptr->context.lcMsgBase),
                          (WPARAM)packet->pkSerialNumber, (LPARAM)ptr->handle,
                            FALSE);
                }
            }
            break;
         }
        ptr = ptr->next;
    }
    LeaveCriticalSection(&csTablet);
    TRACE("Done (%p)\n",ptr);
    return ptr;
}

/*
 * Flushes all packets from the queue.
 */
static inline void TABLET_FlushQueue(LPOPENCONTEXT context)
{
    context->PacketsQueued = 0;
}

static inline int CopyTabletData(LPVOID target, LPVOID src, INT size)
{
    memcpy(target,src,size);
    return(size);
}

static INT TABLET_FindPacket(LPOPENCONTEXT context, UINT wSerial,
                                LPWTPACKET *pkt)
{
    int loop;
    int index  = -1;
    for (loop = 0; loop < context->PacketsQueued; loop++)
        if (context->PacketQueue[loop].pkSerialNumber == wSerial)
        {
            index = loop;
            *pkt = &context->PacketQueue[loop];
            break;
        }

    TRACE("%i .. %i\n",context->PacketsQueued,index);

    return index;
}


static LPVOID TABLET_CopyPacketData(LPOPENCONTEXT context, LPVOID lpPkt,
                                    LPWTPACKET wtp)
{
    LPBYTE ptr;
    CHAR bits[100];

    ptr = lpPkt;
    TRACE("Packet Bits %s\n",DUMPBITS(context->context.lcPktData,bits));

    if (context->context.lcPktData & PK_CONTEXT)
        ptr+=CopyTabletData(ptr,&wtp->pkContext,sizeof(HCTX));
    if (context->context.lcPktData & PK_STATUS)
        ptr+=CopyTabletData(ptr,&wtp->pkStatus,sizeof(UINT));
    if (context->context.lcPktData & PK_TIME)
        ptr+=CopyTabletData(ptr,&wtp->pkTime,sizeof(LONG));
    if (context->context.lcPktData & PK_CHANGED)
        ptr+=CopyTabletData(ptr,&wtp->pkChanged,sizeof(WTPKT));
    if (context->context.lcPktData & PK_SERIAL_NUMBER)
        ptr+=CopyTabletData(ptr,&wtp->pkChanged,sizeof(UINT));
    if (context->context.lcPktData & PK_CURSOR)
        ptr+=CopyTabletData(ptr,&wtp->pkCursor,sizeof(UINT));
    if (context->context.lcPktData & PK_BUTTONS)
        ptr+=CopyTabletData(ptr,&wtp->pkButtons,sizeof(DWORD));
    if (context->context.lcPktData & PK_X)
        ptr+=CopyTabletData(ptr,&wtp->pkX,sizeof(DWORD));
    if (context->context.lcPktData & PK_Y)
        ptr+=CopyTabletData(ptr,&wtp->pkY,sizeof(DWORD));
    if (context->context.lcPktData & PK_Z)
        ptr+=CopyTabletData(ptr,&wtp->pkZ,sizeof(DWORD));
    if (context->context.lcPktData & PK_NORMAL_PRESSURE)
        ptr+=CopyTabletData(ptr,&wtp->pkNormalPressure,sizeof(UINT));
    if (context->context.lcPktData & PK_TANGENT_PRESSURE)
        ptr+=CopyTabletData(ptr,&wtp->pkTangentPressure,sizeof(UINT));
    if (context->context.lcPktData & PK_ORIENTATION)
        ptr+=CopyTabletData(ptr,&wtp->pkOrientation,sizeof(ORIENTATION));
    if (context->context.lcPktData & PK_ROTATION)
        ptr+=CopyTabletData(ptr,&wtp->pkRotation,sizeof(ROTATION));

    /*TRACE("Copied %i bytes\n",(INT)ptr - (INT)lpPkt); */
    return ptr;
}

static VOID TABLET_BlankPacketData(LPOPENCONTEXT context, LPVOID lpPkt, INT n)
{
    int rc = 0;

    if (context->context.lcPktData & PK_CONTEXT)
        rc +=sizeof(HCTX);
    if (context->context.lcPktData & PK_STATUS)
        rc +=sizeof(UINT);
    if (context->context.lcPktData & PK_TIME)
        rc += sizeof(LONG);
    if (context->context.lcPktData & PK_CHANGED)
        rc += sizeof(WTPKT);
    if (context->context.lcPktData & PK_SERIAL_NUMBER)
        rc += sizeof(UINT);
    if (context->context.lcPktData & PK_CURSOR)
        rc += sizeof(UINT);
    if (context->context.lcPktData & PK_BUTTONS)
        rc += sizeof(DWORD);
    if (context->context.lcPktData & PK_X)
        rc += sizeof(DWORD);
    if (context->context.lcPktData & PK_Y)
        rc += sizeof(DWORD);
    if (context->context.lcPktData & PK_Z)
        rc += sizeof(DWORD);
    if (context->context.lcPktData & PK_NORMAL_PRESSURE)
        rc += sizeof(UINT);
    if (context->context.lcPktData & PK_TANGENT_PRESSURE)
        rc += sizeof(UINT);
    if (context->context.lcPktData & PK_ORIENTATION)
        rc += sizeof(ORIENTATION);
    if (context->context.lcPktData & PK_ROTATION)
        rc += sizeof(ROTATION);

    rc *= n;
    memset(lpPkt,0,rc);
}


UINT WINAPI WTInfoT(UINT wCategory, UINT nIndex, LPVOID lpOutput, BOOL bUnicode)
{
    UINT result;
    if (gLoaded == FALSE)
         LoadTablet();

    /*
     *  Handle system extents here, as we can use user32.dll code to set them.
     */
    if(wCategory == WTI_DEFSYSCTX)
    {
        switch(nIndex)
        {
            case CTX_SYSEXTX:
                if(lpOutput != NULL)
                    *(LONG*)lpOutput = GetSystemMetrics(SM_CXSCREEN);
                return sizeof(LONG);
            case CTX_SYSEXTY:
                if(lpOutput != NULL)
                    *(LONG*)lpOutput = GetSystemMetrics(SM_CYSCREEN);
                return sizeof(LONG);
           /* No action, delegate to X11Drv */
        }
    }

    if (is_logcontext_category(wCategory) && nIndex == 0)
    {
        if (lpOutput)
        {
            LOGCONTEXTW buf;
            pWTInfoW(wCategory, nIndex, &buf);

            /*  Handle system extents here, as we can use user32.dll code to set them */
            if(wCategory == WTI_DEFSYSCTX && nIndex == 0)
            {
                buf.lcSysExtX = GetSystemMetrics(SM_CXSCREEN);
                buf.lcSysExtY = GetSystemMetrics(SM_CYSCREEN);
            }

            if (bUnicode)
                memcpy(lpOutput, &buf, sizeof(buf));
            else
                LOGCONTEXTWtoA(&buf, lpOutput);
        }

        return bUnicode ? sizeof(LOGCONTEXTW) : sizeof(LOGCONTEXTA);
    }
    else if (is_string_field(wCategory, nIndex) && !bUnicode)
    {
        int size = pWTInfoW(wCategory, nIndex, NULL);
        WCHAR *buf = HeapAlloc(GetProcessHeap(), 0, size);
        pWTInfoW(wCategory, nIndex, buf);
        result = WideCharToMultiByte(CP_ACP, 0, buf, size/sizeof(WCHAR), lpOutput, lpOutput ? 2*size : 0, NULL, NULL);
        HeapFree(GetProcessHeap(), 0, buf);
    }
    else
        result =  pWTInfoW(wCategory, nIndex, lpOutput);

    return result;
}

/***********************************************************************
 *		WTInfoA (WINTAB32.20)
 */
UINT WINAPI WTInfoA(UINT wCategory, UINT nIndex, LPVOID lpOutput)
{
    return WTInfoT(wCategory, nIndex, lpOutput, FALSE);
}


/***********************************************************************
 *		WTInfoW (WINTAB32.1020)
 */
UINT WINAPI WTInfoW(UINT wCategory, UINT nIndex, LPVOID lpOutput)
{
    return WTInfoT(wCategory, nIndex, lpOutput, TRUE);
}

/***********************************************************************
 *		WTOpenW (WINTAB32.2021)
 */
HCTX WINAPI WTOpenW(HWND hWnd, LPLOGCONTEXTW lpLogCtx, BOOL fEnable)
{
    LPOPENCONTEXT newcontext;

    TRACE("(%p, %p, %u)\n", hWnd, lpLogCtx, fEnable);
    DUMPCONTEXT(*lpLogCtx);

    newcontext = HeapAlloc(GetProcessHeap(), 0 , sizeof(OPENCONTEXT));
    memcpy(&(newcontext->context),lpLogCtx,sizeof(LOGCONTEXTW));
    newcontext->hwndOwner = hWnd;
    newcontext->enabled = fEnable;
    newcontext->ActiveCursor = -1;
    newcontext->QueueSize = 10;
    newcontext->PacketsQueued = 0;
    newcontext->PacketQueue=HeapAlloc(GetProcessHeap(),0,sizeof(WTPACKET)*10);

    EnterCriticalSection(&csTablet);
    newcontext->handle = gTopContext++;
    newcontext->next = gOpenContexts;
    gOpenContexts = newcontext;
    LeaveCriticalSection(&csTablet);

    pAttachEventQueueToTablet(hWnd);

    TABLET_PostTabletMessage(newcontext, _WT_CTXOPEN(newcontext->context.lcMsgBase), (WPARAM)newcontext->handle,
                      newcontext->context.lcStatus, TRUE);

    newcontext->context.lcStatus = CXS_ONTOP;

    TABLET_PostTabletMessage(newcontext, _WT_CTXOVERLAP(newcontext->context.lcMsgBase),
                            (WPARAM)newcontext->handle,
                            newcontext->context.lcStatus, TRUE);

    return newcontext->handle;
}

/***********************************************************************
 *		WTOpenA (WINTAB32.21)
 */
HCTX WINAPI WTOpenA(HWND hWnd, LPLOGCONTEXTA lpLogCtx, BOOL fEnable)
{
    LOGCONTEXTW logCtxW;

    LOGCONTEXTAtoW(lpLogCtx, &logCtxW);
    return WTOpenW(hWnd, &logCtxW, fEnable);
}

/***********************************************************************
 *		WTClose (WINTAB32.22)
 */
BOOL WINAPI WTClose(HCTX hCtx)
{
    LPOPENCONTEXT context,ptr;

    TRACE("(%p)\n", hCtx);

    EnterCriticalSection(&csTablet);

    ptr = context = gOpenContexts;

    while (context && (context->handle != hCtx))
    {
        ptr = context;
        context = context->next;
    }
    if (!context)
    {
        LeaveCriticalSection(&csTablet);
        return TRUE;
    }

    if (context == gOpenContexts)
        gOpenContexts = context->next;
    else
        ptr->next = context->next;

    LeaveCriticalSection(&csTablet);

    TABLET_PostTabletMessage(context, _WT_CTXCLOSE(context->context.lcMsgBase), (WPARAM)context->handle,
                      context->context.lcStatus,TRUE);

    HeapFree(GetProcessHeap(),0,context->PacketQueue);
    HeapFree(GetProcessHeap(),0,context);

    return TRUE;
}

/***********************************************************************
 *		WTPacketsGet (WINTAB32.23)
 */
int WINAPI WTPacketsGet(HCTX hCtx, int cMaxPkts, LPVOID lpPkts)
{
    int limit;
    LPOPENCONTEXT context;
    LPVOID ptr = lpPkts;

    TRACE("(%p, %d, %p)\n", hCtx, cMaxPkts, lpPkts);

    if (!hCtx)
        return 0;

    EnterCriticalSection(&csTablet);

    context = TABLET_FindOpenContext(hCtx);

    if (lpPkts != NULL)
        TABLET_BlankPacketData(context,lpPkts,cMaxPkts);

    if (context->PacketsQueued == 0)
    {
        LeaveCriticalSection(&csTablet);
        return 0;
    }

    limit = min(cMaxPkts,context->PacketsQueued);

    if(ptr != NULL)
    {
        int i = 0;
        for(i = 0; i < limit; i++)
            ptr=TABLET_CopyPacketData(context ,ptr, &context->PacketQueue[i]);
    }


    if (limit < context->PacketsQueued)
    {
        memmove(context->PacketQueue, &context->PacketQueue[limit],
            (context->PacketsQueued - (limit))*sizeof(WTPACKET));
    }
    context->PacketsQueued -= limit;
    LeaveCriticalSection(&csTablet);

    TRACE("Copied %i packets\n",limit);

    return limit;
}

/***********************************************************************
 *		WTPacket (WINTAB32.24)
 */
BOOL WINAPI WTPacket(HCTX hCtx, UINT wSerial, LPVOID lpPkt)
{
    int rc = 0;
    LPOPENCONTEXT context;
    LPWTPACKET wtp = NULL;

    TRACE("(%p, %d, %p)\n", hCtx, wSerial, lpPkt);

    if (!hCtx)
        return 0;

    EnterCriticalSection(&csTablet);

    context = TABLET_FindOpenContext(hCtx);

    rc = TABLET_FindPacket(context ,wSerial, &wtp);

    if (rc >= 0)
    {
        if (lpPkt)
           TABLET_CopyPacketData(context ,lpPkt, wtp);

        if ((rc+1) < context->QueueSize)
        {
            memmove(context->PacketQueue, &context->PacketQueue[rc+1],
                (context->PacketsQueued - (rc+1))*sizeof(WTPACKET));
        }
        context->PacketsQueued -= (rc+1);
    }
    LeaveCriticalSection(&csTablet);

    TRACE("Returning %i\n",rc+1);
    return rc+1;
}

/***********************************************************************
 *		WTEnable (WINTAB32.40)
 */
BOOL WINAPI WTEnable(HCTX hCtx, BOOL fEnable)
{
    LPOPENCONTEXT context;

    TRACE("(%p, %u)\n", hCtx, fEnable);

    if (!hCtx) return 0;

    EnterCriticalSection(&csTablet);
    context = TABLET_FindOpenContext(hCtx);
    if(!fEnable)
        TABLET_FlushQueue(context);
    context->enabled = fEnable;
    LeaveCriticalSection(&csTablet);

    return TRUE;
}

/***********************************************************************
 *		WTOverlap (WINTAB32.41)
 */
BOOL WINAPI WTOverlap(HCTX hCtx, BOOL fToTop)
{
    FIXME("(%p, %u): stub\n", hCtx, fToTop);

    return TRUE;
}

/***********************************************************************
 *		WTConfig (WINTAB32.61)
 */
BOOL WINAPI WTConfig(HCTX hCtx, HWND hWnd)
{
    FIXME("(%p, %p): stub\n", hCtx, hWnd);

    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);

    return FALSE;
}

/***********************************************************************
 *		WTGetA (WINTAB32.61)
 */
BOOL WINAPI WTGetA(HCTX hCtx, LPLOGCONTEXTA lpLogCtx)
{
    LPOPENCONTEXT context;

    TRACE("(%p, %p)\n", hCtx, lpLogCtx);

    if (!hCtx) return 0;

    EnterCriticalSection(&csTablet);
    context = TABLET_FindOpenContext(hCtx);
    LOGCONTEXTWtoA(&context->context, lpLogCtx);
    LeaveCriticalSection(&csTablet);

    return TRUE;
}

/***********************************************************************
 *		WTGetW (WINTAB32.1061)
 */
BOOL WINAPI WTGetW(HCTX hCtx, LPLOGCONTEXTW lpLogCtx)
{
    LPOPENCONTEXT context;

    TRACE("(%p, %p)\n", hCtx, lpLogCtx);

    if (!hCtx) return 0;

    EnterCriticalSection(&csTablet);
    context = TABLET_FindOpenContext(hCtx);
    memmove(lpLogCtx,&context->context,sizeof(LOGCONTEXTW));
    LeaveCriticalSection(&csTablet);

    return TRUE;
}

/***********************************************************************
 *		WTSetA (WINTAB32.62)
 */
BOOL WINAPI WTSetA(HCTX hCtx, LPLOGCONTEXTA lpLogCtx)
{
    FIXME("(%p, %p): stub\n", hCtx, lpLogCtx);

    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);

    return FALSE;
}

/***********************************************************************
 *		WTSetW (WINTAB32.1062)
 */
BOOL WINAPI WTSetW(HCTX hCtx, LPLOGCONTEXTW lpLogCtx)
{
    FIXME("(%p, %p): stub\n", hCtx, lpLogCtx);

    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);

    return FALSE;
}

/***********************************************************************
 *		WTExtGet (WINTAB32.63)
 */
BOOL WINAPI WTExtGet(HCTX hCtx, UINT wExt, LPVOID lpData)
{
    FIXME("(%p, %u, %p): stub\n", hCtx, wExt, lpData);

    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);

    return FALSE;
}

/***********************************************************************
 *		WTExtSet (WINTAB32.64)
 */
BOOL WINAPI WTExtSet(HCTX hCtx, UINT wExt, LPVOID lpData)
{
    FIXME("(%p, %u, %p): stub\n", hCtx, wExt, lpData);

    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);

    return FALSE;
}

/***********************************************************************
 *		WTSave (WINTAB32.65)
 */
BOOL WINAPI WTSave(HCTX hCtx, LPVOID lpSaveInfo)
{
    FIXME("(%p, %p): stub\n", hCtx, lpSaveInfo);

    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);

    return FALSE;
}

/***********************************************************************
 *		WTRestore (WINTAB32.66)
 */
HCTX WINAPI WTRestore(HWND hWnd, LPVOID lpSaveInfo, BOOL fEnable)
{
    FIXME("(%p, %p, %u): stub\n", hWnd, lpSaveInfo, fEnable);

    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);

    return 0;
}

/***********************************************************************
 *		WTPacketsPeek (WINTAB32.80)
 */
int WINAPI WTPacketsPeek(HCTX hCtx, int cMaxPkts, LPVOID lpPkts)
{
    int limit;
    LPOPENCONTEXT context;
    LPVOID ptr = lpPkts;

    TRACE("(%p, %d, %p)\n", hCtx, cMaxPkts, lpPkts);

    if (!hCtx || !lpPkts) return 0;

    EnterCriticalSection(&csTablet);

    context = TABLET_FindOpenContext(hCtx);

    if (context->PacketsQueued == 0)
    {
        LeaveCriticalSection(&csTablet);
        return 0;
    }

    for (limit = 0; limit < cMaxPkts && limit < context->PacketsQueued; limit++)
        ptr = TABLET_CopyPacketData(context ,ptr, &context->PacketQueue[limit]);

    LeaveCriticalSection(&csTablet);
    TRACE("Copied %i packets\n",limit);
    return limit;
}

/***********************************************************************
 *		WTDataGet (WINTAB32.81)
 */
int WINAPI WTDataGet(HCTX hCtx, UINT wBegin, UINT wEnd,
		     int cMaxPkts, LPVOID lpPkts, LPINT lpNPkts)
{
    LPOPENCONTEXT context;
    LPVOID ptr = lpPkts;
    INT bgn = 0;
    INT end = 0;
    INT num = 0;

    TRACE("(%p, %u, %u, %d, %p, %p)\n",
	  hCtx, wBegin, wEnd, cMaxPkts, lpPkts, lpNPkts);

    if (!hCtx) return 0;

    EnterCriticalSection(&csTablet);

    context = TABLET_FindOpenContext(hCtx);

    if (context->PacketsQueued == 0)
    {
        LeaveCriticalSection(&csTablet);
        return 0;
    }

    while (bgn < context->PacketsQueued &&
           context->PacketQueue[bgn].pkSerialNumber != wBegin)
        bgn++;

    end = bgn;
    while (end < context->PacketsQueued &&
           context->PacketQueue[end].pkSerialNumber != wEnd)
        end++;

    if ((bgn == end) && (end == context->PacketsQueued))
    {
        LeaveCriticalSection(&csTablet);
        return 0;
    }

    for (num = bgn; num <= end; num++)
        ptr = TABLET_CopyPacketData(context ,ptr, &context->PacketQueue[num]);

    /* remove read packets */
    if ((end+1) < context->PacketsQueued)
        memmove( &context->PacketQueue[bgn], &context->PacketQueue[end+1],
                (context->PacketsQueued - (end+1)) * sizeof (WTPACKET));

    context->PacketsQueued -= ((end-bgn)+1);
    *lpNPkts = ((end-bgn)+1);

    LeaveCriticalSection(&csTablet);
    TRACE("Copied %i packets\n",*lpNPkts);
    return (end - bgn)+1;
}

/***********************************************************************
 *		WTDataPeek (WINTAB32.82)
 */
int WINAPI WTDataPeek(HCTX hCtx, UINT wBegin, UINT wEnd,
		      int cMaxPkts, LPVOID lpPkts, LPINT lpNPkts)
{
    LPOPENCONTEXT context;
    LPVOID ptr = lpPkts;
    INT bgn = 0;
    INT end = 0;
    INT num = 0;

    TRACE("(%p, %u, %u, %d, %p, %p)\n",
	  hCtx, wBegin, wEnd, cMaxPkts, lpPkts, lpNPkts);

    if (!hCtx || !lpPkts) return 0;

    EnterCriticalSection(&csTablet);

    context = TABLET_FindOpenContext(hCtx);

    if (context->PacketsQueued == 0)
    {
        LeaveCriticalSection(&csTablet);
        return 0;
    }

    while (bgn < context->PacketsQueued &&
           context->PacketQueue[bgn].pkSerialNumber != wBegin)
        bgn++;

    end = bgn;
    while (end < context->PacketsQueued &&
           context->PacketQueue[end].pkSerialNumber != wEnd)
        end++;

    if (bgn == context->PacketsQueued ||  end == context->PacketsQueued)
    {
        TRACE("%i %i %i\n", bgn, end, context->PacketsQueued);
        LeaveCriticalSection(&csTablet);
        return 0;
    }

    for (num = bgn; num <= end; num++)
        ptr = TABLET_CopyPacketData(context ,ptr, &context->PacketQueue[num]);

    *lpNPkts = ((end-bgn)+1);
    LeaveCriticalSection(&csTablet);

    TRACE("Copied %i packets\n",*lpNPkts);
    return (end - bgn)+1;
}

/***********************************************************************
 *		WTQueuePacketsEx (WINTAB32.200)
 */
BOOL WINAPI WTQueuePacketsEx(HCTX hCtx, UINT *lpOld, UINT *lpNew)
{
    LPOPENCONTEXT context;

    TRACE("(%p, %p, %p)\n", hCtx, lpOld, lpNew);

    if (!hCtx) return 0;

    EnterCriticalSection(&csTablet);

    context = TABLET_FindOpenContext(hCtx);

    if (context->PacketsQueued)
    {
        *lpOld = context->PacketQueue[0].pkSerialNumber;
        *lpNew = context->PacketQueue[context->PacketsQueued-1].pkSerialNumber;
    }
    else
    {
        TRACE("No packets\n");
        LeaveCriticalSection(&csTablet);
        return FALSE;
    }
    LeaveCriticalSection(&csTablet);

    return TRUE;
}

/***********************************************************************
 *		WTQueueSizeGet (WINTAB32.84)
 */
int WINAPI WTQueueSizeGet(HCTX hCtx)
{
    LPOPENCONTEXT context;
    TRACE("(%p)\n", hCtx);

    if (!hCtx) return 0;

    EnterCriticalSection(&csTablet);
    context = TABLET_FindOpenContext(hCtx);
    LeaveCriticalSection(&csTablet);
    return context->QueueSize;
}

/***********************************************************************
 *		WTQueueSizeSet (WINTAB32.85)
 */
BOOL WINAPI WTQueueSizeSet(HCTX hCtx, int nPkts)
{
    LPOPENCONTEXT context;

    TRACE("(%p, %d)\n", hCtx, nPkts);

    if (!hCtx) return 0;

    EnterCriticalSection(&csTablet);

    context = TABLET_FindOpenContext(hCtx);

    context->PacketQueue = HeapReAlloc(GetProcessHeap(), 0,
                        context->PacketQueue, sizeof(WTPACKET)*nPkts);

    context->QueueSize = nPkts;
    LeaveCriticalSection(&csTablet);

    return nPkts;
}
