4 * Copyright 2002 Patrik Stridvall
5 * Copyright 2003 CodeWeavers, Aric Stewart
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
33 #include "wintab_internal.h"
35 #include "wine/debug.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(wintab32);
40 * Documentation found at
41 * http://www.csl.sony.co.jp/projects/ar/restricted/wintabl.html
45 static LPOPENCONTEXT gOpenContexts;
46 static HCTX gTopContext = (HCTX)0xc00;
48 static char* DUMPBITS(int x, char* buf)
51 if (x&PK_CONTEXT) strcat(buf,"PK_CONTEXT ");
52 if (x&PK_STATUS) strcat(buf, "PK_STATUS ");
53 if (x&PK_TIME) strcat(buf, "PK_TIME ");
54 if (x&PK_CHANGED) strcat(buf, "PK_CHANGED ");
55 if (x&PK_SERIAL_NUMBER) strcat(buf, "PK_SERIAL_NUMBER ");
56 if (x&PK_CURSOR) strcat(buf, "PK_CURSOR ");
57 if (x&PK_BUTTONS) strcat(buf, "PK_BUTTONS ");
58 if (x&PK_X) strcat(buf, "PK_X ");
59 if (x&PK_Y) strcat(buf, "PK_Y ");
60 if (x&PK_Z) strcat(buf, "PK_Z ");
61 if (x&PK_NORMAL_PRESSURE) strcat(buf, "PK_NORMAL_PRESSURE ");
62 if (x&PK_TANGENT_PRESSURE) strcat(buf, "PK_TANGENT_PRESSURE ");
63 if (x&PK_ORIENTATION) strcat(buf, "PK_ORIENTATION ");
64 if (x&PK_ROTATION) strcat(buf, "PK_ROTATION ");
69 static inline void DUMPPACKET(WTPACKET packet)
71 TRACE("pkContext: 0x%x pkStatus: 0x%x pkTime : 0x%x pkChanged: 0x%x pkSerialNumber: 0x%x pkCursor : %i pkButtons: %x pkX: %li pkY: %li pkZ: %li pkNormalPressure: %i pkTangentPressure: %i pkOrientation: (%i,%i,%i) pkRotation: (%i,%i,%i)\n"
72 ,(UINT)packet.pkContext,
73 (UINT)packet.pkStatus,
75 (UINT)packet.pkChanged,
76 packet.pkSerialNumber,
78 (UINT)packet.pkButtons,
82 packet.pkNormalPressure,
83 packet.pkTangentPressure,
84 packet.pkOrientation.orAzimuth,
85 packet.pkOrientation.orAltitude, packet.pkOrientation.orTwist,
86 packet.pkRotation.roPitch,
87 packet.pkRotation.roRoll, packet.pkRotation.roYaw);
90 static inline void DUMPCONTEXT(LOGCONTEXTA lc)
97 sprintf(mmsg,"%s, %x, %x, %x, %x, %x, %x, %x%s, %x%s, %x%s, %x, %x, %i, %i, %i, %li ,%li, %li, %li, %li, %li,%li, %li, %li, %li, %li, %li, %i, %i, %i, %i, %i %li %li\n",
98 debugstr_a(lc.lcName), lc.lcOptions, lc.lcStatus, lc.lcLocks, lc.lcMsgBase,
99 lc.lcDevice, lc.lcPktRate, (UINT)lc.lcPktData, DUMPBITS(lc.lcPktData,bits),
100 (UINT)lc.lcPktMode, DUMPBITS(lc.lcPktMode,bits1), (UINT)lc.lcMoveMask,
101 DUMPBITS(lc.lcMoveMask,bits2), (INT)lc.lcBtnDnMask, (INT)lc.lcBtnUpMask,
102 (INT)lc.lcInOrgX, (INT)lc.lcInOrgY, (INT)lc.lcInOrgZ, lc.lcInExtX, lc.lcInExtY,
103 lc.lcInExtZ, lc.lcOutOrgX, lc.lcOutOrgY, lc.lcOutOrgZ, lc.lcOutExtX,
104 lc.lcOutExtY, lc.lcOutExtZ, lc.lcSensX, lc.lcSensY, lc.lcSensZ, lc.lcSysMode,
105 lc.lcSysOrgX, lc.lcSysOrgY, lc.lcSysExtX, lc.lcSysExtY, lc.lcSysSensX,
107 TRACE("context: %s",mmsg);
111 /* Find an open context given the handle */
112 static LPOPENCONTEXT TABLET_FindOpenContext(HCTX hCtx)
114 LPOPENCONTEXT ptr = gOpenContexts;
117 if (ptr->handle == hCtx) return ptr;
123 static void LoadTablet()
125 TRACE("Initilizing the tablet to hwnd %p\n",hwndDefault);
127 pLoadTabletInfo(hwndDefault);
130 int TABLET_PostTabletMessage(LPOPENCONTEXT newcontext, UINT msg, WPARAM wParam,
131 LPARAM lParam, BOOL send_always)
133 if ((send_always) || (newcontext->context.lcOptions & CXO_MESSAGES))
135 TRACE("Posting message %x to %x\n",msg, (UINT)newcontext->hwndOwner);
136 return PostMessageA(newcontext->hwndOwner, msg, wParam, lParam);
141 static inline DWORD ScaleForContext(DWORD In, DWORD InOrg, DWORD InExt, DWORD
142 OutOrg, DWORD OutExt)
144 if (((InExt > 0 )&&(OutExt > 0)) || ((InExt<0) && (OutExt < 0)))
145 return ((In - InOrg) * abs(OutExt) / abs(InExt)) + OutOrg;
147 return ((abs(InExt) - (In - InOrg))*abs(OutExt) / abs(InExt)) + OutOrg;
150 LPOPENCONTEXT FindOpenContext(HWND hwnd)
154 EnterCriticalSection(&csTablet);
158 TRACE("Trying Context %p (%p %p)\n",ptr->handle,hwnd,ptr->hwndOwner);
159 if (ptr->hwndOwner == hwnd) break;
161 LeaveCriticalSection(&csTablet);
165 LPOPENCONTEXT AddPacketToContextQueue(LPWTPACKET packet, HWND hwnd)
167 LPOPENCONTEXT ptr=NULL;
169 EnterCriticalSection(&csTablet);
174 TRACE("Trying Queue %p (%p %p)\n", ptr->handle, hwnd, ptr->hwndOwner);
176 if (ptr->hwndOwner == hwnd)
185 tgt = ptr->PacketsQueued;
187 packet->pkContext = ptr->handle;
189 /* translate packet data to the context */
191 /* Scale as per documentation */
192 packet->pkY = ScaleForContext(packet->pkY, ptr->context.lcInOrgY,
193 ptr->context.lcInExtY, ptr->context.lcOutOrgY,
194 ptr->context.lcOutExtY);
196 packet->pkX = ScaleForContext(packet->pkX, ptr->context.lcInOrgX,
197 ptr->context.lcInExtX, ptr->context.lcOutOrgX,
198 ptr->context.lcOutExtX);
200 /* flip the Y axis */
201 if (ptr->context.lcOutExtY > 0)
202 packet->pkY = ptr->context.lcOutExtY - packet->pkY;
206 if (tgt == ptr->QueueSize)
208 TRACE("Queue Overflow %p\n",ptr->handle);
209 ptr->PacketQueue[tgt-1].pkStatus |= TPS_QUEUE_ERR;
213 TRACE("Placed in queue %p index %i\n",ptr->handle,tgt);
214 memcpy(&ptr->PacketQueue[tgt], packet, sizeof
216 ptr->PacketsQueued++;
218 if (ptr->ActiveCursor != packet->pkCursor)
220 ptr->ActiveCursor = packet->pkCursor;
221 if (ptr->context.lcOptions & CXO_CSRMESSAGES)
222 TABLET_PostTabletMessage(ptr, _WT_CSRCHANGE(ptr->context.lcMsgBase),
223 (WPARAM)packet->pkSerialNumber, (LPARAM)ptr->handle,
231 LeaveCriticalSection(&csTablet);
232 TRACE("Done (%p)\n",ptr);
237 * Flushes all packets from the queue.
239 static void inline TABLET_FlushQueue(LPOPENCONTEXT context)
241 context->PacketsQueued = 0;
244 int static inline CopyTabletData(LPVOID target, LPVOID src, INT size)
246 memcpy(target,src,size);
250 static INT TABLET_FindPacket(LPOPENCONTEXT context, UINT wSerial,
255 for (loop = 0; loop < context->PacketsQueued; loop++)
256 if (context->PacketQueue[loop].pkSerialNumber == wSerial)
259 *pkt = &context->PacketQueue[loop];
263 TRACE("%i .. %i\n",context->PacketsQueued,index);
269 static LPVOID TABLET_CopyPacketData(LPOPENCONTEXT context, LPVOID lpPkt,
276 TRACE("Packet Bits %s\n",DUMPBITS(context->context.lcPktData,bits));
278 if (context->context.lcPktData & PK_CONTEXT)
279 ptr+=CopyTabletData(ptr,&wtp->pkContext,sizeof(HCTX));
280 if (context->context.lcPktData & PK_STATUS)
281 ptr+=CopyTabletData(ptr,&wtp->pkStatus,sizeof(UINT));
282 if (context->context.lcPktData & PK_TIME)
283 ptr+=CopyTabletData(ptr,&wtp->pkTime,sizeof(LONG));
284 if (context->context.lcPktData & PK_CHANGED)
285 ptr+=CopyTabletData(ptr,&wtp->pkChanged,sizeof(WTPKT));
286 if (context->context.lcPktData & PK_SERIAL_NUMBER)
287 ptr+=CopyTabletData(ptr,&wtp->pkChanged,sizeof(UINT));
288 if (context->context.lcPktData & PK_CURSOR)
289 ptr+=CopyTabletData(ptr,&wtp->pkCursor,sizeof(UINT));
290 if (context->context.lcPktData & PK_BUTTONS)
291 ptr+=CopyTabletData(ptr,&wtp->pkButtons,sizeof(DWORD));
292 if (context->context.lcPktData & PK_X)
293 ptr+=CopyTabletData(ptr,&wtp->pkX,sizeof(DWORD));
294 if (context->context.lcPktData & PK_Y)
295 ptr+=CopyTabletData(ptr,&wtp->pkY,sizeof(DWORD));
296 if (context->context.lcPktData & PK_Z)
297 ptr+=CopyTabletData(ptr,&wtp->pkZ,sizeof(DWORD));
298 if (context->context.lcPktData & PK_NORMAL_PRESSURE)
299 ptr+=CopyTabletData(ptr,&wtp->pkNormalPressure,sizeof(UINT));
300 if (context->context.lcPktData & PK_TANGENT_PRESSURE)
301 ptr+=CopyTabletData(ptr,&wtp->pkTangentPressure,sizeof(UINT));
302 if (context->context.lcPktData & PK_ORIENTATION)
303 ptr+=CopyTabletData(ptr,&wtp->pkOrientation,sizeof(ORIENTATION));
304 if (context->context.lcPktData & PK_ROTATION)
305 ptr+=CopyTabletData(ptr,&wtp->pkRotation,sizeof(ROTATION));
307 /*TRACE("Copied %i bytes\n",(INT)ptr - (INT)lpPkt); */
311 static VOID TABLET_BlankPacketData(LPOPENCONTEXT context, LPVOID lpPkt, INT n)
315 if (context->context.lcPktData & PK_CONTEXT)
317 if (context->context.lcPktData & PK_STATUS)
319 if (context->context.lcPktData & PK_TIME)
321 if (context->context.lcPktData & PK_CHANGED)
323 if (context->context.lcPktData & PK_SERIAL_NUMBER)
325 if (context->context.lcPktData & PK_CURSOR)
327 if (context->context.lcPktData & PK_BUTTONS)
329 if (context->context.lcPktData & PK_X)
331 if (context->context.lcPktData & PK_Y)
333 if (context->context.lcPktData & PK_Z)
335 if (context->context.lcPktData & PK_NORMAL_PRESSURE)
337 if (context->context.lcPktData & PK_TANGENT_PRESSURE)
339 if (context->context.lcPktData & PK_ORIENTATION)
340 rc += sizeof(ORIENTATION);
341 if (context->context.lcPktData & PK_ROTATION)
342 rc += sizeof(ROTATION);
349 /***********************************************************************
350 * WTInfoA (WINTAB32.20)
352 UINT WINAPI WTInfoA(UINT wCategory, UINT nIndex, LPVOID lpOutput)
355 if (gLoaded == FALSE)
359 * Handle system extents here, as we can use user32.dll code to set them.
361 if(wCategory == WTI_DEFSYSCTX)
367 *(LONG*)lpOutput = GetSystemMetrics(SM_CXSCREEN);
371 *(LONG*)lpOutput = GetSystemMetrics(SM_CYSCREEN);
373 /* No action, delegate to X11Drv */
377 result = pWTInfoA( wCategory, nIndex, lpOutput );
380 * Handle system extents here, as we can use user32.dll code to set them.
382 if(wCategory == WTI_DEFSYSCTX && nIndex == 0)
384 LPLOGCONTEXTA lpCtx = (LPLOGCONTEXTA)lpOutput;
385 lpCtx->lcSysExtX = GetSystemMetrics(SM_CXSCREEN);
386 lpCtx->lcSysExtY = GetSystemMetrics(SM_CYSCREEN);
391 /***********************************************************************
392 * WTInfoW (WINTAB32.1020)
394 UINT WINAPI WTInfoW(UINT wCategory, UINT nIndex, LPVOID lpOutput)
396 FIXME("(%u, %u, %p): stub\n", wCategory, nIndex, lpOutput);
398 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
403 /***********************************************************************
404 * WTOpenA (WINTAB32.21)
406 HCTX WINAPI WTOpenA(HWND hWnd, LPLOGCONTEXTA lpLogCtx, BOOL fEnable)
408 LPOPENCONTEXT newcontext;
410 TRACE("(%p, %p, %u)\n", hWnd, lpLogCtx, fEnable);
411 DUMPCONTEXT(*lpLogCtx);
413 newcontext = HeapAlloc(GetProcessHeap(), 0 , sizeof(OPENCONTEXT));
414 memcpy(&(newcontext->context),lpLogCtx,sizeof(LOGCONTEXTA));
415 newcontext->hwndOwner = hWnd;
416 newcontext->enabled = fEnable;
417 newcontext->ActiveCursor = -1;
418 newcontext->QueueSize = 10;
419 newcontext->PacketsQueued = 0;
420 newcontext->PacketQueue=HeapAlloc(GetProcessHeap(),0,sizeof(WTPACKET)*10);
422 EnterCriticalSection(&csTablet);
423 newcontext->handle = gTopContext++;
424 newcontext->next = gOpenContexts;
425 gOpenContexts = newcontext;
426 LeaveCriticalSection(&csTablet);
428 pAttachEventQueueToTablet(hWnd);
430 TABLET_PostTabletMessage(newcontext, _WT_CTXOPEN(newcontext->context.lcMsgBase), (WPARAM)newcontext->handle,
431 newcontext->context.lcStatus, TRUE);
433 newcontext->context.lcStatus = CXS_ONTOP;
435 TABLET_PostTabletMessage(newcontext, _WT_CTXOVERLAP(newcontext->context.lcMsgBase),
436 (WPARAM)newcontext->handle,
437 newcontext->context.lcStatus, TRUE);
439 return newcontext->handle;
442 /***********************************************************************
443 * WTOpenW (WINTAB32.1021)
445 HCTX WINAPI WTOpenW(HWND hWnd, LPLOGCONTEXTW lpLogCtx, BOOL fEnable)
447 FIXME("(%p, %p, %u): stub\n", hWnd, lpLogCtx, fEnable);
449 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
454 /***********************************************************************
455 * WTClose (WINTAB32.22)
457 BOOL WINAPI WTClose(HCTX hCtx)
459 LPOPENCONTEXT context,ptr;
461 TRACE("(%p)\n", hCtx);
463 EnterCriticalSection(&csTablet);
465 ptr = context = gOpenContexts;
467 while (context && (context->handle != hCtx))
470 context = context->next;
474 LeaveCriticalSection(&csTablet);
478 if (context == gOpenContexts)
479 gOpenContexts = context->next;
481 ptr->next = context->next;
483 LeaveCriticalSection(&csTablet);
485 TABLET_PostTabletMessage(context, _WT_CTXCLOSE(context->context.lcMsgBase), (WPARAM)context->handle,
486 context->context.lcStatus,TRUE);
488 HeapFree(GetProcessHeap(),0,context->PacketQueue);
489 HeapFree(GetProcessHeap(),0,context);
494 /***********************************************************************
495 * WTPacketsGet (WINTAB32.23)
497 int WINAPI WTPacketsGet(HCTX hCtx, int cMaxPkts, LPVOID lpPkts)
500 LPOPENCONTEXT context;
503 TRACE("(%p, %d, %p)\n", hCtx, cMaxPkts, lpPkts);
508 EnterCriticalSection(&csTablet);
510 context = TABLET_FindOpenContext(hCtx);
513 TABLET_BlankPacketData(context,lpPkts,cMaxPkts);
515 if (context->PacketsQueued == 0)
517 LeaveCriticalSection(&csTablet);
521 limit = min(cMaxPkts,context->PacketsQueued);
526 for(i = 0; i < limit; i++)
527 ptr=TABLET_CopyPacketData(context ,ptr, &context->PacketQueue[i]);
531 if (limit < context->PacketsQueued)
533 memmove(context->PacketQueue, &context->PacketQueue[limit],
534 (context->PacketsQueued - (limit))*sizeof(WTPACKET));
536 context->PacketsQueued -= limit;
537 LeaveCriticalSection(&csTablet);
539 TRACE("Copied %i packets\n",limit);
544 /***********************************************************************
545 * WTPacket (WINTAB32.24)
547 BOOL WINAPI WTPacket(HCTX hCtx, UINT wSerial, LPVOID lpPkt)
550 LPOPENCONTEXT context;
553 TRACE("(%p, %d, %p)\n", hCtx, wSerial, lpPkt);
558 EnterCriticalSection(&csTablet);
560 context = TABLET_FindOpenContext(hCtx);
562 rc = TABLET_FindPacket(context ,wSerial, &wtp);
567 TABLET_CopyPacketData(context ,lpPkt, wtp);
569 if ((rc+1) < context->QueueSize)
571 memmove(context->PacketQueue, &context->PacketQueue[rc+1],
572 (context->PacketsQueued - (rc+1))*sizeof(WTPACKET));
574 context->PacketsQueued -= (rc+1);
576 LeaveCriticalSection(&csTablet);
578 TRACE("Returning %i\n",rc+1);
582 /***********************************************************************
583 * WTEnable (WINTAB32.40)
585 BOOL WINAPI WTEnable(HCTX hCtx, BOOL fEnable)
587 LPOPENCONTEXT context;
589 TRACE("(%p, %u)\n", hCtx, fEnable);
593 EnterCriticalSection(&csTablet);
594 context = TABLET_FindOpenContext(hCtx);
596 TABLET_FlushQueue(context);
597 context->enabled = fEnable;
598 LeaveCriticalSection(&csTablet);
603 /***********************************************************************
604 * WTOverlap (WINTAB32.41)
606 BOOL WINAPI WTOverlap(HCTX hCtx, BOOL fToTop)
608 FIXME("(%p, %u): stub\n", hCtx, fToTop);
613 /***********************************************************************
614 * WTConfig (WINTAB32.61)
616 BOOL WINAPI WTConfig(HCTX hCtx, HWND hWnd)
618 FIXME("(%p, %p): stub\n", hCtx, hWnd);
620 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
625 /***********************************************************************
626 * WTGetA (WINTAB32.61)
628 BOOL WINAPI WTGetA(HCTX hCtx, LPLOGCONTEXTA lpLogCtx)
630 LPOPENCONTEXT context;
632 TRACE("(%p, %p)\n", hCtx, lpLogCtx);
636 EnterCriticalSection(&csTablet);
637 context = TABLET_FindOpenContext(hCtx);
638 memmove(lpLogCtx,&context->context,sizeof(LOGCONTEXTA));
639 LeaveCriticalSection(&csTablet);
644 /***********************************************************************
645 * WTGetW (WINTAB32.1061)
647 BOOL WINAPI WTGetW(HCTX hCtx, LPLOGCONTEXTW lpLogCtx)
649 FIXME("(%p, %p): stub\n", hCtx, lpLogCtx);
651 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
656 /***********************************************************************
657 * WTSetA (WINTAB32.62)
659 BOOL WINAPI WTSetA(HCTX hCtx, LPLOGCONTEXTA lpLogCtx)
661 FIXME("(%p, %p): stub\n", hCtx, lpLogCtx);
663 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
668 /***********************************************************************
669 * WTSetW (WINTAB32.1062)
671 BOOL WINAPI WTSetW(HCTX hCtx, LPLOGCONTEXTW lpLogCtx)
673 FIXME("(%p, %p): stub\n", hCtx, lpLogCtx);
675 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
680 /***********************************************************************
681 * WTExtGet (WINTAB32.63)
683 BOOL WINAPI WTExtGet(HCTX hCtx, UINT wExt, LPVOID lpData)
685 FIXME("(%p, %u, %p): stub\n", hCtx, wExt, lpData);
687 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
692 /***********************************************************************
693 * WTExtSet (WINTAB32.64)
695 BOOL WINAPI WTExtSet(HCTX hCtx, UINT wExt, LPVOID lpData)
697 FIXME("(%p, %u, %p): stub\n", hCtx, wExt, lpData);
699 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
704 /***********************************************************************
705 * WTSave (WINTAB32.65)
707 BOOL WINAPI WTSave(HCTX hCtx, LPVOID lpSaveInfo)
709 FIXME("(%p, %p): stub\n", hCtx, lpSaveInfo);
711 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
716 /***********************************************************************
717 * WTRestore (WINTAB32.66)
719 HCTX WINAPI WTRestore(HWND hWnd, LPVOID lpSaveInfo, BOOL fEnable)
721 FIXME("(%p, %p, %u): stub\n", hWnd, lpSaveInfo, fEnable);
723 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
728 /***********************************************************************
729 * WTPacketsPeek (WINTAB32.80)
731 int WINAPI WTPacketsPeek(HCTX hCtx, int cMaxPkts, LPVOID lpPkts)
734 LPOPENCONTEXT context;
737 TRACE("(%p, %d, %p)\n", hCtx, cMaxPkts, lpPkts);
739 if (!hCtx || !lpPkts) return 0;
741 EnterCriticalSection(&csTablet);
743 context = TABLET_FindOpenContext(hCtx);
745 if (context->PacketsQueued == 0)
747 LeaveCriticalSection(&csTablet);
751 for (limit = 0; limit < cMaxPkts && limit < context->PacketsQueued; limit++)
752 ptr = TABLET_CopyPacketData(context ,ptr, &context->PacketQueue[limit]);
754 LeaveCriticalSection(&csTablet);
755 TRACE("Copied %i packets\n",limit);
759 /***********************************************************************
760 * WTDataGet (WINTAB32.81)
762 int WINAPI WTDataGet(HCTX hCtx, UINT wBegin, UINT wEnd,
763 int cMaxPkts, LPVOID lpPkts, LPINT lpNPkts)
765 LPOPENCONTEXT context;
771 TRACE("(%p, %u, %u, %d, %p, %p)\n",
772 hCtx, wBegin, wEnd, cMaxPkts, lpPkts, lpNPkts);
776 EnterCriticalSection(&csTablet);
778 context = TABLET_FindOpenContext(hCtx);
780 if (context->PacketsQueued == 0)
782 LeaveCriticalSection(&csTablet);
786 while (bgn < context->PacketsQueued &&
787 context->PacketQueue[bgn].pkSerialNumber != wBegin)
791 while (end < context->PacketsQueued &&
792 context->PacketQueue[end].pkSerialNumber != wEnd)
795 if ((bgn == end) && (end == context->PacketsQueued))
797 LeaveCriticalSection(&csTablet);
801 for (num = bgn; num <= end; num++)
802 ptr = TABLET_CopyPacketData(context ,ptr, &context->PacketQueue[num]);
804 /* remove read packets */
805 if ((end+1) < context->PacketsQueued)
806 memmove( &context->PacketQueue[bgn], &context->PacketQueue[end+1],
807 (context->PacketsQueued - (end+1)) * sizeof (WTPACKET));
809 context->PacketsQueued -= ((end-bgn)+1);
810 *lpNPkts = ((end-bgn)+1);
812 LeaveCriticalSection(&csTablet);
813 TRACE("Copied %i packets\n",*lpNPkts);
814 return (end - bgn)+1;
817 /***********************************************************************
818 * WTDataPeek (WINTAB32.82)
820 int WINAPI WTDataPeek(HCTX hCtx, UINT wBegin, UINT wEnd,
821 int cMaxPkts, LPVOID lpPkts, LPINT lpNPkts)
823 LPOPENCONTEXT context;
829 TRACE("(%p, %u, %u, %d, %p, %p)\n",
830 hCtx, wBegin, wEnd, cMaxPkts, lpPkts, lpNPkts);
832 if (!hCtx || !lpPkts) return 0;
834 EnterCriticalSection(&csTablet);
836 context = TABLET_FindOpenContext(hCtx);
838 if (context->PacketsQueued == 0)
840 LeaveCriticalSection(&csTablet);
844 while (bgn < context->PacketsQueued &&
845 context->PacketQueue[bgn].pkSerialNumber != wBegin)
849 while (end < context->PacketsQueued &&
850 context->PacketQueue[end].pkSerialNumber != wEnd)
853 if (bgn == context->PacketsQueued || end == context->PacketsQueued)
855 TRACE("%i %i %i \n", bgn, end, context->PacketsQueued);
856 LeaveCriticalSection(&csTablet);
860 for (num = bgn; num <= end; num++)
861 ptr = TABLET_CopyPacketData(context ,ptr, &context->PacketQueue[num]);
863 *lpNPkts = ((end-bgn)+1);
864 LeaveCriticalSection(&csTablet);
866 TRACE("Copied %i packets\n",*lpNPkts);
867 return (end - bgn)+1;
870 /***********************************************************************
871 * WTQueuePacketsEx (WINTAB32.200)
873 BOOL WINAPI WTQueuePacketsEx(HCTX hCtx, UINT *lpOld, UINT *lpNew)
875 LPOPENCONTEXT context;
877 TRACE("(%p, %p, %p)\n", hCtx, lpOld, lpNew);
881 EnterCriticalSection(&csTablet);
883 context = TABLET_FindOpenContext(hCtx);
885 if (context->PacketsQueued)
887 *lpOld = context->PacketQueue[0].pkSerialNumber;
888 *lpNew = context->PacketQueue[context->PacketsQueued-1].pkSerialNumber;
892 TRACE("No packets\n");
893 LeaveCriticalSection(&csTablet);
896 LeaveCriticalSection(&csTablet);
901 /***********************************************************************
902 * WTQueueSizeGet (WINTAB32.84)
904 int WINAPI WTQueueSizeGet(HCTX hCtx)
906 LPOPENCONTEXT context;
907 TRACE("(%p)\n", hCtx);
911 EnterCriticalSection(&csTablet);
912 context = TABLET_FindOpenContext(hCtx);
913 LeaveCriticalSection(&csTablet);
914 return context->QueueSize;
917 /***********************************************************************
918 * WTQueueSizeSet (WINTAB32.85)
920 BOOL WINAPI WTQueueSizeSet(HCTX hCtx, int nPkts)
922 LPOPENCONTEXT context;
924 TRACE("(%p, %d)\n", hCtx, nPkts);
928 EnterCriticalSection(&csTablet);
930 context = TABLET_FindOpenContext(hCtx);
932 context->PacketQueue = HeapReAlloc(GetProcessHeap(), 0,
933 context->PacketQueue, sizeof(WTPACKET)*nPkts);
935 context->QueueSize = nPkts;
936 LeaveCriticalSection(&csTablet);