diff --git a/.gitignore b/.gitignore
index 043daf27a..9fc018179 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,6 +7,7 @@
.directory
.vscode
.DS_Store
+.idea
CMakeCache.txt
CMakeFiles
@@ -44,4 +45,3 @@ clean
*.tar
*.xz
*.zip
-
diff --git a/rtdata/languages/Francais b/rtdata/languages/Francais
index b7b2c7ec7..f4ef5a0db 100644
--- a/rtdata/languages/Francais
+++ b/rtdata/languages/Francais
@@ -2732,8 +2732,8 @@ TP_RGBCURVES_BLUE;B
TP_RGBCURVES_CHANNEL;Canal
TP_RGBCURVES_GREEN;V
TP_RGBCURVES_LABEL;Courbes RVB
-TP_RGBCURVES_LUMAMODE;Mode Lominosité
-TP_RGBCURVES_LUMAMODE_TOOLTIP;Mode Lominosité permet de faire varier la contribution des canaux R, V et B à la luminosité de l'image, sans altérer les couleurs de l'image.
+TP_RGBCURVES_LUMAMODE;Mode Luminosité
+TP_RGBCURVES_LUMAMODE_TOOLTIP;Mode Luminosité permet de faire varier la contribution des canaux R, V et B à la luminosité de l'image, sans altérer les couleurs de l'image.
TP_RGBCURVES_RED;R
TP_ROTATE_DEGREE;Degré
TP_ROTATE_LABEL;Rotation
diff --git a/rtgui/filebrowserentry.cc b/rtgui/filebrowserentry.cc
index b89fe340d..7df29dd92 100644
--- a/rtgui/filebrowserentry.cc
+++ b/rtgui/filebrowserentry.cc
@@ -37,7 +37,6 @@
//extern Glib::Threads::Thread* mainThread;
-bool FileBrowserEntry::iconsLoaded(false);
Glib::RefPtr FileBrowserEntry::editedIcon;
Glib::RefPtr FileBrowserEntry::recentlySavedIcon;
Glib::RefPtr FileBrowserEntry::enqueuedIcon;
@@ -58,15 +57,6 @@ FileBrowserEntry::FileBrowserEntry (Thumbnail* thm, const Glib::ustring& fname)
scale = 1;
- if (!iconsLoaded) {
- editedIcon = RTImage::createPixbufFromFile ("tick-small.png");
- recentlySavedIcon = RTImage::createPixbufFromFile ("save-small.png");
- enqueuedIcon = RTImage::createPixbufFromFile ("gears-small.png");
- hdr = RTImage::createPixbufFromFile ("filetype-hdr.png");
- ps = RTImage::createPixbufFromFile ("filetype-ps.png");
- iconsLoaded = true;
- }
-
thumbnail->addThumbnailListener (this);
}
@@ -90,6 +80,15 @@ FileBrowserEntry::~FileBrowserEntry ()
}
}
+void FileBrowserEntry::init ()
+{
+ editedIcon = RTImage::createPixbufFromFile ("tick-small.png");
+ recentlySavedIcon = RTImage::createPixbufFromFile ("save-small.png");
+ enqueuedIcon = RTImage::createPixbufFromFile ("gears-small.png");
+ hdr = RTImage::createPixbufFromFile ("filetype-hdr.png");
+ ps = RTImage::createPixbufFromFile ("filetype-ps.png");
+}
+
void FileBrowserEntry::refreshThumbnailImage ()
{
diff --git a/rtgui/filebrowserentry.h b/rtgui/filebrowserentry.h
index 67b953514..f8fca4db1 100644
--- a/rtgui/filebrowserentry.h
+++ b/rtgui/filebrowserentry.h
@@ -50,7 +50,6 @@ class FileBrowserEntry final : public ThumbBrowserEntryBase,
{
double scale;
- static bool iconsLoaded;
bool wasInside;
ImageAreaToolListener* iatlistener;
int press_x, press_y, action_x, action_y;
@@ -80,6 +79,7 @@ public:
FileBrowserEntry (Thumbnail* thm, const Glib::ustring& fname);
~FileBrowserEntry () override;
+ static void init ();
void draw (Cairo::RefPtr cc) override;
void setImageAreaToolListener (ImageAreaToolListener* l)
diff --git a/rtgui/guiutils.cc b/rtgui/guiutils.cc
index 18b82fe36..8e039400e 100644
--- a/rtgui/guiutils.cc
+++ b/rtgui/guiutils.cc
@@ -82,59 +82,6 @@ void IdleRegister::destroy()
mutex.unlock();
}
-/*
-gboolean giveMeAGo(void* data) {
- GThreadLock *threadMutex = static_cast(data);
- printf("A\n");
- Glib::Threads::Mutex::Lock GUILock(threadMutex->GUI);
- printf("B\n");
- {
- Glib::Threads::Mutex::Lock operationLock(threadMutex->operation);
- printf("C\n");
-
- threadMutex->operationCond.signal();
- printf("D\n");
- operationLock.release(); // because we're not sure that "lock" destructor happens here...
- }
- threadMutex->GUICond.wait(threadMutex->GUI);
- printf("E\n");
-
- GUILock.release();
-
- return false;
-}
-
-GThreadLock::GThreadLock() : sameThread(false) {
- if (Glib::Threads::Thread::self() == mainThread) {
- sameThread = true;
- return;
- }
-
- printf("10\n");
- {
- Glib::Threads::Mutex::Lock operationLock(operation);
-
- printf("20\n");
- gdk_threads_add_idle(giveMeAGo, this);
-
- printf("30\n");
- operationCond.wait(operation);
- printf("40\n");
- operationLock.release();
- }
-}
-
-GThreadLock::~GThreadLock() {
- if (!sameThread) {
- printf("50\n");
- Glib::Threads::Mutex::Lock lock(GUI);
- printf("60\n");
- GUICond.signal();
- printf("Fin\n");
- }
-}
-*/
-
Glib::ustring escapeHtmlChars(const Glib::ustring &src)
{
diff --git a/rtgui/histogrampanel.cc b/rtgui/histogrampanel.cc
index 821f6f0be..b804218f5 100644
--- a/rtgui/histogrampanel.cc
+++ b/rtgui/histogrampanel.cc
@@ -1197,7 +1197,7 @@ void HistogramArea::update(
break;
case ScopeType::PARADE:
case ScopeType::WAVEFORM: {
- MyWriterLock wave_lock(wave_mutex);
+ MYWRITERLOCK(wave_lock, wave_mutex)
waveform_scale = waveformScale;
rwave = waveformRed;
gwave = waveformGreen;
@@ -1330,7 +1330,7 @@ void HistogramArea::updateBackBuffer ()
cr->unset_dash();
- MyReaderLock wave_lock(wave_mutex);
+ MYREADERLOCK(wave_lock, wave_mutex)
if (valid && (scopeType == ScopeType::HISTOGRAM || scopeType == ScopeType::HISTOGRAM_RAW)) {
bool rawMode = scopeType == ScopeType::HISTOGRAM_RAW;
@@ -1447,7 +1447,7 @@ void HistogramArea::updateBackBuffer ()
} else if (scopeType == ScopeType::VECTORSCOPE_HC || scopeType == ScopeType::VECTORSCOPE_HS) {
drawVectorscope(cr, w, h);
}
- wave_lock.release();
+ MYREADERLOCK_RELEASE(wave_lock);
// Draw the frame's border
style->render_frame(cr, 0, 0, surface->get_width(), surface->get_height());
diff --git a/rtgui/rtwindow.cc b/rtgui/rtwindow.cc
index d588d6aa5..dcfc2f05c 100755
--- a/rtgui/rtwindow.cc
+++ b/rtgui/rtwindow.cc
@@ -241,6 +241,7 @@ RTWindow::RTWindow ()
RTImage::init();
WhiteBalance::init();
MyExpander::init();
+ FileBrowserEntry::init();
#ifndef WIN32
const std::vector> appIcons = {
diff --git a/rtgui/threadutils.cc b/rtgui/threadutils.cc
index 025abf300..9bc9cf35d 100644
--- a/rtgui/threadutils.cc
+++ b/rtgui/threadutils.cc
@@ -27,6 +27,8 @@
#if STRICT_MUTEX && !NDEBUG
+MyMutex::MyMutex() : locked(false) {}
+
void MyMutex::checkLock ()
{
if (locked) {
@@ -61,13 +63,18 @@ void MyMutex::checkUnlock ()
#if !TRACE_MYRWMUTEX
+MyRWMutex::MyRWMutex() :
+ writerCount(0),
+ readerCount(0)
+{}
+
void MyReaderLock::acquire ()
{
if (locked) {
return;
}
- Glib::Threads::Mutex::Lock lock (mutex.mutex);
+ std::unique_lock lock (mutex.mutex);
if (mutex.writerCount == 0) {
// There's no writer operating, we can increment the writer count which will lock writers.
@@ -76,7 +83,7 @@ void MyReaderLock::acquire ()
// The writer count is non null, but a reader can be the owner of the writer lock,
// which will be the case if the reader count is not zero too.
while (mutex.writerCount != 0) {
- mutex.cond.wait(mutex.mutex);
+ mutex.cond.wait (lock);
}
// Then, we can increment the writer count.
@@ -95,7 +102,7 @@ void MyReaderLock::release ()
return;
}
- Glib::Threads::Mutex::Lock lock (mutex.mutex);
+ std::unique_lock lock (mutex.mutex);
// decrement the writer number first...
--mutex.readerCount;
@@ -105,7 +112,7 @@ void MyReaderLock::release ()
--mutex.writerCount;
// ...and signal the next waiting reader/writer that it's free
- mutex.cond.broadcast ();
+ mutex.cond.notify_all ();
}
locked = false;
@@ -117,11 +124,11 @@ void MyWriterLock::acquire ()
return;
}
- Glib::Threads::Mutex::Lock lock (mutex.mutex);
+ std::unique_lock lock (mutex.mutex);
// The writer count is not zero, so we have to wait for it to be zero again...
while (mutex.writerCount != 0) {
- mutex.cond.wait (mutex.mutex);
+ mutex.cond.wait (lock);
}
// ...then we can increment the writer count.
@@ -136,12 +143,12 @@ void MyWriterLock::release ()
return;
}
- Glib::Threads::Mutex::Lock lock (mutex.mutex);
+ std::unique_lock lock (mutex.mutex);
// Decrement the writer number first...
if (--mutex.writerCount == 0) {
- // ...and if the writer count is zero again, we can wake up the next writer or reader.
- mutex.cond.broadcast ();
+ // ...and if the writer count is zero again, we wake up all of the waiting writer or reader.
+ mutex.cond.notify_all ();
}
locked = false;
@@ -154,13 +161,20 @@ namespace
std::ostream& trace (const char* file, int line)
{
- const auto currentThread = Glib::Threads::Thread::self ();
+ const auto currentThread = std::this_thread::get_id();
return std::cout << currentThread << ":" << file << ":" << line << ": ";
}
}
+MyRWMutex::MyRWMutex() :
+ lastWriterFile(nullptr),
+ lastWriterLine(0),
+ writerCount(0),
+ readerCount(0)
+{}
+
void MyReaderLock::acquire (const char* file, int line)
{
if (locked) {
@@ -170,7 +184,7 @@ void MyReaderLock::acquire (const char* file, int line)
trace (file, line) << "Acquiring MyReaderLock..." << std::endl;
- Glib::Threads::Mutex::Lock lock (mutex.mutex);
+ std::unique_lock lock (mutex.mutex);
if (mutex.writerCount == 0) {
// There's no writer operating, we can increment the writer count which will lock writers.
@@ -184,13 +198,13 @@ void MyReaderLock::acquire (const char* file, int line)
<< "\tLast writer file: " << mutex.lastWriterFile << std::endl
<< "\tLast writer line: " << mutex.lastWriterLine << std::endl;
- mutex.cond.wait(mutex.mutex);
+ mutex.cond.wait (lock);
}
// Then, we can increment the writer count.
++mutex.writerCount;
- mutex.ownerThread = Glib::Threads::Thread::self ();
+ mutex.ownerThread = std::this_thread::get_id ();
mutex.lastWriterFile = file;
mutex.lastWriterLine = line;
}
@@ -211,7 +225,7 @@ void MyReaderLock::release (const char* file, int line)
trace (file, line) << "Releasing MyReaderLock..." << std::endl;
- Glib::Threads::Mutex::Lock lock (mutex.mutex);
+ std::unique_lock lock (mutex.mutex);
// decrement the writer number first...
--mutex.readerCount;
@@ -221,9 +235,9 @@ void MyReaderLock::release (const char* file, int line)
--mutex.writerCount;
// ...and signal the next waiting reader/writer that it's free
- mutex.cond.broadcast ();
+ mutex.cond.notify_all ();
- mutex.ownerThread = nullptr;
+ mutex.ownerThread = std::thread::id();
mutex.lastWriterFile = "";
mutex.lastWriterLine = 0;
}
@@ -241,7 +255,7 @@ void MyWriterLock::acquire (const char* file, int line)
trace (file, line) << "Acquiring MyWriterLock..." << std::endl;
- Glib::Threads::Mutex::Lock lock (mutex.mutex);
+ std::unique_lock lock (mutex.mutex);
// The writer count is not zero, so we have to wait for it to be zero again...
while (mutex.writerCount != 0) {
@@ -250,13 +264,13 @@ void MyWriterLock::acquire (const char* file, int line)
<< "\tLast writer file: " << mutex.lastWriterFile << std::endl
<< "\tLast writer line: " << mutex.lastWriterLine << std::endl;
- mutex.cond.wait (mutex.mutex);
+ mutex.cond.wait (lock);
}
// ...then we can increment the writer count.
++mutex.writerCount;
- mutex.ownerThread = Glib::Threads::Thread::self ();
+ mutex.ownerThread = std::this_thread::get_id ();
mutex.lastWriterFile = file;
mutex.lastWriterLine = line;
@@ -273,14 +287,14 @@ void MyWriterLock::release (const char* file, int line)
trace (file, line) << "Releasing MyWriterLock..." << std::endl;
- Glib::Threads::Mutex::Lock lock (mutex.mutex);
+ std::unique_lock lock (mutex.mutex);
// Decrement the writer number first...
if (--mutex.writerCount == 0) {
- // ...and if the writer count is zero again, we can wake up the next writer or reader.
- mutex.cond.broadcast ();
+ // ...and if the writer count is zero again, we wake up all of the waiting writer or reader.
+ mutex.cond.notify_all ();
- mutex.ownerThread = nullptr;
+ mutex.ownerThread = std::thread::id();
mutex.lastWriterFile = "";
mutex.lastWriterLine = 0;
}
diff --git a/rtgui/threadutils.h b/rtgui/threadutils.h
index eae4a9ad2..401660b93 100644
--- a/rtgui/threadutils.h
+++ b/rtgui/threadutils.h
@@ -24,14 +24,15 @@
//#undef STRICT_MUTEX
//#define STRICT_MUTEX 1
-#include
-
+#include
+#include
+#include
#include "../rtengine/noncopyable.h"
#if STRICT_MUTEX && NDEBUG
-using MyMutexBase = Glib::Threads::Mutex;
+using MyMutexBase = std::mutex;
#else
-using MyMutexBase = Glib::Threads::RecMutex;
+using MyMutexBase = std::recursive_mutex;
#endif
/**
@@ -54,8 +55,10 @@ public:
void unlock ();
#if STRICT_MUTEX && !NDEBUG
+ MyMutex();
+
private:
- bool locked = false;
+ bool locked;
void checkLock ();
void checkUnlock ();
#endif
@@ -66,8 +69,6 @@ class MyMutex::MyLock :
{
public:
explicit MyLock (MyMutex& mutex);
- MyLock (MyMutex& mutex, Glib::Threads::NotLock);
- MyLock (MyMutex& mutex, Glib::Threads::TryLock);
~MyLock ();
@@ -90,18 +91,20 @@ public:
friend class MyReaderLock;
friend class MyWriterLock;
+ MyRWMutex();
+
private:
- Glib::Threads::Mutex mutex;
- Glib::Threads::Cond cond;
-
- std::size_t writerCount = 0;
- std::size_t readerCount = 0;
-
#if TRACE_MYRWMUTEX
- Glib::Threads::Thread* ownerThread = nullptr;
- const char* lastWriterFile = "";
- int lastWriterLine = 0;
+ std::thread::id ownerThread;
+ const char* lastWriterFile;
+ int lastWriterLine;
#endif
+
+ std::mutex mutex;
+ std::condition_variable cond;
+
+ std::size_t writerCount;
+ std::size_t readerCount;
};
/**
@@ -167,7 +170,7 @@ inline void MyMutex::lock ()
inline bool MyMutex::trylock ()
{
- if (MyMutexBase::trylock ()) {
+ if (MyMutexBase::try_lock ()) {
#if STRICT_MUTEX && !NDEBUG
checkLock ();
#endif
@@ -194,18 +197,6 @@ inline MyMutex::MyLock::MyLock (MyMutex& mutex)
mutex.lock();
}
-inline MyMutex::MyLock::MyLock (MyMutex& mutex, Glib::Threads::NotLock)
- : mutex (mutex)
- , locked (false)
-{
-}
-
-inline MyMutex::MyLock::MyLock (MyMutex& mutex, Glib::Threads::TryLock)
- : mutex (mutex)
- , locked (mutex.trylock ())
-{
-}
-
inline MyMutex::MyLock::~MyLock ()
{
if (locked) {
diff --git a/rtgui/thumbimageupdater.cc b/rtgui/thumbimageupdater.cc
index 540ad625e..d196fdca5 100644
--- a/rtgui/thumbimageupdater.cc
+++ b/rtgui/thumbimageupdater.cc
@@ -85,9 +85,9 @@ public:
Glib::ThreadPool* threadPool_;
- // Need to be a Glib::Threads::Mutex because used in a Glib::Threads::Cond object...
+ // Need to be a std::mutex because used in a std::condition_variable object...
// This is the only exceptions along with GThreadMutex (guiutils.cc), MyMutex is used everywhere else
- Glib::Threads::Mutex mutex_;
+ std::mutex mutex_;
JobList jobs_;
@@ -95,7 +95,7 @@ public:
bool inactive_waiting_;
- Glib::Threads::Cond inactive_;
+ std::condition_variable inactive_;
void
processNextJob()
@@ -103,7 +103,7 @@ public:
Job j;
{
- Glib::Threads::Mutex::Lock lock(mutex_);
+ std::lock_guard lock(mutex_);
// nothing to do; could be jobs have been removed
if ( jobs_.empty() ) {
@@ -166,10 +166,10 @@ public:
}
if ( --active_ == 0 ) {
- Glib::Threads::Mutex::Lock lock(mutex_);
+ std::lock_guard lock(mutex_);
if (inactive_waiting_) {
inactive_waiting_ = false;
- inactive_.broadcast();
+ inactive_.notify_all();
}
}
}
@@ -198,7 +198,7 @@ void ThumbImageUpdater::add(ThumbBrowserEntryBase* tbe, bool* priority, bool upg
return;
}
- Glib::Threads::Mutex::Lock lock(impl_->mutex_);
+ std::lock_guard lock(impl_->mutex_);
// look up if an older version is in the queue
Impl::JobList::iterator i(impl_->jobs_.begin());
@@ -230,7 +230,7 @@ void ThumbImageUpdater::removeJobs(ThumbImageUpdateListener* listener)
DEBUG("removeJobs(%p)", listener);
{
- Glib::Threads::Mutex::Lock lock(impl_->mutex_);
+ std::lock_guard lock(impl_->mutex_);
for( Impl::JobList::iterator i(impl_->jobs_.begin()); i != impl_->jobs_.end(); ) {
if (i->listener_ == listener) {
@@ -246,9 +246,9 @@ void ThumbImageUpdater::removeJobs(ThumbImageUpdateListener* listener)
while ( impl_->active_ != 0 ) {
DEBUG("waiting for running jobs1");
{
- Glib::Threads::Mutex::Lock lock(impl_->mutex_);
+ std::unique_lock lock(impl_->mutex_);
impl_->inactive_waiting_ = true;
- impl_->inactive_.wait(impl_->mutex_);
+ impl_->inactive_.wait(lock);
}
}
}
@@ -258,7 +258,7 @@ void ThumbImageUpdater::removeAllJobs()
DEBUG("stop");
{
- Glib::Threads::Mutex::Lock lock(impl_->mutex_);
+ std::lock_guard lock(impl_->mutex_);
impl_->jobs_.clear();
}
@@ -266,9 +266,9 @@ void ThumbImageUpdater::removeAllJobs()
while ( impl_->active_ != 0 ) {
DEBUG("waiting for running jobs2");
{
- Glib::Threads::Mutex::Lock lock(impl_->mutex_);
+ std::unique_lock lock(impl_->mutex_);
impl_->inactive_waiting_ = true;
- impl_->inactive_.wait(impl_->mutex_);
+ impl_->inactive_.wait(lock);
}
}
}
diff --git a/tools/osx/macosx_bundle.sh b/tools/osx/macosx_bundle.sh
index 0782e3fc8..ff5a44254 100644
--- a/tools/osx/macosx_bundle.sh
+++ b/tools/osx/macosx_bundle.sh
@@ -225,8 +225,11 @@ ModifyInstallNames 2>&1
# Copy libpng16 to the app bundle
cp ${LOCAL_PREFIX}/lib/libpng16.16.dylib "${CONTENTS}/Frameworks/libpng16.16.dylib"
-# Copy libtiff 5 into the app bundle
-cp ${LOCAL_PREFIX}/lib/libtiff.5.dylib "${CONTENTS}/Frameworks/libtiff.5.dylib"
+# Copy graphite to Frameworks
+cp ${LOCAL_PREFIX}/lib/libgraphite2.3.dylib "${CONTENTS}/Frameworks"
+
+# Copy libtiff 6 into the app bundle
+cp ${LOCAL_PREFIX}/lib/libtiff.6.dylib "${CONTENTS}/Frameworks/libtiff.6.dylib"
# Copy libomp to Frameworks
cp ${LOCAL_PREFIX}/lib/libomp.dylib "${CONTENTS}/Frameworks"