/*********************************************************************** * WTOpenW (WINTAB32.2021) */ HCTX WINAPI WTOpenW(HWND hWnd, LPLOGCONTEXTW lpLogCtx, BOOL fEnable) { LPOPENCONTEXT newcontext; if (!LoadTablet()) return 0; TRACE("hWnd=%p, lpLogCtx=%p, fEnable=%u\n", hWnd, lpLogCtx, fEnable); DUMPCONTEXT(*lpLogCtx); newcontext = HeapAlloc(GetProcessHeap(), 0 , sizeof(OPENCONTEXT)); newcontext->context = *lpLogCtx; newcontext->hwndOwner = hWnd; newcontext->ActiveCursor = -1; newcontext->QueueSize = 10; newcontext->PacketsQueued = 0; newcontext->PacketQueue=HeapAlloc(GetProcessHeap(),0,sizeof(WTPACKET)*10); EnterCriticalSection(&csTablet); newcontext->handle = gTopContext++; newcontext->next = gOpenContexts; gOpenContexts = newcontext; LeaveCriticalSection(&csTablet); pAttachEventQueueToTablet(hWnd); TABLET_PostTabletMessage(newcontext, _WT_CTXOPEN(newcontext->context.lcMsgBase), (WPARAM)newcontext->handle, newcontext->context.lcStatus, TRUE); if (fEnable) { newcontext->enabled = TRUE; /* TODO: Add to top of overlap order */ newcontext->context.lcStatus = CXS_ONTOP; } else { newcontext->enabled = FALSE; newcontext->context.lcStatus = CXS_DISABLED; } TABLET_PostTabletMessage(newcontext, _WT_CTXOVERLAP(newcontext->context.lcMsgBase), (WPARAM)newcontext->handle, newcontext->context.lcStatus, TRUE); return newcontext->handle; }
/*********************************************************************** * WTEnable (WINTAB32.40) */ BOOL WINAPI WTEnable(HCTX hCtx, BOOL fEnable) { LPOPENCONTEXT context; TRACE("hCtx=%p, fEnable=%u\n", hCtx, fEnable); if (!hCtx) return FALSE; EnterCriticalSection(&csTablet); context = TABLET_FindOpenContext(hCtx); if (!context) { LeaveCriticalSection(&csTablet); return FALSE; } /* if we want to enable and it is not enabled then */ if(fEnable && !context->enabled) { context->enabled = TRUE; /* TODO: Add to top of overlap order */ context->context.lcStatus = CXS_ONTOP; TABLET_PostTabletMessage(context, _WT_CTXOVERLAP(context->context.lcMsgBase), (WPARAM)context->handle, context->context.lcStatus, TRUE); } /* if we want to disable and it is not disabled then */ else if (!fEnable && context->enabled) { context->enabled = FALSE; /* TODO: Remove from overlap order?? needs a test */ context->context.lcStatus = CXS_DISABLED; TABLET_FlushQueue(context); TABLET_PostTabletMessage(context, _WT_CTXOVERLAP(context->context.lcMsgBase), (WPARAM)context->handle, context->context.lcStatus, TRUE); } LeaveCriticalSection(&csTablet); return TRUE; }
/* * The window proc for the default TABLET window */ static LRESULT WINAPI TABLET_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { TRACE("Incoming Message 0x%x (0x%08x, 0x%08x)\n", uMsg, (UINT)wParam, (UINT)lParam); switch(uMsg) { case WM_NCCREATE: return TRUE; case WT_PACKET: { WTPACKET packet; LPOPENCONTEXT handler; if (pGetCurrentPacket) { pGetCurrentPacket(&packet); handler = AddPacketToContextQueue(&packet,(HWND)lParam); if (handler && handler->context.lcOptions & CXO_MESSAGES) TABLET_PostTabletMessage(handler, _WT_PACKET(handler->context.lcMsgBase), (WPARAM)packet.pkSerialNumber, (LPARAM)handler->handle, FALSE); } break; } case WT_PROXIMITY: { WTPACKET packet; LPOPENCONTEXT handler; if (pGetCurrentPacket) { pGetCurrentPacket(&packet); handler = AddPacketToContextQueue(&packet,(HWND)wParam); if (handler) TABLET_PostTabletMessage(handler, WT_PROXIMITY, (WPARAM)handler->handle, lParam, TRUE); } break; } } return 0; }
/*********************************************************************** * WTOverlap (WINTAB32.41) * * Move context to top or bottom of overlap order */ BOOL WINAPI WTOverlap(HCTX hCtx, BOOL fToTop) { LPOPENCONTEXT context; TRACE("hCtx=%p, fToTop=%u\n", hCtx, fToTop); if (!hCtx) return FALSE; EnterCriticalSection(&csTablet); context = TABLET_FindOpenContext(hCtx); if (!context) { LeaveCriticalSection(&csTablet); return FALSE; } /* if we want to send to top and it's not already there */ if (fToTop && context->context.lcStatus != CXS_ONTOP) { /* TODO: Move context to top of overlap order */ FIXME("Not moving context to top of overlap order\n"); context->context.lcStatus = CXS_ONTOP; TABLET_PostTabletMessage(context, _WT_CTXOVERLAP(context->context.lcMsgBase), (WPARAM)context->handle, context->context.lcStatus, TRUE); } else if (!fToTop) { /* TODO: Move context to bottom of overlap order */ FIXME("Not moving context to bottom of overlap order\n"); context->context.lcStatus = CXS_OBSCURED; TABLET_PostTabletMessage(context, _WT_CTXOVERLAP(context->context.lcMsgBase), (WPARAM)context->handle, context->context.lcStatus, TRUE); } LeaveCriticalSection(&csTablet); return TRUE; }
/*********************************************************************** * WTClose (WINTAB32.22) */ BOOL WINAPI WTClose(HCTX hCtx) { LPOPENCONTEXT context,ptr; TRACE("(%p)\n", hCtx); EnterCriticalSection(&csTablet); ptr = context = gOpenContexts; while (context && (context->handle != hCtx)) { ptr = context; context = context->next; } if (!context) { LeaveCriticalSection(&csTablet); return TRUE; } if (context == gOpenContexts) gOpenContexts = context->next; else ptr->next = context->next; LeaveCriticalSection(&csTablet); TABLET_PostTabletMessage(context, _WT_CTXCLOSE(context->context.lcMsgBase), (WPARAM)context->handle, context->context.lcStatus,TRUE); HeapFree(GetProcessHeap(),0,context->PacketQueue); HeapFree(GetProcessHeap(),0,context); return TRUE; }
LPOPENCONTEXT AddPacketToContextQueue(LPWTPACKET packet, HWND hwnd) { LPOPENCONTEXT ptr=NULL; EnterCriticalSection(&csTablet); ptr = gOpenContexts; while (ptr) { TRACE("Trying Queue %p (%p %p)\n", ptr->handle, hwnd, ptr->hwndOwner); if (ptr->hwndOwner == hwnd) { int tgt; if (!ptr->enabled) { ptr = ptr->next; continue; } tgt = ptr->PacketsQueued; packet->pkContext = ptr->handle; /* translate packet data to the context */ /* Scale as per documentation */ packet->pkY = ScaleForContext(packet->pkY, ptr->context.lcInOrgY, ptr->context.lcInExtY, ptr->context.lcOutOrgY, ptr->context.lcOutExtY); packet->pkX = ScaleForContext(packet->pkX, ptr->context.lcInOrgX, ptr->context.lcInExtX, ptr->context.lcOutOrgX, ptr->context.lcOutExtX); /* flip the Y axis */ if (ptr->context.lcOutExtY > 0) packet->pkY = ptr->context.lcOutExtY - packet->pkY; else if (ptr->context.lcOutExtY < 0) packet->pkY = abs(ptr->context.lcOutExtY + packet->pkY); DUMPPACKET(*packet); if (tgt == ptr->QueueSize) { TRACE("Queue Overflow %p\n",ptr->handle); ptr->PacketQueue[tgt-1].pkStatus |= TPS_QUEUE_ERR; } else { TRACE("Placed in queue %p index %i\n",ptr->handle,tgt); ptr->PacketQueue[tgt] = *packet; ptr->PacketsQueued++; if (ptr->ActiveCursor != packet->pkCursor) { ptr->ActiveCursor = packet->pkCursor; if (ptr->context.lcOptions & CXO_CSRMESSAGES) TABLET_PostTabletMessage(ptr, _WT_CSRCHANGE(ptr->context.lcMsgBase), (WPARAM)packet->pkSerialNumber, (LPARAM)ptr->handle, FALSE); } } break; } ptr = ptr->next; } LeaveCriticalSection(&csTablet); TRACE("Done (%p)\n",ptr); return ptr; }