X-Git-Url: https://vcs.maemo.org/git/?a=blobdiff_plain;f=otherlibs%2Fhighgui%2Fwindow_gtk.cpp;fp=otherlibs%2Fhighgui%2Fwindow_gtk.cpp;h=0000000000000000000000000000000000000000;hb=e4c14cdbdf2fe805e79cd96ded236f57e7b89060;hp=6182dd7f999e655fafa09b25c60596b1328bdf5a;hpb=454138ff8a20f6edb9b65a910101403d8b520643;p=opencv diff --git a/otherlibs/highgui/window_gtk.cpp b/otherlibs/highgui/window_gtk.cpp deleted file mode 100644 index 6182dd7..0000000 --- a/otherlibs/highgui/window_gtk.cpp +++ /dev/null @@ -1,1273 +0,0 @@ -/*M/////////////////////////////////////////////////////////////////////////////////////// -// -// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. -// -// By downloading, copying, installing or using the software you agree to this license. -// If you do not agree to this license, do not download, install, -// copy or use the software. -// -// -// Intel License Agreement -// For Open Source Computer Vision Library -// -// Copyright (C) 2000, Intel Corporation, all rights reserved. -// Third party copyrights are property of their respective owners. -// -// Redistribution and use in source and binary forms, with or without modification, -// are permitted provided that the following conditions are met: -// -// * Redistribution's of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistribution's in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// * The name of Intel Corporation may not be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// This software is provided by the copyright holders and contributors "as is" and -// any express or implied warranties, including, but not limited to, the implied -// warranties of merchantability and fitness for a particular purpose are disclaimed. -// In no event shall the Intel Corporation or contributors be liable for any direct, -// indirect, incidental, special, exemplary, or consequential damages -// (including, but not limited to, procurement of substitute goods or services; -// loss of use, data, or profits; or business interruption) however caused -// and on any theory of liability, whether in contract, strict liability, -// or tort (including negligence or otherwise) arising in any way out of -// the use of this software, even if advised of the possibility of such damage. -// -//M*/ - -#include "_highgui.h" - -#ifndef WIN32 - -#ifdef HAVE_GTK - -#include "gtk/gtk.h" -#include "gdk/gdkkeysyms.h" -#include - -#include "cv.h" -/*#if _MSC_VER >= 1200 -#pragma warning( disable: 4505 ) -#pragma comment(lib,"gtk-win32-2.0.lib") -#pragma comment(lib,"glib-2.0.lib") -#pragma comment(lib,"gobject-2.0.lib") -#pragma comment(lib,"gdk-win32-2.0.lib") -#pragma comment(lib,"gdk_pixbuf-2.0.lib") -#endif*/ - - -// TODO Fix the initial window size when flags=0. Right now the initial window is by default -// 320x240 size. A better default would be actual size of the image. Problem -// is determining desired window size with trackbars while still allowing resizing. -// -// Gnome Totem source may be of use here, see bacon_video_widget_set_scale_ratio -// in totem/src/backend/bacon-video-widget-xine.c - -//////////////////////////////////////////////////////////// -// CvImageWidget GTK Widget Public API -//////////////////////////////////////////////////////////// -typedef struct _CvImageWidget CvImageWidget; -typedef struct _CvImageWidgetClass CvImageWidgetClass; - -struct _CvImageWidget { - GtkWidget widget; - CvMat * original_image; - CvMat * scaled_image; - int flags; -}; - -struct _CvImageWidgetClass -{ - GtkWidgetClass parent_class; -}; - - -/** Allocate new image viewer widget */ -GtkWidget* cvImageWidgetNew (int flags); - -/** Set the image to display in the widget */ -void cvImageWidgetSetImage(CvImageWidget * widget, const CvArr *arr); - -// standard GTK object macros -#define CV_IMAGE_WIDGET(obj) GTK_CHECK_CAST (obj, cvImageWidget_get_type (), CvImageWidget) -#define CV_IMAGE_WIDGET_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, cvImageWidget_get_type (), CvImageWidgetClass) -#define CV_IS_IMAGE_WIDGET(obj) GTK_CHECK_TYPE (obj, cvImageWidget_get_type ()) - -///////////////////////////////////////////////////////////////////////////// -// Private API //////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// -GtkType cvImageWidget_get_type (void); - -static GtkWidgetClass * parent_class = NULL; - -// flag to help size initial window -#define CV_WINDOW_NO_IMAGE 2 - -void cvImageWidgetSetImage(CvImageWidget * widget, const CvArr *arr){ - CvMat * mat, stub; - int origin=0; - - //printf("cvImageWidgetSetImage\n"); - - if( CV_IS_IMAGE_HDR( arr )) - origin = ((IplImage*)arr)->origin; - - mat = cvGetMat(arr, &stub); - - if(widget->original_image && !CV_ARE_SIZES_EQ(mat, widget->original_image)){ - cvReleaseMat( &widget->original_image ); - } - if(!widget->original_image){ - widget->original_image = cvCreateMat( mat->rows, mat->cols, CV_8UC3 ); - gtk_widget_queue_resize( GTK_WIDGET( widget ) ); - } - cvConvertImage( mat, widget->original_image, - (origin != 0 ? CV_CVTIMG_FLIP : 0) + CV_CVTIMG_SWAP_RB ); - if(widget->scaled_image){ - cvResize( widget->original_image, widget->scaled_image, CV_INTER_AREA ); - } - - // window does not refresh without this - gtk_widget_queue_draw( GTK_WIDGET(widget) ); -} - -GtkWidget* -cvImageWidgetNew (int flags) -{ - CvImageWidget *image_widget; - - image_widget = CV_IMAGE_WIDGET( gtk_type_new (cvImageWidget_get_type ()) ); - image_widget->original_image = 0; - image_widget->scaled_image = 0; - image_widget->flags = flags | CV_WINDOW_NO_IMAGE; - - return GTK_WIDGET (image_widget); -} - -static void -cvImageWidget_realize (GtkWidget *widget) -{ - CvImageWidget *image_widget; - GdkWindowAttr attributes; - gint attributes_mask; - - //printf("cvImageWidget_realize\n"); - g_return_if_fail (widget != NULL); - g_return_if_fail (CV_IS_IMAGE_WIDGET (widget)); - - GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED); - image_widget = CV_IMAGE_WIDGET (widget); - - attributes.x = widget->allocation.x; - attributes.y = widget->allocation.y; - attributes.width = widget->allocation.width; - attributes.height = widget->allocation.height; - attributes.wclass = GDK_INPUT_OUTPUT; - attributes.window_type = GDK_WINDOW_CHILD; - attributes.event_mask = gtk_widget_get_events (widget) | - GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | - GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK; - attributes.visual = gtk_widget_get_visual (widget); - attributes.colormap = gtk_widget_get_colormap (widget); - - attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP; - widget->window = gdk_window_new (widget->parent->window, &attributes, attributes_mask); - - widget->style = gtk_style_attach (widget->style, widget->window); - - gdk_window_set_user_data (widget->window, widget); - - gtk_style_set_background (widget->style, widget->window, GTK_STATE_ACTIVE); -} - -static CvSize cvImageWidget_calc_size( int im_width, int im_height, int max_width, int max_height ){ - float aspect = (float)im_width/(float)im_height; - float max_aspect = (float)max_width/(float)max_height; - if(aspect > max_aspect){ - return cvSize( max_width, cvRound(max_width/aspect) ); - } - return cvSize( cvRound(max_height*aspect), max_height ); -} - -static void -cvImageWidget_size_request (GtkWidget *widget, - GtkRequisition *requisition) -{ - CvImageWidget * image_widget = CV_IMAGE_WIDGET( widget ); - - //printf("cvImageWidget_size_request "); - // the case the first time cvShowImage called or when AUTOSIZE - if( image_widget->original_image && - ((image_widget->flags & CV_WINDOW_AUTOSIZE) || - (image_widget->flags & CV_WINDOW_NO_IMAGE))) - { - //printf("original "); - requisition->width = image_widget->original_image->cols; - requisition->height = image_widget->original_image->rows; - } - // default case - else if(image_widget->scaled_image){ - //printf("scaled "); - requisition->width = image_widget->scaled_image->cols; - requisition->height = image_widget->scaled_image->rows; - } - // the case before cvShowImage called - else{ - //printf("default "); - requisition->width = 320; - requisition->height = 240; - } - //printf("%d %d\n",requisition->width, requisition->height); -} - -static void cvImageWidget_set_size(GtkWidget * widget, int max_width, int max_height){ - CvImageWidget * image_widget = CV_IMAGE_WIDGET( widget ); - - //printf("cvImageWidget_set_size %d %d\n", max_width, max_height); - - // don't allow to set the size - if(image_widget->flags & CV_WINDOW_AUTOSIZE) return; - if(!image_widget->original_image) return; - - CvSize scaled_image_size = cvImageWidget_calc_size( image_widget->original_image->cols, - image_widget->original_image->rows, max_width, max_height ); - - if( image_widget->scaled_image && - ( image_widget->scaled_image->cols != scaled_image_size.width || - image_widget->scaled_image->rows != scaled_image_size.height )) - { - cvReleaseMat( &image_widget->scaled_image ); - } - if( !image_widget->scaled_image ){ - image_widget->scaled_image = cvCreateMat( scaled_image_size.height, scaled_image_size.width, CV_8UC3 ); - - - } - assert( image_widget->scaled_image ); -} - -static void -cvImageWidget_size_allocate (GtkWidget *widget, - GtkAllocation *allocation) -{ - CvImageWidget *image_widget; - - //printf("cvImageWidget_size_allocate\n"); - g_return_if_fail (widget != NULL); - g_return_if_fail (CV_IS_IMAGE_WIDGET (widget)); - g_return_if_fail (allocation != NULL); - - widget->allocation = *allocation; - image_widget = CV_IMAGE_WIDGET (widget); - - - if( (image_widget->flags & CV_WINDOW_AUTOSIZE)==0 && image_widget->original_image ){ - // (re) allocated scaled image - if( image_widget->flags & CV_WINDOW_NO_IMAGE ){ - cvImageWidget_set_size( widget, image_widget->original_image->cols, - image_widget->original_image->rows); - } - else{ - cvImageWidget_set_size( widget, allocation->width, allocation->height ); - } - cvResize( image_widget->original_image, image_widget->scaled_image, CV_INTER_AREA ); - } - - if (GTK_WIDGET_REALIZED (widget)) - { - image_widget = CV_IMAGE_WIDGET (widget); - - if( image_widget->original_image && - ((image_widget->flags & CV_WINDOW_AUTOSIZE) || - (image_widget->flags & CV_WINDOW_NO_IMAGE)) ) - { - widget->allocation.width = image_widget->original_image->cols; - widget->allocation.height = image_widget->original_image->rows; - gdk_window_move_resize( widget->window, allocation->x, allocation->y, - image_widget->original_image->cols, image_widget->original_image->rows ); - if(image_widget->flags & CV_WINDOW_NO_IMAGE){ - image_widget->flags &= ~CV_WINDOW_NO_IMAGE; - gtk_widget_queue_resize( GTK_WIDGET(widget) ); - } - } - else{ - gdk_window_move_resize (widget->window, - allocation->x, allocation->y, - allocation->width, allocation->height ); - - } - } -} - -static gboolean -cvImageWidget_expose( GtkWidget *widget, - GdkEventExpose *event ) -{ - CvImageWidget *image_widget; - - g_return_val_if_fail (widget != NULL, FALSE); - g_return_val_if_fail (CV_IS_IMAGE_WIDGET (widget), FALSE); - g_return_val_if_fail (event != NULL, FALSE); - - if (event->count > 0) - return FALSE; - - image_widget = CV_IMAGE_WIDGET (widget); - - gdk_window_clear_area (widget->window, - 0, 0, - widget->allocation.width, - widget->allocation.height); - if( image_widget->scaled_image ){ - // center image in available region - int x0 = (widget->allocation.width - image_widget->scaled_image->cols)/2; - int y0 = (widget->allocation.height - image_widget->scaled_image->rows)/2; - - gdk_draw_rgb_image( widget->window, widget->style->fg_gc[GTK_STATE_NORMAL], - x0, y0, MIN(image_widget->scaled_image->cols, widget->allocation.width), - MIN(image_widget->scaled_image->rows, widget->allocation.height), - GDK_RGB_DITHER_MAX, image_widget->scaled_image->data.ptr, image_widget->scaled_image->step ); - } - else if( image_widget->original_image ){ - gdk_draw_rgb_image( widget->window, widget->style->fg_gc[GTK_STATE_NORMAL], - 0, 0, - MIN(image_widget->original_image->cols, widget->allocation.width), - MIN(image_widget->original_image->rows, widget->allocation.height), - GDK_RGB_DITHER_MAX, image_widget->original_image->data.ptr, image_widget->original_image->step ); - } - return TRUE; -} - -static void -cvImageWidget_destroy (GtkObject *object) -{ - CvImageWidget *image_widget; - - g_return_if_fail (object != NULL); - g_return_if_fail (CV_IS_IMAGE_WIDGET (object)); - - image_widget = CV_IMAGE_WIDGET (object); - - cvReleaseMat( &image_widget->scaled_image ); - cvReleaseMat( &image_widget->original_image ); - - if (GTK_OBJECT_CLASS (parent_class)->destroy) - (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); -} - -static void cvImageWidget_class_init (CvImageWidgetClass * klass) -{ - GtkObjectClass *object_class; - GtkWidgetClass *widget_class; - - object_class = (GtkObjectClass*) klass; - widget_class = (GtkWidgetClass*) klass; - - parent_class = GTK_WIDGET_CLASS( gtk_type_class (gtk_widget_get_type ()) ); - - object_class->destroy = cvImageWidget_destroy; - - widget_class->realize = cvImageWidget_realize; - widget_class->expose_event = cvImageWidget_expose; - widget_class->size_request = cvImageWidget_size_request; - widget_class->size_allocate = cvImageWidget_size_allocate; - widget_class->button_press_event = NULL; - widget_class->button_release_event = NULL; - widget_class->motion_notify_event = NULL; -} - -static void -cvImageWidget_init (CvImageWidget *image_widget) -{ - image_widget->original_image=0; - image_widget->scaled_image=0; - image_widget->flags=0; -} - -GtkType cvImageWidget_get_type (void){ - static GtkType image_type = 0; - - if (!image_type) - { - static const GtkTypeInfo image_info = - { - "CvImageWidget", - sizeof (CvImageWidget), - sizeof (CvImageWidgetClass), - (GtkClassInitFunc) cvImageWidget_class_init, - (GtkObjectInitFunc) cvImageWidget_init, - /* reserved_1 */ NULL, - /* reserved_1 */ NULL, - (GtkClassInitFunc) NULL - }; - - image_type = gtk_type_unique (GTK_TYPE_WIDGET, &image_info); - } - - return image_type; -} -///////////////////////////////////////////////////////////////////////////// -// End CvImageWidget -///////////////////////////////////////////////////////////////////////////// - - -struct CvWindow; - -typedef struct CvTrackbar -{ - int signature; - GtkWidget* widget; - char* name; - CvTrackbar* next; - CvWindow* parent; - int* data; - int pos; - int maxval; - CvTrackbarCallback notify; -} -CvTrackbar; - -typedef struct CvWindow -{ - int signature; - GtkWidget* widget; - GtkWidget* frame; - GtkWidget* paned; - char* name; - CvWindow* prev; - CvWindow* next; - - int last_key; - int flags; - - CvMouseCallback on_mouse; - void* on_mouse_param; - - struct - { - int pos; - int rows; - CvTrackbar* first; - } - toolbar; -} -CvWindow; - - -static gboolean icvOnClose( GtkWidget* widget, GdkEvent* event, gpointer user_data ); -static gboolean icvOnKeyPress( GtkWidget* widget, GdkEventKey* event, gpointer user_data ); -static void icvOnTrackbar( GtkWidget* widget, gpointer user_data ); -static gboolean icvOnMouse( GtkWidget *widget, GdkEvent *event, gpointer user_data ); - -#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; -#endif - -static int last_key = -1; -static CvWindow* hg_windows = 0; - -CV_IMPL int cvInitSystem( int argc, char** argv ) -{ - static int wasInitialized = 0; - - // check initialization status - if( !wasInitialized ) - { - hg_windows = 0; - - gtk_init( &argc, &argv ); - wasInitialized = 1; - } - - return 0; -} - -CV_IMPL int cvStartWindowThread(){ -#ifdef HAVE_GTHREAD - cvInitSystem(0,NULL); - if (!thread_started) { - if (!g_thread_supported ()) { - /* the GThread system wasn't inited, so init it */ - g_thread_init(NULL); - } - - // this mutex protects the window resources - window_mutex = g_mutex_new(); - - // protects the 'last key pressed' variable - last_key_mutex = g_mutex_new(); - - // conditional that indicates a key has been pressed - cond_have_key = g_cond_new(); - - // this is the window update thread - window_thread = g_thread_create((GThreadFunc) icvWindowThreadLoop, - NULL, TRUE, NULL); - } - thread_started = window_thread!=NULL; - return thread_started; -#else - return 0; -#endif -} - -#ifdef HAVE_GTHREAD -gpointer icvWindowThreadLoop(){ - while(1){ - g_mutex_lock(window_mutex); - gtk_main_iteration_do(FALSE); - g_mutex_unlock(window_mutex); - - // little sleep - g_usleep(500); - - g_thread_yield(); - } - 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 { } - -#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; -} - -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; -} - -CV_IMPL int cvNamedWindow( const char* name, int flags ) -{ - int result = 0; - CV_FUNCNAME( "cvNamedWindow" ); - - __BEGIN__; - - CvWindow* window; - int len; - - 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; - - CV_LOCK_MUTEX(); - - window->frame = gtk_window_new( GTK_WINDOW_TOPLEVEL ); - - window->paned = gtk_vbox_new( FALSE, 0 ); - window->widget = cvImageWidgetNew( flags ); - gtk_box_pack_end( GTK_BOX(window->paned), window->widget, TRUE, TRUE, 0 ); - gtk_widget_show( window->widget ); - gtk_container_add( GTK_CONTAINER(window->frame), window->paned ); - gtk_widget_show( window->paned ); - // - // configure event handlers - // TODO -- move this to CvImageWidget ? - gtk_signal_connect( GTK_OBJECT(window->frame), "key-press-event", - GTK_SIGNAL_FUNC(icvOnKeyPress), window ); - gtk_signal_connect( GTK_OBJECT(window->widget), "button-press-event", - GTK_SIGNAL_FUNC(icvOnMouse), window ); - gtk_signal_connect( GTK_OBJECT(window->widget), "button-release-event", - GTK_SIGNAL_FUNC(icvOnMouse), window ); - gtk_signal_connect( GTK_OBJECT(window->widget), "motion-notify-event", - GTK_SIGNAL_FUNC(icvOnMouse), window ); - gtk_signal_connect( GTK_OBJECT(window->frame), "delete-event", - GTK_SIGNAL_FUNC(icvOnClose), window ); - - gtk_widget_add_events (window->widget, GDK_EXPOSURE_MASK | GDK_BUTTON_RELEASE_MASK | - GDK_BUTTON_PRESS_MASK | GDK_POINTER_MOTION_MASK) ; - - gtk_widget_show( window->frame ); - gtk_window_set_title( GTK_WINDOW(window->frame), name ); - - if( hg_windows ) - hg_windows->prev = window; - hg_windows = window; - - gtk_window_set_resizable( GTK_WINDOW(window->frame), (flags & CV_WINDOW_AUTOSIZE) == 0 ); - - - // allow window to be resized - if( (flags & CV_WINDOW_AUTOSIZE)==0 ){ - GdkGeometry geometry; - geometry.min_width = 50; - geometry.min_height = 50; - gtk_window_set_geometry_hints( GTK_WINDOW( window->frame ), GTK_WIDGET( window->widget ), - &geometry, (GdkWindowHints) (GDK_HINT_MIN_SIZE)); - } - - CV_UNLOCK_MUTEX(); - - result = 1; - __END__; - - return result; -} - - -static void icvDeleteWindow( CvWindow* window ) -{ - 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 ); -#ifdef HAVE_GTHREAD - // if last window, send key press signal - // to jump out of any waiting cvWaitKey's - if(hg_windows==0 && thread_started){ - g_cond_broadcast(cond_have_key); - } -#endif -} - - -CV_IMPL void cvDestroyWindow( const char* name ) -{ - CV_FUNCNAME( "cvDestroyWindow" ); - - __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 ); - - CV_UNLOCK_MUTEX(); - - __END__; -} - - -CV_IMPL void -cvDestroyAllWindows( void ) -{ - CV_LOCK_MUTEX(); - - while( hg_windows ) - { - CvWindow* window = hg_windows; - icvDeleteWindow( window ); - } - CV_UNLOCK_MUTEX(); -} - -CvSize icvCalcOptimalWindowSize( CvWindow * window, CvSize new_image_size){ - CvSize window_size; - GtkWidget * toplevel = gtk_widget_get_toplevel( window->frame ); - gdk_drawable_get_size( GDK_DRAWABLE(toplevel->window), - &window_size.width, &window_size.height ); - - window_size.width = window_size.width + new_image_size.width - window->widget->allocation.width; - window_size.height = window_size.height + new_image_size.height - window->widget->allocation.height; - - return window_size; -} - -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_LOCK_MUTEX(); - - window = icvFindWindowByName(name); - if( window && 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_LOCK_MUTEX(); - - 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_LOCK_MUTEX(); - - 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; -} - -CV_IMPL int -cvCreateTrackbar( const char* trackbar_name, const char* window_name, - int* val, int count, CvTrackbarCallback on_notify ) -{ - int result = 0; - - CV_FUNCNAME( "cvCreateTrackbar" ); - - __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" ); - - if( count <= 0 ) - CV_ERROR( CV_StsOutOfRange, "Bad trackbar maximal value" ); - - window = icvFindWindowByName(window_name); - if( !window ) - EXIT; - - trackbar = icvFindTrackbarByName(window,trackbar_name); - - CV_LOCK_MUTEX(); - - 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 ); - trackbar->parent = window; - trackbar->next = window->toolbar.first; - window->toolbar.first = trackbar; - - GtkWidget* hscale_box = gtk_hbox_new( FALSE, 10 ); - GtkWidget* hscale_label = gtk_label_new( trackbar_name ); - GtkWidget* hscale = gtk_hscale_new_with_range( 0, count, 1 ); - gtk_range_set_update_policy( GTK_RANGE(hscale), GTK_UPDATE_CONTINUOUS ); - gtk_scale_set_digits( GTK_SCALE(hscale), 0 ); - //gtk_scale_set_value_pos( hscale, GTK_POS_TOP ); - gtk_scale_set_draw_value( GTK_SCALE(hscale), TRUE ); - - trackbar->widget = hscale; - gtk_box_pack_start( GTK_BOX(hscale_box), hscale_label, FALSE, FALSE, 5 ); - gtk_widget_show( hscale_label ); - gtk_box_pack_start( GTK_BOX(hscale_box), hscale, TRUE, TRUE, 5 ); - gtk_widget_show( hscale ); - gtk_box_pack_start( GTK_BOX(window->paned), hscale_box, FALSE, FALSE, 5 ); - gtk_widget_show( hscale_box ); - - } - - if( val ) - { - int value = *val; - if( value < 0 ) - value = 0; - if( value > count ) - value = count; - gtk_range_set_value( GTK_RANGE(trackbar->widget), value ); - trackbar->pos = value; - trackbar->data = val; - } - - trackbar->maxval = count; - trackbar->notify = on_notify; - gtk_signal_connect( GTK_OBJECT(trackbar->widget), "value-changed", - GTK_SIGNAL_FUNC(icvOnTrackbar), trackbar ); - - // queue a widget resize to trigger a window resize to - // compensate for the addition of trackbars - gtk_widget_queue_resize( GTK_WIDGET(window->widget) ); - - - CV_UNLOCK_MUTEX(); - - result = 1; - - __END__; - - return result; -} - - -CV_IMPL void -cvSetMouseCallback( const char* window_name, CvMouseCallback on_mouse, void* param ) -{ - CV_FUNCNAME( "cvSetMouseCallback" ); - - __BEGIN__; - - CvWindow* window = 0; - - if( !window_name ) - CV_ERROR( CV_StsNullPtr, "NULL window name" ); - - window = icvFindWindowByName(window_name); - if( !window ) - EXIT; - - 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_FUNCNAME( "cvGetTrackbarPos" ); - - __BEGIN__; - - 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 ); - - if( trackbar ) - pos = trackbar->pos; - - __END__; - - return pos; -} - - -CV_IMPL void cvSetTrackbarPos( const char* trackbar_name, const char* window_name, int pos ) -{ - CV_FUNCNAME( "cvSetTrackbarPos" ); - - __BEGIN__; - - 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 ); - - if( trackbar ) - { - if( pos < 0 ) - pos = 0; - - if( pos > trackbar->maxval ) - pos = trackbar->maxval; - } - - CV_LOCK_MUTEX(); - - gtk_range_set_value( GTK_RANGE(trackbar->widget), pos ); - - CV_UNLOCK_MUTEX(); - - __END__; -} - - -CV_IMPL void* cvGetWindowHandle( const char* window_name ) -{ - void* widget = 0; - - CV_FUNCNAME( "cvGetWindowHandle" ); - - __BEGIN__; - - 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; -} - - -CV_IMPL const char* cvGetWindowName( void* window_handle ) -{ - const char* window_name = ""; - - CV_FUNCNAME( "cvGetWindowName" ); - - __BEGIN__; - - 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; -} - -static gboolean icvOnKeyPress( GtkWidget * /*widget*/, - GdkEventKey* event, gpointer /*user_data*/ ) -{ - int code = 0; - - switch( event->keyval ) - { - case GDK_Escape: - code = 27; - break; - case GDK_Return: - case GDK_Linefeed: - code = '\n'; - break; - case GDK_Tab: - code = '\t'; - break; - default: - code = event->keyval; - } - - code |= event->state << 16; - -#ifdef HAVE_GTHREAD - if(thread_started) g_mutex_lock(last_key_mutex); -#endif - - last_key = code; - -#ifdef HAVE_GTHREAD - if(thread_started){ - // signal any waiting threads - g_cond_broadcast(cond_have_key); - g_mutex_unlock(last_key_mutex); - } -#endif - - return FALSE; -} - - -static void icvOnTrackbar( GtkWidget* widget, gpointer user_data ) -{ - int pos = cvRound( gtk_range_get_value(GTK_RANGE(widget))); - CvTrackbar* trackbar = (CvTrackbar*)user_data; - - if( trackbar && trackbar->signature == CV_TRACKBAR_MAGIC_VAL && - trackbar->widget == widget ) - { - trackbar->pos = pos; - if( trackbar->data ) - *trackbar->data = pos; - if( trackbar->notify ) - trackbar->notify(pos); - } -} - -static gboolean icvOnClose( GtkWidget* widget, GdkEvent* /*event*/, gpointer user_data ) -{ - CvWindow* window = (CvWindow*)user_data; - if( window->signature == CV_WINDOW_MAGIC_VAL && - window->frame == widget ) - { - icvDeleteWindow(window); - } - return TRUE; -} - - -static gboolean icvOnMouse( GtkWidget *widget, GdkEvent *event, gpointer user_data ) -{ - // TODO move this logic to CvImageWidget - CvWindow* window = (CvWindow*)user_data; - CvPoint2D32f pt32f = {-1., -1.}; - CvPoint pt = {-1,-1}; - int cv_event = -1, state = 0; - CvImageWidget * image_widget = CV_IMAGE_WIDGET( widget ); - - if( window->signature != CV_WINDOW_MAGIC_VAL || - window->widget != widget || !window->widget || - !window->on_mouse || !image_widget->original_image) - return FALSE; - - if( event->type == GDK_MOTION_NOTIFY ) - { - GdkEventMotion* event_motion = (GdkEventMotion*)event; - - cv_event = CV_EVENT_MOUSEMOVE; - pt32f.x = cvRound(event_motion->x); - pt32f.y = cvRound(event_motion->y); - state = event_motion->state; - } - else if( event->type == GDK_BUTTON_PRESS || - event->type == GDK_BUTTON_RELEASE || - event->type == GDK_2BUTTON_PRESS ) - { - GdkEventButton* event_button = (GdkEventButton*)event; - pt32f.x = cvRound(event_button->x); - pt32f.y = cvRound(event_button->y); - - - if( event_button->type == GDK_BUTTON_PRESS ) - { - cv_event = event_button->button == 1 ? CV_EVENT_LBUTTONDOWN : - event_button->button == 2 ? CV_EVENT_MBUTTONDOWN : - event_button->button == 3 ? CV_EVENT_RBUTTONDOWN : 0; - } - else if( event_button->type == GDK_BUTTON_RELEASE ) - { - cv_event = event_button->button == 1 ? CV_EVENT_LBUTTONUP : - event_button->button == 2 ? CV_EVENT_MBUTTONUP : - event_button->button == 3 ? CV_EVENT_RBUTTONUP : 0; - } - else if( event_button->type == GDK_2BUTTON_PRESS ) - { - cv_event = event_button->button == 1 ? CV_EVENT_LBUTTONDBLCLK : - event_button->button == 2 ? CV_EVENT_MBUTTONDBLCLK : - event_button->button == 3 ? CV_EVENT_RBUTTONDBLCLK : 0; - } - state = event_button->state; - } - - if( cv_event >= 0 ){ - // scale point if image is scaled - if( (image_widget->flags & CV_WINDOW_AUTOSIZE)==0 && - image_widget->original_image && - image_widget->scaled_image ){ - // image origin is not necessarily at (0,0) - int x0 = (widget->allocation.width - image_widget->scaled_image->cols)/2; - int y0 = (widget->allocation.height - image_widget->scaled_image->rows)/2; - pt.x = cvRound( ((pt32f.x-x0)*image_widget->original_image->cols)/ - image_widget->scaled_image->cols ); - pt.y = cvRound( ((pt32f.y-y0)*image_widget->original_image->rows)/ - image_widget->scaled_image->rows ); - } - else{ - pt = cvPointFrom32f( pt32f ); - } - - if((unsigned)pt.x < (unsigned)(image_widget->original_image->width) && - (unsigned)pt.y < (unsigned)(image_widget->original_image->height) ) - { - int flags = (state & GDK_SHIFT_MASK ? CV_EVENT_FLAG_SHIFTKEY : 0) | - (state & GDK_CONTROL_MASK ? CV_EVENT_FLAG_CTRLKEY : 0) | - (state & (GDK_MOD1_MASK|GDK_MOD2_MASK) ? CV_EVENT_FLAG_ALTKEY : 0) | - (state & GDK_BUTTON1_MASK ? CV_EVENT_FLAG_LBUTTON : 0) | - (state & GDK_BUTTON2_MASK ? CV_EVENT_FLAG_MBUTTON : 0) | - (state & GDK_BUTTON3_MASK ? CV_EVENT_FLAG_RBUTTON : 0); - window->on_mouse( cv_event, pt.x, pt.y, flags, window->on_mouse_param ); - } - } - - return FALSE; - } - - -static gboolean icvAlarm( gpointer user_data ) -{ - *(int*)user_data = 1; - return FALSE; -} - - -CV_IMPL int cvWaitKey( int delay ) -{ -#ifdef HAVE_GTHREAD - if(thread_started && g_thread_self()!=window_thread){ - gboolean expired; - int my_last_key; - - // wait for signal or timeout if delay > 0 - if(delay>0){ - GTimeVal timer; - g_get_current_time(&timer); - g_time_val_add(&timer, delay*1000); - expired = !g_cond_timed_wait(cond_have_key, last_key_mutex, &timer); - } - else{ - g_cond_wait(cond_have_key, last_key_mutex); - expired=false; - } - my_last_key = last_key; - g_mutex_unlock(last_key_mutex); - if(expired || hg_windows==0){ - return -1; - } - return my_last_key; - } - else{ -#endif - int expired = 0; - guint timer = 0; - 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 ) - ; - - if( delay > 0 && !expired ) - g_source_remove(timer); -#ifdef HAVE_GTHREAD - } -#endif - return last_key; -} - - -#endif // HAVE_GTK -#endif // WIN32 - -/* End of file. */