5252#include < stdio.h>
5353
5454#if (GTK_MAJOR_VERSION == 3)
55- #define GTK_VERSION3
55+ #define GTK_VERSION3 1
5656#endif // GTK_MAJOR_VERSION >= 3
57+ #if (GTK_MAJOR_VERSION > 3 || (GTK_MAJOR_VERSION == 3 && GTK_MINOR_VERSION >= 4))
58+ #define GTK_VERSION3_4 1
59+ #endif
5760
5861#ifdef HAVE_OPENGL
5962 #include < gtk/gtkgl.h>
6063 #include < GL/gl.h>
6164 #include < GL/glu.h>
6265#endif
6366
67+ #ifndef BIT_ALLIN
68+ #define BIT_ALLIN (x,y ) ( ((x)&(y)) == (y) )
69+ #endif
70+ #ifndef BIT_MAP
71+ #define BIT_MAP (x,y,z ) ( ((x)&(y)) ? (z) : 0 )
72+ #endif
73+
6474// TODO Fix the initial window size when flags=0. Right now the initial window is by default
6575// 320x240 size. A better default would be actual size of the image. Problem
6676// is determining desired window size with trackbars while still allowing resizing.
@@ -1006,6 +1016,7 @@ CV_IMPL int cvNamedWindow( const char* name, int flags )
10061016
10071017 CvWindow* window;
10081018 int len;
1019+ int b_nautosize;
10091020
10101021 cvInitSystem (1 ,(char **)&name);
10111022 if ( !name )
@@ -1066,6 +1077,8 @@ CV_IMPL int cvNamedWindow( const char* name, int flags )
10661077 G_CALLBACK (icvOnMouse), window );
10671078 g_signal_connect ( window->widget , " motion-notify-event" ,
10681079 G_CALLBACK (icvOnMouse), window );
1080+ g_signal_connect ( window->widget , " scroll-event" ,
1081+ G_CALLBACK (icvOnMouse), window );
10691082 g_signal_connect ( window->frame , " delete-event" ,
10701083 G_CALLBACK (icvOnClose), window );
10711084#if defined(GTK_VERSION3)
@@ -1076,7 +1089,12 @@ CV_IMPL int cvNamedWindow( const char* name, int flags )
10761089 G_CALLBACK (cvImageWidget_expose), window );
10771090#endif // GTK_VERSION3
10781091
1079- gtk_widget_add_events (window->widget , GDK_BUTTON_RELEASE_MASK | GDK_BUTTON_PRESS_MASK | GDK_POINTER_MOTION_MASK) ;
1092+
1093+ #if defined(GTK_VERSION3_4)
1094+ gtk_widget_add_events (window->widget , GDK_BUTTON_RELEASE_MASK | GDK_BUTTON_PRESS_MASK | GDK_POINTER_MOTION_MASK | GDK_SCROLL_MASK | GDK_SMOOTH_SCROLL_MASK) ;
1095+ #else
1096+ gtk_widget_add_events (window->widget , GDK_BUTTON_RELEASE_MASK | GDK_BUTTON_PRESS_MASK | GDK_POINTER_MOTION_MASK | GDK_SCROLL_MASK) ;
1097+ #endif // GTK_VERSION3_4
10801098
10811099 gtk_widget_show ( window->frame );
10821100 gtk_window_set_title ( GTK_WINDOW (window->frame ), name );
@@ -1085,11 +1103,11 @@ CV_IMPL int cvNamedWindow( const char* name, int flags )
10851103 hg_windows->prev = window;
10861104 hg_windows = window;
10871105
1088- gtk_window_set_resizable ( GTK_WINDOW (window-> frame ), ( flags & CV_WINDOW_AUTOSIZE) == 0 );
1089-
1106+ b_nautosize = (( flags & CV_WINDOW_AUTOSIZE) == 0 );
1107+ gtk_window_set_resizable ( GTK_WINDOW (window-> frame ), b_nautosize );
10901108
10911109 // allow window to be resized
1092- if ( (flags & CV_WINDOW_AUTOSIZE)== 0 ){
1110+ if ( b_nautosize ){
10931111 GdkGeometry geometry;
10941112 geometry.min_width = 50 ;
10951113 geometry.min_height = 50 ;
@@ -1817,7 +1835,7 @@ static gboolean icvOnKeyPress(GtkWidget* widget, GdkEventKey* event, gpointer us
18171835{
18181836 int code = 0 ;
18191837
1820- if ( (event->state & GDK_CONTROL_MASK) == GDK_CONTROL_MASK && (event->keyval == GDK_s || event->keyval == GDK_S))
1838+ if ( BIT_ALLIN (event->state , GDK_CONTROL_MASK) && (event->keyval == GDK_s || event->keyval == GDK_S))
18211839 {
18221840 try
18231841 {
@@ -1901,7 +1919,7 @@ static gboolean icvOnMouse( GtkWidget *widget, GdkEvent *event, gpointer user_da
19011919 CvWindow* window = (CvWindow*)user_data;
19021920 CvPoint2D32f pt32f (-1 ., -1 .);
19031921 CvPoint pt (-1 ,-1 );
1904- int cv_event = -1 , state = 0 ;
1922+ int cv_event = -1 , state = 0 , flags = 0 ;
19051923 CvImageWidget * image_widget = CV_IMAGE_WIDGET ( widget );
19061924
19071925 if ( window->signature != CV_WINDOW_MAGIC_VAL ||
@@ -1947,12 +1965,41 @@ static gboolean icvOnMouse( GtkWidget *widget, GdkEvent *event, gpointer user_da
19471965 }
19481966 state = event_button->state ;
19491967 }
1968+ else if ( event->type == GDK_SCROLL )
1969+ {
1970+ #if defined(GTK_VERSION3_4)
1971+ // NOTE: in current implementation doesn't possible to put into callback function delta_x and delta_y separetely
1972+ double delta = (event->scroll .delta_x + event->scroll .delta_y );
1973+ int orient = (event->scroll .delta_y !=0 ) ? CV_EVENT_MOUSEHWHEEL : CV_EVENT_MOUSEWHEEL;
1974+ #else
1975+ int orient = CV_EVENT_MOUSEWHEEL;
1976+ #endif // GTK_VERSION3_4
1977+
1978+ state = event->scroll .state ;
1979+
1980+ switch (event->scroll .direction ) {
1981+ #if defined(GTK_VERSION3_4)
1982+ case GDK_SCROLL_SMOOTH: flags |= (((int )delta << 16 ));
1983+ break ;
1984+ #endif // GTK_VERSION3_4
1985+ case GDK_SCROLL_LEFT: orient = CV_EVENT_MOUSEHWHEEL;
1986+ case GDK_SCROLL_UP: flags |= ((-(int )1 << 16 ));
1987+ break ;
1988+ case GDK_SCROLL_RIGHT: orient = CV_EVENT_MOUSEHWHEEL;
1989+ case GDK_SCROLL_DOWN: flags |= (((int )1 << 16 ));
1990+ break ;
1991+ default : ;
1992+ };
1993+ cv_event = orient;
1994+ }
19501995
1951- if ( cv_event >= 0 ){
1996+ if ( cv_event >= 0 )
1997+ {
19521998 // scale point if image is scaled
19531999 if ( (image_widget->flags & CV_WINDOW_AUTOSIZE)==0 &&
19542000 image_widget->original_image &&
1955- image_widget->scaled_image ){
2001+ image_widget->scaled_image )
2002+ {
19562003 // image origin is not necessarily at (0,0)
19572004#if defined (GTK_VERSION3)
19582005 int x0 = (gtk_widget_get_allocated_width (widget) - image_widget->scaled_image ->cols )/2 ;
@@ -1966,25 +2013,27 @@ static gboolean icvOnMouse( GtkWidget *widget, GdkEvent *event, gpointer user_da
19662013 pt.y = cvFloor ( ((pt32f.y -y0)*image_widget->original_image ->rows )/
19672014 image_widget->scaled_image ->rows );
19682015 }
1969- else {
2016+ else
2017+ {
19702018 pt = cvPointFrom32f ( pt32f );
19712019 }
19722020
19732021// if((unsigned)pt.x < (unsigned)(image_widget->original_image->width) &&
19742022// (unsigned)pt.y < (unsigned)(image_widget->original_image->height) )
19752023 {
1976- int flags = (state & GDK_SHIFT_MASK ? CV_EVENT_FLAG_SHIFTKEY : 0 ) |
1977- (state & GDK_CONTROL_MASK ? CV_EVENT_FLAG_CTRLKEY : 0 ) |
1978- (state & (GDK_MOD1_MASK|GDK_MOD2_MASK) ? CV_EVENT_FLAG_ALTKEY : 0 ) |
1979- (state & GDK_BUTTON1_MASK ? CV_EVENT_FLAG_LBUTTON : 0 ) |
1980- (state & GDK_BUTTON2_MASK ? CV_EVENT_FLAG_MBUTTON : 0 ) |
1981- (state & GDK_BUTTON3_MASK ? CV_EVENT_FLAG_RBUTTON : 0 );
2024+ flags |= BIT_MAP (state, GDK_SHIFT_MASK, CV_EVENT_FLAG_SHIFTKEY) |
2025+ BIT_MAP (state, GDK_CONTROL_MASK, CV_EVENT_FLAG_CTRLKEY) |
2026+ BIT_MAP (state, GDK_MOD1_MASK, CV_EVENT_FLAG_ALTKEY) |
2027+ BIT_MAP (state, GDK_MOD2_MASK, CV_EVENT_FLAG_ALTKEY) |
2028+ BIT_MAP (state, GDK_BUTTON1_MASK, CV_EVENT_FLAG_LBUTTON) |
2029+ BIT_MAP (state, GDK_BUTTON2_MASK, CV_EVENT_FLAG_MBUTTON) |
2030+ BIT_MAP (state, GDK_BUTTON3_MASK, CV_EVENT_FLAG_RBUTTON);
19822031 window->on_mouse ( cv_event, pt.x , pt.y , flags, window->on_mouse_param );
19832032 }
19842033 }
19852034
1986- return FALSE ;
1987- }
2035+ return FALSE ;
2036+ }
19882037
19892038
19902039static gboolean icvAlarm ( gpointer user_data )
0 commit comments