include: Use force_align_arg_pointer on MacOS to fix the stack on entry to Wine.
[wine/multimedia.git] / dlls / wintab32 / context.c
blobd33765cd5d6ee45dd0b0bd669539c6a942fc4b5a
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, 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: %p 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 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(void)
125 TRACE("Initializing 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 %p\n",msg, 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 == ptr->QueueSize)
208 TRACE("Queue Overflow %p\n",ptr->handle);
209 ptr->PacketQueue[tgt-1].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(ptr->context.lcMsgBase),
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;
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);
247 return(size);
250 static INT TABLET_FindPacket(LPOPENCONTEXT context, UINT wSerial,
251 LPWTPACKET *pkt)
253 int loop;
254 int index = -1;
255 for (loop = 0; loop < context->PacketsQueued; loop++)
256 if (context->PacketQueue[loop].pkSerialNumber == wSerial)
258 index = loop;
259 *pkt = &context->PacketQueue[loop];
260 break;
263 TRACE("%i .. %i\n",context->PacketsQueued,index);
265 return index;
269 static LPVOID TABLET_CopyPacketData(LPOPENCONTEXT context, LPVOID lpPkt,
270 LPWTPACKET wtp)
272 LPBYTE ptr;
273 CHAR bits[100];
275 ptr = 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); */
308 return ptr;
311 static VOID TABLET_BlankPacketData(LPOPENCONTEXT context, LPVOID lpPkt, INT n)
313 int rc = 0;
315 if (context->context.lcPktData & PK_CONTEXT)
316 rc +=sizeof(HCTX);
317 if (context->context.lcPktData & PK_STATUS)
318 rc +=sizeof(UINT);
319 if (context->context.lcPktData & PK_TIME)
320 rc += sizeof(LONG);
321 if (context->context.lcPktData & PK_CHANGED)
322 rc += sizeof(WTPKT);
323 if (context->context.lcPktData & PK_SERIAL_NUMBER)
324 rc += sizeof(UINT);
325 if (context->context.lcPktData & PK_CURSOR)
326 rc += sizeof(UINT);
327 if (context->context.lcPktData & PK_BUTTONS)
328 rc += sizeof(DWORD);
329 if (context->context.lcPktData & PK_X)
330 rc += sizeof(DWORD);
331 if (context->context.lcPktData & PK_Y)
332 rc += sizeof(DWORD);
333 if (context->context.lcPktData & PK_Z)
334 rc += sizeof(DWORD);
335 if (context->context.lcPktData & PK_NORMAL_PRESSURE)
336 rc += sizeof(UINT);
337 if (context->context.lcPktData & PK_TANGENT_PRESSURE)
338 rc += sizeof(UINT);
339 if (context->context.lcPktData & PK_ORIENTATION)
340 rc += sizeof(ORIENTATION);
341 if (context->context.lcPktData & PK_ROTATION)
342 rc += sizeof(ROTATION);
344 rc *= n;
345 memset(lpPkt,0,rc);
349 /***********************************************************************
350 * WTInfoA (WINTAB32.20)
352 UINT WINAPI WTInfoA(UINT wCategory, UINT nIndex, LPVOID lpOutput)
354 UINT result;
355 if (gLoaded == FALSE)
356 LoadTablet();
359 * Handle system extents here, as we can use user32.dll code to set them.
361 if(wCategory == WTI_DEFSYSCTX)
363 switch(nIndex)
365 case CTX_SYSEXTX:
366 if(lpOutput != NULL)
367 *(LONG*)lpOutput = GetSystemMetrics(SM_CXSCREEN);
368 return sizeof(LONG);
369 case CTX_SYSEXTY:
370 if(lpOutput != NULL)
371 *(LONG*)lpOutput = GetSystemMetrics(SM_CYSCREEN);
372 return sizeof(LONG);
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);
388 return result;
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);
400 return 0;
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);
451 return NULL;
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))
469 ptr = context;
470 context = context->next;
472 if (!context)
474 LeaveCriticalSection(&csTablet);
475 return TRUE;
478 if (context == gOpenContexts)
479 gOpenContexts = context->next;
480 else
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);
491 return TRUE;
494 /***********************************************************************
495 * WTPacketsGet (WINTAB32.23)
497 int WINAPI WTPacketsGet(HCTX hCtx, int cMaxPkts, LPVOID lpPkts)
499 int limit;
500 LPOPENCONTEXT context;
501 LPVOID ptr = lpPkts;
503 TRACE("(%p, %d, %p)\n", hCtx, cMaxPkts, lpPkts);
505 if (!hCtx)
506 return 0;
508 EnterCriticalSection(&csTablet);
510 context = TABLET_FindOpenContext(hCtx);
512 if (lpPkts != NULL)
513 TABLET_BlankPacketData(context,lpPkts,cMaxPkts);
515 if (context->PacketsQueued == 0)
517 LeaveCriticalSection(&csTablet);
518 return 0;
521 limit = min(cMaxPkts,context->PacketsQueued);
523 if(ptr != NULL)
525 int i = 0;
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);
541 return limit;
544 /***********************************************************************
545 * WTPacket (WINTAB32.24)
547 BOOL WINAPI WTPacket(HCTX hCtx, UINT wSerial, LPVOID lpPkt)
549 int rc = 0;
550 LPOPENCONTEXT context;
551 LPWTPACKET wtp = NULL;
553 TRACE("(%p, %d, %p)\n", hCtx, wSerial, lpPkt);
555 if (!hCtx)
556 return 0;
558 EnterCriticalSection(&csTablet);
560 context = TABLET_FindOpenContext(hCtx);
562 rc = TABLET_FindPacket(context ,wSerial, &wtp);
564 if (rc >= 0)
566 if (lpPkt)
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);
579 return 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);
591 if (!hCtx) return 0;
593 EnterCriticalSection(&csTablet);
594 context = TABLET_FindOpenContext(hCtx);
595 if(!fEnable)
596 TABLET_FlushQueue(context);
597 context->enabled = fEnable;
598 LeaveCriticalSection(&csTablet);
600 return TRUE;
603 /***********************************************************************
604 * WTOverlap (WINTAB32.41)
606 BOOL WINAPI WTOverlap(HCTX hCtx, BOOL fToTop)
608 FIXME("(%p, %u): stub\n", hCtx, fToTop);
610 return TRUE;
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);
622 return FALSE;
625 /***********************************************************************
626 * WTGetA (WINTAB32.61)
628 BOOL WINAPI WTGetA(HCTX hCtx, LPLOGCONTEXTA lpLogCtx)
630 LPOPENCONTEXT context;
632 TRACE("(%p, %p)\n", hCtx, lpLogCtx);
634 if (!hCtx) return 0;
636 EnterCriticalSection(&csTablet);
637 context = TABLET_FindOpenContext(hCtx);
638 memmove(lpLogCtx,&context->context,sizeof(LOGCONTEXTA));
639 LeaveCriticalSection(&csTablet);
641 return TRUE;
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);
653 return FALSE;
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);
665 return FALSE;
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);
677 return FALSE;
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);
689 return FALSE;
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);
701 return FALSE;
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);
713 return FALSE;
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);
725 return 0;
728 /***********************************************************************
729 * WTPacketsPeek (WINTAB32.80)
731 int WINAPI WTPacketsPeek(HCTX hCtx, int cMaxPkts, LPVOID lpPkts)
733 int limit;
734 LPOPENCONTEXT context;
735 LPVOID ptr = lpPkts;
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);
748 return 0;
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);
756 return 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;
766 LPVOID ptr = lpPkts;
767 INT bgn = 0;
768 INT end = 0;
769 INT num = 0;
771 TRACE("(%p, %u, %u, %d, %p, %p)\n",
772 hCtx, wBegin, wEnd, cMaxPkts, lpPkts, lpNPkts);
774 if (!hCtx) return 0;
776 EnterCriticalSection(&csTablet);
778 context = TABLET_FindOpenContext(hCtx);
780 if (context->PacketsQueued == 0)
782 LeaveCriticalSection(&csTablet);
783 return 0;
786 while (bgn < context->PacketsQueued &&
787 context->PacketQueue[bgn].pkSerialNumber != wBegin)
788 bgn++;
790 end = bgn;
791 while (end < context->PacketsQueued &&
792 context->PacketQueue[end].pkSerialNumber != wEnd)
793 end++;
795 if ((bgn == end) && (end == context->PacketsQueued))
797 LeaveCriticalSection(&csTablet);
798 return 0;
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;
824 LPVOID ptr = lpPkts;
825 INT bgn = 0;
826 INT end = 0;
827 INT num = 0;
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);
841 return 0;
844 while (bgn < context->PacketsQueued &&
845 context->PacketQueue[bgn].pkSerialNumber != wBegin)
846 bgn++;
848 end = bgn;
849 while (end < context->PacketsQueued &&
850 context->PacketQueue[end].pkSerialNumber != wEnd)
851 end++;
853 if (bgn == context->PacketsQueued || end == context->PacketsQueued)
855 TRACE("%i %i %i\n", bgn, end, context->PacketsQueued);
856 LeaveCriticalSection(&csTablet);
857 return 0;
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);
879 if (!hCtx) return 0;
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;
890 else
892 TRACE("No packets\n");
893 LeaveCriticalSection(&csTablet);
894 return FALSE;
896 LeaveCriticalSection(&csTablet);
898 return TRUE;
901 /***********************************************************************
902 * WTQueueSizeGet (WINTAB32.84)
904 int WINAPI WTQueueSizeGet(HCTX hCtx)
906 LPOPENCONTEXT context;
907 TRACE("(%p)\n", hCtx);
909 if (!hCtx) return 0;
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);
926 if (!hCtx) return 0;
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);
938 return nPkts;