qmgr: Implement job lists for IBackgroundCopyManager.
[wine/gsoc_dplay.git] / dlls / wintab32 / context.c
blob9c4c262337c2349f45664c92c5310b82ec6e8cf1
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, LONG InOrg, LONG InExt, LONG OutOrg, LONG OutExt)
162 if (((InExt > 0 )&&(OutExt > 0)) || ((InExt<0) && (OutExt < 0)))
163 return ((In - InOrg) * abs(OutExt) / abs(InExt)) + OutOrg;
164 else
165 return ((abs(InExt) - (In - InOrg))*abs(OutExt) / abs(InExt)) + OutOrg;
168 LPOPENCONTEXT AddPacketToContextQueue(LPWTPACKET packet, HWND hwnd)
170 LPOPENCONTEXT ptr=NULL;
172 EnterCriticalSection(&csTablet);
174 ptr = gOpenContexts;
175 while (ptr)
177 TRACE("Trying Queue %p (%p %p)\n", ptr->handle, hwnd, ptr->hwndOwner);
179 if (ptr->hwndOwner == hwnd)
181 int tgt;
182 if (!ptr->enabled)
184 ptr = ptr->next;
185 continue;
188 tgt = ptr->PacketsQueued;
190 packet->pkContext = ptr->handle;
192 /* translate packet data to the context */
194 /* Scale as per documentation */
195 packet->pkY = ScaleForContext(packet->pkY, ptr->context.lcInOrgY,
196 ptr->context.lcInExtY, ptr->context.lcOutOrgY,
197 ptr->context.lcOutExtY);
199 packet->pkX = ScaleForContext(packet->pkX, ptr->context.lcInOrgX,
200 ptr->context.lcInExtX, ptr->context.lcOutOrgX,
201 ptr->context.lcOutExtX);
203 /* flip the Y axis */
204 if (ptr->context.lcOutExtY > 0)
205 packet->pkY = ptr->context.lcOutExtY - packet->pkY;
207 DUMPPACKET(*packet);
209 if (tgt == ptr->QueueSize)
211 TRACE("Queue Overflow %p\n",ptr->handle);
212 ptr->PacketQueue[tgt-1].pkStatus |= TPS_QUEUE_ERR;
214 else
216 TRACE("Placed in queue %p index %i\n",ptr->handle,tgt);
217 memcpy(&ptr->PacketQueue[tgt], packet, sizeof
218 (WTPACKET));
219 ptr->PacketsQueued++;
221 if (ptr->ActiveCursor != packet->pkCursor)
223 ptr->ActiveCursor = packet->pkCursor;
224 if (ptr->context.lcOptions & CXO_CSRMESSAGES)
225 TABLET_PostTabletMessage(ptr, _WT_CSRCHANGE(ptr->context.lcMsgBase),
226 (WPARAM)packet->pkSerialNumber, (LPARAM)ptr->handle,
227 FALSE);
230 break;
232 ptr = ptr->next;
234 LeaveCriticalSection(&csTablet);
235 TRACE("Done (%p)\n",ptr);
236 return ptr;
240 * Flushes all packets from the queue.
242 static inline void TABLET_FlushQueue(LPOPENCONTEXT context)
244 context->PacketsQueued = 0;
247 static inline int CopyTabletData(LPVOID target, LPVOID src, INT size)
249 memcpy(target,src,size);
250 return(size);
253 static INT TABLET_FindPacket(LPOPENCONTEXT context, UINT wSerial,
254 LPWTPACKET *pkt)
256 int loop;
257 int index = -1;
258 for (loop = 0; loop < context->PacketsQueued; loop++)
259 if (context->PacketQueue[loop].pkSerialNumber == wSerial)
261 index = loop;
262 *pkt = &context->PacketQueue[loop];
263 break;
266 TRACE("%i .. %i\n",context->PacketsQueued,index);
268 return index;
272 static LPVOID TABLET_CopyPacketData(LPOPENCONTEXT context, LPVOID lpPkt,
273 LPWTPACKET wtp)
275 LPBYTE ptr;
277 ptr = lpPkt;
278 TRACE("Packet Bits %s\n",DUMPBITS(context->context.lcPktData));
280 if (context->context.lcPktData & PK_CONTEXT)
281 ptr+=CopyTabletData(ptr,&wtp->pkContext,sizeof(HCTX));
282 if (context->context.lcPktData & PK_STATUS)
283 ptr+=CopyTabletData(ptr,&wtp->pkStatus,sizeof(UINT));
284 if (context->context.lcPktData & PK_TIME)
285 ptr+=CopyTabletData(ptr,&wtp->pkTime,sizeof(LONG));
286 if (context->context.lcPktData & PK_CHANGED)
287 ptr+=CopyTabletData(ptr,&wtp->pkChanged,sizeof(WTPKT));
288 if (context->context.lcPktData & PK_SERIAL_NUMBER)
289 ptr+=CopyTabletData(ptr,&wtp->pkChanged,sizeof(UINT));
290 if (context->context.lcPktData & PK_CURSOR)
291 ptr+=CopyTabletData(ptr,&wtp->pkCursor,sizeof(UINT));
292 if (context->context.lcPktData & PK_BUTTONS)
293 ptr+=CopyTabletData(ptr,&wtp->pkButtons,sizeof(DWORD));
294 if (context->context.lcPktData & PK_X)
295 ptr+=CopyTabletData(ptr,&wtp->pkX,sizeof(DWORD));
296 if (context->context.lcPktData & PK_Y)
297 ptr+=CopyTabletData(ptr,&wtp->pkY,sizeof(DWORD));
298 if (context->context.lcPktData & PK_Z)
299 ptr+=CopyTabletData(ptr,&wtp->pkZ,sizeof(DWORD));
300 if (context->context.lcPktData & PK_NORMAL_PRESSURE)
301 ptr+=CopyTabletData(ptr,&wtp->pkNormalPressure,sizeof(UINT));
302 if (context->context.lcPktData & PK_TANGENT_PRESSURE)
303 ptr+=CopyTabletData(ptr,&wtp->pkTangentPressure,sizeof(UINT));
304 if (context->context.lcPktData & PK_ORIENTATION)
305 ptr+=CopyTabletData(ptr,&wtp->pkOrientation,sizeof(ORIENTATION));
306 if (context->context.lcPktData & PK_ROTATION)
307 ptr+=CopyTabletData(ptr,&wtp->pkRotation,sizeof(ROTATION));
309 /*TRACE("Copied %i bytes\n",(INT)ptr - (INT)lpPkt); */
310 return ptr;
313 static VOID TABLET_BlankPacketData(LPOPENCONTEXT context, LPVOID lpPkt, INT n)
315 int rc = 0;
317 if (context->context.lcPktData & PK_CONTEXT)
318 rc +=sizeof(HCTX);
319 if (context->context.lcPktData & PK_STATUS)
320 rc +=sizeof(UINT);
321 if (context->context.lcPktData & PK_TIME)
322 rc += sizeof(LONG);
323 if (context->context.lcPktData & PK_CHANGED)
324 rc += sizeof(WTPKT);
325 if (context->context.lcPktData & PK_SERIAL_NUMBER)
326 rc += sizeof(UINT);
327 if (context->context.lcPktData & PK_CURSOR)
328 rc += sizeof(UINT);
329 if (context->context.lcPktData & PK_BUTTONS)
330 rc += sizeof(DWORD);
331 if (context->context.lcPktData & PK_X)
332 rc += sizeof(DWORD);
333 if (context->context.lcPktData & PK_Y)
334 rc += sizeof(DWORD);
335 if (context->context.lcPktData & PK_Z)
336 rc += sizeof(DWORD);
337 if (context->context.lcPktData & PK_NORMAL_PRESSURE)
338 rc += sizeof(UINT);
339 if (context->context.lcPktData & PK_TANGENT_PRESSURE)
340 rc += sizeof(UINT);
341 if (context->context.lcPktData & PK_ORIENTATION)
342 rc += sizeof(ORIENTATION);
343 if (context->context.lcPktData & PK_ROTATION)
344 rc += sizeof(ROTATION);
346 rc *= n;
347 memset(lpPkt,0,rc);
351 UINT WINAPI WTInfoT(UINT wCategory, UINT nIndex, LPVOID lpOutput, BOOL bUnicode)
353 UINT result;
355 TRACE("(%d, %d, %p, %d)\n", wCategory, nIndex, lpOutput, bUnicode);
356 if (gLoaded == FALSE)
357 LoadTablet();
360 * Handle system extents here, as we can use user32.dll code to set them.
362 if(wCategory == WTI_DEFSYSCTX)
364 switch(nIndex)
366 case CTX_SYSEXTX:
367 if(lpOutput != NULL)
368 *(LONG*)lpOutput = GetSystemMetrics(SM_CXSCREEN);
369 return sizeof(LONG);
370 case CTX_SYSEXTY:
371 if(lpOutput != NULL)
372 *(LONG*)lpOutput = GetSystemMetrics(SM_CYSCREEN);
373 return sizeof(LONG);
374 /* No action, delegate to X11Drv */
378 if (is_logcontext_category(wCategory) && nIndex == 0)
380 if (lpOutput)
382 LOGCONTEXTW buf;
383 pWTInfoW(wCategory, nIndex, &buf);
385 /* Handle system extents here, as we can use user32.dll code to set them */
386 if(wCategory == WTI_DEFSYSCTX && nIndex == 0)
388 buf.lcSysExtX = GetSystemMetrics(SM_CXSCREEN);
389 buf.lcSysExtY = GetSystemMetrics(SM_CYSCREEN);
392 if (bUnicode)
393 memcpy(lpOutput, &buf, sizeof(buf));
394 else
395 LOGCONTEXTWtoA(&buf, lpOutput);
398 result = bUnicode ? sizeof(LOGCONTEXTW) : sizeof(LOGCONTEXTA);
400 else if (is_string_field(wCategory, nIndex) && !bUnicode)
402 int size = pWTInfoW(wCategory, nIndex, NULL);
403 WCHAR *buf = HeapAlloc(GetProcessHeap(), 0, size);
404 pWTInfoW(wCategory, nIndex, buf);
405 result = WideCharToMultiByte(CP_ACP, 0, buf, size/sizeof(WCHAR), lpOutput, lpOutput ? 2*size : 0, NULL, NULL);
406 HeapFree(GetProcessHeap(), 0, buf);
408 else
409 result = pWTInfoW(wCategory, nIndex, lpOutput);
411 TRACE("returns %d\n", result);
412 return result;
415 /***********************************************************************
416 * WTInfoA (WINTAB32.20)
418 UINT WINAPI WTInfoA(UINT wCategory, UINT nIndex, LPVOID lpOutput)
420 return WTInfoT(wCategory, nIndex, lpOutput, FALSE);
424 /***********************************************************************
425 * WTInfoW (WINTAB32.1020)
427 UINT WINAPI WTInfoW(UINT wCategory, UINT nIndex, LPVOID lpOutput)
429 return WTInfoT(wCategory, nIndex, lpOutput, TRUE);
432 /***********************************************************************
433 * WTOpenW (WINTAB32.2021)
435 HCTX WINAPI WTOpenW(HWND hWnd, LPLOGCONTEXTW lpLogCtx, BOOL fEnable)
437 LPOPENCONTEXT newcontext;
439 TRACE("(%p, %p, %u)\n", hWnd, lpLogCtx, fEnable);
440 DUMPCONTEXT(*lpLogCtx);
442 newcontext = HeapAlloc(GetProcessHeap(), 0 , sizeof(OPENCONTEXT));
443 memcpy(&(newcontext->context),lpLogCtx,sizeof(LOGCONTEXTW));
444 newcontext->hwndOwner = hWnd;
445 newcontext->enabled = fEnable;
446 newcontext->ActiveCursor = -1;
447 newcontext->QueueSize = 10;
448 newcontext->PacketsQueued = 0;
449 newcontext->PacketQueue=HeapAlloc(GetProcessHeap(),0,sizeof(WTPACKET)*10);
451 EnterCriticalSection(&csTablet);
452 newcontext->handle = gTopContext++;
453 newcontext->next = gOpenContexts;
454 gOpenContexts = newcontext;
455 LeaveCriticalSection(&csTablet);
457 pAttachEventQueueToTablet(hWnd);
459 TABLET_PostTabletMessage(newcontext, _WT_CTXOPEN(newcontext->context.lcMsgBase), (WPARAM)newcontext->handle,
460 newcontext->context.lcStatus, TRUE);
462 newcontext->context.lcStatus = CXS_ONTOP;
464 TABLET_PostTabletMessage(newcontext, _WT_CTXOVERLAP(newcontext->context.lcMsgBase),
465 (WPARAM)newcontext->handle,
466 newcontext->context.lcStatus, TRUE);
468 return newcontext->handle;
471 /***********************************************************************
472 * WTOpenA (WINTAB32.21)
474 HCTX WINAPI WTOpenA(HWND hWnd, LPLOGCONTEXTA lpLogCtx, BOOL fEnable)
476 LOGCONTEXTW logCtxW;
478 LOGCONTEXTAtoW(lpLogCtx, &logCtxW);
479 return WTOpenW(hWnd, &logCtxW, fEnable);
482 /***********************************************************************
483 * WTClose (WINTAB32.22)
485 BOOL WINAPI WTClose(HCTX hCtx)
487 LPOPENCONTEXT context,ptr;
489 TRACE("(%p)\n", hCtx);
491 EnterCriticalSection(&csTablet);
493 ptr = context = gOpenContexts;
495 while (context && (context->handle != hCtx))
497 ptr = context;
498 context = context->next;
500 if (!context)
502 LeaveCriticalSection(&csTablet);
503 return TRUE;
506 if (context == gOpenContexts)
507 gOpenContexts = context->next;
508 else
509 ptr->next = context->next;
511 LeaveCriticalSection(&csTablet);
513 TABLET_PostTabletMessage(context, _WT_CTXCLOSE(context->context.lcMsgBase), (WPARAM)context->handle,
514 context->context.lcStatus,TRUE);
516 HeapFree(GetProcessHeap(),0,context->PacketQueue);
517 HeapFree(GetProcessHeap(),0,context);
519 return TRUE;
522 /***********************************************************************
523 * WTPacketsGet (WINTAB32.23)
525 int WINAPI WTPacketsGet(HCTX hCtx, int cMaxPkts, LPVOID lpPkts)
527 int limit;
528 LPOPENCONTEXT context;
529 LPVOID ptr = lpPkts;
531 TRACE("(%p, %d, %p)\n", hCtx, cMaxPkts, lpPkts);
533 if (!hCtx)
534 return 0;
536 EnterCriticalSection(&csTablet);
538 context = TABLET_FindOpenContext(hCtx);
540 if (lpPkts != NULL)
541 TABLET_BlankPacketData(context,lpPkts,cMaxPkts);
543 if (context->PacketsQueued == 0)
545 LeaveCriticalSection(&csTablet);
546 return 0;
549 limit = min(cMaxPkts,context->PacketsQueued);
551 if(ptr != NULL)
553 int i = 0;
554 for(i = 0; i < limit; i++)
555 ptr=TABLET_CopyPacketData(context ,ptr, &context->PacketQueue[i]);
559 if (limit < context->PacketsQueued)
561 memmove(context->PacketQueue, &context->PacketQueue[limit],
562 (context->PacketsQueued - (limit))*sizeof(WTPACKET));
564 context->PacketsQueued -= limit;
565 LeaveCriticalSection(&csTablet);
567 TRACE("Copied %i packets\n",limit);
569 return limit;
572 /***********************************************************************
573 * WTPacket (WINTAB32.24)
575 BOOL WINAPI WTPacket(HCTX hCtx, UINT wSerial, LPVOID lpPkt)
577 int rc = 0;
578 LPOPENCONTEXT context;
579 LPWTPACKET wtp = NULL;
581 TRACE("(%p, %d, %p)\n", hCtx, wSerial, lpPkt);
583 if (!hCtx)
584 return 0;
586 EnterCriticalSection(&csTablet);
588 context = TABLET_FindOpenContext(hCtx);
590 rc = TABLET_FindPacket(context ,wSerial, &wtp);
592 if (rc >= 0)
594 if (lpPkt)
595 TABLET_CopyPacketData(context ,lpPkt, wtp);
597 if ((rc+1) < context->QueueSize)
599 memmove(context->PacketQueue, &context->PacketQueue[rc+1],
600 (context->PacketsQueued - (rc+1))*sizeof(WTPACKET));
602 context->PacketsQueued -= (rc+1);
604 LeaveCriticalSection(&csTablet);
606 TRACE("Returning %i\n",rc+1);
607 return rc+1;
610 /***********************************************************************
611 * WTEnable (WINTAB32.40)
613 BOOL WINAPI WTEnable(HCTX hCtx, BOOL fEnable)
615 LPOPENCONTEXT context;
617 TRACE("(%p, %u)\n", hCtx, fEnable);
619 if (!hCtx) return 0;
621 EnterCriticalSection(&csTablet);
622 context = TABLET_FindOpenContext(hCtx);
623 if(!fEnable)
624 TABLET_FlushQueue(context);
625 context->enabled = fEnable;
626 LeaveCriticalSection(&csTablet);
628 return TRUE;
631 /***********************************************************************
632 * WTOverlap (WINTAB32.41)
634 BOOL WINAPI WTOverlap(HCTX hCtx, BOOL fToTop)
636 FIXME("(%p, %u): stub\n", hCtx, fToTop);
638 return TRUE;
641 /***********************************************************************
642 * WTConfig (WINTAB32.61)
644 BOOL WINAPI WTConfig(HCTX hCtx, HWND hWnd)
646 FIXME("(%p, %p): stub\n", hCtx, hWnd);
648 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
650 return FALSE;
653 /***********************************************************************
654 * WTGetA (WINTAB32.61)
656 BOOL WINAPI WTGetA(HCTX hCtx, LPLOGCONTEXTA lpLogCtx)
658 LPOPENCONTEXT context;
660 TRACE("(%p, %p)\n", hCtx, lpLogCtx);
662 if (!hCtx) return 0;
664 EnterCriticalSection(&csTablet);
665 context = TABLET_FindOpenContext(hCtx);
666 LOGCONTEXTWtoA(&context->context, lpLogCtx);
667 LeaveCriticalSection(&csTablet);
669 return TRUE;
672 /***********************************************************************
673 * WTGetW (WINTAB32.1061)
675 BOOL WINAPI WTGetW(HCTX hCtx, LPLOGCONTEXTW lpLogCtx)
677 LPOPENCONTEXT context;
679 TRACE("(%p, %p)\n", hCtx, lpLogCtx);
681 if (!hCtx) return 0;
683 EnterCriticalSection(&csTablet);
684 context = TABLET_FindOpenContext(hCtx);
685 memmove(lpLogCtx,&context->context,sizeof(LOGCONTEXTW));
686 LeaveCriticalSection(&csTablet);
688 return TRUE;
691 /***********************************************************************
692 * WTSetA (WINTAB32.62)
694 BOOL WINAPI WTSetA(HCTX hCtx, LPLOGCONTEXTA lpLogCtx)
696 FIXME("(%p, %p): stub\n", hCtx, lpLogCtx);
698 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
700 return FALSE;
703 /***********************************************************************
704 * WTSetW (WINTAB32.1062)
706 BOOL WINAPI WTSetW(HCTX hCtx, LPLOGCONTEXTW lpLogCtx)
708 FIXME("(%p, %p): stub\n", hCtx, lpLogCtx);
710 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
712 return FALSE;
715 /***********************************************************************
716 * WTExtGet (WINTAB32.63)
718 BOOL WINAPI WTExtGet(HCTX hCtx, UINT wExt, LPVOID lpData)
720 FIXME("(%p, %u, %p): stub\n", hCtx, wExt, lpData);
722 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
724 return FALSE;
727 /***********************************************************************
728 * WTExtSet (WINTAB32.64)
730 BOOL WINAPI WTExtSet(HCTX hCtx, UINT wExt, LPVOID lpData)
732 FIXME("(%p, %u, %p): stub\n", hCtx, wExt, lpData);
734 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
736 return FALSE;
739 /***********************************************************************
740 * WTSave (WINTAB32.65)
742 BOOL WINAPI WTSave(HCTX hCtx, LPVOID lpSaveInfo)
744 FIXME("(%p, %p): stub\n", hCtx, lpSaveInfo);
746 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
748 return FALSE;
751 /***********************************************************************
752 * WTRestore (WINTAB32.66)
754 HCTX WINAPI WTRestore(HWND hWnd, LPVOID lpSaveInfo, BOOL fEnable)
756 FIXME("(%p, %p, %u): stub\n", hWnd, lpSaveInfo, fEnable);
758 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
760 return 0;
763 /***********************************************************************
764 * WTPacketsPeek (WINTAB32.80)
766 int WINAPI WTPacketsPeek(HCTX hCtx, int cMaxPkts, LPVOID lpPkts)
768 int limit;
769 LPOPENCONTEXT context;
770 LPVOID ptr = lpPkts;
772 TRACE("(%p, %d, %p)\n", hCtx, cMaxPkts, lpPkts);
774 if (!hCtx || !lpPkts) return 0;
776 EnterCriticalSection(&csTablet);
778 context = TABLET_FindOpenContext(hCtx);
780 if (context->PacketsQueued == 0)
782 LeaveCriticalSection(&csTablet);
783 return 0;
786 for (limit = 0; limit < cMaxPkts && limit < context->PacketsQueued; limit++)
787 ptr = TABLET_CopyPacketData(context ,ptr, &context->PacketQueue[limit]);
789 LeaveCriticalSection(&csTablet);
790 TRACE("Copied %i packets\n",limit);
791 return limit;
794 /***********************************************************************
795 * WTDataGet (WINTAB32.81)
797 int WINAPI WTDataGet(HCTX hCtx, UINT wBegin, UINT wEnd,
798 int cMaxPkts, LPVOID lpPkts, LPINT lpNPkts)
800 LPOPENCONTEXT context;
801 LPVOID ptr = lpPkts;
802 INT bgn = 0;
803 INT end = 0;
804 INT num = 0;
806 TRACE("(%p, %u, %u, %d, %p, %p)\n",
807 hCtx, wBegin, wEnd, cMaxPkts, lpPkts, lpNPkts);
809 if (!hCtx) return 0;
811 EnterCriticalSection(&csTablet);
813 context = TABLET_FindOpenContext(hCtx);
815 if (context->PacketsQueued == 0)
817 LeaveCriticalSection(&csTablet);
818 return 0;
821 while (bgn < context->PacketsQueued &&
822 context->PacketQueue[bgn].pkSerialNumber != wBegin)
823 bgn++;
825 end = bgn;
826 while (end < context->PacketsQueued &&
827 context->PacketQueue[end].pkSerialNumber != wEnd)
828 end++;
830 if ((bgn == end) && (end == context->PacketsQueued))
832 LeaveCriticalSection(&csTablet);
833 return 0;
836 for (num = bgn; num <= end; num++)
837 ptr = TABLET_CopyPacketData(context ,ptr, &context->PacketQueue[num]);
839 /* remove read packets */
840 if ((end+1) < context->PacketsQueued)
841 memmove( &context->PacketQueue[bgn], &context->PacketQueue[end+1],
842 (context->PacketsQueued - (end+1)) * sizeof (WTPACKET));
844 context->PacketsQueued -= ((end-bgn)+1);
845 *lpNPkts = ((end-bgn)+1);
847 LeaveCriticalSection(&csTablet);
848 TRACE("Copied %i packets\n",*lpNPkts);
849 return (end - bgn)+1;
852 /***********************************************************************
853 * WTDataPeek (WINTAB32.82)
855 int WINAPI WTDataPeek(HCTX hCtx, UINT wBegin, UINT wEnd,
856 int cMaxPkts, LPVOID lpPkts, LPINT lpNPkts)
858 LPOPENCONTEXT context;
859 LPVOID ptr = lpPkts;
860 INT bgn = 0;
861 INT end = 0;
862 INT num = 0;
864 TRACE("(%p, %u, %u, %d, %p, %p)\n",
865 hCtx, wBegin, wEnd, cMaxPkts, lpPkts, lpNPkts);
867 if (!hCtx || !lpPkts) return 0;
869 EnterCriticalSection(&csTablet);
871 context = TABLET_FindOpenContext(hCtx);
873 if (context->PacketsQueued == 0)
875 LeaveCriticalSection(&csTablet);
876 return 0;
879 while (bgn < context->PacketsQueued &&
880 context->PacketQueue[bgn].pkSerialNumber != wBegin)
881 bgn++;
883 end = bgn;
884 while (end < context->PacketsQueued &&
885 context->PacketQueue[end].pkSerialNumber != wEnd)
886 end++;
888 if (bgn == context->PacketsQueued || end == context->PacketsQueued)
890 TRACE("%i %i %i\n", bgn, end, context->PacketsQueued);
891 LeaveCriticalSection(&csTablet);
892 return 0;
895 for (num = bgn; num <= end; num++)
896 ptr = TABLET_CopyPacketData(context ,ptr, &context->PacketQueue[num]);
898 *lpNPkts = ((end-bgn)+1);
899 LeaveCriticalSection(&csTablet);
901 TRACE("Copied %i packets\n",*lpNPkts);
902 return (end - bgn)+1;
905 /***********************************************************************
906 * WTQueuePacketsEx (WINTAB32.200)
908 BOOL WINAPI WTQueuePacketsEx(HCTX hCtx, UINT *lpOld, UINT *lpNew)
910 LPOPENCONTEXT context;
912 TRACE("(%p, %p, %p)\n", hCtx, lpOld, lpNew);
914 if (!hCtx) return 0;
916 EnterCriticalSection(&csTablet);
918 context = TABLET_FindOpenContext(hCtx);
920 if (context->PacketsQueued)
922 *lpOld = context->PacketQueue[0].pkSerialNumber;
923 *lpNew = context->PacketQueue[context->PacketsQueued-1].pkSerialNumber;
925 else
927 TRACE("No packets\n");
928 LeaveCriticalSection(&csTablet);
929 return FALSE;
931 LeaveCriticalSection(&csTablet);
933 return TRUE;
936 /***********************************************************************
937 * WTQueueSizeGet (WINTAB32.84)
939 int WINAPI WTQueueSizeGet(HCTX hCtx)
941 LPOPENCONTEXT context;
942 TRACE("(%p)\n", hCtx);
944 if (!hCtx) return 0;
946 EnterCriticalSection(&csTablet);
947 context = TABLET_FindOpenContext(hCtx);
948 LeaveCriticalSection(&csTablet);
949 return context->QueueSize;
952 /***********************************************************************
953 * WTQueueSizeSet (WINTAB32.85)
955 BOOL WINAPI WTQueueSizeSet(HCTX hCtx, int nPkts)
957 LPOPENCONTEXT context;
959 TRACE("(%p, %d)\n", hCtx, nPkts);
961 if (!hCtx) return 0;
963 EnterCriticalSection(&csTablet);
965 context = TABLET_FindOpenContext(hCtx);
967 context->PacketQueue = HeapReAlloc(GetProcessHeap(), 0,
968 context->PacketQueue, sizeof(WTPACKET)*nPkts);
970 context->QueueSize = nPkts;
971 LeaveCriticalSection(&csTablet);
973 return nPkts;