From 9e239c7a1e86bc76d066c165559df32bacc44dd3 Mon Sep 17 00:00:00 2001 From: Alexander Alekhin Date: Mon, 14 Aug 2017 19:33:00 +0000 Subject: [PATCH] highgui: refactor GTK backend - eliminate legacy C code, used fields - fix mutex synchronization issues - set trackbar min/max without unnecessary truncation; allow negative values --- modules/highgui/src/window_gtk.cpp | 792 ++++++++++------------------- samples/cpp/falsecolor.cpp | 14 +- 2 files changed, 290 insertions(+), 516 deletions(-) diff --git a/modules/highgui/src/window_gtk.cpp b/modules/highgui/src/window_gtk.cpp index 0cfa59b1a9..5bfd29e45d 100644 --- a/modules/highgui/src/window_gtk.cpp +++ b/modules/highgui/src/window_gtk.cpp @@ -42,6 +42,8 @@ #include "precomp.hpp" #include "opencv2/imgproc.hpp" +using namespace cv; + #ifndef _WIN32 #if defined (HAVE_GTK) @@ -508,12 +510,30 @@ GType cvImageWidget_get_type (void){ struct CvWindow; -typedef struct CvTrackbar -{ +struct CvUIBase { + CvUIBase(int signature_) : signature(signature_) { } + int signature; +}; + +struct CvTrackbar : CvUIBase +{ + CvTrackbar(const char* trackbar_name) : + CvUIBase(CV_TRACKBAR_MAGIC_VAL), + widget(NULL), name(trackbar_name), + parent(NULL), data(NULL), + pos(0), maxval(0), minval(0), + notify(NULL), notify2(NULL), userdata(NULL) + { + // nothing + } + ~CvTrackbar() + { + // destroyed by parent window + } + GtkWidget* widget; - char* name; - CvTrackbar* next; + std::string name; CvWindow* parent; int* data; int pos; @@ -522,19 +542,28 @@ typedef struct CvTrackbar CvTrackbarCallback notify; CvTrackbarCallback2 notify2; void* userdata; -} -CvTrackbar; +}; -typedef struct CvWindow +struct CvWindow : CvUIBase { - int signature; + CvWindow(const char* window_name) : + CvUIBase(CV_WINDOW_MAGIC_VAL), + widget(NULL), frame(NULL), paned(NULL), name(window_name), + last_key(0), flags(0), status(0), + on_mouse(NULL), on_mouse_param(NULL) +#ifdef HAVE_OPENGL + ,useGl(false), glDrawCallback(NULL), glDrawData(NULL) +#endif + { + // nothing + } + ~CvWindow(); + GtkWidget* widget; GtkWidget* frame; GtkWidget* paned; - char* name; - CvWindow* prev; - CvWindow* next; + std::string name; int last_key; int flags; @@ -543,13 +572,7 @@ typedef struct CvWindow CvMouseCallback on_mouse; void* on_mouse_param; - struct - { - int pos; - int rows; - CvTrackbar* first; - } - toolbar; + std::vector< Ptr > trackbars; #ifdef HAVE_OPENGL bool useGl; @@ -557,8 +580,7 @@ typedef struct CvWindow CvOpenGlDrawCallback glDrawCallback; void* glDrawData; #endif -} -CvWindow; +}; static gboolean icvOnClose( GtkWidget* widget, GdkEvent* event, gpointer user_data ); @@ -569,15 +591,14 @@ static gboolean icvOnMouse( GtkWidget *widget, GdkEvent *event, gpointer user_da #ifdef HAVE_GTHREAD int thread_started=0; static gpointer icvWindowThreadLoop(); -GMutex* last_key_mutex; -GCond* cond_have_key; -GMutex* window_mutex; -GThread* window_thread; -GtkWidget* cvTopLevelWidget = 0; +GMutex* last_key_mutex = NULL; +GCond* cond_have_key = NULL; +GMutex* window_mutex = NULL; +GThread* window_thread = NULL; #endif static int last_key = -1; -static CvWindow* hg_windows = 0; +static std::vector< Ptr > g_windows; CV_IMPL int cvInitSystem( int argc, char** argv ) { @@ -586,8 +607,6 @@ CV_IMPL int cvInitSystem( int argc, char** argv ) // check initialization status if( !wasInitialized ) { - hg_windows = 0; - gtk_init( &argc, &argv ); setlocale(LC_NUMERIC,"C"); @@ -635,7 +654,8 @@ CV_IMPL int cvStartWindowThread(){ } #ifdef HAVE_GTHREAD -gpointer icvWindowThreadLoop(){ +gpointer icvWindowThreadLoop() +{ while(1){ g_mutex_lock(window_mutex); gtk_main_iteration_do(FALSE); @@ -649,201 +669,152 @@ gpointer icvWindowThreadLoop(){ return NULL; } -#define CV_LOCK_MUTEX() \ -if(thread_started && g_thread_self()!=window_thread){ g_mutex_lock( window_mutex ); } else { } -#define CV_UNLOCK_MUTEX() \ -if(thread_started && g_thread_self()!=window_thread){ g_mutex_unlock( window_mutex); } else { } +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() -#define CV_UNLOCK_MUTEX() #endif static CvWindow* icvFindWindowByName( const char* name ) { - CvWindow* window = hg_windows; - while( window != 0 && strcmp(name, window->name) != 0 ) - window = window->next; - - return window; + for(size_t i = 0; i < g_windows.size(); ++i) + { + CvWindow* window = g_windows[i].get(); + if (window->name == name) + return window; + } + return NULL; } static CvWindow* icvWindowByWidget( GtkWidget* widget ) { - CvWindow* window = hg_windows; - - while( window != 0 && window->widget != widget && - window->frame != widget && window->paned != widget ) - window = window->next; - - return window; + for (size_t i = 0; i < g_windows.size(); ++i) + { + CvWindow* window = g_windows[i].get(); + if (window->widget == widget || window->frame == widget || window->paned == widget) + return window; + } + return NULL; } double cvGetModeWindow_GTK(const char* name)//YV { - double result = -1; - - CV_FUNCNAME( "cvGetModeWindow_GTK" ); - - __BEGIN__; - - CvWindow* window; - - if (!name) - CV_ERROR( CV_StsNullPtr, "NULL name string" ); - - window = icvFindWindowByName( name ); - if (!window) - CV_ERROR( CV_StsNullPtr, "NULL window" ); + CV_Assert(name && "NULL name string"); CV_LOCK_MUTEX(); - result = window->status; - CV_UNLOCK_MUTEX(); + CvWindow* window = icvFindWindowByName(name); + if (!window) + CV_Error( CV_StsNullPtr, "NULL window" ); - __END__; + double result = window->status; return result; } void cvSetModeWindow_GTK( const char* name, double prop_value)//Yannick Verdie { + CV_Assert(name && "NULL name string"); - CV_FUNCNAME( "cvSetModeWindow_GTK" ); + CV_LOCK_MUTEX(); - __BEGIN__; - - CvWindow* window; - - if(!name) - CV_ERROR( CV_StsNullPtr, "NULL name string" ); - - window = icvFindWindowByName( name ); + CvWindow* window = icvFindWindowByName(name); if( !window ) - CV_ERROR( CV_StsNullPtr, "NULL window" ); + CV_Error( CV_StsNullPtr, "NULL window" ); if(window->flags & CV_WINDOW_AUTOSIZE)//if the flag CV_WINDOW_AUTOSIZE is set - EXIT; + return; //so easy to do fullscreen here, Linux rocks ! if (window->status==CV_WINDOW_FULLSCREEN && prop_value==CV_WINDOW_NORMAL) { - CV_LOCK_MUTEX(); gtk_window_unfullscreen(GTK_WINDOW(window->frame)); window->status=CV_WINDOW_NORMAL; - CV_UNLOCK_MUTEX(); - EXIT; + return; } if (window->status==CV_WINDOW_NORMAL && prop_value==CV_WINDOW_FULLSCREEN) { - CV_LOCK_MUTEX(); gtk_window_fullscreen(GTK_WINDOW(window->frame)); window->status=CV_WINDOW_FULLSCREEN; - CV_UNLOCK_MUTEX(); - EXIT; + return; } - - __END__; } void cv::setWindowTitle(const String& winname, const String& title) { + CV_LOCK_MUTEX(); + CvWindow* window = icvFindWindowByName(winname.c_str()); if (!window) { namedWindow(winname); window = icvFindWindowByName(winname.c_str()); + CV_Assert(window); } - if (!window) - CV_Error(Error::StsNullPtr, "NULL window"); - - CV_LOCK_MUTEX(); gtk_window_set_title(GTK_WINDOW(window->frame), title.c_str()); - CV_UNLOCK_MUTEX(); } double cvGetPropWindowAutoSize_GTK(const char* name) { - double result = -1; + CV_Assert(name && "NULL name string"); - CV_FUNCNAME( "cvGetPropWindowAutoSize_GTK" ); + CV_LOCK_MUTEX(); - __BEGIN__; - - CvWindow* window; - - if (!name) - CV_ERROR( CV_StsNullPtr, "NULL name string" ); - - window = icvFindWindowByName( name ); + CvWindow* window = icvFindWindowByName(name); if (!window) - EXIT; // keep silence here - - result = window->flags & CV_WINDOW_AUTOSIZE; - - __END__; + return -1; // keep silence here + double result = window->flags & CV_WINDOW_AUTOSIZE; return result; } double cvGetRatioWindow_GTK(const char* name) { - double result = -1; + CV_Assert(name && "NULL name string"); - CV_FUNCNAME( "cvGetRatioWindow_GTK" ); + CV_LOCK_MUTEX(); - __BEGIN__; - - CvWindow* window; - - if (!name) - CV_ERROR( CV_StsNullPtr, "NULL name string" ); - - window = icvFindWindowByName( name ); + CvWindow* window = icvFindWindowByName(name); if (!window) - EXIT; // keep silence here + return -1; // keep silence here #if defined (GTK_VERSION3) - result = static_cast( + double result = static_cast( gtk_widget_get_allocated_width(window->widget)) / gtk_widget_get_allocated_height(window->widget); #else - result = static_cast(window->widget->allocation.width) / window->widget->allocation.height; + double result = static_cast(window->widget->allocation.width) / window->widget->allocation.height; #endif // GTK_VERSION3 - __END__; - return result; } double cvGetOpenGlProp_GTK(const char* name) { - double result = -1; - #ifdef HAVE_OPENGL - CV_FUNCNAME( "cvGetOpenGlProp_GTK" ); + CV_Assert(name && "NULL name string"); - __BEGIN__; + CV_LOCK_MUTEX(); - CvWindow* window; - - if (!name) - CV_ERROR( CV_StsNullPtr, "NULL name string" ); - - window = icvFindWindowByName( name ); + CvWindow* window = icvFindWindowByName(name); if (!window) - EXIT; // keep silence here + return -1; // keep silence here - result = window->useGl; - - __END__; + double result = window->useGl; + return result; #else (void)name; + return -1; #endif - - return result; } @@ -857,35 +828,25 @@ namespace { GdkGLConfig* glconfig; - CV_FUNCNAME( "createGlContext" ); - - __BEGIN__; - // Try double-buffered visual glconfig = gdk_gl_config_new_by_mode((GdkGLConfigMode)(GDK_GL_MODE_RGB | GDK_GL_MODE_DEPTH | GDK_GL_MODE_DOUBLE)); if (!glconfig) - CV_ERROR( CV_OpenGlApiCallError, "Can't Create A GL Device Context" ); + CV_Error( CV_OpenGlApiCallError, "Can't Create A GL Device Context" ); // Set OpenGL-capability to the widget if (!gtk_widget_set_gl_capability(window->widget, glconfig, NULL, TRUE, GDK_GL_RGBA_TYPE)) - CV_ERROR( CV_OpenGlApiCallError, "Can't Create A GL Device Context" ); + CV_Error( CV_OpenGlApiCallError, "Can't Create A GL Device Context" ); window->useGl = true; - - __END__; } void drawGl(CvWindow* window) { - CV_FUNCNAME( "drawGl" ); - - __BEGIN__; - GdkGLContext* glcontext = gtk_widget_get_gl_context(window->widget); GdkGLDrawable* gldrawable = gtk_widget_get_gl_drawable(window->widget); if (!gdk_gl_drawable_gl_begin (gldrawable, glcontext)) - CV_ERROR( CV_OpenGlApiCallError, "Can't Activate The GL Rendering Context" ); + CV_Error( CV_OpenGlApiCallError, "Can't Activate The GL Rendering Context" ); glViewport(0, 0, window->widget->allocation.width, window->widget->allocation.height); @@ -900,8 +861,6 @@ namespace glFlush(); gdk_gl_drawable_gl_end(gldrawable); - - __END__; } } @@ -1015,43 +974,21 @@ static gboolean cvImageWidget_expose(GtkWidget* widget, GdkEventExpose* event, g CV_IMPL int cvNamedWindow( const char* name, int flags ) { - int result = 0; - CV_FUNCNAME( "cvNamedWindow" ); - - __BEGIN__; - - CvWindow* window; - int len; - int b_nautosize; - - cvInitSystem(1,(char**)&name); - if( !name ) - CV_ERROR( CV_StsNullPtr, "NULL name string" ); - - // Check the name in the storage - if( icvFindWindowByName( name ) != 0 ) - { - result = 1; - EXIT; - } - - len = strlen(name); - CV_CALL( window = (CvWindow*)cvAlloc(sizeof(CvWindow) + len + 1)); - memset( window, 0, sizeof(*window)); - window->name = (char*)(window + 1); - memcpy( window->name, name, len + 1 ); - window->flags = flags; - window->signature = CV_WINDOW_MAGIC_VAL; - window->last_key = 0; - window->on_mouse = 0; - window->on_mouse_param = 0; - memset( &window->toolbar, 0, sizeof(window->toolbar)); - window->next = hg_windows; - window->prev = 0; - window->status = CV_WINDOW_NORMAL;//YV + cvInitSystem(name ? 1 : 0,(char**)&name); + CV_Assert(name && "NULL name string"); CV_LOCK_MUTEX(); + // Check the name in the storage + if (icvFindWindowByName(name)) + { + return 1; + } + + Ptr window = makePtr(name); + window->flags = flags; + window->status = CV_WINDOW_NORMAL;//YV + window->frame = gtk_window_new( GTK_WINDOW_TOPLEVEL ); window->paned = gtk_vbox_new( FALSE, 0 ); @@ -1063,7 +1000,7 @@ CV_IMPL int cvNamedWindow( const char* name, int flags ) #ifndef HAVE_OPENGL if (flags & CV_WINDOW_OPENGL) - CV_ERROR( CV_OpenGlNotSupported, "Library was built without OpenGL support" ); + CV_Error( CV_OpenGlNotSupported, "Library was built without OpenGL support" ); #else if (flags & CV_WINDOW_OPENGL) createGlContext(window); @@ -1105,11 +1042,9 @@ CV_IMPL int cvNamedWindow( const char* name, int flags ) gtk_widget_show( window->frame ); gtk_window_set_title( GTK_WINDOW(window->frame), name ); - if( hg_windows ) - hg_windows->prev = window; - hg_windows = window; + g_windows.push_back(window); - b_nautosize = ((flags & CV_WINDOW_AUTOSIZE) == 0); + bool b_nautosize = ((flags & CV_WINDOW_AUTOSIZE) == 0); gtk_window_set_resizable( GTK_WINDOW(window->frame), b_nautosize ); // allow window to be resized @@ -1121,17 +1056,12 @@ CV_IMPL int cvNamedWindow( const char* name, int flags ) &geometry, (GdkWindowHints) (GDK_HINT_MIN_SIZE)); } - CV_UNLOCK_MUTEX(); - #ifdef HAVE_OPENGL if (window->useGl) cvSetOpenGlContext(name); #endif - result = 1; - __END__; - - return result; + return 1; } @@ -1139,110 +1069,71 @@ CV_IMPL int cvNamedWindow( const char* name, int flags ) CV_IMPL void cvSetOpenGlContext(const char* name) { - CvWindow* window; GdkGLContext* glcontext; GdkGLDrawable* gldrawable; - CV_FUNCNAME( "cvSetOpenGlContext" ); + CV_Assert(name && "NULL name string"); - __BEGIN__; + CV_LOCK_MUTEX(); - if(!name) - CV_ERROR( CV_StsNullPtr, "NULL name string" ); - - window = icvFindWindowByName( name ); + CvWindow* window = icvFindWindowByName(name); if (!window) - CV_ERROR( CV_StsNullPtr, "NULL window" ); + CV_Error( CV_StsNullPtr, "NULL window" ); if (!window->useGl) - CV_ERROR( CV_OpenGlNotSupported, "Window doesn't support OpenGL" ); + CV_Error( CV_OpenGlNotSupported, "Window doesn't support OpenGL" ); glcontext = gtk_widget_get_gl_context(window->widget); gldrawable = gtk_widget_get_gl_drawable(window->widget); if (!gdk_gl_drawable_make_current(gldrawable, glcontext)) - CV_ERROR( CV_OpenGlApiCallError, "Can't Activate The GL Rendering Context" ); - - __END__; + CV_Error( CV_OpenGlApiCallError, "Can't Activate The GL Rendering Context" ); } CV_IMPL void cvUpdateWindow(const char* name) { - CV_FUNCNAME( "cvUpdateWindow" ); + CV_Assert(name && "NULL name string"); - __BEGIN__; + CV_LOCK_MUTEX(); - CvWindow* window; - - if (!name) - CV_ERROR( CV_StsNullPtr, "NULL name string" ); - - window = icvFindWindowByName( name ); + CvWindow* window = icvFindWindowByName(name); if (!window) - EXIT; + return; // window does not refresh without this gtk_widget_queue_draw( GTK_WIDGET(window->widget) ); - - __END__; } CV_IMPL void cvSetOpenGlDrawCallback(const char* name, CvOpenGlDrawCallback callback, void* userdata) { - CvWindow* window; + CV_Assert(name && "NULL name string"); - CV_FUNCNAME( "cvCreateOpenGLCallback" ); + CV_LOCK_MUTEX(); - __BEGIN__; - - if(!name) - CV_ERROR( CV_StsNullPtr, "NULL name string" ); - - window = icvFindWindowByName( name ); + CvWindow* window = icvFindWindowByName(name); if( !window ) - EXIT; + return; if (!window->useGl) - CV_ERROR( CV_OpenGlNotSupported, "Window was created without OpenGL context" ); + CV_Error( CV_OpenGlNotSupported, "Window was created without OpenGL context" ); window->glDrawCallback = callback; window->glDrawData = userdata; - - __END__; } #endif // HAVE_OPENGL - -static void icvDeleteWindow( CvWindow* window ) +CvWindow::~CvWindow() { - CvTrackbar* trackbar; - - if( window->prev ) - window->prev->next = window->next; - else - hg_windows = window->next; - - if( window->next ) - window->next->prev = window->prev; - - window->prev = window->next = 0; - - gtk_widget_destroy( window->frame ); - - for( trackbar = window->toolbar.first; trackbar != 0; ) - { - CvTrackbar* next = trackbar->next; - cvFree( &trackbar ); - trackbar = next; - } - - cvFree( &window ); + gtk_widget_destroy(frame); +} +static void checkLastWindow() +{ // if last window... - if( hg_windows == 0 ) + if (g_windows.empty()) { #ifdef HAVE_GTHREAD if( thread_started ) @@ -1269,32 +1160,44 @@ static void icvDeleteWindow( CvWindow* window ) } } +static void icvDeleteWindow( CvWindow* window ) +{ + bool found = false; + for (std::vector< Ptr >::iterator i = g_windows.begin(); + i != g_windows.end(); ++i) + { + if (i->get() == window) + { + g_windows.erase(i); + found = true; + break; + } + } + CV_Assert(found && "Can't destroy non-registered window"); + + checkLastWindow(); +} CV_IMPL void cvDestroyWindow( const char* name ) { - CV_FUNCNAME( "cvDestroyWindow" ); + CV_Assert(name && "NULL name string"); - __BEGIN__; - - CvWindow* window; - - if(!name) - CV_ERROR( CV_StsNullPtr, "NULL name string" ); - - window = icvFindWindowByName( name ); - if( !window ) - EXIT; - - // note that it is possible for the update thread to run this function - // if there is a call to cvShowImage in a mouse callback - // (this would produce a deadlock on window_mutex) CV_LOCK_MUTEX(); - icvDeleteWindow( window ); + bool found = false; + for (std::vector< Ptr >::iterator i = g_windows.begin(); + i != g_windows.end(); ++i) + { + if (i->get()->name == name) + { + g_windows.erase(i); + found = true; + break; + } + } + CV_Assert(found && "Can't destroy non-registered window"); - CV_UNLOCK_MUTEX(); - - __END__; + checkLastWindow(); } @@ -1303,12 +1206,8 @@ cvDestroyAllWindows( void ) { CV_LOCK_MUTEX(); - while( hg_windows ) - { - CvWindow* window = hg_windows; - icvDeleteWindow( window ); - } - CV_UNLOCK_MUTEX(); + g_windows.clear(); + checkLastWindow(); } // CvSize icvCalcOptimalWindowSize( CvWindow * window, CvSize new_image_size){ @@ -1326,25 +1225,19 @@ cvDestroyAllWindows( void ) CV_IMPL void cvShowImage( const char* name, const CvArr* arr ) { - CV_FUNCNAME( "cvShowImage" ); - - __BEGIN__; - - CvWindow* window; - - if( !name ) - CV_ERROR( CV_StsNullPtr, "NULL name" ); + CV_Assert(name && "NULL name string"); CV_LOCK_MUTEX(); - window = icvFindWindowByName(name); + CvWindow* window = icvFindWindowByName(name); if(!window) { cvNamedWindow(name, 1); window = icvFindWindowByName(name); } + CV_Assert(window); - if( window && arr ) + if (arr) { #ifdef HAVE_OPENGL if (window->useGl) @@ -1357,81 +1250,55 @@ cvShowImage( const char* name, const CvArr* arr ) CvImageWidget * image_widget = CV_IMAGE_WIDGET( window->widget ); cvImageWidgetSetImage( image_widget, arr ); } - - CV_UNLOCK_MUTEX(); - - __END__; } CV_IMPL void cvResizeWindow(const char* name, int width, int height ) { - CV_FUNCNAME( "cvResizeWindow" ); - - __BEGIN__; - - CvWindow* window; - CvImageWidget * image_widget; - - if( !name ) - CV_ERROR( CV_StsNullPtr, "NULL name" ); - - window = icvFindWindowByName(name); - if(!window) - EXIT; - - image_widget = CV_IMAGE_WIDGET( window->widget ); - //if(image_widget->flags & CV_WINDOW_AUTOSIZE) - //EXIT; + CV_Assert(name && "NULL name string"); CV_LOCK_MUTEX(); + CvWindow* window = icvFindWindowByName(name); + if(!window) + return; + + CvImageWidget* image_widget = CV_IMAGE_WIDGET( window->widget ); + //if(image_widget->flags & CV_WINDOW_AUTOSIZE) + //EXIT; + gtk_window_set_resizable( GTK_WINDOW(window->frame), 1 ); gtk_window_resize( GTK_WINDOW(window->frame), width, height ); // disable initial resize since presumably user wants to keep // this window size image_widget->flags &= ~CV_WINDOW_NO_IMAGE; - - CV_UNLOCK_MUTEX(); - - __END__; } CV_IMPL void cvMoveWindow( const char* name, int x, int y ) { - CV_FUNCNAME( "cvMoveWindow" ); - - __BEGIN__; - - CvWindow* window; - - if( !name ) - CV_ERROR( CV_StsNullPtr, "NULL name" ); - - window = icvFindWindowByName(name); - if(!window) - EXIT; + CV_Assert(name && "NULL name string"); CV_LOCK_MUTEX(); + CvWindow* window = icvFindWindowByName(name); + if(!window) + return; + gtk_window_move( GTK_WINDOW(window->frame), x, y ); - - CV_UNLOCK_MUTEX(); - - __END__; } static CvTrackbar* icvFindTrackbarByName( const CvWindow* window, const char* name ) { - CvTrackbar* trackbar = window->toolbar.first; - - for( ; trackbar != 0 && strcmp( trackbar->name, name ) != 0; trackbar = trackbar->next ) - ; - - return trackbar; + for (size_t i = 0; i < window->trackbars.size(); ++i) + { + CvTrackbar* trackbar = window->trackbars[i].get(); + if (trackbar->name == name) + return trackbar; + } + return NULL; } static int @@ -1439,41 +1306,25 @@ icvCreateTrackbar( const char* trackbar_name, const char* window_name, int* val, int count, CvTrackbarCallback on_notify, CvTrackbarCallback2 on_notify2, void* userdata ) { - int result = 0; - - CV_FUNCNAME( "icvCreateTrackbar" ); - - __BEGIN__; - - /*char slider_name[32];*/ - CvWindow* window = 0; - CvTrackbar* trackbar = 0; - - if( !window_name || !trackbar_name ) - CV_ERROR( CV_StsNullPtr, "NULL window or trackbar name" ); + CV_Assert(window_name && "NULL window name"); + CV_Assert(trackbar_name && "NULL trackbar name"); if( count <= 0 ) - CV_ERROR( CV_StsOutOfRange, "Bad trackbar maximal value" ); - - window = icvFindWindowByName(window_name); - if( !window ) - EXIT; - - trackbar = icvFindTrackbarByName(window,trackbar_name); + CV_Error( CV_StsOutOfRange, "Bad trackbar maximal value" ); CV_LOCK_MUTEX(); - if( !trackbar ) + CvWindow* window = icvFindWindowByName(window_name); + if(!window) + return 0; + + CvTrackbar* trackbar = icvFindTrackbarByName(window, trackbar_name); + if (!trackbar) { - int len = strlen(trackbar_name); - trackbar = (CvTrackbar*)cvAlloc(sizeof(CvTrackbar) + len + 1); - memset( trackbar, 0, sizeof(*trackbar)); - trackbar->signature = CV_TRACKBAR_MAGIC_VAL; - trackbar->name = (char*)(trackbar+1); - memcpy( trackbar->name, trackbar_name, len + 1 ); + Ptr trackbar_ = makePtr(trackbar_name); + trackbar = trackbar_.get(); trackbar->parent = window; - trackbar->next = window->toolbar.first; - window->toolbar.first = trackbar; + window->trackbars.push_back(trackbar_); GtkWidget* hscale_box = gtk_hbox_new( FALSE, 10 ); GtkWidget* hscale_label = gtk_label_new( trackbar_name ); @@ -1489,7 +1340,6 @@ icvCreateTrackbar( const char* trackbar_name, const char* window_name, gtk_widget_show( hscale ); gtk_box_pack_start( GTK_BOX(window->paned), hscale_box, FALSE, FALSE, 5 ); gtk_widget_show( hscale_box ); - } if( val ) @@ -1515,14 +1365,7 @@ icvCreateTrackbar( const char* trackbar_name, const char* window_name, // compensate for the addition of trackbars gtk_widget_queue_resize( GTK_WIDGET(window->widget) ); - - CV_UNLOCK_MUTEX(); - - result = 1; - - __END__; - - return result; + return 1; } @@ -1548,209 +1391,134 @@ cvCreateTrackbar2( const char* trackbar_name, const char* window_name, CV_IMPL void cvSetMouseCallback( const char* window_name, CvMouseCallback on_mouse, void* param ) { - CV_FUNCNAME( "cvSetMouseCallback" ); + CV_Assert(window_name && "NULL window name"); - __BEGIN__; + CV_LOCK_MUTEX(); - CvWindow* window = 0; - - if( !window_name ) - CV_ERROR( CV_StsNullPtr, "NULL window name" ); - - window = icvFindWindowByName(window_name); - if( !window ) - EXIT; + CvWindow* window = icvFindWindowByName(window_name); + if (!window) + return; window->on_mouse = on_mouse; window->on_mouse_param = param; - - __END__; } CV_IMPL int cvGetTrackbarPos( const char* trackbar_name, const char* window_name ) { - int pos = -1; + CV_Assert(window_name && "NULL window name"); + CV_Assert(trackbar_name && "NULL trackbar name"); - CV_FUNCNAME( "cvGetTrackbarPos" ); + CV_LOCK_MUTEX(); - __BEGIN__; + CvWindow* window = icvFindWindowByName(window_name); + if (!window) + return -1; - CvWindow* window; - CvTrackbar* trackbar = 0; + CvTrackbar* trackbar = icvFindTrackbarByName(window,trackbar_name); + if (!trackbar) + return -1; - if( trackbar_name == 0 || window_name == 0 ) - CV_ERROR( CV_StsNullPtr, "NULL trackbar or window name" ); - - window = icvFindWindowByName( window_name ); - if( window ) - trackbar = icvFindTrackbarByName( window, trackbar_name ); - - if( trackbar ) - pos = trackbar->pos; - - __END__; - - return pos; + return trackbar->pos; } CV_IMPL void cvSetTrackbarPos( const char* trackbar_name, const char* window_name, int pos ) { - CV_FUNCNAME( "cvSetTrackbarPos" ); + CV_Assert(window_name && "NULL window name"); + CV_Assert(trackbar_name && "NULL trackbar name"); - __BEGIN__; + CV_LOCK_MUTEX(); - CvWindow* window; - CvTrackbar* trackbar = 0; - - if( trackbar_name == 0 || window_name == 0 ) - CV_ERROR( CV_StsNullPtr, "NULL trackbar or window name" ); - - window = icvFindWindowByName( window_name ); - if( window ) - trackbar = icvFindTrackbarByName( window, trackbar_name ); + CvWindow* window = icvFindWindowByName(window_name); + if(!window) + return; + CvTrackbar* trackbar = icvFindTrackbarByName(window,trackbar_name); if( trackbar ) { - if( pos < 0 ) - pos = 0; + if( pos < trackbar->minval ) + pos = trackbar->minval; if( pos > trackbar->maxval ) pos = trackbar->maxval; } else { - CV_ERROR( CV_StsNullPtr, "No trackbar found" ); + CV_Error( CV_StsNullPtr, "No trackbar found" ); } - CV_LOCK_MUTEX(); - gtk_range_set_value( GTK_RANGE(trackbar->widget), pos ); - - CV_UNLOCK_MUTEX(); - - __END__; } CV_IMPL void cvSetTrackbarMax(const char* trackbar_name, const char* window_name, int maxval) { - CV_FUNCNAME("cvSetTrackbarMax"); + CV_Assert(window_name && "NULL window name"); + CV_Assert(trackbar_name && "NULL trackbar name"); - __BEGIN__; + CV_LOCK_MUTEX(); - if (maxval >= 0) - { - CvWindow* window = 0; - CvTrackbar* trackbar = 0; + CvWindow* window = icvFindWindowByName(window_name); + if(!window) + return; - if (trackbar_name == 0 || window_name == 0) - { - CV_ERROR( CV_StsNullPtr, "NULL trackbar or window name"); - } + CvTrackbar* trackbar = icvFindTrackbarByName(window,trackbar_name); + if(!trackbar) + return; - window = icvFindWindowByName( window_name ); - if (window) - { - trackbar = icvFindTrackbarByName(window, trackbar_name); - if (trackbar) - { - trackbar->maxval = (trackbar->minval>maxval)?trackbar->minval:maxval; - - CV_LOCK_MUTEX(); - - gtk_range_set_range(GTK_RANGE(trackbar->widget), 0, trackbar->maxval); - - CV_UNLOCK_MUTEX(); - } - } - } - - __END__; + trackbar->maxval = maxval; + if (trackbar->maxval >= trackbar->minval) + gtk_range_set_range(GTK_RANGE(trackbar->widget), trackbar->minval, trackbar->maxval); } CV_IMPL void cvSetTrackbarMin(const char* trackbar_name, const char* window_name, int minval) { - CV_FUNCNAME("cvSetTrackbarMin"); + CV_Assert(window_name && "NULL window name"); + CV_Assert(trackbar_name && "NULL trackbar name"); - __BEGIN__; + CV_LOCK_MUTEX(); - if (minval >= 0) - { - CvWindow* window = 0; - CvTrackbar* trackbar = 0; + CvWindow* window = icvFindWindowByName(window_name); + if(!window) + return; - if (trackbar_name == 0 || window_name == 0) - { - CV_ERROR( CV_StsNullPtr, "NULL trackbar or window name"); - } + CvTrackbar* trackbar = icvFindTrackbarByName(window,trackbar_name); + if(!trackbar) + return; - window = icvFindWindowByName( window_name ); - if (window) - { - trackbar = icvFindTrackbarByName(window, trackbar_name); - if (trackbar) - { - trackbar->minval = (minvalmaxval)?minval:trackbar->maxval; - - CV_LOCK_MUTEX(); - - gtk_range_set_range(GTK_RANGE(trackbar->widget), minval, trackbar->maxval); - - CV_UNLOCK_MUTEX(); - } - } - } - - __END__; + trackbar->minval = minval; + if (trackbar->maxval >= trackbar->minval) + gtk_range_set_range(GTK_RANGE(trackbar->widget), trackbar->minval, trackbar->maxval); } CV_IMPL void* cvGetWindowHandle( const char* window_name ) { - void* widget = 0; + CV_Assert(window_name && "NULL window name"); - CV_FUNCNAME( "cvGetWindowHandle" ); + CV_LOCK_MUTEX(); - __BEGIN__; + CvWindow* window = icvFindWindowByName(window_name); + if(!window) + return NULL; - CvWindow* window; - - if( window_name == 0 ) - CV_ERROR( CV_StsNullPtr, "NULL window name" ); - - window = icvFindWindowByName( window_name ); - if( window ) - widget = (void*)window->widget; - - __END__; - - return widget; + return (void*)window->widget; } CV_IMPL const char* cvGetWindowName( void* window_handle ) { - const char* window_name = ""; + CV_Assert(window_handle && "NULL window handle"); - CV_FUNCNAME( "cvGetWindowName" ); + CV_LOCK_MUTEX(); - __BEGIN__; + CvWindow* window = icvWindowByWidget( (GtkWidget*)window_handle ); + if (window) + return window->name.c_str(); - CvWindow* window; - - if( window_handle == 0 ) - CV_ERROR( CV_StsNullPtr, "NULL window" ); - - window = icvWindowByWidget( (GtkWidget*)window_handle ); - if( window ) - window_name = window->name; - - __END__; - - return window_name; + return ""; // FIXME: NULL? } static GtkFileFilter* icvMakeGtkFilter(const char* name, const char* patterns, GtkFileFilter* images) @@ -1812,7 +1580,7 @@ static void icvShowSaveAsDialog(GtkWidget* widget, CvWindow* window) }; for (size_t idx = 0; idx < sizeof(file_filters)/sizeof(file_filters[0]); ++idx) - gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), file_filters[idx]); + gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), file_filters[idx]); // filter ownership is transferred to dialog gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(dialog), filter_images); cv::String filename; @@ -1993,9 +1761,11 @@ static gboolean icvOnMouse( GtkWidget *widget, GdkEvent *event, gpointer user_da break; #endif //GTK_VERSION3_4 case GDK_SCROLL_LEFT: cv_event = CV_EVENT_MOUSEHWHEEL; + /* FALLTHRU */ case GDK_SCROLL_UP: flags |= ~0xffff; break; case GDK_SCROLL_RIGHT: cv_event = CV_EVENT_MOUSEHWHEEL; + /* FALLTHRU */ case GDK_SCROLL_DOWN: flags |= (((int)1 << 16)); break; default: ; @@ -2072,7 +1842,7 @@ CV_IMPL int cvWaitKey( int delay ) } my_last_key = last_key; g_mutex_unlock(last_key_mutex); - if(expired || hg_windows==0){ + if(expired || g_windows.empty()){ return -1; } return my_last_key; @@ -2084,7 +1854,7 @@ CV_IMPL int cvWaitKey( int delay ) if( delay > 0 ) timer = g_timeout_add( delay, icvAlarm, &expired ); last_key = -1; - while( gtk_main_iteration_do(TRUE) && last_key < 0 && !expired && hg_windows != 0 ) + while( gtk_main_iteration_do(TRUE) && last_key < 0 && !expired && !g_windows.empty()) ; if( delay > 0 && !expired ) diff --git a/samples/cpp/falsecolor.cpp b/samples/cpp/falsecolor.cpp index 3e62434cf0..c0d9436ea1 100644 --- a/samples/cpp/falsecolor.cpp +++ b/samples/cpp/falsecolor.cpp @@ -15,6 +15,7 @@ String winName="False color"; static void TrackColorMap(int x, void *r) { + std::cout << "selected: " << x << std::endl; ParamColorMar *p = (ParamColorMar*)r; Mat dst; p->iColormap= x; @@ -23,9 +24,8 @@ static void TrackColorMap(int x, void *r) if (!lutRND) { RNG ra; - Mat *palette = new Mat(256, 1, CV_8UC3); - ra.fill(*palette, RNG::UNIFORM, 0, 256); - lutRND = Ptr(palette); + lutRND = makePtr(256, 1, CV_8UC3); + ra.fill(*lutRND, RNG::UNIFORM, 0, 256); } applyColorMap(p->img, dst, *lutRND.get()); } @@ -77,6 +77,7 @@ static void TrackColorMap(int x, void *r) colorMapName = "User colormap : random"; break; } + std::cout << "> " << colorMapName << std::endl; putText(dst, colorMapName, Point(10, 20), cv::FONT_HERSHEY_SIMPLEX, 1, Scalar(255, 255, 255)); imshow(winName, dst); } @@ -144,7 +145,10 @@ int main(int argc, char** argv) setTrackbarMax("colormap", winName, cv::COLORMAP_PARULA+1); setTrackbarPos("colormap", winName, -1); - TrackColorMap(0,(void*)&p); - waitKey(0); + TrackColorMap((int)getTrackbarPos("colormap", winName),(void*)&p); + while (waitKey(0) != 27) + { + std::cout << "Press 'ESC' to exit" << std::endl; + } return 0; }