|
|
@ -40,9 +40,6 @@ |
|
|
|
//M*/
|
|
|
|
//M*/
|
|
|
|
|
|
|
|
|
|
|
|
#include "precomp.hpp" |
|
|
|
#include "precomp.hpp" |
|
|
|
#include "opencv2/imgproc.hpp" |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
using namespace cv; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifndef _WIN32 |
|
|
|
#ifndef _WIN32 |
|
|
|
|
|
|
|
|
|
|
@ -66,6 +63,11 @@ using namespace cv; |
|
|
|
#include <GL/glu.h> |
|
|
|
#include <GL/glu.h> |
|
|
|
#endif |
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include <opencv2/core/utils/logger.hpp> |
|
|
|
|
|
|
|
#include "opencv2/imgproc.hpp" |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
using namespace cv; |
|
|
|
|
|
|
|
|
|
|
|
#ifndef BIT_ALLIN |
|
|
|
#ifndef BIT_ALLIN |
|
|
|
#define BIT_ALLIN(x,y) ( ((x)&(y)) == (y) ) |
|
|
|
#define BIT_ALLIN(x,y) ( ((x)&(y)) == (y) ) |
|
|
|
#endif |
|
|
|
#endif |
|
|
@ -595,10 +597,15 @@ int thread_started=0; |
|
|
|
static gpointer icvWindowThreadLoop(gpointer data); |
|
|
|
static gpointer icvWindowThreadLoop(gpointer data); |
|
|
|
GMutex* last_key_mutex = NULL; |
|
|
|
GMutex* last_key_mutex = NULL; |
|
|
|
GCond* cond_have_key = NULL; |
|
|
|
GCond* cond_have_key = NULL; |
|
|
|
GMutex* window_mutex = NULL; |
|
|
|
|
|
|
|
GThread* window_thread = NULL; |
|
|
|
GThread* window_thread = NULL; |
|
|
|
#endif |
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static cv::Mutex& getWindowMutex() |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
static cv::Mutex* g_window_mutex = new cv::Mutex(); |
|
|
|
|
|
|
|
return *g_window_mutex; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static int last_key = -1; |
|
|
|
static int last_key = -1; |
|
|
|
static std::vector< Ptr<CvWindow> > g_windows; |
|
|
|
static std::vector< Ptr<CvWindow> > g_windows; |
|
|
|
|
|
|
|
|
|
|
@ -625,28 +632,28 @@ CV_IMPL int cvInitSystem( int argc, char** argv ) |
|
|
|
CV_IMPL int cvStartWindowThread(){ |
|
|
|
CV_IMPL int cvStartWindowThread(){ |
|
|
|
#ifdef HAVE_GTHREAD |
|
|
|
#ifdef HAVE_GTHREAD |
|
|
|
cvInitSystem(0,NULL); |
|
|
|
cvInitSystem(0,NULL); |
|
|
|
if (!thread_started) { |
|
|
|
if (!thread_started) |
|
|
|
if (!g_thread_supported ()) { |
|
|
|
{ |
|
|
|
/* the GThread system wasn't inited, so init it */ |
|
|
|
if (!g_thread_supported ()) { |
|
|
|
g_thread_init(NULL); |
|
|
|
/* the GThread system wasn't inited, so init it */ |
|
|
|
} |
|
|
|
g_thread_init(NULL); |
|
|
|
|
|
|
|
} |
|
|
|
// this mutex protects the window resources
|
|
|
|
|
|
|
|
window_mutex = g_mutex_new(); |
|
|
|
(void)getWindowMutex(); // force mutex initialization
|
|
|
|
|
|
|
|
|
|
|
|
// protects the 'last key pressed' variable
|
|
|
|
// protects the 'last key pressed' variable
|
|
|
|
last_key_mutex = g_mutex_new(); |
|
|
|
last_key_mutex = g_mutex_new(); |
|
|
|
|
|
|
|
|
|
|
|
// conditional that indicates a key has been pressed
|
|
|
|
// conditional that indicates a key has been pressed
|
|
|
|
cond_have_key = g_cond_new(); |
|
|
|
cond_have_key = g_cond_new(); |
|
|
|
|
|
|
|
|
|
|
|
#if !GLIB_CHECK_VERSION(2, 32, 0) |
|
|
|
#if !GLIB_CHECK_VERSION(2, 32, 0) |
|
|
|
// this is the window update thread
|
|
|
|
// this is the window update thread
|
|
|
|
window_thread = g_thread_create(icvWindowThreadLoop, |
|
|
|
window_thread = g_thread_create(icvWindowThreadLoop, |
|
|
|
NULL, TRUE, NULL); |
|
|
|
NULL, TRUE, NULL); |
|
|
|
#else |
|
|
|
#else |
|
|
|
window_thread = g_thread_new("OpenCV window update", icvWindowThreadLoop, NULL); |
|
|
|
window_thread = g_thread_new("OpenCV window update", icvWindowThreadLoop, NULL); |
|
|
|
#endif |
|
|
|
#endif |
|
|
|
} |
|
|
|
} |
|
|
|
thread_started = window_thread!=NULL; |
|
|
|
thread_started = window_thread!=NULL; |
|
|
|
return thread_started; |
|
|
|
return thread_started; |
|
|
@ -659,9 +666,10 @@ CV_IMPL int cvStartWindowThread(){ |
|
|
|
gpointer icvWindowThreadLoop(gpointer /*data*/) |
|
|
|
gpointer icvWindowThreadLoop(gpointer /*data*/) |
|
|
|
{ |
|
|
|
{ |
|
|
|
while(1){ |
|
|
|
while(1){ |
|
|
|
g_mutex_lock(window_mutex); |
|
|
|
{ |
|
|
|
gtk_main_iteration_do(FALSE); |
|
|
|
cv::AutoLock lock(getWindowMutex()); |
|
|
|
g_mutex_unlock(window_mutex); |
|
|
|
gtk_main_iteration_do(FALSE); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// little sleep
|
|
|
|
// little sleep
|
|
|
|
g_usleep(500); |
|
|
|
g_usleep(500); |
|
|
@ -671,20 +679,10 @@ gpointer icvWindowThreadLoop(gpointer /*data*/) |
|
|
|
return NULL; |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class GMutexLock { |
|
|
|
|
|
|
|
GMutex* mutex_; |
|
|
|
|
|
|
|
public: |
|
|
|
|
|
|
|
GMutexLock(GMutex* mutex) : mutex_(mutex) { if (mutex_) g_mutex_lock(mutex_); } |
|
|
|
|
|
|
|
~GMutexLock() { if (mutex_) g_mutex_unlock(mutex_); mutex_ = NULL; } |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#define CV_LOCK_MUTEX() GMutexLock lock(window_mutex); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#else |
|
|
|
|
|
|
|
#define CV_LOCK_MUTEX() |
|
|
|
|
|
|
|
#endif |
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#define CV_LOCK_MUTEX() cv::AutoLock lock(getWindowMutex()) |
|
|
|
|
|
|
|
|
|
|
|
static CvWindow* icvFindWindowByName( const char* name ) |
|
|
|
static CvWindow* icvFindWindowByName( const char* name ) |
|
|
|
{ |
|
|
|
{ |
|
|
|
for(size_t i = 0; i < g_windows.size(); ++i) |
|
|
|
for(size_t i = 0; i < g_windows.size(); ++i) |
|
|
@ -1705,18 +1703,19 @@ static gboolean icvOnKeyPress(GtkWidget* widget, GdkEventKey* event, gpointer us |
|
|
|
code |= event->state << 16; |
|
|
|
code |= event->state << 16; |
|
|
|
|
|
|
|
|
|
|
|
#ifdef HAVE_GTHREAD |
|
|
|
#ifdef HAVE_GTHREAD |
|
|
|
if(thread_started) g_mutex_lock(last_key_mutex); |
|
|
|
if(thread_started) |
|
|
|
#endif |
|
|
|
{ |
|
|
|
|
|
|
|
g_mutex_lock(last_key_mutex); |
|
|
|
last_key = code; |
|
|
|
last_key = code; |
|
|
|
|
|
|
|
|
|
|
|
#ifdef HAVE_GTHREAD |
|
|
|
|
|
|
|
if(thread_started){ |
|
|
|
|
|
|
|
// signal any waiting threads
|
|
|
|
// signal any waiting threads
|
|
|
|
g_cond_broadcast(cond_have_key); |
|
|
|
g_cond_broadcast(cond_have_key); |
|
|
|
g_mutex_unlock(last_key_mutex); |
|
|
|
g_mutex_unlock(last_key_mutex); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
else |
|
|
|
#endif |
|
|
|
#endif |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
last_key = code; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return FALSE; |
|
|
|
return FALSE; |
|
|
|
} |
|
|
|
} |
|
|
@ -1886,10 +1885,12 @@ static gboolean icvAlarm( gpointer user_data ) |
|
|
|
CV_IMPL int cvWaitKey( int delay ) |
|
|
|
CV_IMPL int cvWaitKey( int delay ) |
|
|
|
{ |
|
|
|
{ |
|
|
|
#ifdef HAVE_GTHREAD |
|
|
|
#ifdef HAVE_GTHREAD |
|
|
|
if(thread_started && g_thread_self()!=window_thread){ |
|
|
|
if (thread_started && g_thread_self() != window_thread) |
|
|
|
gboolean expired; |
|
|
|
{ |
|
|
|
|
|
|
|
gboolean expired = true; |
|
|
|
int my_last_key; |
|
|
|
int my_last_key; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
g_mutex_lock(last_key_mutex); |
|
|
|
// wait for signal or timeout if delay > 0
|
|
|
|
// wait for signal or timeout if delay > 0
|
|
|
|
if(delay>0){ |
|
|
|
if(delay>0){ |
|
|
|
GTimeVal timer; |
|
|
|
GTimeVal timer; |
|
|
@ -1898,8 +1899,15 @@ CV_IMPL int cvWaitKey( int delay ) |
|
|
|
expired = !g_cond_timed_wait(cond_have_key, last_key_mutex, &timer); |
|
|
|
expired = !g_cond_timed_wait(cond_have_key, last_key_mutex, &timer); |
|
|
|
} |
|
|
|
} |
|
|
|
else{ |
|
|
|
else{ |
|
|
|
g_cond_wait(cond_have_key, last_key_mutex); |
|
|
|
if (g_windows.empty()) |
|
|
|
expired=false; |
|
|
|
{ |
|
|
|
|
|
|
|
CV_LOG_WARNING(NULL, "cv::waitKey() is called without timeout and missing active windows. Ignoring"); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
g_cond_wait(cond_have_key, last_key_mutex); |
|
|
|
|
|
|
|
expired=false; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
my_last_key = last_key; |
|
|
|
my_last_key = last_key; |
|
|
|
g_mutex_unlock(last_key_mutex); |
|
|
|
g_mutex_unlock(last_key_mutex); |
|
|
@ -1908,21 +1916,20 @@ CV_IMPL int cvWaitKey( int delay ) |
|
|
|
} |
|
|
|
} |
|
|
|
return my_last_key; |
|
|
|
return my_last_key; |
|
|
|
} |
|
|
|
} |
|
|
|
else{ |
|
|
|
else |
|
|
|
#endif |
|
|
|
#endif |
|
|
|
|
|
|
|
{ |
|
|
|
int expired = 0; |
|
|
|
int expired = 0; |
|
|
|
guint timer = 0; |
|
|
|
guint timer = 0; |
|
|
|
if( delay > 0 ) |
|
|
|
if( delay > 0 ) |
|
|
|
timer = g_timeout_add( delay, icvAlarm, &expired ); |
|
|
|
timer = g_timeout_add( delay, icvAlarm, &expired ); |
|
|
|
last_key = -1; |
|
|
|
last_key = -1; |
|
|
|
while( gtk_main_iteration_do(TRUE) && last_key < 0 && !expired && !g_windows.empty()) |
|
|
|
while( gtk_main_iteration_do(TRUE) && last_key < 0 && !expired && (delay > 0 || !g_windows.empty())) |
|
|
|
; |
|
|
|
; |
|
|
|
|
|
|
|
|
|
|
|
if( delay > 0 && !expired ) |
|
|
|
if( delay > 0 && !expired ) |
|
|
|
g_source_remove(timer); |
|
|
|
g_source_remove(timer); |
|
|
|
#ifdef HAVE_GTHREAD |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
#endif |
|
|
|
|
|
|
|
return last_key; |
|
|
|
return last_key; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|