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);
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)
347 if (gLoaded == FALSE)
351 * Handle system extents here, as we can use user32.dll code to set them.
353 if(wCategory == WTI_DEFSYSCTX)
359 *(LONG*)lpOutput = GetSystemMetrics(SM_CXSCREEN);
363 *(LONG*)lpOutput = GetSystemMetrics(SM_CYSCREEN);
365 /* No action, delegate to X11Drv */
369 result = pWTInfoA( wCategory, nIndex, lpOutput );
372 * Handle system extents here, as we can use user32.dll code to set them.
374 if(wCategory == WTI_DEFSYSCTX && nIndex == 0)
376 LPLOGCONTEXTA lpCtx = (LPLOGCONTEXTA)lpOutput;
377 lpCtx->lcSysExtX = GetSystemMetrics(SM_CXSCREEN);
378 lpCtx->lcSysExtY = GetSystemMetrics(SM_CYSCREEN);
383 /***********************************************************************
384 * WTInfoW (WINTAB32.1020)
386 UINT WINAPI WTInfoW(UINT wCategory, UINT nIndex, LPVOID lpOutput)
388 FIXME("(%u, %u, %p): stub\n", wCategory, nIndex, lpOutput);
390 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
395 /***********************************************************************
396 * WTOpenA (WINTAB32.21)
398 HCTX WINAPI WTOpenA(HWND hWnd, LPLOGCONTEXTA lpLogCtx, BOOL fEnable)
400 LPOPENCONTEXT newcontext;
402 TRACE("(%p, %p, %u)\n", hWnd, lpLogCtx, fEnable);
403 DUMPCONTEXT(*lpLogCtx);
405 newcontext = HeapAlloc(GetProcessHeap(), 0 , sizeof(OPENCONTEXT));
406 memcpy(&(newcontext->context),lpLogCtx,sizeof(LOGCONTEXTA));
407 newcontext->hwndOwner = hWnd;
408 newcontext->enabled = fEnable;
409 newcontext->ActiveCursor = -1;
410 newcontext->QueueSize = 10;
411 newcontext->PacketsQueued = 0;
412 newcontext->PacketQueue=HeapAlloc(GetProcessHeap(),0,sizeof(WTPACKET)*10);
414 EnterCriticalSection(&csTablet);
415 newcontext->handle = gTopContext++;
416 newcontext->next = gOpenContexts;
417 gOpenContexts = newcontext;
418 LeaveCriticalSection(&csTablet);
420 pAttachEventQueueToTablet(hWnd);
422 TABLET_PostTabletMessage(newcontext, _WT_CTXOPEN(newcontext->context.lcMsgBase), (WPARAM)newcontext->handle,
423 newcontext->context.lcStatus, TRUE);
425 newcontext->context.lcStatus = CXS_ONTOP;
427 TABLET_PostTabletMessage(newcontext, _WT_CTXOVERLAP(newcontext->context.lcMsgBase),
428 (WPARAM)newcontext->handle,
429 newcontext->context.lcStatus, TRUE);
431 return newcontext->handle;
434 /***********************************************************************
435 * WTOpenW (WINTAB32.1021)
437 HCTX WINAPI WTOpenW(HWND hWnd, LPLOGCONTEXTW lpLogCtx, BOOL fEnable)
439 FIXME("(%p, %p, %u): stub\n", hWnd, lpLogCtx, fEnable);
441 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
446 /***********************************************************************
447 * WTClose (WINTAB32.22)
449 BOOL WINAPI WTClose(HCTX hCtx)
451 LPOPENCONTEXT context,ptr;
453 TRACE("(%p)\n", hCtx);
455 EnterCriticalSection(&csTablet);
457 ptr = context = gOpenContexts;
459 while (context && (context->handle != hCtx))
462 context = context->next;
466 LeaveCriticalSection(&csTablet);
470 if (context == gOpenContexts)
471 gOpenContexts = context->next;
473 ptr->next = context->next;
475 LeaveCriticalSection(&csTablet);
477 TABLET_PostTabletMessage(context, _WT_CTXCLOSE(context->context.lcMsgBase), (WPARAM)context->handle,
478 context->context.lcStatus,TRUE);
480 HeapFree(GetProcessHeap(),0,context->PacketQueue);
481 HeapFree(GetProcessHeap(),0,context);
486 /***********************************************************************
487 * WTPacketsGet (WINTAB32.23)
489 int WINAPI WTPacketsGet(HCTX hCtx, int cMaxPkts, LPVOID lpPkts)
492 LPOPENCONTEXT context;
495 TRACE("(%p, %d, %p)\n", hCtx, cMaxPkts, lpPkts);
500 EnterCriticalSection(&csTablet);
502 context = TABLET_FindOpenContext(hCtx);
505 TABLET_BlankPacketData(context,lpPkts,cMaxPkts);
507 if (context->PacketsQueued == 0)
509 LeaveCriticalSection(&csTablet);
513 limit = min(cMaxPkts,context->PacketsQueued);
518 for(i = 0; i < limit; i++)
519 ptr=TABLET_CopyPacketData(context ,ptr, &context->PacketQueue[i]);
523 if (limit < context->PacketsQueued)
525 memmove(context->PacketQueue, &context->PacketQueue[limit],
526 (context->PacketsQueued - (limit))*sizeof(WTPACKET));
528 context->PacketsQueued -= limit;
529 LeaveCriticalSection(&csTablet);
531 TRACE("Copied %i packets\n",limit);
536 /***********************************************************************
537 * WTPacket (WINTAB32.24)
539 BOOL WINAPI WTPacket(HCTX hCtx, UINT wSerial, LPVOID lpPkt)
542 LPOPENCONTEXT context;
545 TRACE("(%p, %d, %p)\n", hCtx, wSerial, lpPkt);
550 EnterCriticalSection(&csTablet);
552 context = TABLET_FindOpenContext(hCtx);
554 rc = TABLET_FindPacket(context ,wSerial, &wtp);
559 TABLET_CopyPacketData(context ,lpPkt, wtp);
561 if ((rc+1) < context->QueueSize)
563 memmove(context->PacketQueue, &context->PacketQueue[rc+1],
564 (context->PacketsQueued - (rc+1))*sizeof(WTPACKET));
566 context->PacketsQueued -= (rc+1);
568 LeaveCriticalSection(&csTablet);
570 TRACE("Returning %i\n",rc+1);
574 /***********************************************************************
575 * WTEnable (WINTAB32.40)
577 BOOL WINAPI WTEnable(HCTX hCtx, BOOL fEnable)
579 LPOPENCONTEXT context;
581 TRACE("(%p, %u)\n", hCtx, fEnable);
585 EnterCriticalSection(&csTablet);
586 context = TABLET_FindOpenContext(hCtx);
587 context->enabled = fEnable;
588 LeaveCriticalSection(&csTablet);
593 /***********************************************************************
594 * WTOverlap (WINTAB32.41)
596 BOOL WINAPI WTOverlap(HCTX hCtx, BOOL fToTop)
598 FIXME("(%p, %u): stub\n", hCtx, fToTop);
603 /***********************************************************************
604 * WTConfig (WINTAB32.61)
606 BOOL WINAPI WTConfig(HCTX hCtx, HWND hWnd)
608 FIXME("(%p, %p): stub\n", hCtx, hWnd);
610 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
615 /***********************************************************************
616 * WTGetA (WINTAB32.61)
618 BOOL WINAPI WTGetA(HCTX hCtx, LPLOGCONTEXTA lpLogCtx)
620 LPOPENCONTEXT context;
622 TRACE("(%p, %p)\n", hCtx, lpLogCtx);
626 EnterCriticalSection(&csTablet);
627 context = TABLET_FindOpenContext(hCtx);
628 memmove(lpLogCtx,&context->context,sizeof(LOGCONTEXTA));
629 LeaveCriticalSection(&csTablet);
634 /***********************************************************************
635 * WTGetW (WINTAB32.1061)
637 BOOL WINAPI WTGetW(HCTX hCtx, LPLOGCONTEXTW lpLogCtx)
639 FIXME("(%p, %p): stub\n", hCtx, lpLogCtx);
641 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
646 /***********************************************************************
647 * WTSetA (WINTAB32.62)
649 BOOL WINAPI WTSetA(HCTX hCtx, LPLOGCONTEXTA lpLogCtx)
651 FIXME("(%p, %p): stub\n", hCtx, lpLogCtx);
653 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
658 /***********************************************************************
659 * WTSetW (WINTAB32.1062)
661 BOOL WINAPI WTSetW(HCTX hCtx, LPLOGCONTEXTW lpLogCtx)
663 FIXME("(%p, %p): stub\n", hCtx, lpLogCtx);
665 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
670 /***********************************************************************
671 * WTExtGet (WINTAB32.63)
673 BOOL WINAPI WTExtGet(HCTX hCtx, UINT wExt, LPVOID lpData)
675 FIXME("(%p, %u, %p): stub\n", hCtx, wExt, lpData);
677 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
682 /***********************************************************************
683 * WTExtSet (WINTAB32.64)
685 BOOL WINAPI WTExtSet(HCTX hCtx, UINT wExt, LPVOID lpData)
687 FIXME("(%p, %u, %p): stub\n", hCtx, wExt, lpData);
689 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
694 /***********************************************************************
695 * WTSave (WINTAB32.65)
697 BOOL WINAPI WTSave(HCTX hCtx, LPVOID lpSaveInfo)
699 FIXME("(%p, %p): stub\n", hCtx, lpSaveInfo);
701 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
706 /***********************************************************************
707 * WTRestore (WINTAB32.66)
709 HCTX WINAPI WTRestore(HWND hWnd, LPVOID lpSaveInfo, BOOL fEnable)
711 FIXME("(%p, %p, %u): stub\n", hWnd, lpSaveInfo, fEnable);
713 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
718 /***********************************************************************
719 * WTPacketsPeek (WINTAB32.80)
721 int WINAPI WTPacketsPeek(HCTX hCtx, int cMaxPkts, LPVOID lpPkts)
724 LPOPENCONTEXT context;
727 TRACE("(%p, %d, %p)\n", hCtx, cMaxPkts, lpPkts);
729 if (!hCtx || !lpPkts) return 0;
731 EnterCriticalSection(&csTablet);
733 context = TABLET_FindOpenContext(hCtx);
735 if (context->PacketsQueued == 0)
737 LeaveCriticalSection(&csTablet);
741 for (limit = 0; limit < cMaxPkts && limit < context->PacketsQueued; limit++)
742 ptr = TABLET_CopyPacketData(context ,ptr, &context->PacketQueue[limit]);
744 LeaveCriticalSection(&csTablet);
745 TRACE("Copied %i packets\n",limit);
749 /***********************************************************************
750 * WTDataGet (WINTAB32.81)
752 int WINAPI WTDataGet(HCTX hCtx, UINT wBegin, UINT wEnd,
753 int cMaxPkts, LPVOID lpPkts, LPINT lpNPkts)
755 LPOPENCONTEXT context;
761 TRACE("(%p, %u, %u, %d, %p, %p)\n",
762 hCtx, wBegin, wEnd, cMaxPkts, lpPkts, lpNPkts);
766 EnterCriticalSection(&csTablet);
768 context = TABLET_FindOpenContext(hCtx);
770 if (context->PacketsQueued == 0)
772 LeaveCriticalSection(&csTablet);
776 while (bgn < context->PacketsQueued &&
777 context->PacketQueue[bgn].pkSerialNumber != wBegin)
781 while (end < context->PacketsQueued &&
782 context->PacketQueue[end].pkSerialNumber != wEnd)
785 if ((bgn == end) && (end == context->PacketsQueued))
787 LeaveCriticalSection(&csTablet);
791 for (num = bgn; num <= end; num++)
792 ptr = TABLET_CopyPacketData(context ,ptr, &context->PacketQueue[num]);
794 /* remove read packets */
795 if ((end+1) < context->PacketsQueued)
796 memmove( &context->PacketQueue[bgn], &context->PacketQueue[end+1],
797 (context->PacketsQueued - (end+1)) * sizeof (WTPACKET));
799 context->PacketsQueued -= ((end-bgn)+1);
800 *lpNPkts = ((end-bgn)+1);
802 LeaveCriticalSection(&csTablet);
803 TRACE("Copied %i packets\n",*lpNPkts);
804 return (end - bgn)+1;
807 /***********************************************************************
808 * WTDataPeek (WINTAB32.82)
810 int WINAPI WTDataPeek(HCTX hCtx, UINT wBegin, UINT wEnd,
811 int cMaxPkts, LPVOID lpPkts, LPINT lpNPkts)
813 LPOPENCONTEXT context;
819 TRACE("(%p, %u, %u, %d, %p, %p)\n",
820 hCtx, wBegin, wEnd, cMaxPkts, lpPkts, lpNPkts);
822 if (!hCtx || !lpPkts) return 0;
824 EnterCriticalSection(&csTablet);
826 context = TABLET_FindOpenContext(hCtx);
828 if (context->PacketsQueued == 0)
830 LeaveCriticalSection(&csTablet);
834 while (bgn < context->PacketsQueued &&
835 context->PacketQueue[bgn].pkSerialNumber != wBegin)
839 while (end < context->PacketsQueued &&
840 context->PacketQueue[end].pkSerialNumber != wEnd)
843 if (bgn == context->PacketsQueued || end == context->PacketsQueued)
845 TRACE("%i %i %i \n", bgn, end, context->PacketsQueued);
846 LeaveCriticalSection(&csTablet);
850 for (num = bgn; num <= end; num++)
851 ptr = TABLET_CopyPacketData(context ,ptr, &context->PacketQueue[num]);
853 *lpNPkts = ((end-bgn)+1);
854 LeaveCriticalSection(&csTablet);
856 TRACE("Copied %i packets\n",*lpNPkts);
857 return (end - bgn)+1;
860 /***********************************************************************
861 * WTQueuePacketsEx (WINTAB32.200)
863 BOOL WINAPI WTQueuePacketsEx(HCTX hCtx, UINT *lpOld, UINT *lpNew)
865 LPOPENCONTEXT context;
867 TRACE("(%p, %p, %p)\n", hCtx, lpOld, lpNew);
871 EnterCriticalSection(&csTablet);
873 context = TABLET_FindOpenContext(hCtx);
875 if (context->PacketsQueued)
877 *lpOld = context->PacketQueue[0].pkSerialNumber;
878 *lpNew = context->PacketQueue[context->PacketsQueued-1].pkSerialNumber;
882 TRACE("No packets\n");
883 LeaveCriticalSection(&csTablet);
886 LeaveCriticalSection(&csTablet);
891 /***********************************************************************
892 * WTQueueSizeGet (WINTAB32.84)
894 int WINAPI WTQueueSizeGet(HCTX hCtx)
896 LPOPENCONTEXT context;
897 TRACE("(%p)\n", hCtx);
901 EnterCriticalSection(&csTablet);
902 context = TABLET_FindOpenContext(hCtx);
903 LeaveCriticalSection(&csTablet);
904 return context->QueueSize;
907 /***********************************************************************
908 * WTQueueSizeSet (WINTAB32.85)
910 BOOL WINAPI WTQueueSizeSet(HCTX hCtx, int nPkts)
912 LPOPENCONTEXT context;
914 TRACE("(%p, %d)\n", hCtx, nPkts);
918 EnterCriticalSection(&csTablet);
920 context = TABLET_FindOpenContext(hCtx);
922 context->PacketQueue = HeapReAlloc(GetProcessHeap(), 0,
923 context->PacketQueue, sizeof(WTPACKET)*nPkts);
925 context->QueueSize = nPkts;
926 LeaveCriticalSection(&csTablet);