Release 20040408.
[wine.git] / dlls / wintab32 / context.c
blob7e41396e4a2608cb6bdd43df49374d8e77e7d4a7
1 /*
2 * Tablet Context
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
22 #include "config.h"
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <stdarg.h>
27 #include "windef.h"
28 #include "winerror.h"
29 #include "winbase.h"
30 #include "winuser.h"
32 #include "wintab.h"
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
44 static BOOL gLoaded;
45 static LPOPENCONTEXT gOpenContexts;
46 static HCTX gTopContext = (HCTX)0xc00;
48 static char* DUMPBITS(int x, char* buf)
50 strcpy(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 ");
65 strcat(buf, "}");
66 return buf;
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,
74 (UINT)packet.pkTime,
75 (UINT)packet.pkChanged,
76 packet.pkSerialNumber,
77 packet.pkCursor,
78 (UINT)packet.pkButtons,
79 packet.pkX,
80 packet.pkY,
81 packet.pkZ,
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)
92 CHAR mmsg[4000];
93 CHAR bits[100];
94 CHAR bits1[100];
95 CHAR bits2[100];
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,
106 lc.lcSysSensY);
107 TRACE("context: %s",mmsg);
111 /* Find an open context given the handle */
112 static LPOPENCONTEXT TABLET_FindOpenContext(HCTX hCtx)
114 LPOPENCONTEXT ptr = gOpenContexts;
115 while (ptr)
117 if (ptr->handle == hCtx) return ptr;
118 ptr = ptr->next;
120 return NULL;
123 static void LoadTablet()
125 TRACE("Initilizing the tablet to hwnd %p\n",hwndDefault);
126 gLoaded= TRUE;
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);
138 return 0;
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;
146 else
147 return ((abs(InExt) - (In - InOrg))*abs(OutExt) / abs(InExt)) + OutOrg;
150 LPOPENCONTEXT FindOpenContext(HWND hwnd)
152 LPOPENCONTEXT ptr;
154 EnterCriticalSection(&csTablet);
155 ptr = gOpenContexts;
156 while (ptr)
158 TRACE("Trying Context %p (%p %p)\n",ptr->handle,hwnd,ptr->hwndOwner);
159 if (ptr->hwndOwner == hwnd) break;
161 LeaveCriticalSection(&csTablet);
162 return ptr;
165 LPOPENCONTEXT AddPacketToContextQueue(LPWTPACKET packet, HWND hwnd)
167 LPOPENCONTEXT ptr=NULL;
169 EnterCriticalSection(&csTablet);
171 ptr = gOpenContexts;
172 while (ptr)
174 TRACE("Trying Queue %p (%p %p)\n", ptr->handle, hwnd, ptr->hwndOwner);
176 if (ptr->hwndOwner == hwnd)
178 int tgt;
179 if (!ptr->enabled)
181 ptr = ptr->next;
182 continue;
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;
204 DUMPPACKET(*packet);
206 if (tgt + 1 == ptr->QueueSize)
208 TRACE("Queue Overflow %p\n",ptr->handle);
209 packet->pkStatus = TPS_QUEUE_ERR;
211 else
213 TRACE("Placed in queue %p index %i\n",ptr->handle,tgt);
214 memcpy(&ptr->PacketQueue[tgt], packet, sizeof
215 (WTPACKET));
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,
224 FALSE);
227 break;
229 ptr = ptr->next;
231 LeaveCriticalSection(&csTablet);
232 TRACE("Done (%p)\n",ptr);
233 return ptr;
236 int static inline CopyTabletData(LPVOID target, LPVOID src, INT size)
238 memcpy(target,src,size);
239 return(size);
242 static INT TABLET_FindPacket(LPOPENCONTEXT context, UINT wSerial,
243 LPWTPACKET *pkt)
245 int loop;
246 int index = -1;
247 for (loop = 0; loop < context->PacketsQueued; loop++)
248 if (context->PacketQueue[loop].pkSerialNumber == wSerial)
250 index = loop;
251 *pkt = &context->PacketQueue[loop];
252 break;
255 TRACE("%i .. %i\n",context->PacketsQueued,index);
257 return index;
261 static LPVOID TABLET_CopyPacketData(LPOPENCONTEXT context, LPVOID lpPkt,
262 LPWTPACKET wtp)
264 LPBYTE ptr;
265 CHAR bits[100];
267 ptr = 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); */
300 return ptr;
303 static VOID TABLET_BlankPacketData(LPOPENCONTEXT context, LPVOID lpPkt, INT n)
305 int rc = 0;
307 if (context->context.lcPktData & PK_CONTEXT)
308 rc +=sizeof(HCTX);
309 if (context->context.lcPktData & PK_STATUS)
310 rc +=sizeof(UINT);
311 if (context->context.lcPktData & PK_TIME)
312 rc += sizeof(LONG);
313 if (context->context.lcPktData & PK_CHANGED)
314 rc += sizeof(WTPKT);
315 if (context->context.lcPktData & PK_SERIAL_NUMBER)
316 rc += sizeof(UINT);
317 if (context->context.lcPktData & PK_CURSOR)
318 rc += sizeof(UINT);
319 if (context->context.lcPktData & PK_BUTTONS)
320 rc += sizeof(DWORD);
321 if (context->context.lcPktData & PK_X)
322 rc += sizeof(DWORD);
323 if (context->context.lcPktData & PK_Y)
324 rc += sizeof(DWORD);
325 if (context->context.lcPktData & PK_Z)
326 rc += sizeof(DWORD);
327 if (context->context.lcPktData & PK_NORMAL_PRESSURE)
328 rc += sizeof(UINT);
329 if (context->context.lcPktData & PK_TANGENT_PRESSURE)
330 rc += sizeof(UINT);
331 if (context->context.lcPktData & PK_ORIENTATION)
332 rc += sizeof(ORIENTATION);
333 if (context->context.lcPktData & PK_ROTATION)
334 rc += sizeof(ROTATION);
336 rc *= n;
337 memset(lpPkt,0,rc);
341 /***********************************************************************
342 * WTInfoA (WINTAB32.20)
344 UINT WINAPI WTInfoA(UINT wCategory, UINT nIndex, LPVOID lpOutput)
346 if (gLoaded == FALSE)
347 LoadTablet();
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);
361 return 0;
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);
412 return NULL;
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))
430 ptr = context;
431 context = context->next;
433 if (!context)
435 LeaveCriticalSection(&csTablet);
436 return TRUE;
439 if (context == gOpenContexts)
440 gOpenContexts = context->next;
441 else
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);
452 return TRUE;
455 /***********************************************************************
456 * WTPacketsGet (WINTAB32.23)
458 int WINAPI WTPacketsGet(HCTX hCtx, int cMaxPkts, LPVOID lpPkts)
460 int limit;
461 LPOPENCONTEXT context;
462 LPVOID ptr = lpPkts;
464 TRACE("(%p, %d, %p)\n", hCtx, cMaxPkts, lpPkts);
466 if (!hCtx || !lpPkts) return 0;
468 EnterCriticalSection(&csTablet);
470 context = TABLET_FindOpenContext(hCtx);
471 TABLET_BlankPacketData(context,lpPkts,cMaxPkts);
473 if (context->PacketsQueued == 0)
475 LeaveCriticalSection(&csTablet);
476 return 0;
479 for(limit = 0; limit < cMaxPkts && limit < context->PacketsQueued; limit++)
480 ptr=TABLET_CopyPacketData(context ,ptr, &context->PacketQueue[limit]);
482 if (limit < context->PacketsQueued)
484 memcpy(context->PacketQueue, &context->PacketQueue[limit],
485 (context->QueueSize - (limit))*sizeof(WTPACKET));
487 context->PacketsQueued -= limit;
488 LeaveCriticalSection(&csTablet);
490 TRACE("Copied %i packets\n",limit);
492 return limit;
495 /***********************************************************************
496 * WTPacket (WINTAB32.24)
498 BOOL WINAPI WTPacket(HCTX hCtx, UINT wSerial, LPVOID lpPkt)
500 int rc = 0;
501 LPOPENCONTEXT context;
502 LPWTPACKET wtp;
504 TRACE("(%p, %d, %p)\n", hCtx, wSerial, lpPkt);
506 if (!hCtx) return 0;
508 EnterCriticalSection(&csTablet);
510 context = TABLET_FindOpenContext(hCtx);
512 rc = TABLET_FindPacket(context ,wSerial, &wtp);
514 if (rc >= 0)
516 if (lpPkt)
517 TABLET_CopyPacketData(context ,lpPkt, wtp);
519 if ((rc+1) < context->QueueSize)
521 memcpy(context->PacketQueue, &context->PacketQueue[rc+1],
522 (context->QueueSize - (rc+1))*sizeof(WTPACKET));
524 context->PacketsQueued -= (rc+1);
526 LeaveCriticalSection(&csTablet);
528 TRACE("Returning %i\n",rc+1);
529 return rc+1;
532 /***********************************************************************
533 * WTEnable (WINTAB32.40)
535 BOOL WINAPI WTEnable(HCTX hCtx, BOOL fEnable)
537 LPOPENCONTEXT context;
539 TRACE("(%p, %u)\n", hCtx, fEnable);
541 if (!hCtx) return 0;
543 EnterCriticalSection(&csTablet);
544 context = TABLET_FindOpenContext(hCtx);
545 context->enabled = fEnable;
546 LeaveCriticalSection(&csTablet);
548 return TRUE;
551 /***********************************************************************
552 * WTOverlap (WINTAB32.41)
554 BOOL WINAPI WTOverlap(HCTX hCtx, BOOL fToTop)
556 FIXME("(%p, %u): stub\n", hCtx, fToTop);
558 return TRUE;
561 /***********************************************************************
562 * WTConfig (WINTAB32.61)
564 BOOL WINAPI WTConfig(HCTX hCtx, HWND hWnd)
566 FIXME("(%p, %p): stub\n", hCtx, hWnd);
568 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
570 return FALSE;
573 /***********************************************************************
574 * WTGetA (WINTAB32.61)
576 BOOL WINAPI WTGetA(HCTX hCtx, LPLOGCONTEXTA lpLogCtx)
578 LPOPENCONTEXT context;
580 TRACE("(%p, %p)\n", hCtx, lpLogCtx);
582 if (!hCtx) return 0;
584 EnterCriticalSection(&csTablet);
585 context = TABLET_FindOpenContext(hCtx);
586 memcpy(lpLogCtx,&context->context,sizeof(LOGCONTEXTA));
587 LeaveCriticalSection(&csTablet);
589 return TRUE;
592 /***********************************************************************
593 * WTGetW (WINTAB32.1061)
595 BOOL WINAPI WTGetW(HCTX hCtx, LPLOGCONTEXTW lpLogCtx)
597 FIXME("(%p, %p): stub\n", hCtx, lpLogCtx);
599 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
601 return FALSE;
604 /***********************************************************************
605 * WTSetA (WINTAB32.62)
607 BOOL WINAPI WTSetA(HCTX hCtx, LPLOGCONTEXTA lpLogCtx)
609 FIXME("(%p, %p): stub\n", hCtx, lpLogCtx);
611 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
613 return FALSE;
616 /***********************************************************************
617 * WTSetW (WINTAB32.1062)
619 BOOL WINAPI WTSetW(HCTX hCtx, LPLOGCONTEXTW lpLogCtx)
621 FIXME("(%p, %p): stub\n", hCtx, lpLogCtx);
623 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
625 return FALSE;
628 /***********************************************************************
629 * WTExtGet (WINTAB32.63)
631 BOOL WINAPI WTExtGet(HCTX hCtx, UINT wExt, LPVOID lpData)
633 FIXME("(%p, %u, %p): stub\n", hCtx, wExt, lpData);
635 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
637 return FALSE;
640 /***********************************************************************
641 * WTExtSet (WINTAB32.64)
643 BOOL WINAPI WTExtSet(HCTX hCtx, UINT wExt, LPVOID lpData)
645 FIXME("(%p, %u, %p): stub\n", hCtx, wExt, lpData);
647 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
649 return FALSE;
652 /***********************************************************************
653 * WTSave (WINTAB32.65)
655 BOOL WINAPI WTSave(HCTX hCtx, LPVOID lpSaveInfo)
657 FIXME("(%p, %p): stub\n", hCtx, lpSaveInfo);
659 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
661 return FALSE;
664 /***********************************************************************
665 * WTRestore (WINTAB32.66)
667 HCTX WINAPI WTRestore(HWND hWnd, LPVOID lpSaveInfo, BOOL fEnable)
669 FIXME("(%p, %p, %u): stub\n", hWnd, lpSaveInfo, fEnable);
671 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
673 return 0;
676 /***********************************************************************
677 * WTPacketsPeek (WINTAB32.80)
679 int WINAPI WTPacketsPeek(HCTX hCtx, int cMaxPkts, LPVOID lpPkts)
681 int limit;
682 LPOPENCONTEXT context;
683 LPVOID ptr = lpPkts;
685 TRACE("(%p, %d, %p)\n", hCtx, cMaxPkts, lpPkts);
687 if (!hCtx || !lpPkts) return 0;
689 EnterCriticalSection(&csTablet);
691 context = TABLET_FindOpenContext(hCtx);
693 if (context->PacketsQueued == 0)
695 LeaveCriticalSection(&csTablet);
696 return 0;
699 for (limit = 0; limit < cMaxPkts && limit < context->PacketsQueued; limit++)
700 ptr = TABLET_CopyPacketData(context ,ptr, &context->PacketQueue[limit]);
702 LeaveCriticalSection(&csTablet);
703 TRACE("Copied %i packets\n",limit);
704 return limit;
707 /***********************************************************************
708 * WTDataGet (WINTAB32.81)
710 int WINAPI WTDataGet(HCTX hCtx, UINT wBegin, UINT wEnd,
711 int cMaxPkts, LPVOID lpPkts, LPINT lpNPkts)
713 LPOPENCONTEXT context;
714 LPVOID ptr = lpPkts;
715 UINT bgn = 0;
716 UINT end = 0;
717 UINT num = 0;
719 TRACE("(%p, %u, %u, %d, %p, %p)\n",
720 hCtx, wBegin, wEnd, cMaxPkts, lpPkts, lpNPkts);
722 if (!hCtx) return 0;
724 EnterCriticalSection(&csTablet);
726 context = TABLET_FindOpenContext(hCtx);
728 if (context->PacketsQueued == 0)
730 LeaveCriticalSection(&csTablet);
731 return 0;
734 while (bgn < context->PacketsQueued &&
735 context->PacketQueue[bgn].pkSerialNumber != wBegin)
736 bgn++;
738 end = bgn;
739 while (end < context->PacketsQueued &&
740 context->PacketQueue[end].pkSerialNumber != wEnd)
741 end++;
743 if (bgn == end == context->PacketsQueued)
745 LeaveCriticalSection(&csTablet);
746 return 0;
749 for (num = bgn; num <= end; num++)
750 ptr = TABLET_CopyPacketData(context ,ptr, &context->PacketQueue[end]);
752 /* remove read packets */
753 if ((end+1) < context->PacketsQueued)
754 memcpy( &context->PacketQueue[bgn], &context->PacketQueue[end+1],
755 (context->PacketsQueued - ((end-bgn)+1)) * sizeof (WTPACKET));
757 context->PacketsQueued -= ((end-bgn)+1);
758 *lpNPkts = ((end-bgn)+1);
760 LeaveCriticalSection(&csTablet);
761 TRACE("Copied %i packets\n",*lpNPkts);
762 return (end - bgn)+1;
765 /***********************************************************************
766 * WTDataPeek (WINTAB32.82)
768 int WINAPI WTDataPeek(HCTX hCtx, UINT wBegin, UINT wEnd,
769 int cMaxPkts, LPVOID lpPkts, LPINT lpNPkts)
771 LPOPENCONTEXT context;
772 LPVOID ptr = lpPkts;
773 UINT bgn = 0;
774 UINT end = 0;
775 UINT num = 0;
777 TRACE("(%p, %u, %u, %d, %p, %p)\n",
778 hCtx, wBegin, wEnd, cMaxPkts, lpPkts, lpNPkts);
780 if (!hCtx) return 0;
782 EnterCriticalSection(&csTablet);
784 context = TABLET_FindOpenContext(hCtx);
786 if (context->PacketsQueued == 0)
788 LeaveCriticalSection(&csTablet);
789 return 0;
792 while (bgn < context->PacketsQueued &&
793 context->PacketQueue[bgn].pkSerialNumber != wBegin)
794 bgn++;
796 end = bgn;
797 while (end < context->PacketsQueued &&
798 context->PacketQueue[end].pkSerialNumber != wEnd)
799 end++;
801 if (bgn == context->PacketsQueued || end == context->PacketsQueued)
803 TRACE("%i %i %i \n", bgn, end, context->PacketsQueued);
804 LeaveCriticalSection(&csTablet);
805 return 0;
808 for (num = bgn; num <= end; num++)
809 ptr = TABLET_CopyPacketData(context ,ptr, &context->PacketQueue[end]);
811 *lpNPkts = ((end-bgn)+1);
812 LeaveCriticalSection(&csTablet);
814 TRACE("Copied %i packets\n",*lpNPkts);
815 return (end - bgn)+1;
818 /***********************************************************************
819 * WTQueuePacketsEx (WINTAB32.200)
821 BOOL WINAPI WTQueuePacketsEx(HCTX hCtx, UINT *lpOld, UINT *lpNew)
823 LPOPENCONTEXT context;
825 TRACE("(%p, %p, %p)\n", hCtx, lpOld, lpNew);
827 if (!hCtx) return 0;
829 EnterCriticalSection(&csTablet);
831 context = TABLET_FindOpenContext(hCtx);
833 if (context->PacketsQueued)
835 *lpOld = context->PacketQueue[0].pkSerialNumber;
836 *lpNew = context->PacketQueue[context->PacketsQueued-1].pkSerialNumber;
838 else
840 TRACE("No packets\n");
841 LeaveCriticalSection(&csTablet);
842 return FALSE;
844 LeaveCriticalSection(&csTablet);
846 return TRUE;
849 /***********************************************************************
850 * WTQueueSizeGet (WINTAB32.84)
852 int WINAPI WTQueueSizeGet(HCTX hCtx)
854 LPOPENCONTEXT context;
855 TRACE("(%p)\n", hCtx);
857 if (!hCtx) return 0;
859 EnterCriticalSection(&csTablet);
860 context = TABLET_FindOpenContext(hCtx);
861 LeaveCriticalSection(&csTablet);
862 return context->QueueSize;
865 /***********************************************************************
866 * WTQueueSizeSet (WINTAB32.85)
868 BOOL WINAPI WTQueueSizeSet(HCTX hCtx, int nPkts)
870 LPOPENCONTEXT context;
872 TRACE("(%p, %d)\n", hCtx, nPkts);
874 if (!hCtx) return 0;
876 EnterCriticalSection(&csTablet);
878 context = TABLET_FindOpenContext(hCtx);
880 context->PacketQueue = HeapReAlloc(GetProcessHeap(), 0,
881 context->PacketQueue, sizeof(WTPACKET)*nPkts);
883 context->QueueSize = nPkts;
884 LeaveCriticalSection(&csTablet);
886 return nPkts;