shell32: Localize 'new folder' string.
[wine/wine-kai.git] / dlls / wintab32 / context.c
blobcb85e08a33bcf982b99c260e4d26fd4407d7c923
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 return TRUE;
78 if (wCategory == WTI_DEVICES && (nIndex == DVC_NAME || nIndex == DVC_PNPID))
79 return TRUE;
80 return FALSE;
83 static char* DUMPBITS(int x, char* buf)
85 strcpy(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 ");
100 strcat(buf, "}");
101 return buf;
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",
107 packet.pkContext,
108 (UINT)packet.pkStatus,
109 (UINT)packet.pkTime,
110 (UINT)packet.pkChanged,
111 packet.pkSerialNumber,
112 packet.pkCursor,
113 (UINT)packet.pkButtons,
114 packet.pkX,
115 packet.pkY,
116 packet.pkZ,
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)
127 CHAR mmsg[4000];
128 CHAR bits[100];
129 CHAR bits1[100];
130 CHAR bits2[100];
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,
141 lc.lcSysSensY);
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;
150 while (ptr)
152 if (ptr->handle == hCtx) return ptr;
153 ptr = ptr->next;
155 return NULL;
158 static void LoadTablet(void)
160 TRACE("Initializing the tablet to hwnd %p\n",hwndDefault);
161 gLoaded= TRUE;
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);
173 return 0;
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;
181 else
182 return ((abs(InExt) - (In - InOrg))*abs(OutExt) / abs(InExt)) + OutOrg;
185 LPOPENCONTEXT FindOpenContext(HWND hwnd)
187 LPOPENCONTEXT ptr;
189 EnterCriticalSection(&csTablet);
190 ptr = gOpenContexts;
191 while (ptr)
193 TRACE("Trying Context %p (%p %p)\n",ptr->handle,hwnd,ptr->hwndOwner);
194 if (ptr->hwndOwner == hwnd) break;
196 LeaveCriticalSection(&csTablet);
197 return ptr;
200 LPOPENCONTEXT AddPacketToContextQueue(LPWTPACKET packet, HWND hwnd)
202 LPOPENCONTEXT ptr=NULL;
204 EnterCriticalSection(&csTablet);
206 ptr = gOpenContexts;
207 while (ptr)
209 TRACE("Trying Queue %p (%p %p)\n", ptr->handle, hwnd, ptr->hwndOwner);
211 if (ptr->hwndOwner == hwnd)
213 int tgt;
214 if (!ptr->enabled)
216 ptr = ptr->next;
217 continue;
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;
239 DUMPPACKET(*packet);
241 if (tgt == ptr->QueueSize)
243 TRACE("Queue Overflow %p\n",ptr->handle);
244 ptr->PacketQueue[tgt-1].pkStatus |= TPS_QUEUE_ERR;
246 else
248 TRACE("Placed in queue %p index %i\n",ptr->handle,tgt);
249 memcpy(&ptr->PacketQueue[tgt], packet, sizeof
250 (WTPACKET));
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,
259 FALSE);
262 break;
264 ptr = ptr->next;
266 LeaveCriticalSection(&csTablet);
267 TRACE("Done (%p)\n",ptr);
268 return 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);
282 return(size);
285 static INT TABLET_FindPacket(LPOPENCONTEXT context, UINT wSerial,
286 LPWTPACKET *pkt)
288 int loop;
289 int index = -1;
290 for (loop = 0; loop < context->PacketsQueued; loop++)
291 if (context->PacketQueue[loop].pkSerialNumber == wSerial)
293 index = loop;
294 *pkt = &context->PacketQueue[loop];
295 break;
298 TRACE("%i .. %i\n",context->PacketsQueued,index);
300 return index;
304 static LPVOID TABLET_CopyPacketData(LPOPENCONTEXT context, LPVOID lpPkt,
305 LPWTPACKET wtp)
307 LPBYTE ptr;
308 CHAR bits[100];
310 ptr = 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); */
343 return ptr;
346 static VOID TABLET_BlankPacketData(LPOPENCONTEXT context, LPVOID lpPkt, INT n)
348 int rc = 0;
350 if (context->context.lcPktData & PK_CONTEXT)
351 rc +=sizeof(HCTX);
352 if (context->context.lcPktData & PK_STATUS)
353 rc +=sizeof(UINT);
354 if (context->context.lcPktData & PK_TIME)
355 rc += sizeof(LONG);
356 if (context->context.lcPktData & PK_CHANGED)
357 rc += sizeof(WTPKT);
358 if (context->context.lcPktData & PK_SERIAL_NUMBER)
359 rc += sizeof(UINT);
360 if (context->context.lcPktData & PK_CURSOR)
361 rc += sizeof(UINT);
362 if (context->context.lcPktData & PK_BUTTONS)
363 rc += sizeof(DWORD);
364 if (context->context.lcPktData & PK_X)
365 rc += sizeof(DWORD);
366 if (context->context.lcPktData & PK_Y)
367 rc += sizeof(DWORD);
368 if (context->context.lcPktData & PK_Z)
369 rc += sizeof(DWORD);
370 if (context->context.lcPktData & PK_NORMAL_PRESSURE)
371 rc += sizeof(UINT);
372 if (context->context.lcPktData & PK_TANGENT_PRESSURE)
373 rc += sizeof(UINT);
374 if (context->context.lcPktData & PK_ORIENTATION)
375 rc += sizeof(ORIENTATION);
376 if (context->context.lcPktData & PK_ROTATION)
377 rc += sizeof(ROTATION);
379 rc *= n;
380 memset(lpPkt,0,rc);
384 UINT WINAPI WTInfoT(UINT wCategory, UINT nIndex, LPVOID lpOutput, BOOL bUnicode)
386 UINT result;
387 if (gLoaded == FALSE)
388 LoadTablet();
391 * Handle system extents here, as we can use user32.dll code to set them.
393 if(wCategory == WTI_DEFSYSCTX)
395 switch(nIndex)
397 case CTX_SYSEXTX:
398 if(lpOutput != NULL)
399 *(LONG*)lpOutput = GetSystemMetrics(SM_CXSCREEN);
400 return sizeof(LONG);
401 case CTX_SYSEXTY:
402 if(lpOutput != NULL)
403 *(LONG*)lpOutput = GetSystemMetrics(SM_CYSCREEN);
404 return sizeof(LONG);
405 /* No action, delegate to X11Drv */
409 if (is_logcontext_category(wCategory) && nIndex == 0)
411 if (lpOutput)
413 LOGCONTEXTW buf;
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);
423 if (bUnicode)
424 memcpy(lpOutput, &buf, sizeof(buf));
425 else
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);
439 else
440 result = pWTInfoW(wCategory, nIndex, lpOutput);
442 return result;
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)
506 LOGCONTEXTW logCtxW;
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))
527 ptr = context;
528 context = context->next;
530 if (!context)
532 LeaveCriticalSection(&csTablet);
533 return TRUE;
536 if (context == gOpenContexts)
537 gOpenContexts = context->next;
538 else
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);
549 return TRUE;
552 /***********************************************************************
553 * WTPacketsGet (WINTAB32.23)
555 int WINAPI WTPacketsGet(HCTX hCtx, int cMaxPkts, LPVOID lpPkts)
557 int limit;
558 LPOPENCONTEXT context;
559 LPVOID ptr = lpPkts;
561 TRACE("(%p, %d, %p)\n", hCtx, cMaxPkts, lpPkts);
563 if (!hCtx)
564 return 0;
566 EnterCriticalSection(&csTablet);
568 context = TABLET_FindOpenContext(hCtx);
570 if (lpPkts != NULL)
571 TABLET_BlankPacketData(context,lpPkts,cMaxPkts);
573 if (context->PacketsQueued == 0)
575 LeaveCriticalSection(&csTablet);
576 return 0;
579 limit = min(cMaxPkts,context->PacketsQueued);
581 if(ptr != NULL)
583 int i = 0;
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);
599 return limit;
602 /***********************************************************************
603 * WTPacket (WINTAB32.24)
605 BOOL WINAPI WTPacket(HCTX hCtx, UINT wSerial, LPVOID lpPkt)
607 int rc = 0;
608 LPOPENCONTEXT context;
609 LPWTPACKET wtp = NULL;
611 TRACE("(%p, %d, %p)\n", hCtx, wSerial, lpPkt);
613 if (!hCtx)
614 return 0;
616 EnterCriticalSection(&csTablet);
618 context = TABLET_FindOpenContext(hCtx);
620 rc = TABLET_FindPacket(context ,wSerial, &wtp);
622 if (rc >= 0)
624 if (lpPkt)
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);
637 return 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);
649 if (!hCtx) return 0;
651 EnterCriticalSection(&csTablet);
652 context = TABLET_FindOpenContext(hCtx);
653 if(!fEnable)
654 TABLET_FlushQueue(context);
655 context->enabled = fEnable;
656 LeaveCriticalSection(&csTablet);
658 return TRUE;
661 /***********************************************************************
662 * WTOverlap (WINTAB32.41)
664 BOOL WINAPI WTOverlap(HCTX hCtx, BOOL fToTop)
666 FIXME("(%p, %u): stub\n", hCtx, fToTop);
668 return TRUE;
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);
680 return FALSE;
683 /***********************************************************************
684 * WTGetA (WINTAB32.61)
686 BOOL WINAPI WTGetA(HCTX hCtx, LPLOGCONTEXTA lpLogCtx)
688 LPOPENCONTEXT context;
690 TRACE("(%p, %p)\n", hCtx, lpLogCtx);
692 if (!hCtx) return 0;
694 EnterCriticalSection(&csTablet);
695 context = TABLET_FindOpenContext(hCtx);
696 LOGCONTEXTWtoA(&context->context, lpLogCtx);
697 LeaveCriticalSection(&csTablet);
699 return TRUE;
702 /***********************************************************************
703 * WTGetW (WINTAB32.1061)
705 BOOL WINAPI WTGetW(HCTX hCtx, LPLOGCONTEXTW lpLogCtx)
707 LPOPENCONTEXT context;
709 TRACE("(%p, %p)\n", hCtx, lpLogCtx);
711 if (!hCtx) return 0;
713 EnterCriticalSection(&csTablet);
714 context = TABLET_FindOpenContext(hCtx);
715 memmove(lpLogCtx,&context->context,sizeof(LOGCONTEXTW));
716 LeaveCriticalSection(&csTablet);
718 return TRUE;
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);
730 return FALSE;
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);
742 return FALSE;
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);
754 return FALSE;
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);
766 return FALSE;
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);
778 return FALSE;
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);
790 return 0;
793 /***********************************************************************
794 * WTPacketsPeek (WINTAB32.80)
796 int WINAPI WTPacketsPeek(HCTX hCtx, int cMaxPkts, LPVOID lpPkts)
798 int limit;
799 LPOPENCONTEXT context;
800 LPVOID ptr = lpPkts;
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);
813 return 0;
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);
821 return 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;
831 LPVOID ptr = lpPkts;
832 INT bgn = 0;
833 INT end = 0;
834 INT num = 0;
836 TRACE("(%p, %u, %u, %d, %p, %p)\n",
837 hCtx, wBegin, wEnd, cMaxPkts, lpPkts, lpNPkts);
839 if (!hCtx) return 0;
841 EnterCriticalSection(&csTablet);
843 context = TABLET_FindOpenContext(hCtx);
845 if (context->PacketsQueued == 0)
847 LeaveCriticalSection(&csTablet);
848 return 0;
851 while (bgn < context->PacketsQueued &&
852 context->PacketQueue[bgn].pkSerialNumber != wBegin)
853 bgn++;
855 end = bgn;
856 while (end < context->PacketsQueued &&
857 context->PacketQueue[end].pkSerialNumber != wEnd)
858 end++;
860 if ((bgn == end) && (end == context->PacketsQueued))
862 LeaveCriticalSection(&csTablet);
863 return 0;
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;
889 LPVOID ptr = lpPkts;
890 INT bgn = 0;
891 INT end = 0;
892 INT num = 0;
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);
906 return 0;
909 while (bgn < context->PacketsQueued &&
910 context->PacketQueue[bgn].pkSerialNumber != wBegin)
911 bgn++;
913 end = bgn;
914 while (end < context->PacketsQueued &&
915 context->PacketQueue[end].pkSerialNumber != wEnd)
916 end++;
918 if (bgn == context->PacketsQueued || end == context->PacketsQueued)
920 TRACE("%i %i %i\n", bgn, end, context->PacketsQueued);
921 LeaveCriticalSection(&csTablet);
922 return 0;
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);
944 if (!hCtx) return 0;
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;
955 else
957 TRACE("No packets\n");
958 LeaveCriticalSection(&csTablet);
959 return FALSE;
961 LeaveCriticalSection(&csTablet);
963 return TRUE;
966 /***********************************************************************
967 * WTQueueSizeGet (WINTAB32.84)
969 int WINAPI WTQueueSizeGet(HCTX hCtx)
971 LPOPENCONTEXT context;
972 TRACE("(%p)\n", hCtx);
974 if (!hCtx) return 0;
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);
991 if (!hCtx) return 0;
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);
1003 return nPkts;