msxml3: Suppress IID_IRunnableObject FIXME since its not supported.
[wine.git] / dlls / wintab32 / context.c
blob609ec22db8ab05686151eee3ce032a279b8a4138
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"
31 #include "winnls.h"
33 #include "wintab.h"
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
45 static BOOL gLoaded;
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)
73 return TRUE;
74 if (is_logcontext_category(wCategory) && nIndex == CTX_NAME)
75 return TRUE;
76 if ((wCategory >= WTI_CURSORS && wCategory <= WTI_CURSORS + 9) &&
77 (nIndex == CSR_NAME || nIndex == CSR_BTNNAMES))
78 return TRUE;
79 if (wCategory == WTI_DEVICES && (nIndex == DVC_NAME || nIndex == DVC_PNPID))
80 return TRUE;
81 return FALSE;
84 static const char* DUMPBITS(int x)
86 char buf[200];
87 buf[0] = 0;
88 if (x&PK_CONTEXT) strcat(buf,"PK_CONTEXT ");
89 if (x&PK_STATUS) strcat(buf, "PK_STATUS ");
90 if (x&PK_TIME) strcat(buf, "PK_TIME ");
91 if (x&PK_CHANGED) strcat(buf, "PK_CHANGED ");
92 if (x&PK_SERIAL_NUMBER) strcat(buf, "PK_SERIAL_NUMBER ");
93 if (x&PK_CURSOR) strcat(buf, "PK_CURSOR ");
94 if (x&PK_BUTTONS) strcat(buf, "PK_BUTTONS ");
95 if (x&PK_X) strcat(buf, "PK_X ");
96 if (x&PK_Y) strcat(buf, "PK_Y ");
97 if (x&PK_Z) strcat(buf, "PK_Z ");
98 if (x&PK_NORMAL_PRESSURE) strcat(buf, "PK_NORMAL_PRESSURE ");
99 if (x&PK_TANGENT_PRESSURE) strcat(buf, "PK_TANGENT_PRESSURE ");
100 if (x&PK_ORIENTATION) strcat(buf, "PK_ORIENTATION ");
101 if (x&PK_ROTATION) strcat(buf, "PK_ROTATION ");
102 return wine_dbg_sprintf("{%s}",buf);
105 static inline void DUMPPACKET(WTPACKET packet)
107 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 packet.pkContext, packet.pkStatus, packet.pkTime, packet.pkChanged, packet.pkSerialNumber,
109 packet.pkCursor, packet.pkButtons, packet.pkX, packet.pkY, packet.pkZ,
110 packet.pkNormalPressure, packet.pkTangentPressure,
111 packet.pkOrientation.orAzimuth, packet.pkOrientation.orAltitude, packet.pkOrientation.orTwist,
112 packet.pkRotation.roPitch, packet.pkRotation.roRoll, packet.pkRotation.roYaw);
115 static inline void DUMPCONTEXT(LOGCONTEXTW lc)
117 TRACE("context: %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\n",
118 wine_dbgstr_w(lc.lcName), lc.lcOptions, lc.lcStatus, lc.lcLocks, lc.lcMsgBase,
119 lc.lcDevice, lc.lcPktRate, lc.lcPktData, DUMPBITS(lc.lcPktData),
120 lc.lcPktMode, DUMPBITS(lc.lcPktMode), lc.lcMoveMask,
121 DUMPBITS(lc.lcMoveMask), lc.lcBtnDnMask, lc.lcBtnUpMask,
122 lc.lcInOrgX, lc.lcInOrgY, lc.lcInOrgZ, lc.lcInExtX, lc.lcInExtY,
123 lc.lcInExtZ, lc.lcOutOrgX, lc.lcOutOrgY, lc.lcOutOrgZ, lc.lcOutExtX,
124 lc.lcOutExtY, lc.lcOutExtZ, lc.lcSensX, lc.lcSensY, lc.lcSensZ, lc.lcSysMode,
125 lc.lcSysOrgX, lc.lcSysOrgY, lc.lcSysExtX, lc.lcSysExtY, lc.lcSysSensX,
126 lc.lcSysSensY);
130 /* Find an open context given the handle */
131 static LPOPENCONTEXT TABLET_FindOpenContext(HCTX hCtx)
133 LPOPENCONTEXT ptr = gOpenContexts;
134 while (ptr)
136 if (ptr->handle == hCtx) return ptr;
137 ptr = ptr->next;
139 return NULL;
142 static void LoadTablet(void)
144 TRACE("Initializing the tablet to hwnd %p\n",hwndDefault);
145 gLoaded= TRUE;
146 pLoadTabletInfo(hwndDefault);
149 int TABLET_PostTabletMessage(LPOPENCONTEXT newcontext, UINT msg, WPARAM wParam,
150 LPARAM lParam, BOOL send_always)
152 if ((send_always) || (newcontext->context.lcOptions & CXO_MESSAGES))
154 TRACE("Posting message %x to %p\n",msg, newcontext->hwndOwner);
155 return PostMessageA(newcontext->hwndOwner, msg, wParam, lParam);
157 return 0;
160 static inline DWORD ScaleForContext(DWORD In, DWORD InOrg, DWORD InExt, DWORD
161 OutOrg, DWORD OutExt)
163 if (((InExt > 0 )&&(OutExt > 0)) || ((InExt<0) && (OutExt < 0)))
164 return ((In - InOrg) * abs(OutExt) / abs(InExt)) + OutOrg;
165 else
166 return ((abs(InExt) - (In - InOrg))*abs(OutExt) / abs(InExt)) + OutOrg;
169 LPOPENCONTEXT AddPacketToContextQueue(LPWTPACKET packet, HWND hwnd)
171 LPOPENCONTEXT ptr=NULL;
173 EnterCriticalSection(&csTablet);
175 ptr = gOpenContexts;
176 while (ptr)
178 TRACE("Trying Queue %p (%p %p)\n", ptr->handle, hwnd, ptr->hwndOwner);
180 if (ptr->hwndOwner == hwnd)
182 int tgt;
183 if (!ptr->enabled)
185 ptr = ptr->next;
186 continue;
189 tgt = ptr->PacketsQueued;
191 packet->pkContext = ptr->handle;
193 /* translate packet data to the context */
195 /* Scale as per documentation */
196 packet->pkY = ScaleForContext(packet->pkY, ptr->context.lcInOrgY,
197 ptr->context.lcInExtY, ptr->context.lcOutOrgY,
198 ptr->context.lcOutExtY);
200 packet->pkX = ScaleForContext(packet->pkX, ptr->context.lcInOrgX,
201 ptr->context.lcInExtX, ptr->context.lcOutOrgX,
202 ptr->context.lcOutExtX);
204 /* flip the Y axis */
205 if (ptr->context.lcOutExtY > 0)
206 packet->pkY = ptr->context.lcOutExtY - packet->pkY;
208 DUMPPACKET(*packet);
210 if (tgt == ptr->QueueSize)
212 TRACE("Queue Overflow %p\n",ptr->handle);
213 ptr->PacketQueue[tgt-1].pkStatus |= TPS_QUEUE_ERR;
215 else
217 TRACE("Placed in queue %p index %i\n",ptr->handle,tgt);
218 memcpy(&ptr->PacketQueue[tgt], packet, sizeof
219 (WTPACKET));
220 ptr->PacketsQueued++;
222 if (ptr->ActiveCursor != packet->pkCursor)
224 ptr->ActiveCursor = packet->pkCursor;
225 if (ptr->context.lcOptions & CXO_CSRMESSAGES)
226 TABLET_PostTabletMessage(ptr, _WT_CSRCHANGE(ptr->context.lcMsgBase),
227 (WPARAM)packet->pkSerialNumber, (LPARAM)ptr->handle,
228 FALSE);
231 break;
233 ptr = ptr->next;
235 LeaveCriticalSection(&csTablet);
236 TRACE("Done (%p)\n",ptr);
237 return ptr;
241 * Flushes all packets from the queue.
243 static inline void TABLET_FlushQueue(LPOPENCONTEXT context)
245 context->PacketsQueued = 0;
248 static inline int CopyTabletData(LPVOID target, LPVOID src, INT size)
250 memcpy(target,src,size);
251 return(size);
254 static INT TABLET_FindPacket(LPOPENCONTEXT context, UINT wSerial,
255 LPWTPACKET *pkt)
257 int loop;
258 int index = -1;
259 for (loop = 0; loop < context->PacketsQueued; loop++)
260 if (context->PacketQueue[loop].pkSerialNumber == wSerial)
262 index = loop;
263 *pkt = &context->PacketQueue[loop];
264 break;
267 TRACE("%i .. %i\n",context->PacketsQueued,index);
269 return index;
273 static LPVOID TABLET_CopyPacketData(LPOPENCONTEXT context, LPVOID lpPkt,
274 LPWTPACKET wtp)
276 LPBYTE ptr;
278 ptr = lpPkt;
279 TRACE("Packet Bits %s\n",DUMPBITS(context->context.lcPktData));
281 if (context->context.lcPktData & PK_CONTEXT)
282 ptr+=CopyTabletData(ptr,&wtp->pkContext,sizeof(HCTX));
283 if (context->context.lcPktData & PK_STATUS)
284 ptr+=CopyTabletData(ptr,&wtp->pkStatus,sizeof(UINT));
285 if (context->context.lcPktData & PK_TIME)
286 ptr+=CopyTabletData(ptr,&wtp->pkTime,sizeof(LONG));
287 if (context->context.lcPktData & PK_CHANGED)
288 ptr+=CopyTabletData(ptr,&wtp->pkChanged,sizeof(WTPKT));
289 if (context->context.lcPktData & PK_SERIAL_NUMBER)
290 ptr+=CopyTabletData(ptr,&wtp->pkChanged,sizeof(UINT));
291 if (context->context.lcPktData & PK_CURSOR)
292 ptr+=CopyTabletData(ptr,&wtp->pkCursor,sizeof(UINT));
293 if (context->context.lcPktData & PK_BUTTONS)
294 ptr+=CopyTabletData(ptr,&wtp->pkButtons,sizeof(DWORD));
295 if (context->context.lcPktData & PK_X)
296 ptr+=CopyTabletData(ptr,&wtp->pkX,sizeof(DWORD));
297 if (context->context.lcPktData & PK_Y)
298 ptr+=CopyTabletData(ptr,&wtp->pkY,sizeof(DWORD));
299 if (context->context.lcPktData & PK_Z)
300 ptr+=CopyTabletData(ptr,&wtp->pkZ,sizeof(DWORD));
301 if (context->context.lcPktData & PK_NORMAL_PRESSURE)
302 ptr+=CopyTabletData(ptr,&wtp->pkNormalPressure,sizeof(UINT));
303 if (context->context.lcPktData & PK_TANGENT_PRESSURE)
304 ptr+=CopyTabletData(ptr,&wtp->pkTangentPressure,sizeof(UINT));
305 if (context->context.lcPktData & PK_ORIENTATION)
306 ptr+=CopyTabletData(ptr,&wtp->pkOrientation,sizeof(ORIENTATION));
307 if (context->context.lcPktData & PK_ROTATION)
308 ptr+=CopyTabletData(ptr,&wtp->pkRotation,sizeof(ROTATION));
310 /*TRACE("Copied %i bytes\n",(INT)ptr - (INT)lpPkt); */
311 return ptr;
314 static VOID TABLET_BlankPacketData(LPOPENCONTEXT context, LPVOID lpPkt, INT n)
316 int rc = 0;
318 if (context->context.lcPktData & PK_CONTEXT)
319 rc +=sizeof(HCTX);
320 if (context->context.lcPktData & PK_STATUS)
321 rc +=sizeof(UINT);
322 if (context->context.lcPktData & PK_TIME)
323 rc += sizeof(LONG);
324 if (context->context.lcPktData & PK_CHANGED)
325 rc += sizeof(WTPKT);
326 if (context->context.lcPktData & PK_SERIAL_NUMBER)
327 rc += sizeof(UINT);
328 if (context->context.lcPktData & PK_CURSOR)
329 rc += sizeof(UINT);
330 if (context->context.lcPktData & PK_BUTTONS)
331 rc += sizeof(DWORD);
332 if (context->context.lcPktData & PK_X)
333 rc += sizeof(DWORD);
334 if (context->context.lcPktData & PK_Y)
335 rc += sizeof(DWORD);
336 if (context->context.lcPktData & PK_Z)
337 rc += sizeof(DWORD);
338 if (context->context.lcPktData & PK_NORMAL_PRESSURE)
339 rc += sizeof(UINT);
340 if (context->context.lcPktData & PK_TANGENT_PRESSURE)
341 rc += sizeof(UINT);
342 if (context->context.lcPktData & PK_ORIENTATION)
343 rc += sizeof(ORIENTATION);
344 if (context->context.lcPktData & PK_ROTATION)
345 rc += sizeof(ROTATION);
347 rc *= n;
348 memset(lpPkt,0,rc);
352 UINT WINAPI WTInfoT(UINT wCategory, UINT nIndex, LPVOID lpOutput, BOOL bUnicode)
354 UINT result;
356 TRACE("(%d, %d, %p, %d)\n", wCategory, nIndex, lpOutput, bUnicode);
357 if (gLoaded == FALSE)
358 LoadTablet();
361 * Handle system extents here, as we can use user32.dll code to set them.
363 if(wCategory == WTI_DEFSYSCTX)
365 switch(nIndex)
367 case CTX_SYSEXTX:
368 if(lpOutput != NULL)
369 *(LONG*)lpOutput = GetSystemMetrics(SM_CXSCREEN);
370 return sizeof(LONG);
371 case CTX_SYSEXTY:
372 if(lpOutput != NULL)
373 *(LONG*)lpOutput = GetSystemMetrics(SM_CYSCREEN);
374 return sizeof(LONG);
375 /* No action, delegate to X11Drv */
379 if (is_logcontext_category(wCategory) && nIndex == 0)
381 if (lpOutput)
383 LOGCONTEXTW buf;
384 pWTInfoW(wCategory, nIndex, &buf);
386 /* Handle system extents here, as we can use user32.dll code to set them */
387 if(wCategory == WTI_DEFSYSCTX && nIndex == 0)
389 buf.lcSysExtX = GetSystemMetrics(SM_CXSCREEN);
390 buf.lcSysExtY = GetSystemMetrics(SM_CYSCREEN);
393 if (bUnicode)
394 memcpy(lpOutput, &buf, sizeof(buf));
395 else
396 LOGCONTEXTWtoA(&buf, lpOutput);
399 result = bUnicode ? sizeof(LOGCONTEXTW) : sizeof(LOGCONTEXTA);
401 else if (is_string_field(wCategory, nIndex) && !bUnicode)
403 int size = pWTInfoW(wCategory, nIndex, NULL);
404 WCHAR *buf = HeapAlloc(GetProcessHeap(), 0, size);
405 pWTInfoW(wCategory, nIndex, buf);
406 result = WideCharToMultiByte(CP_ACP, 0, buf, size/sizeof(WCHAR), lpOutput, lpOutput ? 2*size : 0, NULL, NULL);
407 HeapFree(GetProcessHeap(), 0, buf);
409 else
410 result = pWTInfoW(wCategory, nIndex, lpOutput);
412 TRACE("returns %d\n", result);
413 return result;
416 /***********************************************************************
417 * WTInfoA (WINTAB32.20)
419 UINT WINAPI WTInfoA(UINT wCategory, UINT nIndex, LPVOID lpOutput)
421 return WTInfoT(wCategory, nIndex, lpOutput, FALSE);
425 /***********************************************************************
426 * WTInfoW (WINTAB32.1020)
428 UINT WINAPI WTInfoW(UINT wCategory, UINT nIndex, LPVOID lpOutput)
430 return WTInfoT(wCategory, nIndex, lpOutput, TRUE);
433 /***********************************************************************
434 * WTOpenW (WINTAB32.2021)
436 HCTX WINAPI WTOpenW(HWND hWnd, LPLOGCONTEXTW lpLogCtx, BOOL fEnable)
438 LPOPENCONTEXT newcontext;
440 TRACE("(%p, %p, %u)\n", hWnd, lpLogCtx, fEnable);
441 DUMPCONTEXT(*lpLogCtx);
443 newcontext = HeapAlloc(GetProcessHeap(), 0 , sizeof(OPENCONTEXT));
444 memcpy(&(newcontext->context),lpLogCtx,sizeof(LOGCONTEXTW));
445 newcontext->hwndOwner = hWnd;
446 newcontext->enabled = fEnable;
447 newcontext->ActiveCursor = -1;
448 newcontext->QueueSize = 10;
449 newcontext->PacketsQueued = 0;
450 newcontext->PacketQueue=HeapAlloc(GetProcessHeap(),0,sizeof(WTPACKET)*10);
452 EnterCriticalSection(&csTablet);
453 newcontext->handle = gTopContext++;
454 newcontext->next = gOpenContexts;
455 gOpenContexts = newcontext;
456 LeaveCriticalSection(&csTablet);
458 pAttachEventQueueToTablet(hWnd);
460 TABLET_PostTabletMessage(newcontext, _WT_CTXOPEN(newcontext->context.lcMsgBase), (WPARAM)newcontext->handle,
461 newcontext->context.lcStatus, TRUE);
463 newcontext->context.lcStatus = CXS_ONTOP;
465 TABLET_PostTabletMessage(newcontext, _WT_CTXOVERLAP(newcontext->context.lcMsgBase),
466 (WPARAM)newcontext->handle,
467 newcontext->context.lcStatus, TRUE);
469 return newcontext->handle;
472 /***********************************************************************
473 * WTOpenA (WINTAB32.21)
475 HCTX WINAPI WTOpenA(HWND hWnd, LPLOGCONTEXTA lpLogCtx, BOOL fEnable)
477 LOGCONTEXTW logCtxW;
479 LOGCONTEXTAtoW(lpLogCtx, &logCtxW);
480 return WTOpenW(hWnd, &logCtxW, fEnable);
483 /***********************************************************************
484 * WTClose (WINTAB32.22)
486 BOOL WINAPI WTClose(HCTX hCtx)
488 LPOPENCONTEXT context,ptr;
490 TRACE("(%p)\n", hCtx);
492 EnterCriticalSection(&csTablet);
494 ptr = context = gOpenContexts;
496 while (context && (context->handle != hCtx))
498 ptr = context;
499 context = context->next;
501 if (!context)
503 LeaveCriticalSection(&csTablet);
504 return TRUE;
507 if (context == gOpenContexts)
508 gOpenContexts = context->next;
509 else
510 ptr->next = context->next;
512 LeaveCriticalSection(&csTablet);
514 TABLET_PostTabletMessage(context, _WT_CTXCLOSE(context->context.lcMsgBase), (WPARAM)context->handle,
515 context->context.lcStatus,TRUE);
517 HeapFree(GetProcessHeap(),0,context->PacketQueue);
518 HeapFree(GetProcessHeap(),0,context);
520 return TRUE;
523 /***********************************************************************
524 * WTPacketsGet (WINTAB32.23)
526 int WINAPI WTPacketsGet(HCTX hCtx, int cMaxPkts, LPVOID lpPkts)
528 int limit;
529 LPOPENCONTEXT context;
530 LPVOID ptr = lpPkts;
532 TRACE("(%p, %d, %p)\n", hCtx, cMaxPkts, lpPkts);
534 if (!hCtx)
535 return 0;
537 EnterCriticalSection(&csTablet);
539 context = TABLET_FindOpenContext(hCtx);
541 if (lpPkts != NULL)
542 TABLET_BlankPacketData(context,lpPkts,cMaxPkts);
544 if (context->PacketsQueued == 0)
546 LeaveCriticalSection(&csTablet);
547 return 0;
550 limit = min(cMaxPkts,context->PacketsQueued);
552 if(ptr != NULL)
554 int i = 0;
555 for(i = 0; i < limit; i++)
556 ptr=TABLET_CopyPacketData(context ,ptr, &context->PacketQueue[i]);
560 if (limit < context->PacketsQueued)
562 memmove(context->PacketQueue, &context->PacketQueue[limit],
563 (context->PacketsQueued - (limit))*sizeof(WTPACKET));
565 context->PacketsQueued -= limit;
566 LeaveCriticalSection(&csTablet);
568 TRACE("Copied %i packets\n",limit);
570 return limit;
573 /***********************************************************************
574 * WTPacket (WINTAB32.24)
576 BOOL WINAPI WTPacket(HCTX hCtx, UINT wSerial, LPVOID lpPkt)
578 int rc = 0;
579 LPOPENCONTEXT context;
580 LPWTPACKET wtp = NULL;
582 TRACE("(%p, %d, %p)\n", hCtx, wSerial, lpPkt);
584 if (!hCtx)
585 return 0;
587 EnterCriticalSection(&csTablet);
589 context = TABLET_FindOpenContext(hCtx);
591 rc = TABLET_FindPacket(context ,wSerial, &wtp);
593 if (rc >= 0)
595 if (lpPkt)
596 TABLET_CopyPacketData(context ,lpPkt, wtp);
598 if ((rc+1) < context->QueueSize)
600 memmove(context->PacketQueue, &context->PacketQueue[rc+1],
601 (context->PacketsQueued - (rc+1))*sizeof(WTPACKET));
603 context->PacketsQueued -= (rc+1);
605 LeaveCriticalSection(&csTablet);
607 TRACE("Returning %i\n",rc+1);
608 return rc+1;
611 /***********************************************************************
612 * WTEnable (WINTAB32.40)
614 BOOL WINAPI WTEnable(HCTX hCtx, BOOL fEnable)
616 LPOPENCONTEXT context;
618 TRACE("(%p, %u)\n", hCtx, fEnable);
620 if (!hCtx) return 0;
622 EnterCriticalSection(&csTablet);
623 context = TABLET_FindOpenContext(hCtx);
624 if(!fEnable)
625 TABLET_FlushQueue(context);
626 context->enabled = fEnable;
627 LeaveCriticalSection(&csTablet);
629 return TRUE;
632 /***********************************************************************
633 * WTOverlap (WINTAB32.41)
635 BOOL WINAPI WTOverlap(HCTX hCtx, BOOL fToTop)
637 FIXME("(%p, %u): stub\n", hCtx, fToTop);
639 return TRUE;
642 /***********************************************************************
643 * WTConfig (WINTAB32.61)
645 BOOL WINAPI WTConfig(HCTX hCtx, HWND hWnd)
647 FIXME("(%p, %p): stub\n", hCtx, hWnd);
649 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
651 return FALSE;
654 /***********************************************************************
655 * WTGetA (WINTAB32.61)
657 BOOL WINAPI WTGetA(HCTX hCtx, LPLOGCONTEXTA lpLogCtx)
659 LPOPENCONTEXT context;
661 TRACE("(%p, %p)\n", hCtx, lpLogCtx);
663 if (!hCtx) return 0;
665 EnterCriticalSection(&csTablet);
666 context = TABLET_FindOpenContext(hCtx);
667 LOGCONTEXTWtoA(&context->context, lpLogCtx);
668 LeaveCriticalSection(&csTablet);
670 return TRUE;
673 /***********************************************************************
674 * WTGetW (WINTAB32.1061)
676 BOOL WINAPI WTGetW(HCTX hCtx, LPLOGCONTEXTW lpLogCtx)
678 LPOPENCONTEXT context;
680 TRACE("(%p, %p)\n", hCtx, lpLogCtx);
682 if (!hCtx) return 0;
684 EnterCriticalSection(&csTablet);
685 context = TABLET_FindOpenContext(hCtx);
686 memmove(lpLogCtx,&context->context,sizeof(LOGCONTEXTW));
687 LeaveCriticalSection(&csTablet);
689 return TRUE;
692 /***********************************************************************
693 * WTSetA (WINTAB32.62)
695 BOOL WINAPI WTSetA(HCTX hCtx, LPLOGCONTEXTA lpLogCtx)
697 FIXME("(%p, %p): stub\n", hCtx, lpLogCtx);
699 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
701 return FALSE;
704 /***********************************************************************
705 * WTSetW (WINTAB32.1062)
707 BOOL WINAPI WTSetW(HCTX hCtx, LPLOGCONTEXTW lpLogCtx)
709 FIXME("(%p, %p): stub\n", hCtx, lpLogCtx);
711 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
713 return FALSE;
716 /***********************************************************************
717 * WTExtGet (WINTAB32.63)
719 BOOL WINAPI WTExtGet(HCTX hCtx, UINT wExt, LPVOID lpData)
721 FIXME("(%p, %u, %p): stub\n", hCtx, wExt, lpData);
723 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
725 return FALSE;
728 /***********************************************************************
729 * WTExtSet (WINTAB32.64)
731 BOOL WINAPI WTExtSet(HCTX hCtx, UINT wExt, LPVOID lpData)
733 FIXME("(%p, %u, %p): stub\n", hCtx, wExt, lpData);
735 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
737 return FALSE;
740 /***********************************************************************
741 * WTSave (WINTAB32.65)
743 BOOL WINAPI WTSave(HCTX hCtx, LPVOID lpSaveInfo)
745 FIXME("(%p, %p): stub\n", hCtx, lpSaveInfo);
747 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
749 return FALSE;
752 /***********************************************************************
753 * WTRestore (WINTAB32.66)
755 HCTX WINAPI WTRestore(HWND hWnd, LPVOID lpSaveInfo, BOOL fEnable)
757 FIXME("(%p, %p, %u): stub\n", hWnd, lpSaveInfo, fEnable);
759 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
761 return 0;
764 /***********************************************************************
765 * WTPacketsPeek (WINTAB32.80)
767 int WINAPI WTPacketsPeek(HCTX hCtx, int cMaxPkts, LPVOID lpPkts)
769 int limit;
770 LPOPENCONTEXT context;
771 LPVOID ptr = lpPkts;
773 TRACE("(%p, %d, %p)\n", hCtx, cMaxPkts, lpPkts);
775 if (!hCtx || !lpPkts) return 0;
777 EnterCriticalSection(&csTablet);
779 context = TABLET_FindOpenContext(hCtx);
781 if (context->PacketsQueued == 0)
783 LeaveCriticalSection(&csTablet);
784 return 0;
787 for (limit = 0; limit < cMaxPkts && limit < context->PacketsQueued; limit++)
788 ptr = TABLET_CopyPacketData(context ,ptr, &context->PacketQueue[limit]);
790 LeaveCriticalSection(&csTablet);
791 TRACE("Copied %i packets\n",limit);
792 return limit;
795 /***********************************************************************
796 * WTDataGet (WINTAB32.81)
798 int WINAPI WTDataGet(HCTX hCtx, UINT wBegin, UINT wEnd,
799 int cMaxPkts, LPVOID lpPkts, LPINT lpNPkts)
801 LPOPENCONTEXT context;
802 LPVOID ptr = lpPkts;
803 INT bgn = 0;
804 INT end = 0;
805 INT num = 0;
807 TRACE("(%p, %u, %u, %d, %p, %p)\n",
808 hCtx, wBegin, wEnd, cMaxPkts, lpPkts, lpNPkts);
810 if (!hCtx) return 0;
812 EnterCriticalSection(&csTablet);
814 context = TABLET_FindOpenContext(hCtx);
816 if (context->PacketsQueued == 0)
818 LeaveCriticalSection(&csTablet);
819 return 0;
822 while (bgn < context->PacketsQueued &&
823 context->PacketQueue[bgn].pkSerialNumber != wBegin)
824 bgn++;
826 end = bgn;
827 while (end < context->PacketsQueued &&
828 context->PacketQueue[end].pkSerialNumber != wEnd)
829 end++;
831 if ((bgn == end) && (end == context->PacketsQueued))
833 LeaveCriticalSection(&csTablet);
834 return 0;
837 for (num = bgn; num <= end; num++)
838 ptr = TABLET_CopyPacketData(context ,ptr, &context->PacketQueue[num]);
840 /* remove read packets */
841 if ((end+1) < context->PacketsQueued)
842 memmove( &context->PacketQueue[bgn], &context->PacketQueue[end+1],
843 (context->PacketsQueued - (end+1)) * sizeof (WTPACKET));
845 context->PacketsQueued -= ((end-bgn)+1);
846 *lpNPkts = ((end-bgn)+1);
848 LeaveCriticalSection(&csTablet);
849 TRACE("Copied %i packets\n",*lpNPkts);
850 return (end - bgn)+1;
853 /***********************************************************************
854 * WTDataPeek (WINTAB32.82)
856 int WINAPI WTDataPeek(HCTX hCtx, UINT wBegin, UINT wEnd,
857 int cMaxPkts, LPVOID lpPkts, LPINT lpNPkts)
859 LPOPENCONTEXT context;
860 LPVOID ptr = lpPkts;
861 INT bgn = 0;
862 INT end = 0;
863 INT num = 0;
865 TRACE("(%p, %u, %u, %d, %p, %p)\n",
866 hCtx, wBegin, wEnd, cMaxPkts, lpPkts, lpNPkts);
868 if (!hCtx || !lpPkts) return 0;
870 EnterCriticalSection(&csTablet);
872 context = TABLET_FindOpenContext(hCtx);
874 if (context->PacketsQueued == 0)
876 LeaveCriticalSection(&csTablet);
877 return 0;
880 while (bgn < context->PacketsQueued &&
881 context->PacketQueue[bgn].pkSerialNumber != wBegin)
882 bgn++;
884 end = bgn;
885 while (end < context->PacketsQueued &&
886 context->PacketQueue[end].pkSerialNumber != wEnd)
887 end++;
889 if (bgn == context->PacketsQueued || end == context->PacketsQueued)
891 TRACE("%i %i %i\n", bgn, end, context->PacketsQueued);
892 LeaveCriticalSection(&csTablet);
893 return 0;
896 for (num = bgn; num <= end; num++)
897 ptr = TABLET_CopyPacketData(context ,ptr, &context->PacketQueue[num]);
899 *lpNPkts = ((end-bgn)+1);
900 LeaveCriticalSection(&csTablet);
902 TRACE("Copied %i packets\n",*lpNPkts);
903 return (end - bgn)+1;
906 /***********************************************************************
907 * WTQueuePacketsEx (WINTAB32.200)
909 BOOL WINAPI WTQueuePacketsEx(HCTX hCtx, UINT *lpOld, UINT *lpNew)
911 LPOPENCONTEXT context;
913 TRACE("(%p, %p, %p)\n", hCtx, lpOld, lpNew);
915 if (!hCtx) return 0;
917 EnterCriticalSection(&csTablet);
919 context = TABLET_FindOpenContext(hCtx);
921 if (context->PacketsQueued)
923 *lpOld = context->PacketQueue[0].pkSerialNumber;
924 *lpNew = context->PacketQueue[context->PacketsQueued-1].pkSerialNumber;
926 else
928 TRACE("No packets\n");
929 LeaveCriticalSection(&csTablet);
930 return FALSE;
932 LeaveCriticalSection(&csTablet);
934 return TRUE;
937 /***********************************************************************
938 * WTQueueSizeGet (WINTAB32.84)
940 int WINAPI WTQueueSizeGet(HCTX hCtx)
942 LPOPENCONTEXT context;
943 TRACE("(%p)\n", hCtx);
945 if (!hCtx) return 0;
947 EnterCriticalSection(&csTablet);
948 context = TABLET_FindOpenContext(hCtx);
949 LeaveCriticalSection(&csTablet);
950 return context->QueueSize;
953 /***********************************************************************
954 * WTQueueSizeSet (WINTAB32.85)
956 BOOL WINAPI WTQueueSizeSet(HCTX hCtx, int nPkts)
958 LPOPENCONTEXT context;
960 TRACE("(%p, %d)\n", hCtx, nPkts);
962 if (!hCtx) return 0;
964 EnterCriticalSection(&csTablet);
966 context = TABLET_FindOpenContext(hCtx);
968 context->PacketQueue = HeapReAlloc(GetProcessHeap(), 0,
969 context->PacketQueue, sizeof(WTPACKET)*nPkts);
971 context->QueueSize = nPkts;
972 LeaveCriticalSection(&csTablet);
974 return nPkts;