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 + 1 == ptr->QueueSize)
208 TRACE("Queue Overflow %p\n",ptr->handle);
209 packet->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,
223 (WPARAM)packet->pkSerialNumber, (LPARAM)ptr->handle,
231 LeaveCriticalSection(&csTablet);
232 TRACE("Done (%p)\n",ptr);
236 int static inline CopyTabletData(LPVOID target, LPVOID src, INT size)
238 memcpy(target,src,size);
242 static INT TABLET_FindPacket(LPOPENCONTEXT context, UINT wSerial,
247 for (loop = 0; loop < context->PacketsQueued; loop++)
248 if (context->PacketQueue[loop].pkSerialNumber == wSerial)
251 *pkt = &context->PacketQueue[loop];
255 TRACE("%i .. %i\n",context->PacketsQueued,index);
261 static LPVOID TABLET_CopyPacketData(LPOPENCONTEXT context, LPVOID lpPkt,
268 TRACE("Packet Bits %s\n",DUMPBITS(context->context.lcPktData,bits));
270 if (context->context.lcPktData & PK_CONTEXT)
271 ptr+=CopyTabletData(ptr,&wtp->pkContext,sizeof(HCTX));
272 if (context->context.lcPktData & PK_STATUS)
273 ptr+=CopyTabletData(ptr,&wtp->pkStatus,sizeof(UINT));
274 if (context->context.lcPktData & PK_TIME)
275 ptr+=CopyTabletData(ptr,&wtp->pkTime,sizeof(LONG));
276 if (context->context.lcPktData & PK_CHANGED)
277 ptr+=CopyTabletData(ptr,&wtp->pkChanged,sizeof(WTPKT));
278 if (context->context.lcPktData & PK_SERIAL_NUMBER)
279 ptr+=CopyTabletData(ptr,&wtp->pkChanged,sizeof(UINT));
280 if (context->context.lcPktData & PK_CURSOR)
281 ptr+=CopyTabletData(ptr,&wtp->pkCursor,sizeof(UINT));
282 if (context->context.lcPktData & PK_BUTTONS)
283 ptr+=CopyTabletData(ptr,&wtp->pkButtons,sizeof(DWORD));
284 if (context->context.lcPktData & PK_X)
285 ptr+=CopyTabletData(ptr,&wtp->pkX,sizeof(DWORD));
286 if (context->context.lcPktData & PK_Y)
287 ptr+=CopyTabletData(ptr,&wtp->pkY,sizeof(DWORD));
288 if (context->context.lcPktData & PK_Z)
289 ptr+=CopyTabletData(ptr,&wtp->pkZ,sizeof(DWORD));
290 if (context->context.lcPktData & PK_NORMAL_PRESSURE)
291 ptr+=CopyTabletData(ptr,&wtp->pkNormalPressure,sizeof(UINT));
292 if (context->context.lcPktData & PK_TANGENT_PRESSURE)
293 ptr+=CopyTabletData(ptr,&wtp->pkTangentPressure,sizeof(UINT));
294 if (context->context.lcPktData & PK_ORIENTATION)
295 ptr+=CopyTabletData(ptr,&wtp->pkOrientation,sizeof(ORIENTATION));
296 if (context->context.lcPktData & PK_ROTATION)
297 ptr+=CopyTabletData(ptr,&wtp->pkRotation,sizeof(ROTATION));
299 /*TRACE("Copied %i bytes\n",(INT)ptr - (INT)lpPkt); */
303 static VOID TABLET_BlankPacketData(LPOPENCONTEXT context, LPVOID lpPkt, INT n)
307 if (context->context.lcPktData & PK_CONTEXT)
309 if (context->context.lcPktData & PK_STATUS)
311 if (context->context.lcPktData & PK_TIME)
313 if (context->context.lcPktData & PK_CHANGED)
315 if (context->context.lcPktData & PK_SERIAL_NUMBER)
317 if (context->context.lcPktData & PK_CURSOR)
319 if (context->context.lcPktData & PK_BUTTONS)
321 if (context->context.lcPktData & PK_X)
323 if (context->context.lcPktData & PK_Y)
325 if (context->context.lcPktData & PK_Z)
327 if (context->context.lcPktData & PK_NORMAL_PRESSURE)
329 if (context->context.lcPktData & PK_TANGENT_PRESSURE)
331 if (context->context.lcPktData & PK_ORIENTATION)
332 rc += sizeof(ORIENTATION);
333 if (context->context.lcPktData & PK_ROTATION)
334 rc += sizeof(ROTATION);
341 /***********************************************************************
342 * WTInfoA (WINTAB32.20)
344 UINT WINAPI WTInfoA(UINT wCategory, UINT nIndex, LPVOID lpOutput)
346 if (gLoaded == FALSE)
349 return pWTInfoA( wCategory, nIndex, lpOutput );
352 /***********************************************************************
353 * WTInfoW (WINTAB32.1020)
355 UINT WINAPI WTInfoW(UINT wCategory, UINT nIndex, LPVOID lpOutput)
357 FIXME("(%u, %u, %p): stub\n", wCategory, nIndex, lpOutput);
359 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
364 /***********************************************************************
365 * WTOpenA (WINTAB32.21)
367 HCTX WINAPI WTOpenA(HWND hWnd, LPLOGCONTEXTA lpLogCtx, BOOL fEnable)
369 LPOPENCONTEXT newcontext;
371 TRACE("(%p, %p, %u)\n", hWnd, lpLogCtx, fEnable);
372 DUMPCONTEXT(*lpLogCtx);
374 newcontext = HeapAlloc(GetProcessHeap(), 0 , sizeof(OPENCONTEXT));
375 memcpy(&(newcontext->context),lpLogCtx,sizeof(LOGCONTEXTA));
376 newcontext->hwndOwner = hWnd;
377 newcontext->enabled = fEnable;
378 newcontext->ActiveCursor = -1;
379 newcontext->QueueSize = 10;
380 newcontext->PacketsQueued = 0;
381 newcontext->PacketQueue=HeapAlloc(GetProcessHeap(),0,sizeof(WTPACKET)*10);
383 EnterCriticalSection(&csTablet);
384 newcontext->handle = gTopContext++;
385 newcontext->next = gOpenContexts;
386 gOpenContexts = newcontext;
387 LeaveCriticalSection(&csTablet);
389 pAttachEventQueueToTablet(hWnd);
391 TABLET_PostTabletMessage(newcontext, WT_CTXOPEN, (WPARAM)newcontext->handle,
392 newcontext->context.lcStatus, TRUE);
394 newcontext->context.lcStatus = CXS_ONTOP;
396 TABLET_PostTabletMessage(newcontext, WT_CTXOVERLAP,
397 (WPARAM)newcontext->handle,
398 newcontext->context.lcStatus, TRUE);
400 return newcontext->handle;
403 /***********************************************************************
404 * WTOpenW (WINTAB32.1021)
406 HCTX WINAPI WTOpenW(HWND hWnd, LPLOGCONTEXTW lpLogCtx, BOOL fEnable)
408 FIXME("(%p, %p, %u): stub\n", hWnd, lpLogCtx, fEnable);
410 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
415 /***********************************************************************
416 * WTClose (WINTAB32.22)
418 BOOL WINAPI WTClose(HCTX hCtx)
420 LPOPENCONTEXT context,ptr;
422 TRACE("(%p)\n", hCtx);
424 EnterCriticalSection(&csTablet);
426 ptr = context = gOpenContexts;
428 while (context && (context->handle != hCtx))
431 context = context->next;
435 LeaveCriticalSection(&csTablet);
439 if (context == gOpenContexts)
440 gOpenContexts = context->next;
442 ptr->next = context->next;
444 LeaveCriticalSection(&csTablet);
446 TABLET_PostTabletMessage(context, WT_CTXCLOSE, (WPARAM)context->handle,
447 context->context.lcStatus,TRUE);
449 HeapFree(GetProcessHeap(),0,context->PacketQueue);
450 HeapFree(GetProcessHeap(),0,context);
455 /***********************************************************************
456 * WTPacketsGet (WINTAB32.23)
458 int WINAPI WTPacketsGet(HCTX hCtx, int cMaxPkts, LPVOID lpPkts)
461 LPOPENCONTEXT context;
464 TRACE("(%p, %d, %p)\n", hCtx, cMaxPkts, lpPkts);
469 EnterCriticalSection(&csTablet);
471 context = TABLET_FindOpenContext(hCtx);
474 TABLET_BlankPacketData(context,lpPkts,cMaxPkts);
476 if (context->PacketsQueued == 0)
478 LeaveCriticalSection(&csTablet);
482 limit = min(cMaxPkts,context->PacketsQueued);
487 for(i = 0; i < limit; i++)
488 ptr=TABLET_CopyPacketData(context ,ptr, &context->PacketQueue[i]);
492 if (limit < context->PacketsQueued)
494 memmove(context->PacketQueue, &context->PacketQueue[limit],
495 (context->PacketsQueued - (limit))*sizeof(WTPACKET));
497 context->PacketsQueued -= limit;
498 LeaveCriticalSection(&csTablet);
500 TRACE("Copied %i packets\n",limit);
505 /***********************************************************************
506 * WTPacket (WINTAB32.24)
508 BOOL WINAPI WTPacket(HCTX hCtx, UINT wSerial, LPVOID lpPkt)
511 LPOPENCONTEXT context;
514 TRACE("(%p, %d, %p)\n", hCtx, wSerial, lpPkt);
519 EnterCriticalSection(&csTablet);
521 context = TABLET_FindOpenContext(hCtx);
523 rc = TABLET_FindPacket(context ,wSerial, &wtp);
528 TABLET_CopyPacketData(context ,lpPkt, wtp);
530 if ((rc+1) < context->QueueSize)
532 memmove(context->PacketQueue, &context->PacketQueue[rc+1],
533 (context->PacketsQueued - (rc+1))*sizeof(WTPACKET));
535 context->PacketsQueued -= (rc+1);
537 LeaveCriticalSection(&csTablet);
539 TRACE("Returning %i\n",rc+1);
543 /***********************************************************************
544 * WTEnable (WINTAB32.40)
546 BOOL WINAPI WTEnable(HCTX hCtx, BOOL fEnable)
548 LPOPENCONTEXT context;
550 TRACE("(%p, %u)\n", hCtx, fEnable);
554 EnterCriticalSection(&csTablet);
555 context = TABLET_FindOpenContext(hCtx);
556 context->enabled = fEnable;
557 LeaveCriticalSection(&csTablet);
562 /***********************************************************************
563 * WTOverlap (WINTAB32.41)
565 BOOL WINAPI WTOverlap(HCTX hCtx, BOOL fToTop)
567 FIXME("(%p, %u): stub\n", hCtx, fToTop);
572 /***********************************************************************
573 * WTConfig (WINTAB32.61)
575 BOOL WINAPI WTConfig(HCTX hCtx, HWND hWnd)
577 FIXME("(%p, %p): stub\n", hCtx, hWnd);
579 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
584 /***********************************************************************
585 * WTGetA (WINTAB32.61)
587 BOOL WINAPI WTGetA(HCTX hCtx, LPLOGCONTEXTA lpLogCtx)
589 LPOPENCONTEXT context;
591 TRACE("(%p, %p)\n", hCtx, lpLogCtx);
595 EnterCriticalSection(&csTablet);
596 context = TABLET_FindOpenContext(hCtx);
597 memmove(lpLogCtx,&context->context,sizeof(LOGCONTEXTA));
598 LeaveCriticalSection(&csTablet);
603 /***********************************************************************
604 * WTGetW (WINTAB32.1061)
606 BOOL WINAPI WTGetW(HCTX hCtx, LPLOGCONTEXTW lpLogCtx)
608 FIXME("(%p, %p): stub\n", hCtx, lpLogCtx);
610 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
615 /***********************************************************************
616 * WTSetA (WINTAB32.62)
618 BOOL WINAPI WTSetA(HCTX hCtx, LPLOGCONTEXTA lpLogCtx)
620 FIXME("(%p, %p): stub\n", hCtx, lpLogCtx);
622 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
627 /***********************************************************************
628 * WTSetW (WINTAB32.1062)
630 BOOL WINAPI WTSetW(HCTX hCtx, LPLOGCONTEXTW lpLogCtx)
632 FIXME("(%p, %p): stub\n", hCtx, lpLogCtx);
634 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
639 /***********************************************************************
640 * WTExtGet (WINTAB32.63)
642 BOOL WINAPI WTExtGet(HCTX hCtx, UINT wExt, LPVOID lpData)
644 FIXME("(%p, %u, %p): stub\n", hCtx, wExt, lpData);
646 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
651 /***********************************************************************
652 * WTExtSet (WINTAB32.64)
654 BOOL WINAPI WTExtSet(HCTX hCtx, UINT wExt, LPVOID lpData)
656 FIXME("(%p, %u, %p): stub\n", hCtx, wExt, lpData);
658 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
663 /***********************************************************************
664 * WTSave (WINTAB32.65)
666 BOOL WINAPI WTSave(HCTX hCtx, LPVOID lpSaveInfo)
668 FIXME("(%p, %p): stub\n", hCtx, lpSaveInfo);
670 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
675 /***********************************************************************
676 * WTRestore (WINTAB32.66)
678 HCTX WINAPI WTRestore(HWND hWnd, LPVOID lpSaveInfo, BOOL fEnable)
680 FIXME("(%p, %p, %u): stub\n", hWnd, lpSaveInfo, fEnable);
682 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
687 /***********************************************************************
688 * WTPacketsPeek (WINTAB32.80)
690 int WINAPI WTPacketsPeek(HCTX hCtx, int cMaxPkts, LPVOID lpPkts)
693 LPOPENCONTEXT context;
696 TRACE("(%p, %d, %p)\n", hCtx, cMaxPkts, lpPkts);
698 if (!hCtx || !lpPkts) return 0;
700 EnterCriticalSection(&csTablet);
702 context = TABLET_FindOpenContext(hCtx);
704 if (context->PacketsQueued == 0)
706 LeaveCriticalSection(&csTablet);
710 for (limit = 0; limit < cMaxPkts && limit < context->PacketsQueued; limit++)
711 ptr = TABLET_CopyPacketData(context ,ptr, &context->PacketQueue[limit]);
713 LeaveCriticalSection(&csTablet);
714 TRACE("Copied %i packets\n",limit);
718 /***********************************************************************
719 * WTDataGet (WINTAB32.81)
721 int WINAPI WTDataGet(HCTX hCtx, UINT wBegin, UINT wEnd,
722 int cMaxPkts, LPVOID lpPkts, LPINT lpNPkts)
724 LPOPENCONTEXT context;
730 TRACE("(%p, %u, %u, %d, %p, %p)\n",
731 hCtx, wBegin, wEnd, cMaxPkts, lpPkts, lpNPkts);
735 EnterCriticalSection(&csTablet);
737 context = TABLET_FindOpenContext(hCtx);
739 if (context->PacketsQueued == 0)
741 LeaveCriticalSection(&csTablet);
745 while (bgn < context->PacketsQueued &&
746 context->PacketQueue[bgn].pkSerialNumber != wBegin)
750 while (end < context->PacketsQueued &&
751 context->PacketQueue[end].pkSerialNumber != wEnd)
754 if ((bgn == end) && (end == context->PacketsQueued))
756 LeaveCriticalSection(&csTablet);
760 for (num = bgn; num <= end; num++)
761 ptr = TABLET_CopyPacketData(context ,ptr, &context->PacketQueue[num]);
763 /* remove read packets */
764 if ((end+1) < context->PacketsQueued)
765 memmove( &context->PacketQueue[bgn], &context->PacketQueue[end+1],
766 (context->PacketsQueued - (end+1)) * sizeof (WTPACKET));
768 context->PacketsQueued -= ((end-bgn)+1);
769 *lpNPkts = ((end-bgn)+1);
771 LeaveCriticalSection(&csTablet);
772 TRACE("Copied %i packets\n",*lpNPkts);
773 return (end - bgn)+1;
776 /***********************************************************************
777 * WTDataPeek (WINTAB32.82)
779 int WINAPI WTDataPeek(HCTX hCtx, UINT wBegin, UINT wEnd,
780 int cMaxPkts, LPVOID lpPkts, LPINT lpNPkts)
782 LPOPENCONTEXT context;
788 TRACE("(%p, %u, %u, %d, %p, %p)\n",
789 hCtx, wBegin, wEnd, cMaxPkts, lpPkts, lpNPkts);
791 if (!hCtx || !lpPkts) return 0;
793 EnterCriticalSection(&csTablet);
795 context = TABLET_FindOpenContext(hCtx);
797 if (context->PacketsQueued == 0)
799 LeaveCriticalSection(&csTablet);
803 while (bgn < context->PacketsQueued &&
804 context->PacketQueue[bgn].pkSerialNumber != wBegin)
808 while (end < context->PacketsQueued &&
809 context->PacketQueue[end].pkSerialNumber != wEnd)
812 if (bgn == context->PacketsQueued || end == context->PacketsQueued)
814 TRACE("%i %i %i \n", bgn, end, context->PacketsQueued);
815 LeaveCriticalSection(&csTablet);
819 for (num = bgn; num <= end; num++)
820 ptr = TABLET_CopyPacketData(context ,ptr, &context->PacketQueue[num]);
822 *lpNPkts = ((end-bgn)+1);
823 LeaveCriticalSection(&csTablet);
825 TRACE("Copied %i packets\n",*lpNPkts);
826 return (end - bgn)+1;
829 /***********************************************************************
830 * WTQueuePacketsEx (WINTAB32.200)
832 BOOL WINAPI WTQueuePacketsEx(HCTX hCtx, UINT *lpOld, UINT *lpNew)
834 LPOPENCONTEXT context;
836 TRACE("(%p, %p, %p)\n", hCtx, lpOld, lpNew);
840 EnterCriticalSection(&csTablet);
842 context = TABLET_FindOpenContext(hCtx);
844 if (context->PacketsQueued)
846 *lpOld = context->PacketQueue[0].pkSerialNumber;
847 *lpNew = context->PacketQueue[context->PacketsQueued-1].pkSerialNumber;
851 TRACE("No packets\n");
852 LeaveCriticalSection(&csTablet);
855 LeaveCriticalSection(&csTablet);
860 /***********************************************************************
861 * WTQueueSizeGet (WINTAB32.84)
863 int WINAPI WTQueueSizeGet(HCTX hCtx)
865 LPOPENCONTEXT context;
866 TRACE("(%p)\n", hCtx);
870 EnterCriticalSection(&csTablet);
871 context = TABLET_FindOpenContext(hCtx);
872 LeaveCriticalSection(&csTablet);
873 return context->QueueSize;
876 /***********************************************************************
877 * WTQueueSizeSet (WINTAB32.85)
879 BOOL WINAPI WTQueueSizeSet(HCTX hCtx, int nPkts)
881 LPOPENCONTEXT context;
883 TRACE("(%p, %d)\n", hCtx, nPkts);
887 EnterCriticalSection(&csTablet);
889 context = TABLET_FindOpenContext(hCtx);
891 context->PacketQueue = HeapReAlloc(GetProcessHeap(), 0,
892 context->PacketQueue, sizeof(WTPACKET)*nPkts);
894 context->QueueSize = nPkts;
895 LeaveCriticalSection(&csTablet);