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.h8
-rw-r--r--intern/ghost/GHOST_IWindow.h6
-rw-r--r--intern/ghost/GHOST_Types.h7
-rw-r--r--intern/ghost/intern/GHOST_C-api.cpp8
-rw-r--r--intern/ghost/intern/GHOST_SystemCarbon.cpp90
-rw-r--r--intern/ghost/intern/GHOST_SystemCarbon.h7
-rwxr-xr-xintern/ghost/intern/GHOST_SystemX11.cpp20
-rw-r--r--intern/ghost/intern/GHOST_WindowCarbon.cpp2
-rw-r--r--intern/ghost/intern/GHOST_WindowCarbon.h7
-rw-r--r--intern/ghost/intern/GHOST_WindowWin32.h3
-rwxr-xr-xintern/ghost/intern/GHOST_WindowX11.cpp65
-rwxr-xr-xintern/ghost/intern/GHOST_WindowX11.h29
12 files changed, 239 insertions, 13 deletions
diff --git a/intern/ghost/GHOST_C-api.h b/intern/ghost/GHOST_C-api.h
index ba22074a620..4c4094409dd 100644
--- a/intern/ghost/GHOST_C-api.h
+++ b/intern/ghost/GHOST_C-api.h
@@ -608,6 +608,13 @@ extern GHOST_TSuccess GHOST_ActivateWindowDrawingContext(GHOST_WindowHandle wind
extern GHOST_TSuccess GHOST_InvalidateWindow(GHOST_WindowHandle windowhandle);
/**
+ * Returns the status of the tablet
+ * @param windowhandle The handle to the window
+ * @return Status of tablet
+ */
+extern const GHOST_TabletData *GHOST_GetTabletData(GHOST_WindowHandle windowhandle);
+
+/**
* Access to rectangle width.
* @param rectanglehandle The handle to the rectangle
* @return width of the rectangle
@@ -751,7 +758,6 @@ extern void GHOST_SetRectangleCenter(GHOST_RectangleHandle rectanglehandle,
*/
extern GHOST_TSuccess GHOST_ClipRectangle(GHOST_RectangleHandle rectanglehandle,
GHOST_RectangleHandle anotherrectanglehandle);
-
#ifdef __cplusplus
}
#endif
diff --git a/intern/ghost/GHOST_IWindow.h b/intern/ghost/GHOST_IWindow.h
index 903d1e4498d..5f6bbe553c6 100644
--- a/intern/ghost/GHOST_IWindow.h
+++ b/intern/ghost/GHOST_IWindow.h
@@ -201,6 +201,12 @@ public:
*/
virtual void setUserData(const GHOST_TUserDataPtr userData) = 0;
+ /**
+ * Returns the tablet data (pressure etc).
+ * @return The tablet data (pressure etc).
+ */
+ virtual const GHOST_TabletData* GetTabletData() = 0;
+
/***************************************************************************************
** Cursor management functionality
***************************************************************************************/
diff --git a/intern/ghost/GHOST_Types.h b/intern/ghost/GHOST_Types.h
index 8e439cfc9e3..4abecce50c1 100644
--- a/intern/ghost/GHOST_Types.h
+++ b/intern/ghost/GHOST_Types.h
@@ -55,6 +55,13 @@ typedef enum
GHOST_kSuccess
} GHOST_TSuccess;
+typedef struct GHOST_TabletData {
+ char Active; /* 0=None, 1=Stylus, 2=Eraser */
+ float Pressure;
+ float Xtilt;
+ float Ytilt;
+} GHOST_TabletData;
+
typedef enum {
GHOST_kNotVisible = 0,
diff --git a/intern/ghost/intern/GHOST_C-api.cpp b/intern/ghost/intern/GHOST_C-api.cpp
index 6f8ddd858ef..fbb4cca91e0 100644
--- a/intern/ghost/intern/GHOST_C-api.cpp
+++ b/intern/ghost/intern/GHOST_C-api.cpp
@@ -649,6 +649,11 @@ GHOST_TSuccess GHOST_InvalidateWindow(GHOST_WindowHandle windowhandle)
}
+extern const GHOST_TabletData* GHOST_GetTabletData(GHOST_WindowHandle windowhandle)
+{
+ return ((GHOST_IWindow*)windowhandle)->GetTabletData();
+}
+
GHOST_TInt32 GHOST_GetWidthRectangle(GHOST_RectangleHandle rectanglehandle)
{
@@ -795,6 +800,3 @@ GHOST_TSuccess GHOST_ClipRectangle(GHOST_RectangleHandle rectanglehandle,
return result;
}
-
-
-
diff --git a/intern/ghost/intern/GHOST_SystemCarbon.cpp b/intern/ghost/intern/GHOST_SystemCarbon.cpp
index ef9e91ec3df..9e790154eb9 100644
--- a/intern/ghost/intern/GHOST_SystemCarbon.cpp
+++ b/intern/ghost/intern/GHOST_SystemCarbon.cpp
@@ -688,6 +688,79 @@ OSStatus GHOST_SystemCarbon::handleWindowEvent(EventRef event)
return err;
}
+OSStatus GHOST_SystemCarbon::handleTabletEvent(EventRef event)
+{
+ GHOST_IWindow* window = m_windowManager->getActiveWindow();
+ TabletPointRec tabletPointRecord;
+ TabletProximityRec tabletProximityRecord;
+ UInt32 anInt32;
+ GHOST_TabletData& ct=((GHOST_WindowCarbon*)window)->GetCarbonTabletData();
+ OSStatus err = eventNotHandledErr;
+
+ ct.Pressure = 0;
+ ct.Xtilt = 0;
+ ct.Ytilt = 0;
+
+ // is there an embedded tablet event inside this mouse event?
+ if(noErr == GetEventParameter(event, kEventParamTabletEventType, typeUInt32, NULL, sizeof(UInt32), NULL, (void *)&anInt32))
+ {
+ // yes there is one!
+ // Embedded tablet events can either be a proximity or pointer event.
+ if(anInt32 == kEventTabletPoint)
+ {
+ //GHOST_PRINT("Embedded pointer event!\n");
+
+ // Extract the tablet Pointer Event. If there is no Tablet Pointer data
+ // in this event, then this call will return an error. Just ignore the
+ // error and go on. This can occur when a proximity event is embedded in
+ // a mouse event and you did not check the mouse event to see which type
+ // of tablet event was embedded.
+ if(noErr == GetEventParameter(event, kEventParamTabletPointRec,
+ typeTabletPointRec, NULL,
+ sizeof(TabletPointRec),
+ NULL, (void *)&tabletPointRecord))
+ {
+ ct.Pressure = tabletPointRecord.pressure / 65535.0f;
+ ct.Xtilt = tabletPointRecord.tiltX / 32767.0f; /* can be positive or negative */
+ ct.Ytilt = tabletPointRecord.tiltY / 32767.0f; /* can be positive or negative */
+ }
+ } else {
+ //GHOST_PRINT("Embedded proximity event\n");
+
+ // Extract the Tablet Proximity record from the event.
+ if(noErr == GetEventParameter(event, kEventParamTabletProximityRec,
+ typeTabletProximityRec, NULL,
+ sizeof(TabletProximityRec),
+ NULL, (void *)&tabletProximityRecord))
+ {
+ if (tabletProximityRecord.enterProximity) {
+ //pointer is entering tablet area proximity
+
+ switch(tabletProximityRecord.pointerType)
+ {
+ case 1: /* stylus */
+ ct.Active = 1;
+ break;
+ case 2: /* puck, not supported so far */
+ ct.Active = 0;
+ break;
+ case 3: /* eraser */
+ ct.Active = 2;
+ break;
+ default:
+ ct.Active = 0;
+ break;
+ }
+ } else {
+ // pointer is leaving - return to mouse
+ ct.Active = 0;
+ }
+ }
+ }
+ err = noErr;
+ }
+}
+
OSStatus GHOST_SystemCarbon::handleMouseEvent(EventRef event)
{
OSStatus err = eventNotHandledErr;
@@ -708,6 +781,9 @@ OSStatus GHOST_SystemCarbon::handleMouseEvent(EventRef event)
/* Window still gets mouse up after command-H */
if (m_windowManager->getActiveWindow()) {
+ // handle any tablet events that may have come with the mouse event (optional)
+ handleTabletEvent(event);
+
::GetEventParameter(event, kEventParamMouseButton, typeMouseButton, NULL, sizeof(button), NULL, &button);
pushEvent(new GHOST_EventButton(getMilliSeconds(), type, window, convertButton(button)));
err = noErr;
@@ -716,15 +792,19 @@ OSStatus GHOST_SystemCarbon::handleMouseEvent(EventRef event)
break;
case kEventMouseMoved:
- case kEventMouseDragged:
- Point mousePos;
+ case kEventMouseDragged: {
+ Point mousePos;
+
if (window) {
+ //handle any tablet events that may have come with the mouse event (optional)
+ handleTabletEvent(event);
+
::GetEventParameter(event, kEventParamMouseLocation, typeQDPoint, NULL, sizeof(Point), NULL, &mousePos);
pushEvent(new GHOST_EventCursor(getMilliSeconds(), GHOST_kEventCursorMove, window, mousePos.h, mousePos.v));
err = noErr;
- }
- break;
-
+ }
+ break;
+ }
case kEventMouseWheelMoved:
{
OSStatus status;
diff --git a/intern/ghost/intern/GHOST_SystemCarbon.h b/intern/ghost/intern/GHOST_SystemCarbon.h
index 740006a335f..93022aa78ff 100644
--- a/intern/ghost/intern/GHOST_SystemCarbon.h
+++ b/intern/ghost/intern/GHOST_SystemCarbon.h
@@ -182,6 +182,13 @@ protected:
*/
virtual GHOST_TSuccess exit();
+
+ /**
+ * Handles a tablet event.
+ * @param event A Mac event.
+ * @return Indication whether the event was handled.
+ */
+ OSStatus handleTabletEvent(EventRef event);
/**
* Handles a mouse event.
* @param event A Mac event.
diff --git a/intern/ghost/intern/GHOST_SystemX11.cpp b/intern/ghost/intern/GHOST_SystemX11.cpp
index e6d1962958a..68bdd1a09a3 100755
--- a/intern/ghost/intern/GHOST_SystemX11.cpp
+++ b/intern/ghost/intern/GHOST_SystemX11.cpp
@@ -338,7 +338,7 @@ processEvent(
if (!window) {
return;
}
-
+
switch (xe->type) {
case Expose:
{
@@ -357,6 +357,7 @@ processEvent(
}
break;
}
+
case MotionNotify:
{
XMotionEvent &xme = xe->xmotion;
@@ -506,8 +507,23 @@ processEvent(
case ReparentNotify:
break;
- default:
+ default: {
+ if(xe->type == window->GetXTablet().MotionEvent) {
+ XDeviceMotionEvent* data = (XDeviceMotionEvent*)xe;
+ window->GetXTablet().CommonData.Pressure= data->axis_data[2]/((float)window->GetXTablet().PressureLevels);
+ }
+ else if(xe->type == window->GetXTablet().ProxInEvent) {
+ XProximityNotifyEvent* data = (XProximityNotifyEvent*)xe;
+ if(data->deviceid == window->GetXTablet().StylusID)
+ window->GetXTablet().CommonData.Active= 1;
+ else if(data->deviceid == window->GetXTablet().EraserID)
+ window->GetXTablet().CommonData.Active= 2;
+ }
+ else if(xe->type == window->GetXTablet().ProxOutEvent)
+ window->GetXTablet().CommonData.Active= 0;
+
break;
+ }
}
if (g_event) {
diff --git a/intern/ghost/intern/GHOST_WindowCarbon.cpp b/intern/ghost/intern/GHOST_WindowCarbon.cpp
index 30c88ccd777..4484ec54da6 100644
--- a/intern/ghost/intern/GHOST_WindowCarbon.cpp
+++ b/intern/ghost/intern/GHOST_WindowCarbon.cpp
@@ -185,6 +185,8 @@ GHOST_WindowCarbon::GHOST_WindowCarbon(
setDrawingContextType(GHOST_kDrawingContextTypeOpenGL);;installDrawingContext(GHOST_kDrawingContextTypeOpenGL);
updateDrawingContext();
activateDrawingContext();
+
+ m_tablet.Active = 0;
}
}
diff --git a/intern/ghost/intern/GHOST_WindowCarbon.h b/intern/ghost/intern/GHOST_WindowCarbon.h
index 582979e6248..5b81470a030 100644
--- a/intern/ghost/intern/GHOST_WindowCarbon.h
+++ b/intern/ghost/intern/GHOST_WindowCarbon.h
@@ -213,6 +213,11 @@ public:
virtual short getMac_windowState();
+ const GHOST_TabletData* GetTabletData()
+ { return &m_tablet; }
+
+ GHOST_TabletData& GetCarbonTabletData()
+ { return m_tablet; }
protected:
/**
* Tries to install a rendering context in this window.
@@ -276,6 +281,8 @@ protected:
static AGLContext s_firstaglCtx;
Cursor* m_customCursor;
+
+ GHOST_TabletData m_tablet;
/** When running in full-screen this tells whether to refresh the window. */
bool m_fullScreenDirty;
diff --git a/intern/ghost/intern/GHOST_WindowWin32.h b/intern/ghost/intern/GHOST_WindowWin32.h
index b96e0f401ea..5a0ff3e2052 100644
--- a/intern/ghost/intern/GHOST_WindowWin32.h
+++ b/intern/ghost/intern/GHOST_WindowWin32.h
@@ -216,7 +216,8 @@ public:
*/
void loadCursor(bool visible, GHOST_TStandardCursor cursorShape) const;
-
+ const GHOST_TabletData* GetTabletData()
+ { return NULL; }
protected:
/**
* Tries to install a rendering context in this window.
diff --git a/intern/ghost/intern/GHOST_WindowX11.cpp b/intern/ghost/intern/GHOST_WindowX11.cpp
index cfdc1739074..87798b02ff4 100755
--- a/intern/ghost/intern/GHOST_WindowX11.cpp
+++ b/intern/ghost/intern/GHOST_WindowX11.cpp
@@ -193,7 +193,9 @@ GHOST_WindowX11(
XFree(xclasshint);
setTitle(title);
-
+
+ initXInputDevices();
+
// now set up the rendering context.
if (installDrawingContext(type) == GHOST_kSuccess) {
m_valid_setup = true;
@@ -206,6 +208,67 @@ GHOST_WindowX11(
XFlush(m_display);
}
+void GHOST_WindowX11::initXInputDevices()
+{
+ XExtensionVersion *version = XGetExtensionVersion(m_display, INAME);
+ if(version && (version != (XExtensionVersion*)NoSuchExtension)) {
+ if(version->present) {
+ int device_count;
+ XDeviceInfo* device_info = XListInputDevices(m_display, &device_count);
+ m_xtablet.StylusDevice = 0;
+ m_xtablet.EraserDevice = 0;
+ m_xtablet.CommonData.Active= 0;
+
+ for(int i=0; i<device_count; ++i) {
+ if(!strcmp(device_info[i].name, "stylus")) {
+ m_xtablet.StylusID= device_info[i].id;
+ m_xtablet.StylusDevice = XOpenDevice(m_display, m_xtablet.StylusID);
+
+ /* Find how many pressure levels tablet has */
+ XAnyClassPtr ici = device_info[i].inputclassinfo;
+ for(int j=0; j<m_xtablet.StylusDevice->num_classes; ++j) {
+ if(ici->c_class==ValuatorClass) {
+ XValuatorInfo* xvi = (XValuatorInfo*)ici;
+ m_xtablet.PressureLevels = xvi->axes[2].max_value;
+ break;
+ }
+
+ ici = (XAnyClassPtr)(((char *)ici) + ici->length);
+ }
+ }
+ if(!strcmp(device_info[i].name, "eraser")) {
+ m_xtablet.EraserID= device_info[i].id;
+ m_xtablet.EraserDevice = XOpenDevice(m_display, m_xtablet.EraserID);
+ }
+ }
+ XFreeDeviceList(device_info);
+
+ XEventClass xevents[10], ev;
+ int dcount = 0;
+ if(m_xtablet.StylusDevice) {
+ DeviceMotionNotify(m_xtablet.StylusDevice, m_xtablet.MotionEvent, ev);
+ if(ev) xevents[dcount++] = ev;
+ ProximityIn(m_xtablet.StylusDevice, m_xtablet.ProxInEvent, ev);
+ if(ev) xevents[dcount++] = ev;
+ ProximityOut(m_xtablet.StylusDevice, m_xtablet.ProxOutEvent, ev);
+ if(ev) xevents[dcount++] = ev;
+ }
+ if(m_xtablet.EraserDevice) {
+ DeviceMotionNotify(m_xtablet.EraserDevice, m_xtablet.MotionEvent, ev);
+ if(ev) xevents[dcount++] = ev;
+ ProximityIn(m_xtablet.EraserDevice, m_xtablet.ProxInEvent, ev);
+ if(ev) xevents[dcount++] = ev;
+ ProximityOut(m_xtablet.EraserDevice, m_xtablet.ProxOutEvent, ev);
+ if(ev) xevents[dcount++] = ev;
+ }
+
+ XSelectExtensionEvent(m_display, m_window, xevents, dcount);
+ }
+ XFree(version);
+ }
+}
+
+
Window
GHOST_WindowX11::
getXWindow(
diff --git a/intern/ghost/intern/GHOST_WindowX11.h b/intern/ghost/intern/GHOST_WindowX11.h
index d8b5f61697e..863644da095 100755
--- a/intern/ghost/intern/GHOST_WindowX11.h
+++ b/intern/ghost/intern/GHOST_WindowX11.h
@@ -39,6 +39,8 @@
#include "GHOST_Window.h"
#include <X11/Xlib.h>
#include <GL/glx.h>
+// For tablets
+#include <X11/extensions/XInput.h>
#include <map>
@@ -188,6 +190,28 @@ public:
getXWindow(
);
+ class XTablet
+ {
+ public:
+ GHOST_TabletData CommonData;
+
+ XDevice* StylusDevice;
+ XDevice* EraserDevice;
+
+ XID StylusID, EraserID;
+
+ int MotionEvent;
+ int ProxInEvent;
+ int ProxOutEvent;
+
+ int PressureLevels;
+ };
+
+ XTablet& GetXTablet()
+ { return m_xtablet; }
+
+ const GHOST_TabletData* GetTabletData()
+ { return &m_xtablet.CommonData; }
protected:
/**
* Tries to install a rendering context in this window.
@@ -272,6 +296,8 @@ private :
Cursor
getEmptyCursor(
);
+
+ void initXInputDevices();
GLXContext m_context;
Window m_window;
@@ -298,6 +324,9 @@ private :
/** Cache of XC_* ID's to XCursor structures */
std::map<unsigned int, Cursor> m_standard_cursors;
+
+ /* Tablet devices */
+ XTablet m_xtablet;
};