Grand validation:
Ajouté interface pour plusiers APIs de tablette. Essayé d'ajouter .NET interop Changé storage des champs Nouveau functions pour afficher du texte
This commit is contained in:
parent
422ec60f3b
commit
b2eeb12fc3
|
@ -1,4 +1,20 @@
|
||||||
cmake_minimum_required(VERSION 3.10)
|
cmake_minimum_required(VERSION 3.10)
|
||||||
|
set(CMAKE_CXX_STANDARD 20)
|
||||||
|
|
||||||
|
#include(CMakePrintHelpers)
|
||||||
|
|
||||||
|
|
||||||
|
# Runtime checks are not compatiable
|
||||||
|
#string(REGEX REPLACE "/RTC(su|[1su])" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
|
||||||
|
#string(REGEX REPLACE "/RTC(su|[1su])" "" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}")
|
||||||
|
#string(REGEX REPLACE "/RTC(su|[1su])" "" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
|
||||||
|
#string(REGEX REPLACE "/RTC(su|[1su])" "" CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG}")
|
||||||
|
#cmake_print_variables(CMAKE_C_FLAGS)
|
||||||
|
#cmake_print_variables(CMAKE_C_FLAGS_DEBUG)
|
||||||
|
|
||||||
|
# Exception handling should use C++ standard stack unwinding
|
||||||
|
#string(REGEX REPLACE "/EHs" "/EHa" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
|
||||||
|
#string(REGEX REPLACE "/EHs" "/EHa" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}")
|
||||||
project(yaw-audio)
|
project(yaw-audio)
|
||||||
add_subdirectory("lib")
|
add_subdirectory("lib")
|
||||||
add_subdirectory("src")
|
add_subdirectory("src")
|
|
@ -12,5 +12,11 @@ target_include_directories(yaw-tab PUBLIC
|
||||||
"."
|
"."
|
||||||
"../../lib/wintab"
|
"../../lib/wintab"
|
||||||
)
|
)
|
||||||
|
target_compile_definitions(yaw-tab PUBLIC YAW_USE_WINTAB)
|
||||||
|
|
||||||
|
set_target_properties(yaw-tab PROPERTIES VS_DOTNET_REFERENCES "System")
|
||||||
|
set_target_properties(yaw-tab PROPERTIES COMPILE_FLAGS "/clr")
|
||||||
|
set_target_properties(yaw-tab PROPERTIES COMPILE_FLAGS "/Zc:twoPhase-")
|
||||||
|
|
||||||
|
# default compiler flags from CMAKE conflict with managed code compliation, probably a better way of doing this.
|
||||||
|
|
||||||
target_compile_definitions(yaw-tab PUBLIC YAW_USE_WINTAB=1 YAW_USE_RTSTYLUS=1)
|
|
|
@ -19,11 +19,11 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
enum Parameters {
|
enum Parameters {
|
||||||
kParameterTabletX = 0,
|
ktpax = 0,
|
||||||
kParameterTabletY,
|
ktpay,
|
||||||
kParameterTabletZ,
|
ktpaz,
|
||||||
kParameterTabletPressure,
|
ktpap,
|
||||||
kParameterTabletButtons,
|
ktpab,
|
||||||
kParameterTime,
|
kParameterTime,
|
||||||
kParameterCount
|
kParameterCount
|
||||||
};
|
};
|
||||||
|
|
|
@ -33,23 +33,23 @@ protected:
|
||||||
|
|
||||||
switch (index)
|
switch (index)
|
||||||
{
|
{
|
||||||
case kParameterTabletX:
|
case ktpax:
|
||||||
parameter.name = "x";
|
parameter.name = "x";
|
||||||
parameter.symbol = "x";
|
parameter.symbol = "x";
|
||||||
break;
|
break;
|
||||||
case kParameterTabletY:
|
case ktpay:
|
||||||
parameter.name = "y";
|
parameter.name = "y";
|
||||||
parameter.symbol = "y";
|
parameter.symbol = "y";
|
||||||
break;
|
break;
|
||||||
case kParameterTabletZ:
|
case ktpaz:
|
||||||
parameter.name = "z";
|
parameter.name = "z";
|
||||||
parameter.symbol = "z";
|
parameter.symbol = "z";
|
||||||
break;
|
break;
|
||||||
case kParameterTabletPressure:
|
case ktpap:
|
||||||
parameter.name = "p";
|
parameter.name = "p";
|
||||||
parameter.symbol = "p";
|
parameter.symbol = "p";
|
||||||
break;
|
break;
|
||||||
case kParameterTabletButtons:
|
case ktpab:
|
||||||
parameter.name = "Buttons";
|
parameter.name = "Buttons";
|
||||||
parameter.symbol = "b";
|
parameter.symbol = "b";
|
||||||
parameter.hints = kParameterIsAutomable | kParameterIsInteger;
|
parameter.hints = kParameterIsAutomable | kParameterIsInteger;
|
||||||
|
@ -78,17 +78,17 @@ protected:
|
||||||
{
|
{
|
||||||
fParameters[idx] = val;
|
fParameters[idx] = val;
|
||||||
switch (idx) {
|
switch (idx) {
|
||||||
case kParameterTabletX:
|
case ktpax:
|
||||||
period = 0.02f * val * static_cast<float>(sampleRate);
|
period = 0.02f * val * static_cast<float>(sampleRate);
|
||||||
break;
|
break;
|
||||||
case kParameterTabletY:
|
case ktpay:
|
||||||
break;
|
break;
|
||||||
case kParameterTabletZ:
|
case ktpaz:
|
||||||
break;
|
break;
|
||||||
case kParameterTabletPressure:
|
case ktpap:
|
||||||
volume = val;
|
volume = val;
|
||||||
break;
|
break;
|
||||||
case kParameterTabletButtons:
|
case ktpab:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
#ifdef YAW_USE_OTD
|
||||||
|
// text_write.cpp
|
||||||
|
// compile with: /clr
|
||||||
|
using namespace System;
|
||||||
|
using namespace System::IO;
|
||||||
|
|
||||||
|
int func()
|
||||||
|
{
|
||||||
|
String^ fileName = "textfile.txt";
|
||||||
|
|
||||||
|
StreamWriter^ sw = gcnew StreamWriter(fileName);
|
||||||
|
sw->WriteLine("A text file is born!");
|
||||||
|
sw->Write("You can use WriteLine");
|
||||||
|
sw->WriteLine("...or just Write");
|
||||||
|
sw->WriteLine("and do {0} output too.", "formatted");
|
||||||
|
sw->WriteLine("You can also send non-text objects:");
|
||||||
|
sw->WriteLine(DateTime::Now);
|
||||||
|
sw->Close();
|
||||||
|
Console::WriteLine("a new file ('{0}') has been written", fileName);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
|
@ -0,0 +1,45 @@
|
||||||
|
//Interface to supported tablet APIs.
|
||||||
|
#include <array>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#ifdef YAW_USE_WINTAB
|
||||||
|
#include <Windows.h>
|
||||||
|
#include "MSGPACK.H"
|
||||||
|
#include "wintab.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
struct Packet {
|
||||||
|
float x;
|
||||||
|
float y;
|
||||||
|
float z;
|
||||||
|
float p;
|
||||||
|
unsigned long buttons;
|
||||||
|
bool operator==(const Packet& p)
|
||||||
|
{ return
|
||||||
|
this->x == p.x &&
|
||||||
|
this->y == p.y &&
|
||||||
|
this->z == p.z &&
|
||||||
|
this->p == p.p &&
|
||||||
|
this->buttons == p.buttons;
|
||||||
|
};
|
||||||
|
bool operator!=(const Packet& p) { return !(*this == p); }
|
||||||
|
};
|
||||||
|
|
||||||
|
class Tablet {
|
||||||
|
public:
|
||||||
|
Tablet(uintptr_t handle);
|
||||||
|
~Tablet();
|
||||||
|
bool GetPacket( Packet &pkt );
|
||||||
|
bool initialized;
|
||||||
|
std::string errormsg = "";
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
Packet ext = { 0 };
|
||||||
|
|
||||||
|
#ifdef YAW_USE_WINTAB
|
||||||
|
void NewContext(HWND hwnd);
|
||||||
|
HCTX hctx = NULL;
|
||||||
|
#endif
|
||||||
|
};
|
|
@ -1,10 +1,6 @@
|
||||||
#include "DistrhoUI.hpp"
|
#include "DistrhoUI.hpp"
|
||||||
#ifdef YAW_USE_WINTAB
|
#include "tablet.h"
|
||||||
#include "wintab.cpp"
|
#include <format>
|
||||||
#endif
|
|
||||||
#ifdef YAW_USE_RTSTYLUS
|
|
||||||
#include "rtstylus.cpp"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
START_NAMESPACE_DISTRHO
|
START_NAMESPACE_DISTRHO
|
||||||
|
|
||||||
|
@ -18,12 +14,8 @@ public:
|
||||||
: UI(kInitialWidth, kInitialHeight),
|
: UI(kInitialWidth, kInitialHeight),
|
||||||
fSampleRate(getSampleRate()),
|
fSampleRate(getSampleRate()),
|
||||||
fResizable(isResizable()),
|
fResizable(isResizable()),
|
||||||
fScale(1.0f),
|
tab(getWindow().getNativeWindowHandle())
|
||||||
fScaleFactor(getScaleFactor()),
|
|
||||||
tab(reinterpret_cast<HWND>(getWindow().getNativeWindowHandle()))
|
|
||||||
{
|
{
|
||||||
std::memset(fParameters, 0, sizeof(float) * kParameterCount);
|
|
||||||
std::memset(fStrBuf, 0, sizeof(char) * (0xff + 1));
|
|
||||||
|
|
||||||
#ifdef DGL_NO_SHARED_RESOURCES
|
#ifdef DGL_NO_SHARED_RESOURCES
|
||||||
createFontFromFile("sans", "/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans.ttf");
|
createFontFromFile("sans", "/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans.ttf");
|
||||||
|
@ -38,42 +30,32 @@ protected:
|
||||||
|
|
||||||
void getTabletData()
|
void getTabletData()
|
||||||
{
|
{
|
||||||
//Lire donnés de la tablet
|
if (!tab.initialized || !tab.GetPacket(pkt)) return;
|
||||||
tab.NewPacket();
|
if (pkt == lastPkt) return;
|
||||||
|
if (pkt.x != lastPkt.x) setParameterValue(ktpax, pkt.x);
|
||||||
float x = static_cast<float>(tab.pkt.pkX) / tab.extX;
|
if (pkt.y != lastPkt.y) setParameterValue(ktpay, pkt.y);
|
||||||
float y = static_cast<float>(tab.pkt.pkY) / tab.extY;
|
if (pkt.z != lastPkt.z) setParameterValue(ktpaz, pkt.z);
|
||||||
float z = static_cast<float>(tab.pkt.pkZ) / tab.extZ;
|
if (pkt.p != lastPkt.p) setParameterValue(ktpap, pkt.p);
|
||||||
float p = static_cast<float>(tab.pkt.pkNormalPressure) / tab.extP;
|
if (pkt.buttons != lastPkt.buttons) setParameterValue(ktpab, pkt.buttons);
|
||||||
|
lastPkt = pkt;
|
||||||
if (x != fParameters[kParameterTabletX]) {
|
|
||||||
setParameterValue(kParameterTabletX, x);
|
|
||||||
fParameters[kParameterTabletX] = x;
|
|
||||||
}
|
|
||||||
if (y != fParameters[kParameterTabletY]) {
|
|
||||||
setParameterValue(kParameterTabletY, y);
|
|
||||||
fParameters[kParameterTabletY] = y;
|
|
||||||
}
|
|
||||||
if (z != fParameters[kParameterTabletZ]) {
|
|
||||||
setParameterValue(kParameterTabletZ, z);
|
|
||||||
fParameters[kParameterTabletZ] = z;
|
|
||||||
}
|
|
||||||
if (p != fParameters[kParameterTabletPressure]) {
|
|
||||||
setParameterValue(kParameterTabletPressure, p);
|
|
||||||
fParameters[kParameterTabletPressure] = p;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void parameterChanged(uint32_t index, float value) override
|
void parameterChanged(uint32_t index, float value) override
|
||||||
{
|
{
|
||||||
|
|
||||||
if (index != kParameterTime) {
|
if (index != kParameterTime && index < kParameterCount) {
|
||||||
fParameters[index] = value;
|
switch (index)
|
||||||
|
{
|
||||||
|
case(ktpax): pkt.x = value;
|
||||||
|
case(ktpay): pkt.y = value;
|
||||||
|
case(ktpaz): pkt.z = value;
|
||||||
|
case(ktpap): pkt.p = value;
|
||||||
|
case(ktpab): pkt.buttons = static_cast<unsigned long>(value);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
getTabletData();
|
getTabletData();
|
||||||
|
|
||||||
repaint();
|
repaint();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,44 +82,30 @@ protected:
|
||||||
|
|
||||||
void onNanoDisplay() override
|
void onNanoDisplay() override
|
||||||
{
|
{
|
||||||
drawCircle(
|
fontSize(15.0f);
|
||||||
fParameters[kParameterTabletX],
|
textLineHeight(1.f);
|
||||||
fParameters[kParameterTabletY],
|
|
||||||
fParameters[kParameterTabletZ],
|
|
||||||
fParameters[kParameterTabletPressure]
|
|
||||||
);
|
|
||||||
|
|
||||||
const float lineHeight = 20 * fScale;
|
//Report tablet errors.
|
||||||
|
if (!tab.initialized) {
|
||||||
fontSize(15.0f * fScale);
|
const std::string err = std::vformat("Tablet not supported:\n{}",
|
||||||
textLineHeight(lineHeight);
|
std::make_format_args(tab.errormsg));
|
||||||
|
beginPath();
|
||||||
|
fillColor(200, 200, 200);
|
||||||
|
// textBox(0.f, 15.f, 250.f, err.c_str(), nullptr);
|
||||||
float x = 0.0f * fScale;
|
closePath();
|
||||||
float y = 15.0f * fScale;
|
|
||||||
|
|
||||||
if (!tab.wintabAvailable) {
|
|
||||||
drawLeft(x, y, "Failed to connect to tablet.");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
drawLeft(x, y, "x:");
|
//Numerical feedback.
|
||||||
drawRight(x, y, getTextBufFloat(fParameters[kParameterTabletX]));
|
beginPath();
|
||||||
y += lineHeight;
|
fillColor(200, 200, 200);
|
||||||
|
textBox(0.f, 15.f, 250.f,
|
||||||
drawLeft(x, y, "y:");
|
std::format("x: {:.3f}\ny: {:.3f}\nz: {:.3f}\np: {:.3f}\nb: {}",
|
||||||
drawRight(x, y, getTextBufFloat(fParameters[kParameterTabletY]));
|
pkt.x, pkt.y, pkt.z, pkt.p, pkt.buttons).c_str(), nullptr);
|
||||||
y += lineHeight;
|
closePath();
|
||||||
|
|
||||||
drawLeft(x, y, "z:");
|
|
||||||
drawRight(x, y, getTextBufFloat(fParameters[kParameterTabletZ]));
|
|
||||||
y += lineHeight;
|
|
||||||
|
|
||||||
drawLeft(x, y, "p:");
|
|
||||||
drawRight(x, y, getTextBufFloat(fParameters[kParameterTabletPressure]));
|
|
||||||
y += lineHeight;
|
|
||||||
|
|
||||||
|
//Pen position and pressure.
|
||||||
|
drawCircle(pkt.x, pkt.y, pkt.z, pkt.p);
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawCircle(float x, float y, float z, float p) {
|
void drawCircle(float x, float y, float z, float p) {
|
||||||
|
@ -156,8 +124,8 @@ protected:
|
||||||
|
|
||||||
beginPath();
|
beginPath();
|
||||||
strokeColor(1.f, 1.f, 1.f, 0.5f);
|
strokeColor(1.f, 1.f, 1.f, 0.5f);
|
||||||
moveTo(x , y - z * circleRadius);
|
moveTo(x, y - z * circleRadius);
|
||||||
lineTo(x , y + z * circleRadius);
|
lineTo(x, y + z * circleRadius);
|
||||||
stroke();
|
stroke();
|
||||||
closePath();
|
closePath();
|
||||||
|
|
||||||
|
@ -192,7 +160,6 @@ protected:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Parameters
|
// Parameters
|
||||||
float fParameters[kParameterCount];
|
|
||||||
double fSampleRate;
|
double fSampleRate;
|
||||||
|
|
||||||
// UI stuff
|
// UI stuff
|
||||||
|
@ -202,61 +169,9 @@ private:
|
||||||
|
|
||||||
// Tablet context handler
|
// Tablet context handler
|
||||||
Tablet tab;
|
Tablet tab;
|
||||||
|
Packet pkt = { 0 };
|
||||||
|
Packet lastPkt = { 0 };
|
||||||
|
|
||||||
// temp buf for text
|
|
||||||
char fStrBuf[0xff + 1];
|
|
||||||
|
|
||||||
// helpers for putting text into fStrBuf and returning it
|
|
||||||
const char* getTextBufInt(const int value)
|
|
||||||
{
|
|
||||||
std::snprintf(fStrBuf, 0xff, "%i", value);
|
|
||||||
return fStrBuf;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* getTextBufFloat(const float value)
|
|
||||||
{
|
|
||||||
std::snprintf(fStrBuf, 0xff, "%.1f", value);
|
|
||||||
return fStrBuf;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* getTextBufFloatExtra(const float value)
|
|
||||||
{
|
|
||||||
std::snprintf(fStrBuf, 0xff, "%.2f", value + 0.001f);
|
|
||||||
return fStrBuf;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* getTextBufTime(const uint64_t frame)
|
|
||||||
{
|
|
||||||
const uint32_t time = frame / uint64_t(fSampleRate);
|
|
||||||
const uint32_t secs = time % 60;
|
|
||||||
const uint32_t mins = (time / 60) % 60;
|
|
||||||
const uint32_t hrs = (time / 3600) % 60;
|
|
||||||
std::snprintf(fStrBuf, 0xff, "%02i:%02i:%02i", hrs, mins, secs);
|
|
||||||
return fStrBuf;
|
|
||||||
}
|
|
||||||
|
|
||||||
// helpers for drawing text
|
|
||||||
void drawLeft(float x, const float y, const char* const text, const int offset = 0)
|
|
||||||
{
|
|
||||||
const float width = (100.0f + offset) * fScale;
|
|
||||||
x += offset * fScale;
|
|
||||||
beginPath();
|
|
||||||
fillColor(200, 200, 200);
|
|
||||||
textAlign(ALIGN_RIGHT | ALIGN_TOP);
|
|
||||||
textBox(x, y, width, text);
|
|
||||||
closePath();
|
|
||||||
}
|
|
||||||
|
|
||||||
void drawRight(float x, const float y, const char* const text, const int offset = 0)
|
|
||||||
{
|
|
||||||
const float width = (100.0f + offset) * fScale;
|
|
||||||
x += offset * fScale;
|
|
||||||
beginPath();
|
|
||||||
fillColor(255, 255, 255);
|
|
||||||
textAlign(ALIGN_LEFT | ALIGN_TOP);
|
|
||||||
textBox(x + (105 * fScale), y, width, text);
|
|
||||||
closePath();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Set our UI class as non-copyable and add a leak detector just in case.
|
Set our UI class as non-copyable and add a leak detector just in case.
|
||||||
|
|
|
@ -1,104 +1,81 @@
|
||||||
#include <string>
|
#ifdef YAW_USE_WINTAB
|
||||||
#include <Windows.h>
|
#include "tablet.h"
|
||||||
#include "MSGPACK.H"
|
|
||||||
#include "wintab.h"
|
|
||||||
|
|
||||||
#define PACKETDATA (PK_X | PK_Y | PK_Z | PK_BUTTONS | PK_NORMAL_PRESSURE)
|
#define PACKETDATA (PK_X | PK_Y | PK_Z | PK_BUTTONS | PK_NORMAL_PRESSURE)
|
||||||
#define PACKETMODE PK_BUTTONS
|
//#define PACKETMODE
|
||||||
#include "pktdef.h"
|
#include "pktdef.h"
|
||||||
#include "wtutil.h"
|
#include "wtutil.h"
|
||||||
|
|
||||||
class Tablet {
|
Tablet::Tablet(uintptr_t handle)
|
||||||
public:
|
{
|
||||||
|
HWND hwnd = reinterpret_cast<HWND>(handle);
|
||||||
|
if (!hwnd) { return; }
|
||||||
|
|
||||||
Tablet(HWND hwnd) {
|
if (!LoadWintab() || !gpWTInfoA(0, 0, NULL)) {
|
||||||
if (!hwnd) { return; }
|
errormsg = "Wintab not installed.";
|
||||||
|
return;
|
||||||
if (!LoadWintab() || !gpWTInfoA(0, 0, NULL)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
NewContext(hwnd);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
~Tablet() {
|
NewContext(hwnd);
|
||||||
if (hctx) { gpWTClose(hctx); }
|
}
|
||||||
UnloadWintab();
|
|
||||||
|
Tablet::~Tablet() {
|
||||||
|
if (hctx) { gpWTClose(hctx); }
|
||||||
|
UnloadWintab();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Tablet::GetPacket( Packet& packet ) {
|
||||||
|
//Serial number of newest packet.
|
||||||
|
UINT oldest, newest;
|
||||||
|
//This function returns false when it fails
|
||||||
|
//which may happen with a full or empty queue.
|
||||||
|
if (!gpWTQueuePacketsEx(hctx, &oldest, &newest)) {
|
||||||
|
//Queue may be full, flush it all just in case.
|
||||||
|
gpWTPacketsGet(hctx, gpWTQueueSizeGet(hctx), nullptr);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NewPacket() {
|
//Store newest packet in pkt, flush older packets.
|
||||||
//Serial number of newest packet.
|
PACKET pkt;
|
||||||
UINT oldest, newest;
|
bool newData = gpWTPacket(hctx, newest, &pkt);
|
||||||
//This function returns false when it fails
|
if (!newData) return false;
|
||||||
//which may happen with a full or empty queue.
|
packet.x = static_cast<float>(pkt.pkX) / ext.x;
|
||||||
if (!gpWTQueuePacketsEx(hctx, &oldest, &newest)) {
|
packet.y = static_cast<float>(pkt.pkY) / ext.y;
|
||||||
//Queue may be full, flush it all just in case.
|
packet.z = static_cast<float>(pkt.pkZ) / ext.z;
|
||||||
gpWTPacketsGet(hctx, gpWTQueueSizeGet(hctx), nullptr);
|
packet.p = static_cast<float>(pkt.pkNormalPressure) / ext.p;
|
||||||
return false;
|
packet.buttons = pkt.pkButtons;
|
||||||
}
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
//Store newest packet in pkt, flush older packets.
|
void Tablet::NewContext(HWND hwnd) {
|
||||||
return gpWTPacket(hctx, newest, &pkt);
|
if (hctx) { gpWTClose(hctx); }
|
||||||
}
|
LOGCONTEXT ctx = {};
|
||||||
|
|
||||||
bool wintabAvailable = false;
|
|
||||||
PACKET pkt = { 0 };
|
|
||||||
UINT maxPressure = 1;
|
|
||||||
float extX;
|
|
||||||
float extY;
|
|
||||||
float extZ;
|
|
||||||
float extP;
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
HCTX hctx = NULL;
|
|
||||||
UINT wDevice = 0;
|
|
||||||
AXIS TabletX = { 0 };
|
AXIS TabletX = { 0 };
|
||||||
AXIS TabletY = { 0 };
|
AXIS TabletY = { 0 };
|
||||||
AXIS TabletZ = { 0 };
|
AXIS TabletZ = { 0 };
|
||||||
AXIS TabletPressure = { 0 };
|
AXIS TabletPressure = { 0 };
|
||||||
LOGCONTEXT ctx = {};
|
gpWTInfoA(WTI_DEFCONTEXT, 0, &ctx);
|
||||||
|
ctx.lcOptions |= CXO_MESSAGES; //TODO: checker çela
|
||||||
|
ctx.lcPktData = PACKETDATA;
|
||||||
|
ctx.lcPktMode = 0;
|
||||||
|
|
||||||
void NewContext(HWND hwnd) {
|
//Tablet extents.
|
||||||
if (hctx) { gpWTClose(hctx); }
|
gpWTInfoA(WTI_DEVICES, DVC_X, &TabletX);
|
||||||
gpWTInfoA(WTI_DEFCONTEXT, 0, &ctx);
|
gpWTInfoA(WTI_DEVICES, DVC_Y, &TabletY);
|
||||||
ctx.lcOptions |= CXO_MESSAGES; //TODO: checker çela
|
gpWTInfoA(WTI_DEVICES, DVC_Z, &TabletZ);
|
||||||
ctx.lcPktData = PACKETDATA;
|
gpWTInfoA(WTI_DEVICES, DVC_NPRESSURE, &TabletPressure);
|
||||||
ctx.lcPktMode = PACKETMODE;
|
|
||||||
|
|
||||||
//Tablet extents.
|
|
||||||
gpWTInfoA(WTI_DEVICES, DVC_X, &TabletX);
|
|
||||||
gpWTInfoA(WTI_DEVICES, DVC_Y, &TabletY);
|
|
||||||
gpWTInfoA(WTI_DEVICES, DVC_Z, &TabletZ);
|
|
||||||
gpWTInfoA(WTI_DEVICES, DVC_NPRESSURE, &TabletPressure);
|
|
||||||
|
|
||||||
ctx.lcInOrgX = TabletX.axMin;
|
ext.x = static_cast<float>(TabletX.axMax);
|
||||||
ctx.lcInExtX = TabletX.axMax;
|
ext.y = static_cast<float>(TabletY.axMax);
|
||||||
ctx.lcOutOrgX = TabletX.axMin;
|
ext.z = static_cast<float>(TabletZ.axMax);
|
||||||
ctx.lcOutExtX = TabletX.axMax;
|
ext.p = static_cast<float>(TabletPressure.axMax);
|
||||||
extX = static_cast<float>(TabletX.axMax);
|
|
||||||
|
|
||||||
ctx.lcInOrgY = TabletY.axMin;
|
hctx = gpWTOpenA(hwnd, &ctx, TRUE);
|
||||||
ctx.lcInExtY = TabletY.axMax;
|
|
||||||
ctx.lcOutOrgY = TabletY.axMin;
|
|
||||||
ctx.lcOutExtY = TabletY.axMax;
|
|
||||||
extY = static_cast<float>(TabletY.axMax);
|
|
||||||
|
|
||||||
ctx.lcInOrgZ = TabletZ.axMin;
|
if (!hctx)
|
||||||
ctx.lcInExtZ = TabletZ.axMax;
|
{
|
||||||
ctx.lcOutOrgZ = TabletZ.axMin;
|
errormsg = "Could not open Wintab context.";
|
||||||
ctx.lcOutExtZ = TabletZ.axMax;
|
return;
|
||||||
extZ = static_cast<float>(TabletZ.axMax);
|
|
||||||
|
|
||||||
extP = static_cast<float>(TabletPressure.axMax);
|
|
||||||
|
|
||||||
hctx = gpWTOpenA(hwnd, &ctx, FALSE);
|
|
||||||
|
|
||||||
if (!hctx) { return; }
|
|
||||||
|
|
||||||
gpWTEnable(hctx, TRUE);
|
|
||||||
wintabAvailable = true;
|
|
||||||
}
|
}
|
||||||
|
initialized = true;
|
||||||
|
};
|
||||||
};
|
#endif
|
Loading…
Reference in New Issue