Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--intern/ghost/GHOST_C-api.h7
-rw-r--r--intern/ghost/GHOST_ISystem.h6
-rw-r--r--intern/ghost/GHOST_Types.h6
-rw-r--r--intern/ghost/intern/GHOST_C-api.cpp7
-rw-r--r--intern/ghost/intern/GHOST_System.cpp15
-rw-r--r--intern/ghost/intern/GHOST_System.h13
-rw-r--r--intern/ghost/intern/GHOST_SystemWin32.cpp9
-rw-r--r--intern/ghost/intern/GHOST_WindowWin32.cpp90
-rw-r--r--intern/ghost/intern/GHOST_WindowWin32.h76
-rw-r--r--release/scripts/startup/bl_ui/space_userpref.py5
-rw-r--r--source/blender/makesdna/DNA_userdef_types.h12
-rw-r--r--source/blender/makesrna/intern/rna_userdef.c17
-rw-r--r--source/blender/windowmanager/WM_api.h1
-rw-r--r--source/blender/windowmanager/intern/wm_window.c20
14 files changed, 277 insertions, 7 deletions
diff --git a/intern/ghost/GHOST_C-api.h b/intern/ghost/GHOST_C-api.h
index 1ce051d2660..45ec41f63a0 100644
--- a/intern/ghost/GHOST_C-api.h
+++ b/intern/ghost/GHOST_C-api.h
@@ -743,6 +743,13 @@ extern GHOST_TSuccess GHOST_ActivateOpenGLContext(GHOST_ContextHandle contexthan
extern GHOST_TSuccess GHOST_ReleaseOpenGLContext(GHOST_ContextHandle contexthandle);
/**
+ * Set which tablet API to use. Only affects Windows, other platforms have a single API.
+ * \param systemhandle The handle to the system
+ * \param api Enum indicating which API to use.
+ */
+extern void GHOST_SetTabletAPI(GHOST_SystemHandle systemhandle, GHOST_TTabletAPI api);
+
+/**
* Returns the status of the tablet
* \param windowhandle The handle to the window
* \return Status of tablet
diff --git a/intern/ghost/GHOST_ISystem.h b/intern/ghost/GHOST_ISystem.h
index 42ae750e20a..39686c56719 100644
--- a/intern/ghost/GHOST_ISystem.h
+++ b/intern/ghost/GHOST_ISystem.h
@@ -397,6 +397,12 @@ public:
*/
virtual GHOST_TSuccess getButtonState(GHOST_TButtonMask mask, bool& isDown) const = 0;
+ /**
+ * Set which tablet API to use. Only affects Windows, other platforms have a single API.
+ * \param api Enum indicating which API to use.
+ */
+ virtual void setTabletAPI(GHOST_TTabletAPI api) = 0;
+
#ifdef WITH_INPUT_NDOF
/**
* Sets 3D mouse deadzone
diff --git a/intern/ghost/GHOST_Types.h b/intern/ghost/GHOST_Types.h
index 1fc1d1a3e56..f786c99342b 100644
--- a/intern/ghost/GHOST_Types.h
+++ b/intern/ghost/GHOST_Types.h
@@ -90,6 +90,12 @@ typedef enum {
GHOST_kTabletModeEraser
} GHOST_TTabletMode;
+typedef enum {
+ GHOST_kTabletAutomatic = 0,
+ GHOST_kTabletNative,
+ GHOST_kTabletWintab,
+} GHOST_TTabletAPI;
+
typedef struct GHOST_TabletData {
GHOST_TTabletMode Active; /* 0=None, 1=Stylus, 2=Eraser */
float Pressure; /* range 0.0 (not touching) to 1.0 (full pressure) */
diff --git a/intern/ghost/intern/GHOST_C-api.cpp b/intern/ghost/intern/GHOST_C-api.cpp
index ab0e7b724b8..d3fb7d6f043 100644
--- a/intern/ghost/intern/GHOST_C-api.cpp
+++ b/intern/ghost/intern/GHOST_C-api.cpp
@@ -750,8 +750,13 @@ GHOST_TSuccess GHOST_InvalidateWindow(GHOST_WindowHandle windowhandle)
return window->invalidate();
}
+void GHOST_SetTabletAPI(GHOST_SystemHandle systemhandle, GHOST_TTabletAPI api)
+{
+ GHOST_ISystem *system = (GHOST_ISystem *) systemhandle;
+ system->setTabletAPI(api);
+}
-extern const GHOST_TabletData *GHOST_GetTabletData(GHOST_WindowHandle windowhandle)
+const GHOST_TabletData *GHOST_GetTabletData(GHOST_WindowHandle windowhandle)
{
return ((GHOST_IWindow *)windowhandle)->GetTabletData();
}
diff --git a/intern/ghost/intern/GHOST_System.cpp b/intern/ghost/intern/GHOST_System.cpp
index fc69900acdf..149649f11d1 100644
--- a/intern/ghost/intern/GHOST_System.cpp
+++ b/intern/ghost/intern/GHOST_System.cpp
@@ -52,10 +52,11 @@ GHOST_System::GHOST_System()
m_displayManager(NULL),
m_timerManager(NULL),
m_windowManager(NULL),
- m_eventManager(NULL)
+ m_eventManager(NULL),
#ifdef WITH_INPUT_NDOF
- , m_ndofManager(0)
+ m_ndofManager(0),
#endif
+ m_tabletAPI(GHOST_kTabletAutomatic)
{
}
@@ -297,6 +298,16 @@ GHOST_TSuccess GHOST_System::getButtonState(GHOST_TButtonMask mask, bool& isDown
return success;
}
+void GHOST_System::setTabletAPI(GHOST_TTabletAPI api)
+{
+ m_tabletAPI = api;
+}
+
+bool GHOST_System::useTabletAPI(GHOST_TTabletAPI api) const
+{
+ return (m_tabletAPI == GHOST_kTabletAutomatic || m_tabletAPI == api);
+}
+
#ifdef WITH_INPUT_NDOF
void GHOST_System::setNDOFDeadZone(float deadzone)
{
diff --git a/intern/ghost/intern/GHOST_System.h b/intern/ghost/intern/GHOST_System.h
index ee3c30c35b4..7660ddc947e 100644
--- a/intern/ghost/intern/GHOST_System.h
+++ b/intern/ghost/intern/GHOST_System.h
@@ -247,6 +247,17 @@ public:
*/
GHOST_TSuccess getButtonState(GHOST_TButtonMask mask, bool& isDown) const;
+ /**
+ * Set which tablet API to use. Only affects Windows, other platforms have a single API.
+ * \param api Enum indicating which API to use.
+ */
+ void setTabletAPI(GHOST_TTabletAPI api);
+
+ /**
+ * Test if given tablet API should be used by event handling.
+ */
+ bool useTabletAPI(GHOST_TTabletAPI api) const;
+
#ifdef WITH_INPUT_NDOF
/***************************************************************************************
* Access to 3D mouse.
@@ -380,6 +391,8 @@ protected:
/** Settings of the display before the display went fullscreen. */
GHOST_DisplaySetting m_preFullScreenSetting;
+ /** Which tablet API to use. */
+ GHOST_TTabletAPI m_tabletAPI;
};
inline GHOST_TimerManager *GHOST_System::getTimerManager() const
diff --git a/intern/ghost/intern/GHOST_SystemWin32.cpp b/intern/ghost/intern/GHOST_SystemWin32.cpp
index 00852c1ad05..70010f8b558 100644
--- a/intern/ghost/intern/GHOST_SystemWin32.cpp
+++ b/intern/ghost/intern/GHOST_SystemWin32.cpp
@@ -122,6 +122,10 @@
#define WM_DPICHANGED 0x02E0
#endif // WM_DPICHANGED
+#ifndef WM_POINTERUPDATE
+#define WM_POINTERUPDATE 0x0245
+#endif // WM_POINTERUPDATE
+
/* Workaround for some laptop touchpads, some of which seems to
* have driver issues which makes it so window function receives
* the message, but PeekMessage doesn't pick those messages for
@@ -1233,6 +1237,9 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
case WT_PROXIMITY:
window->processWin32TabletInitEvent();
break;
+ case WM_POINTERUPDATE:
+ window->processWin32PointerEvent(wParam);
+ break;
////////////////////////////////////////////////////////////////////////
// Mouse events, processed
////////////////////////////////////////////////////////////////////////
@@ -1450,8 +1457,6 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
* change such as when the window is moved to a monitor with a different DPI.
*/
{
- WORD newYAxisDPI = HIWORD(wParam);
- WORD newXAxisDPI = LOWORD(wParam);
// The suggested new size and position of the window.
RECT* const suggestedWindowRect = (RECT*)lParam;
diff --git a/intern/ghost/intern/GHOST_WindowWin32.cpp b/intern/ghost/intern/GHOST_WindowWin32.cpp
index 7027c2af368..da23baa3111 100644
--- a/intern/ghost/intern/GHOST_WindowWin32.cpp
+++ b/intern/ghost/intern/GHOST_WindowWin32.cpp
@@ -51,7 +51,9 @@
#include <string.h>
#include <assert.h>
-
+#ifndef GET_POINTERID_WPARAM
+#define GET_POINTERID_WPARAM(wParam) (LOWORD(wParam))
+#endif // GET_POINTERID_WPARAM
const wchar_t *GHOST_WindowWin32::s_windowClassName = L"GHOST_WindowClass";
const int GHOST_WindowWin32::s_maxTitleLength = 128;
@@ -89,6 +91,8 @@ GHOST_WindowWin32::GHOST_WindowWin32(GHOST_SystemWin32 *system,
m_wantAlphaBackground(alphaBackground),
m_normal_state(GHOST_kWindowStateNormal),
m_user32(NULL),
+ m_fpGetPointerInfo(NULL),
+ m_fpGetPointerPenInfo(NULL),
m_parentWindowHwnd(parentwindowhwnd),
m_debug_context(is_debug)
{
@@ -284,6 +288,12 @@ GHOST_WindowWin32::GHOST_WindowWin32(GHOST_SystemWin32 *system,
RegisterRawInputDevices(&device, 1, sizeof(device));
}
+ // Initialize Windows Ink
+ if (m_user32) {
+ m_fpGetPointerInfo = (GHOST_WIN32_GetPointerInfo) ::GetProcAddress(m_user32, "GetPointerInfo");
+ m_fpGetPointerPenInfo = (GHOST_WIN32_GetPointerPenInfo) ::GetProcAddress(m_user32, "GetPointerPenInfo");
+ }
+
// Initialize Wintab
m_wintab.handle = ::LoadLibrary("Wintab32.dll");
if (m_wintab.handle) {
@@ -353,6 +363,7 @@ GHOST_WindowWin32::~GHOST_WindowWin32()
if (m_Bar) {
m_Bar->SetProgressState(m_hWnd, TBPF_NOPROGRESS);
m_Bar->Release();
+ m_Bar = NULL;
}
if (m_wintab.handle) {
@@ -364,6 +375,13 @@ GHOST_WindowWin32::~GHOST_WindowWin32()
memset(&m_wintab, 0, sizeof(m_wintab));
}
+ if (m_user32) {
+ FreeLibrary(m_user32);
+ m_user32 = NULL;
+ m_fpGetPointerInfo = NULL;
+ m_fpGetPointerPenInfo = NULL;
+ }
+
if (m_customCursor) {
DestroyCursor(m_customCursor);
m_customCursor = NULL;
@@ -371,6 +389,7 @@ GHOST_WindowWin32::~GHOST_WindowWin32()
if (m_hWnd != NULL && m_hDC != NULL && releaseNativeHandles()) {
::ReleaseDC(m_hWnd, m_hDC);
+ m_hDC = NULL;
}
if (m_hWnd) {
@@ -379,6 +398,7 @@ GHOST_WindowWin32::~GHOST_WindowWin32()
RevokeDragDrop(m_hWnd);
// Release our reference of the DropTarget and it will delete itself eventually.
m_dropTarget->Release();
+ m_dropTarget = NULL;
}
::SetWindowLongPtr(m_hWnd, GWLP_USERDATA, NULL);
::DestroyWindow(m_hWnd);
@@ -866,8 +886,62 @@ GHOST_TSuccess GHOST_WindowWin32::setWindowCursorShape(GHOST_TStandardCursor cur
return GHOST_kSuccess;
}
+void GHOST_WindowWin32::processWin32PointerEvent(WPARAM wParam)
+{
+ if (!m_system->useTabletAPI(GHOST_kTabletNative)) {
+ return; // Other tablet API specified by user
+ }
+
+ if (!m_fpGetPointerInfo || !m_fpGetPointerPenInfo) {
+ return; // OS version does not support pointer API
+ }
+
+ UINT32 pointerId = GET_POINTERID_WPARAM(wParam);
+ POINTER_INFO pointerInfo;
+ if (!m_fpGetPointerInfo(pointerId, &pointerInfo)) {
+ return; // Invalid pointer info
+ }
+
+ m_tabletData.Active = GHOST_kTabletModeNone;
+ m_tabletData.Pressure = 1.0f;
+ m_tabletData.Xtilt = 0.0f;
+ m_tabletData.Ytilt = 0.0f;
+
+ if (pointerInfo.pointerType & PT_POINTER) {
+ POINTER_PEN_INFO pointerPenInfo;
+ if (!m_fpGetPointerPenInfo(pointerId, &pointerPenInfo)) {
+ return;
+ }
+
+ // With the Microsoft Surface Pen if you hover the within 1cm of the screen the WM_POINTERUPDATE
+ // event will fire with PEN_MASK_PRESSURE mask set and zero pressure. In this case we disable
+ // tablet mode until the pen is physically touching. This enables the user to switch to the
+ // mouse and draw at full pressure.
+ if (pointerPenInfo.penMask & PEN_MASK_PRESSURE && pointerPenInfo.pressure > 0) {
+ m_tabletData.Active = GHOST_kTabletModeStylus;
+ m_tabletData.Pressure = pointerPenInfo.pressure / 1024.0f;
+ }
+
+ if (pointerPenInfo.penFlags & PEN_FLAG_ERASER) {
+ m_tabletData.Active = GHOST_kTabletModeEraser;
+ }
+
+ if (pointerPenInfo.penFlags & PEN_MASK_TILT_X) {
+ m_tabletData.Xtilt = fmin(fabs(pointerPenInfo.tiltX / 90), 1.0f);
+ }
+
+ if (pointerPenInfo.penFlags & PEN_MASK_TILT_Y) {
+ m_tabletData.Ytilt = fmin(fabs(pointerPenInfo.tiltY / 90), 1.0f);
+ }
+ }
+}
+
void GHOST_WindowWin32::processWin32TabletActivateEvent(WORD state)
{
+ if (!m_system->useTabletAPI(GHOST_kTabletWintab)) {
+ return;
+ }
+
if (m_wintab.enable && m_wintab.tablet) {
m_wintab.enable(m_wintab.tablet, state);
@@ -879,6 +953,10 @@ void GHOST_WindowWin32::processWin32TabletActivateEvent(WORD state)
void GHOST_WindowWin32::processWin32TabletInitEvent()
{
+ if (!m_system->useTabletAPI(GHOST_kTabletWintab)) {
+ return;
+ }
+
// Let's see if we can initialize tablet here
if (m_wintab.info && m_wintab.tablet) {
AXIS Pressure, Orientation[3]; /* The maximum tablet size */
@@ -903,10 +981,16 @@ void GHOST_WindowWin32::processWin32TabletInitEvent()
m_tabletData.Active = GHOST_kTabletModeNone;
}
+
+ m_tabletData.Active = GHOST_kTabletModeNone;
}
void GHOST_WindowWin32::processWin32TabletEvent(WPARAM wParam, LPARAM lParam)
{
+ if (!m_system->useTabletAPI(GHOST_kTabletWintab)) {
+ return;
+ }
+
if (m_wintab.packet && m_wintab.tablet) {
PACKET pkt;
if (m_wintab.packet((HCTX)lParam, wParam, &pkt)) {
@@ -972,6 +1056,10 @@ void GHOST_WindowWin32::processWin32TabletEvent(WPARAM wParam, LPARAM lParam)
void GHOST_WindowWin32::bringTabletContextToFront()
{
+ if (!m_system->useTabletAPI(GHOST_kTabletWintab)) {
+ return;
+ }
+
if (m_wintab.overlap && m_wintab.tablet) {
m_wintab.overlap(m_wintab.tablet, TRUE);
}
diff --git a/intern/ghost/intern/GHOST_WindowWin32.h b/intern/ghost/intern/GHOST_WindowWin32.h
index d790d5c3d24..4efcac53c85 100644
--- a/intern/ghost/intern/GHOST_WindowWin32.h
+++ b/intern/ghost/intern/GHOST_WindowWin32.h
@@ -68,6 +68,79 @@ typedef UINT(API * GHOST_WIN32_GetDpiForWindow)(HWND);
#define USER_DEFAULT_SCREEN_DPI 96
#endif // USER_DEFAULT_SCREEN_DPI
+// typedefs for user32 functions to allow pointer functions
+enum tagPOINTER_INPUT_TYPE {
+ PT_POINTER = 1, // Generic pointer
+ PT_TOUCH = 2, // Touch
+ PT_PEN = 3, // Pen
+ PT_MOUSE = 4, // Mouse
+#if(WINVER >= 0x0603)
+ PT_TOUCHPAD = 5, // Touchpad
+#endif /* WINVER >= 0x0603 */
+};
+
+typedef enum tagPOINTER_BUTTON_CHANGE_TYPE {
+ POINTER_CHANGE_NONE,
+ POINTER_CHANGE_FIRSTBUTTON_DOWN,
+ POINTER_CHANGE_FIRSTBUTTON_UP,
+ POINTER_CHANGE_SECONDBUTTON_DOWN,
+ POINTER_CHANGE_SECONDBUTTON_UP,
+ POINTER_CHANGE_THIRDBUTTON_DOWN,
+ POINTER_CHANGE_THIRDBUTTON_UP,
+ POINTER_CHANGE_FOURTHBUTTON_DOWN,
+ POINTER_CHANGE_FOURTHBUTTON_UP,
+ POINTER_CHANGE_FIFTHBUTTON_DOWN,
+ POINTER_CHANGE_FIFTHBUTTON_UP,
+} POINTER_BUTTON_CHANGE_TYPE;
+
+typedef DWORD POINTER_INPUT_TYPE;
+typedef UINT32 POINTER_FLAGS;
+
+typedef struct tagPOINTER_INFO {
+ POINTER_INPUT_TYPE pointerType;
+ UINT32 pointerId;
+ UINT32 frameId;
+ POINTER_FLAGS pointerFlags;
+ HANDLE sourceDevice;
+ HWND hwndTarget;
+ POINT ptPixelLocation;
+ POINT ptHimetricLocation;
+ POINT ptPixelLocationRaw;
+ POINT ptHimetricLocationRaw;
+ DWORD dwTime;
+ UINT32 historyCount;
+ INT32 InputData;
+ DWORD dwKeyStates;
+ UINT64 PerformanceCount;
+ POINTER_BUTTON_CHANGE_TYPE ButtonChangeType;
+} POINTER_INFO;
+
+typedef UINT32 PEN_FLAGS;
+#define PEN_FLAG_NONE 0x00000000 // Default
+#define PEN_FLAG_BARREL 0x00000001 // The barrel button is pressed
+#define PEN_FLAG_INVERTED 0x00000002 // The pen is inverted
+#define PEN_FLAG_ERASER 0x00000004 // The eraser button is pressed
+
+typedef UINT32 PEN_MASK;
+#define PEN_MASK_NONE 0x00000000 // Default - none of the optional fields are valid
+#define PEN_MASK_PRESSURE 0x00000001 // The pressure field is valid
+#define PEN_MASK_ROTATION 0x00000002 // The rotation field is valid
+#define PEN_MASK_TILT_X 0x00000004 // The tiltX field is valid
+#define PEN_MASK_TILT_Y 0x00000008 // The tiltY field is valid
+
+typedef struct tagPOINTER_PEN_INFO {
+ POINTER_INFO pointerInfo;
+ PEN_FLAGS penFlags;
+ PEN_MASK penMask;
+ UINT32 pressure;
+ UINT32 rotation;
+ INT32 tiltX;
+ INT32 tiltY;
+} POINTER_PEN_INFO;
+
+typedef BOOL (API * GHOST_WIN32_GetPointerInfo)(UINT32 pointerId, POINTER_INFO *pointerInfo);
+typedef BOOL (API * GHOST_WIN32_GetPointerPenInfo)(UINT32 pointerId, POINTER_PEN_INFO *penInfo);
+
/**
* GHOST window on M$ Windows OSs.
* \author Maarten Gribnau
@@ -253,6 +326,7 @@ public:
return &m_tabletData;
}
+ void processWin32PointerEvent(WPARAM wParam);
void processWin32TabletActivateEvent(WORD state);
void processWin32TabletInitEvent();
void processWin32TabletEvent(WPARAM wParam, LPARAM lParam);
@@ -377,6 +451,8 @@ private:
/** user32 dll handle*/
HMODULE m_user32;
+ GHOST_WIN32_GetPointerInfo m_fpGetPointerInfo;
+ GHOST_WIN32_GetPointerPenInfo m_fpGetPointerPenInfo;
/** Hwnd to parent window */
GHOST_TEmbedderWindowID m_parentWindowHwnd;
diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py
index 6abf2e92da8..a4feabf7254 100644
--- a/release/scripts/startup/bl_ui/space_userpref.py
+++ b/release/scripts/startup/bl_ui/space_userpref.py
@@ -1504,6 +1504,11 @@ class USERPREF_PT_input_devices_tablet(PreferencePanel):
prefs = context.preferences
inputs = prefs.inputs
+ import sys
+ if sys.platform[:3] == "win":
+ layout.prop(inputs, "tablet_api")
+ layout.separator()
+
flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=False)
flow.prop(inputs, "pressure_threshold_max")
diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h
index a749fba5026..a653aaec671 100644
--- a/source/blender/makesdna/DNA_userdef_types.h
+++ b/source/blender/makesdna/DNA_userdef_types.h
@@ -694,13 +694,16 @@ typedef struct UserDef {
/** Seconds to zoom around current frame. */
float view_frame_seconds;
- char _pad1[4];
+ char _pad1[2];
/** Private, defaults to 20 for 72 DPI setting. */
short widget_unit;
short anisotropic_filter;
short use_16bit_textures, use_gpu_mipmap;
+ /** Tablet API to use (Windows only). */
+ short tablet_api;
+
/** Raw tablet pressure that maps to 100%. */
float pressure_threshold_max;
/** Curve non-linearity parameter. */
@@ -915,6 +918,13 @@ typedef enum eUserpref_UI_Flag2 {
USER_TRACKPAD_NATURAL = (1 << 2),
} eUserpref_UI_Flag2;
+/* UserDef.tablet_api */
+typedef enum eUserpref_TableAPI {
+ USER_TABLET_AUTOMATIC = 0,
+ USER_TABLET_NATIVE = 1,
+ USER_TABLET_WINTAB = 2,
+} eUserpref_TabletAPI;
+
/* UserDef.app_flag */
typedef enum eUserpref_APP_Flag {
USER_APP_LOCK_UI_LAYOUT = (1 << 0),
diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c
index 15f20a6aba7..eea2595d2a7 100644
--- a/source/blender/makesrna/intern/rna_userdef.c
+++ b/source/blender/makesrna/intern/rna_userdef.c
@@ -236,6 +236,11 @@ static void rna_userdef_autokeymode_set(PointerRNA *ptr, int value)
}
}
+static void rna_userdef_tablet_api_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *UNUSED(ptr))
+{
+ WM_init_tablet_api();
+}
+
#ifdef WITH_INPUT_NDOF
static void rna_userdef_ndof_deadzone_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
{
@@ -4608,6 +4613,13 @@ static void rna_def_userdef_input(BlenderRNA *brna)
};
#endif /* WITH_INPUT_NDOF */
+ static const EnumPropertyItem tablet_api[] = {
+ {USER_TABLET_AUTOMATIC, "AUTOMATIC", 0, "Automatic", "Automatically choose Wintab or Windows Ink depending on the device"},
+ {USER_TABLET_NATIVE, "WINDOWS_INK", 0, "Windows Ink", "Use native Windows Ink API, for modern tablet and pen devices. Requires Windows 8 or newer"},
+ {USER_TABLET_WINTAB, "WINTAB", 0, "Wintab", "Use Wintab driver for older tablets and Windows versions"},
+ {0, NULL, 0, NULL, NULL}
+ };
+
static const EnumPropertyItem view_zoom_styles[] = {
{USER_ZOOM_CONT, "CONTINUE", 0, "Continue", "Old style zoom, continues while moving mouse up or down"},
{USER_ZOOM_DOLLY, "DOLLY", 0, "Dolly", "Zoom in and out based on vertical mouse movement"},
@@ -4733,6 +4745,11 @@ static void rna_def_userdef_input(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Softness",
"Adjusts softness of the low pressure response onset using a gamma curve");
+ prop = RNA_def_property(srna, "tablet_api", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_items(prop, tablet_api);
+ RNA_def_property_ui_text(prop, "Tablet API", "Select the tablet API to use for pressure sensitivity");
+ RNA_def_property_update(prop, 0, "rna_userdef_tablet_api_update");
+
#ifdef WITH_INPUT_NDOF
/* 3D mouse settings */
/* global options */
diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h
index adf082982b7..9daed32ee33 100644
--- a/source/blender/windowmanager/WM_api.h
+++ b/source/blender/windowmanager/WM_api.h
@@ -91,6 +91,7 @@ void WM_init_state_fullscreen_set(void);
void WM_init_state_normal_set(void);
void WM_init_window_focus_set(bool do_it);
void WM_init_native_pixels(bool do_it);
+void WM_init_tablet_api(void);
void WM_init (struct bContext *C, int argc, const char **argv);
void WM_exit_ext (struct bContext *C, const bool do_python);
diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c
index 281a556a62d..8b76b2a5d32 100644
--- a/source/blender/windowmanager/intern/wm_window.c
+++ b/source/blender/windowmanager/intern/wm_window.c
@@ -1690,6 +1690,8 @@ void wm_ghost_init(bContext *C)
}
GHOST_UseWindowFocus(wm_init_state.window_focus);
+
+ WM_init_tablet_api();
}
}
@@ -1979,6 +1981,24 @@ void WM_init_native_pixels(bool do_it)
wm_init_state.native_pixels = do_it;
}
+void WM_init_tablet_api(void)
+{
+ if (g_system) {
+ switch(U.tablet_api) {
+ case USER_TABLET_NATIVE:
+ GHOST_SetTabletAPI(g_system, GHOST_kTabletNative);
+ break;
+ case USER_TABLET_WINTAB:
+ GHOST_SetTabletAPI(g_system, GHOST_kTabletWintab);
+ break;
+ case USER_TABLET_AUTOMATIC:
+ default:
+ GHOST_SetTabletAPI(g_system, GHOST_kTabletAutomatic);
+ break;
+ }
+ }
+}
+
/* This function requires access to the GHOST_SystemHandle (g_system) */
void WM_cursor_warp(wmWindow *win, int x, int y)
{