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:
Diffstat (limited to 'intern/ghost/intern')
-rw-r--r--intern/ghost/intern/GHOST_Path-api.cpp6
-rw-r--r--intern/ghost/intern/GHOST_SystemCocoa.mm11
-rw-r--r--intern/ghost/intern/GHOST_SystemPathsCocoa.h6
-rw-r--r--intern/ghost/intern/GHOST_SystemPathsCocoa.mm52
-rw-r--r--intern/ghost/intern/GHOST_SystemPathsUnix.cpp59
-rw-r--r--intern/ghost/intern/GHOST_SystemPathsUnix.h6
-rw-r--r--intern/ghost/intern/GHOST_SystemPathsWin32.cpp45
-rw-r--r--intern/ghost/intern/GHOST_SystemPathsWin32.h6
-rw-r--r--intern/ghost/intern/GHOST_SystemWin32.cpp4
-rw-r--r--intern/ghost/intern/GHOST_WindowWayland.cpp2
-rw-r--r--intern/ghost/intern/GHOST_WindowWin32.cpp69
-rw-r--r--intern/ghost/intern/GHOST_WindowWin32.h14
12 files changed, 243 insertions, 37 deletions
diff --git a/intern/ghost/intern/GHOST_Path-api.cpp b/intern/ghost/intern/GHOST_Path-api.cpp
index df3592fb5e5..c82e9819f3c 100644
--- a/intern/ghost/intern/GHOST_Path-api.cpp
+++ b/intern/ghost/intern/GHOST_Path-api.cpp
@@ -50,6 +50,12 @@ const GHOST_TUns8 *GHOST_getUserDir(int version, const char *versionstr)
return systemPaths ? systemPaths->getUserDir(version, versionstr) : NULL; /* shouldn't be NULL */
}
+const GHOST_TUns8 *GHOST_getUserSpecialDir(GHOST_TUserSpecialDirTypes type)
+{
+ GHOST_ISystemPaths *systemPaths = GHOST_ISystemPaths::get();
+ return systemPaths ? systemPaths->getUserSpecialDir(type) : NULL; /* shouldn't be NULL */
+}
+
const GHOST_TUns8 *GHOST_getBinaryDir()
{
GHOST_ISystemPaths *systemPaths = GHOST_ISystemPaths::get();
diff --git a/intern/ghost/intern/GHOST_SystemCocoa.mm b/intern/ghost/intern/GHOST_SystemCocoa.mm
index d5b8311349b..d7dbfbe8813 100644
--- a/intern/ghost/intern/GHOST_SystemCocoa.mm
+++ b/intern/ghost/intern/GHOST_SystemCocoa.mm
@@ -82,8 +82,8 @@ static GHOST_TButtonMask convertButton(int button)
/**
* Converts Mac rawkey codes (same for Cocoa & Carbon)
* into GHOST key codes
- * \param rawCode The raw physical key code
- * \param recvChar the character ignoring modifiers (except for shift)
+ * \param rawCode: The raw physical key code
+ * \param recvChar: the character ignoring modifiers (except for shift)
* \return Ghost key code
*/
static GHOST_TKey convertKey(int rawCode, unichar recvChar, UInt16 keyAction)
@@ -783,7 +783,7 @@ GHOST_IContext *GHOST_SystemCocoa::createOffscreenContext(GHOST_GLSettings glSet
/**
* Dispose of a context.
- * \param context Pointer to the context to be disposed.
+ * \param context: Pointer to the context to be disposed.
* \return Indication of success.
*/
GHOST_TSuccess GHOST_SystemCocoa::disposeContext(GHOST_IContext *context)
@@ -1730,13 +1730,14 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr)
}
window->clientToScreenIntern(mousePos.x, mousePos.y, x, y);
+ NSPoint delta = [[cocoawindow contentView] convertPointToBacking:NSMakePoint(dx, dy)];
pushEvent(new GHOST_EventTrackpad([event timestamp] * 1000,
window,
GHOST_kTrackpadEventScroll,
x,
y,
- dx,
- dy,
+ delta.x,
+ delta.y,
[event isDirectionInvertedFromDevice]));
}
} break;
diff --git a/intern/ghost/intern/GHOST_SystemPathsCocoa.h b/intern/ghost/intern/GHOST_SystemPathsCocoa.h
index 188f6f02286..14633d46f03 100644
--- a/intern/ghost/intern/GHOST_SystemPathsCocoa.h
+++ b/intern/ghost/intern/GHOST_SystemPathsCocoa.h
@@ -56,6 +56,12 @@ class GHOST_SystemPathsCocoa : public GHOST_SystemPaths {
const GHOST_TUns8 *getUserDir(int version, const char *versionstr) const;
/**
+ * Determine a special ("well known") and easy to reach user directory.
+ * \return Unsigned char string pointing to user dir (eg `~/Documents/`).
+ */
+ const GHOST_TUns8 *getUserSpecialDir(GHOST_TUserSpecialDirTypes type) const;
+
+ /**
* Determine the directory of the current binary
* \return Unsigned char string pointing to the binary dir
*/
diff --git a/intern/ghost/intern/GHOST_SystemPathsCocoa.mm b/intern/ghost/intern/GHOST_SystemPathsCocoa.mm
index 830d58ba42c..7c6184837bf 100644
--- a/intern/ghost/intern/GHOST_SystemPathsCocoa.mm
+++ b/intern/ghost/intern/GHOST_SystemPathsCocoa.mm
@@ -21,6 +21,7 @@
#import <Foundation/Foundation.h>
+#include "GHOST_Debug.h"
#include "GHOST_SystemPathsCocoa.h"
#pragma mark initialization/finalization
@@ -89,6 +90,57 @@ const GHOST_TUns8 *GHOST_SystemPathsCocoa::getUserDir(int, const char *versionst
return (GHOST_TUns8 *)tempPath;
}
+const GHOST_TUns8 *GHOST_SystemPathsCocoa::getUserSpecialDir(GHOST_TUserSpecialDirTypes type) const
+{
+ static char tempPath[512] = "";
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ NSString *basePath;
+ NSArray *paths;
+ NSSearchPathDirectory ns_directory;
+
+ switch (type) {
+ case GHOST_kUserSpecialDirDesktop:
+ ns_directory = NSDesktopDirectory;
+ break;
+ case GHOST_kUserSpecialDirDocuments:
+ ns_directory = NSDocumentDirectory;
+ break;
+ case GHOST_kUserSpecialDirDownloads:
+ ns_directory = NSDownloadsDirectory;
+ break;
+ case GHOST_kUserSpecialDirMusic:
+ ns_directory = NSMusicDirectory;
+ break;
+ case GHOST_kUserSpecialDirPictures:
+ ns_directory = NSPicturesDirectory;
+ break;
+ case GHOST_kUserSpecialDirVideos:
+ ns_directory = NSMoviesDirectory;
+ break;
+ default:
+ GHOST_ASSERT(
+ false,
+ "GHOST_SystemPathsCocoa::getUserSpecialDir(): Invalid enum value for type parameter");
+ [pool drain];
+ return NULL;
+ }
+
+ paths = NSSearchPathForDirectoriesInDomains(ns_directory, NSUserDomainMask, YES);
+
+ if ([paths count] > 0)
+ basePath = [paths objectAtIndex:0];
+ else {
+ [pool drain];
+ return NULL;
+ }
+
+ strncpy(
+ (char *)tempPath, [basePath cStringUsingEncoding:NSASCIIStringEncoding], sizeof(tempPath));
+
+ [pool drain];
+ return (GHOST_TUns8 *)tempPath;
+}
+
const GHOST_TUns8 *GHOST_SystemPathsCocoa::getBinaryDir() const
{
static GHOST_TUns8 tempPath[512] = "";
diff --git a/intern/ghost/intern/GHOST_SystemPathsUnix.cpp b/intern/ghost/intern/GHOST_SystemPathsUnix.cpp
index ad3d490eb91..86f3a0a31fb 100644
--- a/intern/ghost/intern/GHOST_SystemPathsUnix.cpp
+++ b/intern/ghost/intern/GHOST_SystemPathsUnix.cpp
@@ -21,6 +21,9 @@
* \ingroup GHOST
*/
+#include <cstdio>
+#include <sstream>
+
#include "GHOST_SystemPathsUnix.h"
#include "GHOST_Debug.h"
@@ -108,6 +111,62 @@ const GHOST_TUns8 *GHOST_SystemPathsUnix::getUserDir(int version, const char *ve
}
}
+const GHOST_TUns8 *GHOST_SystemPathsUnix::getUserSpecialDir(GHOST_TUserSpecialDirTypes type) const
+{
+ const char *type_str;
+
+ switch (type) {
+ case GHOST_kUserSpecialDirDesktop:
+ type_str = "DESKTOP";
+ break;
+ case GHOST_kUserSpecialDirDocuments:
+ type_str = "DOCUMENTS";
+ break;
+ case GHOST_kUserSpecialDirDownloads:
+ type_str = "DOWNLOAD";
+ break;
+ case GHOST_kUserSpecialDirMusic:
+ type_str = "MUSIC";
+ break;
+ case GHOST_kUserSpecialDirPictures:
+ type_str = "PICTURES";
+ break;
+ case GHOST_kUserSpecialDirVideos:
+ type_str = "VIDEOS";
+ break;
+ default:
+ GHOST_ASSERT(
+ false,
+ "GHOST_SystemPathsUnix::getUserSpecialDir(): Invalid enum value for type parameter");
+ return NULL;
+ }
+
+ static string path = "";
+ /* Pipe stderr to /dev/null to avoid error prints. We will fail gracefully still. */
+ string command = string("xdg-user-dir ") + type_str + " 2> /dev/null";
+
+ FILE *fstream = popen(command.c_str(), "r");
+ if (fstream == NULL) {
+ return NULL;
+ }
+ std::stringstream path_stream;
+ while (!feof(fstream)) {
+ char c = fgetc(fstream);
+ /* xdg-user-dir ends the path with '\n'. */
+ if (c == '\n') {
+ break;
+ }
+ path_stream << c;
+ }
+ if (pclose(fstream) == -1) {
+ perror("GHOST_SystemPathsUnix::getUserSpecialDir failed at pclose()");
+ return NULL;
+ }
+
+ path = path_stream.str();
+ return path[0] ? (const GHOST_TUns8 *)path.c_str() : NULL;
+}
+
const GHOST_TUns8 *GHOST_SystemPathsUnix::getBinaryDir() const
{
return NULL;
diff --git a/intern/ghost/intern/GHOST_SystemPathsUnix.h b/intern/ghost/intern/GHOST_SystemPathsUnix.h
index 8d2f26a28aa..bc9272ecd8f 100644
--- a/intern/ghost/intern/GHOST_SystemPathsUnix.h
+++ b/intern/ghost/intern/GHOST_SystemPathsUnix.h
@@ -54,6 +54,12 @@ class GHOST_SystemPathsUnix : public GHOST_SystemPaths {
const GHOST_TUns8 *getUserDir(int version, const char *versionstr) const;
/**
+ * Determine a special ("well known") and easy to reach user directory.
+ * \return Unsigned char string pointing to user dir (eg `~/Documents/`).
+ */
+ const GHOST_TUns8 *getUserSpecialDir(GHOST_TUserSpecialDirTypes type) const;
+
+ /**
* Determine the directory of the current binary
* \return Unsigned char string pointing to the binary dir
*/
diff --git a/intern/ghost/intern/GHOST_SystemPathsWin32.cpp b/intern/ghost/intern/GHOST_SystemPathsWin32.cpp
index 673cbcad97e..193633b5c3e 100644
--- a/intern/ghost/intern/GHOST_SystemPathsWin32.cpp
+++ b/intern/ghost/intern/GHOST_SystemPathsWin32.cpp
@@ -22,6 +22,7 @@
*/
#include "GHOST_SystemPathsWin32.h"
+#include "GHOST_Debug.h"
#ifndef _WIN32_IE
# define _WIN32_IE 0x0501
@@ -76,6 +77,50 @@ const GHOST_TUns8 *GHOST_SystemPathsWin32::getUserDir(int, const char *versionst
return NULL;
}
+const GHOST_TUns8 *GHOST_SystemPathsWin32::getUserSpecialDir(GHOST_TUserSpecialDirTypes type) const
+{
+ GUID folderid;
+
+ switch (type) {
+ case GHOST_kUserSpecialDirDesktop:
+ folderid = FOLDERID_Desktop;
+ break;
+ case GHOST_kUserSpecialDirDocuments:
+ folderid = FOLDERID_Documents;
+ break;
+ case GHOST_kUserSpecialDirDownloads:
+ folderid = FOLDERID_Downloads;
+ break;
+ case GHOST_kUserSpecialDirMusic:
+ folderid = FOLDERID_Music;
+ break;
+ case GHOST_kUserSpecialDirPictures:
+ folderid = FOLDERID_Pictures;
+ break;
+ case GHOST_kUserSpecialDirVideos:
+ folderid = FOLDERID_Videos;
+ break;
+ default:
+ GHOST_ASSERT(
+ false,
+ "GHOST_SystemPathsWin32::getUserSpecialDir(): Invalid enum value for type parameter");
+ return NULL;
+ }
+
+ static char knownpath[MAX_PATH * 3] = {0};
+ PWSTR knownpath_16 = NULL;
+ HRESULT hResult = SHGetKnownFolderPath(folderid, KF_FLAG_DEFAULT, NULL, &knownpath_16);
+
+ if (hResult == S_OK) {
+ conv_utf_16_to_8(knownpath_16, knownpath, MAX_PATH * 3);
+ CoTaskMemFree(knownpath_16);
+ return (GHOST_TUns8 *)knownpath;
+ }
+
+ CoTaskMemFree(knownpath_16);
+ return NULL;
+}
+
const GHOST_TUns8 *GHOST_SystemPathsWin32::getBinaryDir() const
{
static char fullname[MAX_PATH * 3] = {0};
diff --git a/intern/ghost/intern/GHOST_SystemPathsWin32.h b/intern/ghost/intern/GHOST_SystemPathsWin32.h
index 1a1eab21bad..45e03e744a5 100644
--- a/intern/ghost/intern/GHOST_SystemPathsWin32.h
+++ b/intern/ghost/intern/GHOST_SystemPathsWin32.h
@@ -63,6 +63,12 @@ class GHOST_SystemPathsWin32 : public GHOST_SystemPaths {
const GHOST_TUns8 *getUserDir(int version, const char *versionstr) const;
/**
+ * Determine a special ("well known") and easy to reach user directory.
+ * \return Unsigned char string pointing to user dir (eg `~/Documents/`).
+ */
+ const GHOST_TUns8 *getUserSpecialDir(GHOST_TUserSpecialDirTypes type) const;
+
+ /**
* Determine the directory of the current binary
* \return Unsigned char string pointing to the binary dir
*/
diff --git a/intern/ghost/intern/GHOST_SystemWin32.cpp b/intern/ghost/intern/GHOST_SystemWin32.cpp
index 8178b9bdf1e..2bf1d0c2d35 100644
--- a/intern/ghost/intern/GHOST_SystemWin32.cpp
+++ b/intern/ghost/intern/GHOST_SystemWin32.cpp
@@ -422,7 +422,7 @@ finished:
/**
* Dispose of a context.
- * \param context Pointer to the context to be disposed.
+ * \param context: Pointer to the context to be disposed.
* \return Indication of success.
*/
GHOST_TSuccess GHOST_SystemWin32::disposeContext(GHOST_IContext *context)
@@ -1614,7 +1614,7 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
break;
}
case WT_PACKET:
- window->updatePendingWintabEvents();
+ window->updateWintabEventsSyncTime();
break;
////////////////////////////////////////////////////////////////////////
// Pointer events, processed
diff --git a/intern/ghost/intern/GHOST_WindowWayland.cpp b/intern/ghost/intern/GHOST_WindowWayland.cpp
index fe65162d168..1e1d0814d3a 100644
--- a/intern/ghost/intern/GHOST_WindowWayland.cpp
+++ b/intern/ghost/intern/GHOST_WindowWayland.cpp
@@ -407,7 +407,7 @@ void GHOST_WindowWayland::setOpaque() const
#endif
/**
- * \param type The type of rendering context create.
+ * \param type: The type of rendering context create.
* \return Indication of success.
*/
GHOST_Context *GHOST_WindowWayland::newDrawingContext(GHOST_TDrawingContextType type)
diff --git a/intern/ghost/intern/GHOST_WindowWin32.cpp b/intern/ghost/intern/GHOST_WindowWin32.cpp
index af02663985d..a4cbf66b22d 100644
--- a/intern/ghost/intern/GHOST_WindowWin32.cpp
+++ b/intern/ghost/intern/GHOST_WindowWin32.cpp
@@ -1292,7 +1292,7 @@ GHOST_TSuccess GHOST_WindowWin32::getWintabInfo(std::vector<GHOST_WintabInfoWin3
GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)GHOST_System::getSystem();
- updatePendingWintabEvents();
+ updateWintabEvents();
auto &pendingEvents = m_wintab.pendingEvents;
size_t pendingEventSize = pendingEvents.size();
@@ -1388,6 +1388,44 @@ GHOST_TSuccess GHOST_WindowWin32::getWintabInfo(std::vector<GHOST_WintabInfoWin3
return GHOST_kSuccess;
}
+void GHOST_WindowWin32::updateWintabEvents()
+{
+ readWintabEvents();
+ // When a Wintab device is used to leave window focus, some of it's packets are periodically not
+ // queued in time to be flushed. Reading packets needs to occur before expiring packets to clear
+ // these from the queue.
+ expireWintabEvents();
+}
+
+void GHOST_WindowWin32::updateWintabEventsSyncTime()
+{
+ readWintabEvents();
+
+ if (!m_wintab.pendingEvents.empty()) {
+ auto lastEvent = m_wintab.pendingEvents.back();
+ m_wintab.sysTimeOffset = ::GetTickCount() - lastEvent.pkTime;
+ }
+
+ expireWintabEvents();
+}
+
+void GHOST_WindowWin32::readWintabEvents()
+{
+ if (!(m_wintab.packetsGet && m_wintab.context)) {
+ return;
+ }
+
+ auto &pendingEvents = m_wintab.pendingEvents;
+
+ /* Get new packets. */
+ const int numPackets = m_wintab.packetsGet(
+ m_wintab.context, m_wintab.pkts.size(), m_wintab.pkts.data());
+
+ for (int i = 0; i < numPackets; i++) {
+ pendingEvents.push(m_wintab.pkts[i]);
+ }
+}
+
/* Wintab (per documentation but may vary with implementation) does not update when its event
* buffer is full. This is an issue because we need some synchronization point between Wintab
* events and Win32 events, so we can't drain and process the queue immediately. We need to
@@ -1396,17 +1434,12 @@ GHOST_TSuccess GHOST_WindowWin32::getWintabInfo(std::vector<GHOST_WintabInfoWin3
* mode from the Wintab API alone. There is no guaranteed ordering between Wintab and Win32 mouse
* events and no documented time stamp shared between the two, so we synchronize on mouse button
* events. */
-void GHOST_WindowWin32::updatePendingWintabEvents()
+void GHOST_WindowWin32::expireWintabEvents()
{
- if (!(m_wintab.packetsGet && m_wintab.context)) {
- return;
- }
-
auto &pendingEvents = m_wintab.pendingEvents;
- /* Clear outdated events from queue. */
- DWORD currTime = ::GetTickCount();
- DWORD millisTimeout = 500;
+ DWORD currTime = ::GetTickCount() - m_wintab.sysTimeOffset;
+ DWORD millisTimeout = 300;
while (!pendingEvents.empty()) {
DWORD pkTime = pendingEvents.front().pkTime;
@@ -1417,24 +1450,6 @@ void GHOST_WindowWin32::updatePendingWintabEvents()
break;
}
}
-
- /* Get new packets. */
- const int numPackets = m_wintab.packetsGet(
- m_wintab.context, m_wintab.pkts.size(), m_wintab.pkts.data());
-
- int i = 0;
- /* Don't queue outdated packets, such events can include packets that occurred before the current
- * window lost and regained focus. */
- for (; i < numPackets; i++) {
- DWORD pkTime = m_wintab.pkts[i].pkTime;
-
- if (currTime < pkTime + millisTimeout) {
- break;
- }
- }
- for (; i < numPackets; i++) {
- pendingEvents.push(m_wintab.pkts[i]);
- }
}
GHOST_TUns16 GHOST_WindowWin32::getDPIHint()
diff --git a/intern/ghost/intern/GHOST_WindowWin32.h b/intern/ghost/intern/GHOST_WindowWin32.h
index a761d7d84dc..829bbdea051 100644
--- a/intern/ghost/intern/GHOST_WindowWin32.h
+++ b/intern/ghost/intern/GHOST_WindowWin32.h
@@ -486,9 +486,14 @@ class GHOST_WindowWin32 : public GHOST_Window {
GHOST_TSuccess getWintabInfo(std::vector<GHOST_WintabInfoWin32> &outWintabInfo);
/**
- * Updates stored pending Wintab events.
+ * Updates pending Wintab events and syncs Wintab time with OS time.
*/
- void updatePendingWintabEvents();
+ void updateWintabEventsSyncTime();
+
+ /**
+ * Updates pending Wintab events.
+ */
+ void updateWintabEvents();
GHOST_TSuccess beginFullScreen() const
{
@@ -629,6 +634,7 @@ class GHOST_WindowWin32 : public GHOST_Window {
GHOST_TUns8 numSysButtons = 0;
/** Cursors currently in contact mapped to system buttons */
DWORD sysButtonsPressed = 0;
+ DWORD sysTimeOffset = 0;
LONG maxPressure = 0;
LONG maxAzimuth = 0, maxAltitude = 0;
/** Reusable buffer to read in Wintab Packets. */
@@ -642,6 +648,10 @@ class GHOST_WindowWin32 : public GHOST_Window {
*/
void initializeWintab();
+ void readWintabEvents();
+
+ void expireWintabEvents();
+
/**
* Convert Wintab system mapped (mouse) buttons into Ghost button mask.
* \param cursor: The Wintab cursor associated to the button.