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
34 #include "wintab_internal.h"
36 #include "wine/debug.h"
38 WINE_DEFAULT_DEBUG_CHANNEL(wintab32
);
41 * Documentation found at
42 * http://www.csl.sony.co.jp/projects/ar/restricted/wintabl.html
46 static LPOPENCONTEXT gOpenContexts
;
47 static HCTX gTopContext
= (HCTX
)0xc00;
49 static void LOGCONTEXTAtoW(const LOGCONTEXTA
*in
, LOGCONTEXTW
*out
)
51 MultiByteToWideChar(CP_ACP
, 0, in
->lcName
, -1, out
->lcName
, LCNAMELEN
);
52 out
->lcName
[LCNAMELEN
- 1] = 0;
53 /* we use the fact that the fields after lcName are the same in LOGCONTEXTA and W */
54 memcpy(&out
->lcOptions
, &in
->lcOptions
, sizeof(LOGCONTEXTA
) - FIELD_OFFSET(LOGCONTEXTA
, lcOptions
));
57 static void LOGCONTEXTWtoA(const LOGCONTEXTW
*in
, LOGCONTEXTA
*out
)
59 WideCharToMultiByte(CP_ACP
, 0, in
->lcName
, LCNAMELEN
, out
->lcName
, LCNAMELEN
, NULL
, NULL
);
60 out
->lcName
[LCNAMELEN
- 1] = 0;
61 /* we use the fact that the fields after lcName are the same in LOGCONTEXTA and W */
62 memcpy(&out
->lcOptions
, &in
->lcOptions
, sizeof(LOGCONTEXTW
) - FIELD_OFFSET(LOGCONTEXTW
, lcOptions
));
65 static BOOL
is_logcontext_category(UINT wCategory
)
67 return wCategory
== WTI_DEFSYSCTX
|| wCategory
== WTI_DEFCONTEXT
|| wCategory
== WTI_DDCTXS
;
70 static BOOL
is_string_field(UINT wCategory
, UINT nIndex
)
72 if (wCategory
== WTI_INTERFACE
&& nIndex
== IFC_WINTABID
)
74 if (is_logcontext_category(wCategory
) && nIndex
== CTX_NAME
)
76 if (wCategory
>= WTI_CURSORS
&& wCategory
<= WTI_CURSORS
+ 9)
78 if (wCategory
== WTI_DEVICES
&& (nIndex
== DVC_NAME
|| nIndex
== DVC_PNPID
))
83 static char* DUMPBITS(int x
, char* buf
)
86 if (x
&PK_CONTEXT
) strcat(buf
,"PK_CONTEXT ");
87 if (x
&PK_STATUS
) strcat(buf
, "PK_STATUS ");
88 if (x
&PK_TIME
) strcat(buf
, "PK_TIME ");
89 if (x
&PK_CHANGED
) strcat(buf
, "PK_CHANGED ");
90 if (x
&PK_SERIAL_NUMBER
) strcat(buf
, "PK_SERIAL_NUMBER ");
91 if (x
&PK_CURSOR
) strcat(buf
, "PK_CURSOR ");
92 if (x
&PK_BUTTONS
) strcat(buf
, "PK_BUTTONS ");
93 if (x
&PK_X
) strcat(buf
, "PK_X ");
94 if (x
&PK_Y
) strcat(buf
, "PK_Y ");
95 if (x
&PK_Z
) strcat(buf
, "PK_Z ");
96 if (x
&PK_NORMAL_PRESSURE
) strcat(buf
, "PK_NORMAL_PRESSURE ");
97 if (x
&PK_TANGENT_PRESSURE
) strcat(buf
, "PK_TANGENT_PRESSURE ");
98 if (x
&PK_ORIENTATION
) strcat(buf
, "PK_ORIENTATION ");
99 if (x
&PK_ROTATION
) strcat(buf
, "PK_ROTATION ");
104 static inline void DUMPPACKET(WTPACKET packet
)
106 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",
108 (UINT
)packet
.pkStatus
,
110 (UINT
)packet
.pkChanged
,
111 packet
.pkSerialNumber
,
113 (UINT
)packet
.pkButtons
,
117 packet
.pkNormalPressure
,
118 packet
.pkTangentPressure
,
119 packet
.pkOrientation
.orAzimuth
,
120 packet
.pkOrientation
.orAltitude
, packet
.pkOrientation
.orTwist
,
121 packet
.pkRotation
.roPitch
,
122 packet
.pkRotation
.roRoll
, packet
.pkRotation
.roYaw
);
125 static inline void DUMPCONTEXT(LOGCONTEXTW lc
)
132 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",
133 wine_dbgstr_w(lc
.lcName
), lc
.lcOptions
, lc
.lcStatus
, lc
.lcLocks
, lc
.lcMsgBase
,
134 lc
.lcDevice
, lc
.lcPktRate
, (UINT
)lc
.lcPktData
, DUMPBITS(lc
.lcPktData
,bits
),
135 (UINT
)lc
.lcPktMode
, DUMPBITS(lc
.lcPktMode
,bits1
), (UINT
)lc
.lcMoveMask
,
136 DUMPBITS(lc
.lcMoveMask
,bits2
), (INT
)lc
.lcBtnDnMask
, (INT
)lc
.lcBtnUpMask
,
137 (INT
)lc
.lcInOrgX
, (INT
)lc
.lcInOrgY
, (INT
)lc
.lcInOrgZ
, lc
.lcInExtX
, lc
.lcInExtY
,
138 lc
.lcInExtZ
, lc
.lcOutOrgX
, lc
.lcOutOrgY
, lc
.lcOutOrgZ
, lc
.lcOutExtX
,
139 lc
.lcOutExtY
, lc
.lcOutExtZ
, lc
.lcSensX
, lc
.lcSensY
, lc
.lcSensZ
, lc
.lcSysMode
,
140 lc
.lcSysOrgX
, lc
.lcSysOrgY
, lc
.lcSysExtX
, lc
.lcSysExtY
, lc
.lcSysSensX
,
142 TRACE("context: %s\n",mmsg
);
146 /* Find an open context given the handle */
147 static LPOPENCONTEXT
TABLET_FindOpenContext(HCTX hCtx
)
149 LPOPENCONTEXT ptr
= gOpenContexts
;
152 if (ptr
->handle
== hCtx
) return ptr
;
158 static void LoadTablet(void)
160 TRACE("Initializing the tablet to hwnd %p\n",hwndDefault
);
162 pLoadTabletInfo(hwndDefault
);
165 int TABLET_PostTabletMessage(LPOPENCONTEXT newcontext
, UINT msg
, WPARAM wParam
,
166 LPARAM lParam
, BOOL send_always
)
168 if ((send_always
) || (newcontext
->context
.lcOptions
& CXO_MESSAGES
))
170 TRACE("Posting message %x to %p\n",msg
, newcontext
->hwndOwner
);
171 return PostMessageA(newcontext
->hwndOwner
, msg
, wParam
, lParam
);
176 static inline DWORD
ScaleForContext(DWORD In
, DWORD InOrg
, DWORD InExt
, DWORD
177 OutOrg
, DWORD OutExt
)
179 if (((InExt
> 0 )&&(OutExt
> 0)) || ((InExt
<0) && (OutExt
< 0)))
180 return ((In
- InOrg
) * abs(OutExt
) / abs(InExt
)) + OutOrg
;
182 return ((abs(InExt
) - (In
- InOrg
))*abs(OutExt
) / abs(InExt
)) + OutOrg
;
185 LPOPENCONTEXT
FindOpenContext(HWND hwnd
)
189 EnterCriticalSection(&csTablet
);
193 TRACE("Trying Context %p (%p %p)\n",ptr
->handle
,hwnd
,ptr
->hwndOwner
);
194 if (ptr
->hwndOwner
== hwnd
) break;
196 LeaveCriticalSection(&csTablet
);
200 LPOPENCONTEXT
AddPacketToContextQueue(LPWTPACKET packet
, HWND hwnd
)
202 LPOPENCONTEXT ptr
=NULL
;
204 EnterCriticalSection(&csTablet
);
209 TRACE("Trying Queue %p (%p %p)\n", ptr
->handle
, hwnd
, ptr
->hwndOwner
);
211 if (ptr
->hwndOwner
== hwnd
)
220 tgt
= ptr
->PacketsQueued
;
222 packet
->pkContext
= ptr
->handle
;
224 /* translate packet data to the context */
226 /* Scale as per documentation */
227 packet
->pkY
= ScaleForContext(packet
->pkY
, ptr
->context
.lcInOrgY
,
228 ptr
->context
.lcInExtY
, ptr
->context
.lcOutOrgY
,
229 ptr
->context
.lcOutExtY
);
231 packet
->pkX
= ScaleForContext(packet
->pkX
, ptr
->context
.lcInOrgX
,
232 ptr
->context
.lcInExtX
, ptr
->context
.lcOutOrgX
,
233 ptr
->context
.lcOutExtX
);
235 /* flip the Y axis */
236 if (ptr
->context
.lcOutExtY
> 0)
237 packet
->pkY
= ptr
->context
.lcOutExtY
- packet
->pkY
;
241 if (tgt
== ptr
->QueueSize
)
243 TRACE("Queue Overflow %p\n",ptr
->handle
);
244 ptr
->PacketQueue
[tgt
-1].pkStatus
|= TPS_QUEUE_ERR
;
248 TRACE("Placed in queue %p index %i\n",ptr
->handle
,tgt
);
249 memcpy(&ptr
->PacketQueue
[tgt
], packet
, sizeof
251 ptr
->PacketsQueued
++;
253 if (ptr
->ActiveCursor
!= packet
->pkCursor
)
255 ptr
->ActiveCursor
= packet
->pkCursor
;
256 if (ptr
->context
.lcOptions
& CXO_CSRMESSAGES
)
257 TABLET_PostTabletMessage(ptr
, _WT_CSRCHANGE(ptr
->context
.lcMsgBase
),
258 (WPARAM
)packet
->pkSerialNumber
, (LPARAM
)ptr
->handle
,
266 LeaveCriticalSection(&csTablet
);
267 TRACE("Done (%p)\n",ptr
);
272 * Flushes all packets from the queue.
274 static inline void TABLET_FlushQueue(LPOPENCONTEXT context
)
276 context
->PacketsQueued
= 0;
279 static inline int CopyTabletData(LPVOID target
, LPVOID src
, INT size
)
281 memcpy(target
,src
,size
);
285 static INT
TABLET_FindPacket(LPOPENCONTEXT context
, UINT wSerial
,
290 for (loop
= 0; loop
< context
->PacketsQueued
; loop
++)
291 if (context
->PacketQueue
[loop
].pkSerialNumber
== wSerial
)
294 *pkt
= &context
->PacketQueue
[loop
];
298 TRACE("%i .. %i\n",context
->PacketsQueued
,index
);
304 static LPVOID
TABLET_CopyPacketData(LPOPENCONTEXT context
, LPVOID lpPkt
,
311 TRACE("Packet Bits %s\n",DUMPBITS(context
->context
.lcPktData
,bits
));
313 if (context
->context
.lcPktData
& PK_CONTEXT
)
314 ptr
+=CopyTabletData(ptr
,&wtp
->pkContext
,sizeof(HCTX
));
315 if (context
->context
.lcPktData
& PK_STATUS
)
316 ptr
+=CopyTabletData(ptr
,&wtp
->pkStatus
,sizeof(UINT
));
317 if (context
->context
.lcPktData
& PK_TIME
)
318 ptr
+=CopyTabletData(ptr
,&wtp
->pkTime
,sizeof(LONG
));
319 if (context
->context
.lcPktData
& PK_CHANGED
)
320 ptr
+=CopyTabletData(ptr
,&wtp
->pkChanged
,sizeof(WTPKT
));
321 if (context
->context
.lcPktData
& PK_SERIAL_NUMBER
)
322 ptr
+=CopyTabletData(ptr
,&wtp
->pkChanged
,sizeof(UINT
));
323 if (context
->context
.lcPktData
& PK_CURSOR
)
324 ptr
+=CopyTabletData(ptr
,&wtp
->pkCursor
,sizeof(UINT
));
325 if (context
->context
.lcPktData
& PK_BUTTONS
)
326 ptr
+=CopyTabletData(ptr
,&wtp
->pkButtons
,sizeof(DWORD
));
327 if (context
->context
.lcPktData
& PK_X
)
328 ptr
+=CopyTabletData(ptr
,&wtp
->pkX
,sizeof(DWORD
));
329 if (context
->context
.lcPktData
& PK_Y
)
330 ptr
+=CopyTabletData(ptr
,&wtp
->pkY
,sizeof(DWORD
));
331 if (context
->context
.lcPktData
& PK_Z
)
332 ptr
+=CopyTabletData(ptr
,&wtp
->pkZ
,sizeof(DWORD
));
333 if (context
->context
.lcPktData
& PK_NORMAL_PRESSURE
)
334 ptr
+=CopyTabletData(ptr
,&wtp
->pkNormalPressure
,sizeof(UINT
));
335 if (context
->context
.lcPktData
& PK_TANGENT_PRESSURE
)
336 ptr
+=CopyTabletData(ptr
,&wtp
->pkTangentPressure
,sizeof(UINT
));
337 if (context
->context
.lcPktData
& PK_ORIENTATION
)
338 ptr
+=CopyTabletData(ptr
,&wtp
->pkOrientation
,sizeof(ORIENTATION
));
339 if (context
->context
.lcPktData
& PK_ROTATION
)
340 ptr
+=CopyTabletData(ptr
,&wtp
->pkRotation
,sizeof(ROTATION
));
342 /*TRACE("Copied %i bytes\n",(INT)ptr - (INT)lpPkt); */
346 static VOID
TABLET_BlankPacketData(LPOPENCONTEXT context
, LPVOID lpPkt
, INT n
)
350 if (context
->context
.lcPktData
& PK_CONTEXT
)
352 if (context
->context
.lcPktData
& PK_STATUS
)
354 if (context
->context
.lcPktData
& PK_TIME
)
356 if (context
->context
.lcPktData
& PK_CHANGED
)
358 if (context
->context
.lcPktData
& PK_SERIAL_NUMBER
)
360 if (context
->context
.lcPktData
& PK_CURSOR
)
362 if (context
->context
.lcPktData
& PK_BUTTONS
)
364 if (context
->context
.lcPktData
& PK_X
)
366 if (context
->context
.lcPktData
& PK_Y
)
368 if (context
->context
.lcPktData
& PK_Z
)
370 if (context
->context
.lcPktData
& PK_NORMAL_PRESSURE
)
372 if (context
->context
.lcPktData
& PK_TANGENT_PRESSURE
)
374 if (context
->context
.lcPktData
& PK_ORIENTATION
)
375 rc
+= sizeof(ORIENTATION
);
376 if (context
->context
.lcPktData
& PK_ROTATION
)
377 rc
+= sizeof(ROTATION
);
384 UINT WINAPI
WTInfoT(UINT wCategory
, UINT nIndex
, LPVOID lpOutput
, BOOL bUnicode
)
387 if (gLoaded
== FALSE
)
391 * Handle system extents here, as we can use user32.dll code to set them.
393 if(wCategory
== WTI_DEFSYSCTX
)
399 *(LONG
*)lpOutput
= GetSystemMetrics(SM_CXSCREEN
);
403 *(LONG
*)lpOutput
= GetSystemMetrics(SM_CYSCREEN
);
405 /* No action, delegate to X11Drv */
409 if (is_logcontext_category(wCategory
) && nIndex
== 0)
414 pWTInfoW(wCategory
, nIndex
, &buf
);
416 /* Handle system extents here, as we can use user32.dll code to set them */
417 if(wCategory
== WTI_DEFSYSCTX
&& nIndex
== 0)
419 buf
.lcSysExtX
= GetSystemMetrics(SM_CXSCREEN
);
420 buf
.lcSysExtY
= GetSystemMetrics(SM_CYSCREEN
);
424 memcpy(lpOutput
, &buf
, sizeof(buf
));
426 LOGCONTEXTWtoA(&buf
, lpOutput
);
429 return bUnicode
? sizeof(LOGCONTEXTW
) : sizeof(LOGCONTEXTA
);
431 else if (is_string_field(wCategory
, nIndex
) && !bUnicode
)
433 int size
= pWTInfoW(wCategory
, nIndex
, NULL
);
434 WCHAR
*buf
= HeapAlloc(GetProcessHeap(), 0, size
);
435 pWTInfoW(wCategory
, nIndex
, buf
);
436 result
= WideCharToMultiByte(CP_ACP
, 0, buf
, size
/sizeof(WCHAR
), lpOutput
, lpOutput
? 2*size
: 0, NULL
, NULL
);
437 HeapFree(GetProcessHeap(), 0, buf
);
440 result
= pWTInfoW(wCategory
, nIndex
, lpOutput
);
445 /***********************************************************************
446 * WTInfoA (WINTAB32.20)
448 UINT WINAPI
WTInfoA(UINT wCategory
, UINT nIndex
, LPVOID lpOutput
)
450 return WTInfoT(wCategory
, nIndex
, lpOutput
, FALSE
);
454 /***********************************************************************
455 * WTInfoW (WINTAB32.1020)
457 UINT WINAPI
WTInfoW(UINT wCategory
, UINT nIndex
, LPVOID lpOutput
)
459 return WTInfoT(wCategory
, nIndex
, lpOutput
, TRUE
);
462 /***********************************************************************
463 * WTOpenW (WINTAB32.2021)
465 HCTX WINAPI
WTOpenW(HWND hWnd
, LPLOGCONTEXTW lpLogCtx
, BOOL fEnable
)
467 LPOPENCONTEXT newcontext
;
469 TRACE("(%p, %p, %u)\n", hWnd
, lpLogCtx
, fEnable
);
470 DUMPCONTEXT(*lpLogCtx
);
472 newcontext
= HeapAlloc(GetProcessHeap(), 0 , sizeof(OPENCONTEXT
));
473 memcpy(&(newcontext
->context
),lpLogCtx
,sizeof(LOGCONTEXTW
));
474 newcontext
->hwndOwner
= hWnd
;
475 newcontext
->enabled
= fEnable
;
476 newcontext
->ActiveCursor
= -1;
477 newcontext
->QueueSize
= 10;
478 newcontext
->PacketsQueued
= 0;
479 newcontext
->PacketQueue
=HeapAlloc(GetProcessHeap(),0,sizeof(WTPACKET
)*10);
481 EnterCriticalSection(&csTablet
);
482 newcontext
->handle
= gTopContext
++;
483 newcontext
->next
= gOpenContexts
;
484 gOpenContexts
= newcontext
;
485 LeaveCriticalSection(&csTablet
);
487 pAttachEventQueueToTablet(hWnd
);
489 TABLET_PostTabletMessage(newcontext
, _WT_CTXOPEN(newcontext
->context
.lcMsgBase
), (WPARAM
)newcontext
->handle
,
490 newcontext
->context
.lcStatus
, TRUE
);
492 newcontext
->context
.lcStatus
= CXS_ONTOP
;
494 TABLET_PostTabletMessage(newcontext
, _WT_CTXOVERLAP(newcontext
->context
.lcMsgBase
),
495 (WPARAM
)newcontext
->handle
,
496 newcontext
->context
.lcStatus
, TRUE
);
498 return newcontext
->handle
;
501 /***********************************************************************
502 * WTOpenA (WINTAB32.21)
504 HCTX WINAPI
WTOpenA(HWND hWnd
, LPLOGCONTEXTA lpLogCtx
, BOOL fEnable
)
508 LOGCONTEXTAtoW(lpLogCtx
, &logCtxW
);
509 return WTOpenW(hWnd
, &logCtxW
, fEnable
);
512 /***********************************************************************
513 * WTClose (WINTAB32.22)
515 BOOL WINAPI
WTClose(HCTX hCtx
)
517 LPOPENCONTEXT context
,ptr
;
519 TRACE("(%p)\n", hCtx
);
521 EnterCriticalSection(&csTablet
);
523 ptr
= context
= gOpenContexts
;
525 while (context
&& (context
->handle
!= hCtx
))
528 context
= context
->next
;
532 LeaveCriticalSection(&csTablet
);
536 if (context
== gOpenContexts
)
537 gOpenContexts
= context
->next
;
539 ptr
->next
= context
->next
;
541 LeaveCriticalSection(&csTablet
);
543 TABLET_PostTabletMessage(context
, _WT_CTXCLOSE(context
->context
.lcMsgBase
), (WPARAM
)context
->handle
,
544 context
->context
.lcStatus
,TRUE
);
546 HeapFree(GetProcessHeap(),0,context
->PacketQueue
);
547 HeapFree(GetProcessHeap(),0,context
);
552 /***********************************************************************
553 * WTPacketsGet (WINTAB32.23)
555 int WINAPI
WTPacketsGet(HCTX hCtx
, int cMaxPkts
, LPVOID lpPkts
)
558 LPOPENCONTEXT context
;
561 TRACE("(%p, %d, %p)\n", hCtx
, cMaxPkts
, lpPkts
);
566 EnterCriticalSection(&csTablet
);
568 context
= TABLET_FindOpenContext(hCtx
);
571 TABLET_BlankPacketData(context
,lpPkts
,cMaxPkts
);
573 if (context
->PacketsQueued
== 0)
575 LeaveCriticalSection(&csTablet
);
579 limit
= min(cMaxPkts
,context
->PacketsQueued
);
584 for(i
= 0; i
< limit
; i
++)
585 ptr
=TABLET_CopyPacketData(context
,ptr
, &context
->PacketQueue
[i
]);
589 if (limit
< context
->PacketsQueued
)
591 memmove(context
->PacketQueue
, &context
->PacketQueue
[limit
],
592 (context
->PacketsQueued
- (limit
))*sizeof(WTPACKET
));
594 context
->PacketsQueued
-= limit
;
595 LeaveCriticalSection(&csTablet
);
597 TRACE("Copied %i packets\n",limit
);
602 /***********************************************************************
603 * WTPacket (WINTAB32.24)
605 BOOL WINAPI
WTPacket(HCTX hCtx
, UINT wSerial
, LPVOID lpPkt
)
608 LPOPENCONTEXT context
;
609 LPWTPACKET wtp
= NULL
;
611 TRACE("(%p, %d, %p)\n", hCtx
, wSerial
, lpPkt
);
616 EnterCriticalSection(&csTablet
);
618 context
= TABLET_FindOpenContext(hCtx
);
620 rc
= TABLET_FindPacket(context
,wSerial
, &wtp
);
625 TABLET_CopyPacketData(context
,lpPkt
, wtp
);
627 if ((rc
+1) < context
->QueueSize
)
629 memmove(context
->PacketQueue
, &context
->PacketQueue
[rc
+1],
630 (context
->PacketsQueued
- (rc
+1))*sizeof(WTPACKET
));
632 context
->PacketsQueued
-= (rc
+1);
634 LeaveCriticalSection(&csTablet
);
636 TRACE("Returning %i\n",rc
+1);
640 /***********************************************************************
641 * WTEnable (WINTAB32.40)
643 BOOL WINAPI
WTEnable(HCTX hCtx
, BOOL fEnable
)
645 LPOPENCONTEXT context
;
647 TRACE("(%p, %u)\n", hCtx
, fEnable
);
651 EnterCriticalSection(&csTablet
);
652 context
= TABLET_FindOpenContext(hCtx
);
654 TABLET_FlushQueue(context
);
655 context
->enabled
= fEnable
;
656 LeaveCriticalSection(&csTablet
);
661 /***********************************************************************
662 * WTOverlap (WINTAB32.41)
664 BOOL WINAPI
WTOverlap(HCTX hCtx
, BOOL fToTop
)
666 FIXME("(%p, %u): stub\n", hCtx
, fToTop
);
671 /***********************************************************************
672 * WTConfig (WINTAB32.61)
674 BOOL WINAPI
WTConfig(HCTX hCtx
, HWND hWnd
)
676 FIXME("(%p, %p): stub\n", hCtx
, hWnd
);
678 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
683 /***********************************************************************
684 * WTGetA (WINTAB32.61)
686 BOOL WINAPI
WTGetA(HCTX hCtx
, LPLOGCONTEXTA lpLogCtx
)
688 LPOPENCONTEXT context
;
690 TRACE("(%p, %p)\n", hCtx
, lpLogCtx
);
694 EnterCriticalSection(&csTablet
);
695 context
= TABLET_FindOpenContext(hCtx
);
696 LOGCONTEXTWtoA(&context
->context
, lpLogCtx
);
697 LeaveCriticalSection(&csTablet
);
702 /***********************************************************************
703 * WTGetW (WINTAB32.1061)
705 BOOL WINAPI
WTGetW(HCTX hCtx
, LPLOGCONTEXTW lpLogCtx
)
707 LPOPENCONTEXT context
;
709 TRACE("(%p, %p)\n", hCtx
, lpLogCtx
);
713 EnterCriticalSection(&csTablet
);
714 context
= TABLET_FindOpenContext(hCtx
);
715 memmove(lpLogCtx
,&context
->context
,sizeof(LOGCONTEXTW
));
716 LeaveCriticalSection(&csTablet
);
721 /***********************************************************************
722 * WTSetA (WINTAB32.62)
724 BOOL WINAPI
WTSetA(HCTX hCtx
, LPLOGCONTEXTA lpLogCtx
)
726 FIXME("(%p, %p): stub\n", hCtx
, lpLogCtx
);
728 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
733 /***********************************************************************
734 * WTSetW (WINTAB32.1062)
736 BOOL WINAPI
WTSetW(HCTX hCtx
, LPLOGCONTEXTW lpLogCtx
)
738 FIXME("(%p, %p): stub\n", hCtx
, lpLogCtx
);
740 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
745 /***********************************************************************
746 * WTExtGet (WINTAB32.63)
748 BOOL WINAPI
WTExtGet(HCTX hCtx
, UINT wExt
, LPVOID lpData
)
750 FIXME("(%p, %u, %p): stub\n", hCtx
, wExt
, lpData
);
752 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
757 /***********************************************************************
758 * WTExtSet (WINTAB32.64)
760 BOOL WINAPI
WTExtSet(HCTX hCtx
, UINT wExt
, LPVOID lpData
)
762 FIXME("(%p, %u, %p): stub\n", hCtx
, wExt
, lpData
);
764 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
769 /***********************************************************************
770 * WTSave (WINTAB32.65)
772 BOOL WINAPI
WTSave(HCTX hCtx
, LPVOID lpSaveInfo
)
774 FIXME("(%p, %p): stub\n", hCtx
, lpSaveInfo
);
776 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
781 /***********************************************************************
782 * WTRestore (WINTAB32.66)
784 HCTX WINAPI
WTRestore(HWND hWnd
, LPVOID lpSaveInfo
, BOOL fEnable
)
786 FIXME("(%p, %p, %u): stub\n", hWnd
, lpSaveInfo
, fEnable
);
788 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
793 /***********************************************************************
794 * WTPacketsPeek (WINTAB32.80)
796 int WINAPI
WTPacketsPeek(HCTX hCtx
, int cMaxPkts
, LPVOID lpPkts
)
799 LPOPENCONTEXT context
;
802 TRACE("(%p, %d, %p)\n", hCtx
, cMaxPkts
, lpPkts
);
804 if (!hCtx
|| !lpPkts
) return 0;
806 EnterCriticalSection(&csTablet
);
808 context
= TABLET_FindOpenContext(hCtx
);
810 if (context
->PacketsQueued
== 0)
812 LeaveCriticalSection(&csTablet
);
816 for (limit
= 0; limit
< cMaxPkts
&& limit
< context
->PacketsQueued
; limit
++)
817 ptr
= TABLET_CopyPacketData(context
,ptr
, &context
->PacketQueue
[limit
]);
819 LeaveCriticalSection(&csTablet
);
820 TRACE("Copied %i packets\n",limit
);
824 /***********************************************************************
825 * WTDataGet (WINTAB32.81)
827 int WINAPI
WTDataGet(HCTX hCtx
, UINT wBegin
, UINT wEnd
,
828 int cMaxPkts
, LPVOID lpPkts
, LPINT lpNPkts
)
830 LPOPENCONTEXT context
;
836 TRACE("(%p, %u, %u, %d, %p, %p)\n",
837 hCtx
, wBegin
, wEnd
, cMaxPkts
, lpPkts
, lpNPkts
);
841 EnterCriticalSection(&csTablet
);
843 context
= TABLET_FindOpenContext(hCtx
);
845 if (context
->PacketsQueued
== 0)
847 LeaveCriticalSection(&csTablet
);
851 while (bgn
< context
->PacketsQueued
&&
852 context
->PacketQueue
[bgn
].pkSerialNumber
!= wBegin
)
856 while (end
< context
->PacketsQueued
&&
857 context
->PacketQueue
[end
].pkSerialNumber
!= wEnd
)
860 if ((bgn
== end
) && (end
== context
->PacketsQueued
))
862 LeaveCriticalSection(&csTablet
);
866 for (num
= bgn
; num
<= end
; num
++)
867 ptr
= TABLET_CopyPacketData(context
,ptr
, &context
->PacketQueue
[num
]);
869 /* remove read packets */
870 if ((end
+1) < context
->PacketsQueued
)
871 memmove( &context
->PacketQueue
[bgn
], &context
->PacketQueue
[end
+1],
872 (context
->PacketsQueued
- (end
+1)) * sizeof (WTPACKET
));
874 context
->PacketsQueued
-= ((end
-bgn
)+1);
875 *lpNPkts
= ((end
-bgn
)+1);
877 LeaveCriticalSection(&csTablet
);
878 TRACE("Copied %i packets\n",*lpNPkts
);
879 return (end
- bgn
)+1;
882 /***********************************************************************
883 * WTDataPeek (WINTAB32.82)
885 int WINAPI
WTDataPeek(HCTX hCtx
, UINT wBegin
, UINT wEnd
,
886 int cMaxPkts
, LPVOID lpPkts
, LPINT lpNPkts
)
888 LPOPENCONTEXT context
;
894 TRACE("(%p, %u, %u, %d, %p, %p)\n",
895 hCtx
, wBegin
, wEnd
, cMaxPkts
, lpPkts
, lpNPkts
);
897 if (!hCtx
|| !lpPkts
) return 0;
899 EnterCriticalSection(&csTablet
);
901 context
= TABLET_FindOpenContext(hCtx
);
903 if (context
->PacketsQueued
== 0)
905 LeaveCriticalSection(&csTablet
);
909 while (bgn
< context
->PacketsQueued
&&
910 context
->PacketQueue
[bgn
].pkSerialNumber
!= wBegin
)
914 while (end
< context
->PacketsQueued
&&
915 context
->PacketQueue
[end
].pkSerialNumber
!= wEnd
)
918 if (bgn
== context
->PacketsQueued
|| end
== context
->PacketsQueued
)
920 TRACE("%i %i %i\n", bgn
, end
, context
->PacketsQueued
);
921 LeaveCriticalSection(&csTablet
);
925 for (num
= bgn
; num
<= end
; num
++)
926 ptr
= TABLET_CopyPacketData(context
,ptr
, &context
->PacketQueue
[num
]);
928 *lpNPkts
= ((end
-bgn
)+1);
929 LeaveCriticalSection(&csTablet
);
931 TRACE("Copied %i packets\n",*lpNPkts
);
932 return (end
- bgn
)+1;
935 /***********************************************************************
936 * WTQueuePacketsEx (WINTAB32.200)
938 BOOL WINAPI
WTQueuePacketsEx(HCTX hCtx
, UINT
*lpOld
, UINT
*lpNew
)
940 LPOPENCONTEXT context
;
942 TRACE("(%p, %p, %p)\n", hCtx
, lpOld
, lpNew
);
946 EnterCriticalSection(&csTablet
);
948 context
= TABLET_FindOpenContext(hCtx
);
950 if (context
->PacketsQueued
)
952 *lpOld
= context
->PacketQueue
[0].pkSerialNumber
;
953 *lpNew
= context
->PacketQueue
[context
->PacketsQueued
-1].pkSerialNumber
;
957 TRACE("No packets\n");
958 LeaveCriticalSection(&csTablet
);
961 LeaveCriticalSection(&csTablet
);
966 /***********************************************************************
967 * WTQueueSizeGet (WINTAB32.84)
969 int WINAPI
WTQueueSizeGet(HCTX hCtx
)
971 LPOPENCONTEXT context
;
972 TRACE("(%p)\n", hCtx
);
976 EnterCriticalSection(&csTablet
);
977 context
= TABLET_FindOpenContext(hCtx
);
978 LeaveCriticalSection(&csTablet
);
979 return context
->QueueSize
;
982 /***********************************************************************
983 * WTQueueSizeSet (WINTAB32.85)
985 BOOL WINAPI
WTQueueSizeSet(HCTX hCtx
, int nPkts
)
987 LPOPENCONTEXT context
;
989 TRACE("(%p, %d)\n", hCtx
, nPkts
);
993 EnterCriticalSection(&csTablet
);
995 context
= TABLET_FindOpenContext(hCtx
);
997 context
->PacketQueue
= HeapReAlloc(GetProcessHeap(), 0,
998 context
->PacketQueue
, sizeof(WTPACKET
)*nPkts
);
1000 context
->QueueSize
= nPkts
;
1001 LeaveCriticalSection(&csTablet
);