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
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: %p pkStatus: 0x%x pkTime : 0x%x pkChanged: 0x%x pkSerialNumber: 0x%x pkCursor : %i pkButtons: %x pkX: %i pkY: %i pkZ: %i pkNormalPressure: %i pkTangentPressure: %i pkOrientation: (%i,%i,%i) pkRotation: (%i,%i,%i)\n",
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, %i ,%i, %i, %i, %i, %i,%i, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i %i %i",
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\n",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(void)
125 TRACE("Initializing 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 %p\n",msg
, 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 inline static void TABLET_FlushQueue(LPOPENCONTEXT context
)
241 context
->PacketsQueued
= 0;
244 inline static int 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
;
551 LPWTPACKET wtp
= NULL
;
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
);