--- /dev/null
+/*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"
+
+#include <Carbon/Carbon.h>
+
+#include <unistd.h>
+#include <cstdio>
+#include <cmath>
+
+//#define MS_TO_TICKS(a) a*3/50
+
+#define LABELWIDTH 64
+#define INTERWIDGETSPACE 16
+#define WIDGETHEIGHT 32
+#define NO_KEY -1
+
+struct CvWindow;
+
+typedef struct CvTrackbar
+{
+ int signature;
+
+ ControlRef trackbar;
+ ControlRef label;
+
+ char* name;
+ CvTrackbar* next;
+ CvWindow* parent;
+ int* data;
+ int pos;
+ int maxval;
+ CvTrackbarCallback notify;
+ CvTrackbarCallback2 notify2;
+ void* userdata;
+}
+CvTrackbar;
+
+
+typedef struct CvWindow
+{
+ int signature;
+
+ char* name;
+ CvWindow* prev;
+ CvWindow* next;
+
+ WindowRef window;
+ CGImageRef imageRef;
+ int imageWidth;//FD
+ int imageHeight;//FD
+
+ CvMat* image;
+ CvMat* dst_image;
+ int converted;
+ int last_key;
+ int flags;
+
+ CvMouseCallback on_mouse;
+ void* on_mouse_param;
+
+ struct {
+ int pos;
+ int rows;
+ CvTrackbar* first;
+ }
+ toolbar;
+ int trackbarheight;
+}
+CvWindow;
+
+static CvWindow* hg_windows = 0;
+
+#define Assert(exp) \
+if( !(exp) ) \
+{ \
+ printf("Assertion: %s %s: %d\n", #exp, __FILE__, __LINE__);\
+ assert(exp); \
+}
+
+static int wasInitialized = 0;
+static char lastKey = NO_KEY;
+OSStatus keyHandler(EventHandlerCallRef hcr, EventRef theEvent, void* inUserData);
+static pascal OSStatus windowEventHandler(EventHandlerCallRef nextHandler, EventRef theEvent, void *inUserData);
+
+static const EventTypeSpec applicationKeyboardEvents[] =
+{
+ { kEventClassKeyboard, kEventRawKeyDown },
+};
+
+CV_IMPL int cvInitSystem( int argc, char** argv )
+{
+ OSErr err = noErr;
+ if( !wasInitialized )
+ {
+
+ hg_windows = 0;
+ err = InstallApplicationEventHandler(NewEventHandlerUPP( keyHandler),GetEventTypeCount(applicationKeyboardEvents),applicationKeyboardEvents,NULL,NULL);
+ if (err != noErr)
+ {
+ fprintf(stderr,"InstallApplicationEventHandler was not ok\n");
+ }
+ wasInitialized = 1;
+ }
+
+ return 0;
+}
+
+// TODO: implement missing functionality
+CV_IMPL int cvStartWindowThread()
+{
+ return 0;
+}
+
+static int icvCountTrackbarInWindow( const CvWindow* window)
+{
+ CvTrackbar* trackbar = window->toolbar.first;
+ int count = 0;
+ while (trackbar != 0) {
+ count++;
+ trackbar = trackbar->next;
+ }
+ return count;
+}
+
+static CvTrackbar* icvTrackbarByHandle( void * handle )
+{
+ CvWindow* window = hg_windows;
+ CvTrackbar* trackbar = NULL;
+ while( window != 0 && window->window != handle) {
+ trackbar = window->toolbar.first;
+ while (trackbar != 0 && trackbar->trackbar != handle)
+ trackbar = trackbar->next;
+ if (trackbar != 0 && trackbar->trackbar == handle)
+ break;
+ window = window->next;
+ }
+ return trackbar;
+}
+
+static CvWindow* icvWindowByHandle( void * handle )
+{
+ CvWindow* window = hg_windows;
+
+ while( window != 0 && window->window != handle)
+ window = window->next;
+
+ return window;
+}
+
+CV_IMPL CvWindow * icvFindWindowByName( const char* name)
+{
+ CvWindow* window = hg_windows;
+ while( window != 0 && strcmp(name, window->name) != 0 )
+ window = window->next;
+
+ return window;
+}
+
+static CvTrackbar* icvFindTrackbarByName( const CvWindow* window, const char* name )
+{
+ CvTrackbar* trackbar = window->toolbar.first;
+
+ while (trackbar != 0 && strcmp( trackbar->name, name ) != 0)
+ trackbar = trackbar->next;
+
+ return trackbar;
+}
+
+//FD
+/* draw image to frame */
+static void icvDrawImage( CvWindow* window )
+{
+ Assert( window != 0 );
+ if( window->imageRef == 0 ) return;
+
+ CGContextRef myContext;
+ CGRect rect;
+ Rect portrect;
+ int width = window->imageWidth;
+ int height = window->imageHeight;
+
+ GetWindowPortBounds(window->window, &portrect);
+
+ if( window->flags & CV_WINDOW_AUTOSIZE )
+ {
+ CGPoint origin = {0,0};
+ CGSize size = {portrect.right-portrect.left, portrect.bottom-portrect.top-window->trackbarheight};
+ rect.origin = origin; rect.size = size;
+ }
+ else
+ {
+ CGPoint origin = {0, portrect.bottom - height - window->trackbarheight};
+ CGSize size = {width, height};
+ rect.origin = origin; rect.size = size;
+ }
+
+ /* To be sybnchronous we are using this, better would be to susbcribe to the draw event and process whenever requested, we might save SOME CPU cycles*/
+ SetPortWindowPort (window->window);
+ QDBeginCGContext (GetWindowPort (window->window), &myContext);
+ CGContextSetInterpolationQuality (myContext, kCGInterpolationLow);
+ CGContextDrawImage(myContext,rect,window->imageRef);
+ CGContextFlush(myContext);// 4
+ QDEndCGContext (GetWindowPort(window->window), &myContext);// 5
+}
+
+//FD
+/* update imageRef */
+static void icvPutImage( CvWindow* window )
+{
+ Assert( window != 0 );
+ if( window->image == 0 ) return;
+
+ CGColorSpaceRef colorspace = NULL;
+ CGDataProviderRef provider = NULL;
+ int width = window->imageWidth = window->image->cols;
+ int height = window->imageHeight = window->image->rows;
+
+ colorspace = CGColorSpaceCreateDeviceRGB();
+
+ int size = 8;
+ int nbChannels = 3;
+
+ provider = CGDataProviderCreateWithData(NULL, window->image->data.ptr, width * height , NULL );
+
+ if (window->imageRef != NULL){
+ CGImageRelease(window->imageRef);
+ window->imageRef = NULL;
+ }
+
+ window->imageRef = CGImageCreate( width, height, size , size*nbChannels , window->image->step, colorspace, kCGImageAlphaNone , provider, NULL, true, kCGRenderingIntentDefault );
+ icvDrawImage( window );
+
+ /* release the provider's memory */
+ CGDataProviderRelease( provider );
+}
+
+static void icvUpdateWindowSize( const CvWindow* window )
+{
+ int width = 0, height = 240; /* init à al taille de base de l'image*/
+ Rect globalBounds;
+
+ GetWindowBounds(window->window, kWindowContentRgn, &globalBounds);
+
+ int minWidth = 320;
+
+ if( window->image ) {
+ width = MAX(MAX(window->image->width, width), minWidth);
+ height = window->image->height;
+ } else
+ width = minWidth;
+
+ height += window->trackbarheight;
+
+ //height +=WIDGETHEIGHT; /* 32 pixels are spearating tracbars from the video display */
+
+ globalBounds.right = globalBounds.left + width;
+ globalBounds.bottom = globalBounds.top + height;
+ SetWindowBounds(window->window, kWindowContentRgn, &globalBounds);
+}
+
+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;
+
+ cvReleaseMat( &window->image );
+ cvReleaseMat( &window->dst_image );
+
+ for( trackbar = window->toolbar.first; trackbar != 0; )
+ {
+ CvTrackbar* next = trackbar->next;
+ cvFree( (void**)&trackbar );
+ trackbar = next;
+ }
+
+ if (window->imageRef != NULL)
+ CGImageRelease(window->imageRef);
+
+ cvFree( (void**)&window );
+}
+
+
+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;
+
+ icvDeleteWindow( window );
+
+ __END__;
+}
+
+
+CV_IMPL void cvDestroyAllWindows( void )
+{
+ while( hg_windows )
+ {
+ CvWindow* window = hg_windows;
+ icvDeleteWindow( window );
+ }
+}
+
+
+CV_IMPL void cvShowImage( const char* name, const CvArr* arr)
+{
+ CV_FUNCNAME( "cvShowImage" );
+
+ __BEGIN__;
+
+ CvWindow* window;
+ int origin = 0;
+ int resize = 0;
+ CvMat stub, *image;
+
+ if( !name )
+ CV_ERROR( CV_StsNullPtr, "NULL name" );
+
+ window = icvFindWindowByName(name);
+ if(!window)
+ {
+ cvNamedWindow(name, 1);
+ window = icvFindWindowByName(name);
+ }
+
+ if( !window || !arr )
+ EXIT; // keep silence here.
+
+ if( CV_IS_IMAGE_HDR( arr ))
+ origin = ((IplImage*)arr)->origin;
+
+ CV_CALL( image = cvGetMat( arr, &stub ));
+
+ /*
+ if( !window->image )
+ cvResizeWindow( name, image->cols, image->rows );
+ */
+
+ if( window->image &&
+ !CV_ARE_SIZES_EQ(window->image, image) ) {
+ if ( ! (window->flags & CV_WINDOW_AUTOSIZE) )//FD
+ resize = 1;
+ cvReleaseMat( &window->image );
+ }
+
+ if( !window->image ) {
+ resize = 1;//FD
+ window->image = cvCreateMat( image->rows, image->cols, CV_8UC3 );
+ }
+
+ cvConvertImage( image, window->image, (origin != 0 ? CV_CVTIMG_FLIP : 0) + CV_CVTIMG_SWAP_RB );
+ icvPutImage( window );
+ if ( resize )//FD
+ icvUpdateWindowSize( window );
+
+ __END__;
+}
+
+CV_IMPL void cvResizeWindow( const char* name, int width, int height)
+{
+ CV_FUNCNAME( "cvResizeWindow" );
+
+ __BEGIN__;
+
+ CvWindow* window;
+ //CvTrackbar* trackbar;
+
+ if( !name )
+ CV_ERROR( CV_StsNullPtr, "NULL name" );
+
+ window = icvFindWindowByName(name);
+ if(!window)
+ EXIT;
+
+ SizeWindow(window->window, width, height, true);
+
+ __END__;
+}
+
+CV_IMPL void cvMoveWindow( const char* name, int x, int y)
+{
+ CV_FUNCNAME( "cvMoveWindow" );
+
+ __BEGIN__;
+
+ CvWindow* window;
+ //CvTrackbar* trackbar;
+
+ if( !name )
+ CV_ERROR( CV_StsNullPtr, "NULL name" );
+
+ window = icvFindWindowByName(name);
+ if(!window)
+ EXIT;
+
+ MoveWindow(window->window, x, y, true);
+
+ __END__;
+}
+
+void TrackbarActionProcPtr (ControlRef theControl, ControlPartCode partCode)
+{
+ CvTrackbar * trackbar = icvTrackbarByHandle (theControl);
+
+ if (trackbar == NULL)
+ {
+ fprintf(stderr,"Error getting trackbar\n");
+ return;
+ }
+ else
+ {
+ int pos = GetControl32BitValue (theControl);
+ if ( trackbar->data )
+ *trackbar->data = pos;
+ if ( trackbar->notify )
+ trackbar->notify(pos);
+ else if ( trackbar->notify2 )
+ trackbar->notify2(pos, trackbar->userdata);
+ }
+}
+
+
+static int 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;
+ Rect stboundsRect;
+ ControlRef outControl;
+ ControlRef stoutControl;
+ Rect bounds;
+
+ 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);
+ 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;
+
+ if( val )
+ {
+ int value = *val;
+ if( value < 0 )
+ value = 0;
+ if( value > count )
+ value = count;
+ trackbar->pos = value;
+ trackbar->data = val;
+ }
+
+ trackbar->maxval = count;
+
+ int c = icvCountTrackbarInWindow(window);
+
+ GetWindowBounds(window->window,kWindowContentRgn,&bounds);
+
+ stboundsRect.top = (INTERWIDGETSPACE +WIDGETHEIGHT)* (c-1)+INTERWIDGETSPACE;
+ stboundsRect.left = INTERWIDGETSPACE;
+ stboundsRect.bottom = stboundsRect.top + WIDGETHEIGHT;
+ stboundsRect.right = stboundsRect.left+LABELWIDTH;
+
+ //fprintf(stdout,"create trackabar bounds (%d %d %d %d)\n",stboundsRect.top,stboundsRect.left,stboundsRect.bottom,stboundsRect.right);
+ CreateStaticTextControl (window->window,&stboundsRect,CFStringCreateWithCString(NULL,trackbar_name,kCFStringEncodingASCII),NULL,&stoutControl);
+
+ stboundsRect.top = (INTERWIDGETSPACE +WIDGETHEIGHT)* (c-1)+INTERWIDGETSPACE;
+ stboundsRect.left = INTERWIDGETSPACE*2+LABELWIDTH;
+ stboundsRect.bottom = stboundsRect.top + WIDGETHEIGHT;
+ stboundsRect.right = bounds.right-INTERWIDGETSPACE;
+
+ CreateSliderControl (window->window,&stboundsRect, trackbar->pos,0,trackbar->maxval,kControlSliderLiveFeedback,0,true,NewControlActionUPP(TrackbarActionProcPtr),&outControl);
+
+ bounds.bottom += INTERWIDGETSPACE + WIDGETHEIGHT;
+ SetControlVisibility (outControl,true,true);
+ SetControlVisibility (stoutControl,true,true);
+
+ trackbar->trackbar = outControl;
+ trackbar->label = stoutControl;
+ if (c == 1)
+ window->trackbarheight = INTERWIDGETSPACE*2 + WIDGETHEIGHT;
+ else
+ window->trackbarheight += INTERWIDGETSPACE + WIDGETHEIGHT;
+ icvUpdateWindowSize( window );
+ }
+
+ trackbar->notify = on_notify;
+ trackbar->notify2 = on_notify2;
+ trackbar->userdata = userdata;
+
+ result = 1;
+
+ __END__;
+ return result;
+}
+
+
+CV_IMPL int cvCreateTrackbar (const char* trackbar_name,
+ const char* window_name,
+ int* val, int count,
+ CvTrackbarCallback on_notify)
+{
+ return icvCreateTrackbar(trackbar_name, window_name, val, count, on_notify, 0, 0);
+}
+
+
+CV_IMPL int cvCreateTrackbar2(const char* trackbar_name,
+ const char* window_name,
+ int* val, int count,
+ CvTrackbarCallback2 on_notify2,
+ void* userdata)
+{
+ return icvCreateTrackbar(trackbar_name, window_name, val,
+ count, 0, on_notify2, userdata);
+}
+
+
+CV_IMPL void
+cvSetMouseCallback( const char* name, CvMouseCallback function, void* info)
+{
+ CvWindow* window = icvFindWindowByName( name );
+ if (window != NULL)
+ {
+ window->on_mouse = function;
+ window->on_mouse_param = info;
+ }
+ else
+ {
+ fprintf(stdout,"Error with cvSetMouseCallback. Window not found : %s\n",name);
+ }
+}
+
+ 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;
+
+ // Set new value and redraw the trackbar
+ SetControlValue( trackbar->trackbar, pos );
+ Draw1Control( trackbar->trackbar );
+ }
+
+ __END__;
+ return ;
+}
+
+CV_IMPL void* cvGetWindowHandle( const char* name )
+{
+ WindowRef result = 0;
+
+ __BEGIN__;
+
+ CvWindow* window;
+ window = icvFindWindowByName( name );
+ if (window != NULL)
+ result = window->window;
+ else
+ result = NULL;
+
+ __END__;
+
+ return result;
+}
+
+
+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 = icvWindowByHandle(window_handle );
+ if( window )
+ window_name = window->name;
+
+ __END__;
+
+ return window_name;
+}
+
+
+CV_IMPL int cvNamedWindow( const char* name, int flags )
+{
+ int result = 0;
+ CV_FUNCNAME( "cvNamedWindow" );
+ if (!wasInitialized)
+ cvInitSystem(0, NULL);
+
+ // to be able to display a window, we need to be a 'faceful' application
+ // http://lists.apple.com/archives/carbon-dev/2005/Jun/msg01414.html
+ static bool switched_to_faceful = false;
+ if (! switched_to_faceful)
+ {
+ ProcessSerialNumber psn = { 0, kCurrentProcess };
+ OSStatus ret = TransformProcessType (&psn, kProcessTransformToForegroundApplication );
+
+ if (ret == noErr)
+ {
+ SetFrontProcess( &psn );
+ switched_to_faceful = true;
+ }
+ else
+ {
+ fprintf(stderr, "Failed to tranform process type: %d\n", (int) ret);
+ fflush (stderr);
+ }
+ }
+
+ __BEGIN__;
+
+ WindowRef outWindow = NULL;
+ OSStatus err = noErr;
+ Rect contentBounds = {100,100,320,440};
+
+ CvWindow* window;
+ UInt wAttributes = 0;
+
+ int len;
+
+ const EventTypeSpec genericWindowEventHandler[] = {
+ { kEventClassMouse, kEventMouseMoved},
+ { kEventClassMouse, kEventMouseDragged},
+ { kEventClassMouse, kEventMouseUp},
+ { kEventClassMouse, kEventMouseDown},
+ { kEventClassWindow, kEventWindowClose },
+ { kEventClassWindow, kEventWindowBoundsChanged }//FD
+ };
+
+ if( !name )
+ CV_ERROR( CV_StsNullPtr, "NULL name string" );
+
+ 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->image = 0;
+ window->last_key = 0;
+ window->on_mouse = 0;
+ window->on_mouse_param = 0;
+
+ window->next = hg_windows;
+ window->prev = 0;
+ if( hg_windows )
+ hg_windows->prev = window;
+ hg_windows = window;
+ wAttributes = kWindowStandardDocumentAttributes | kWindowStandardHandlerAttribute | kWindowLiveResizeAttribute;
+
+ err = CreateNewWindow ( kDocumentWindowClass,wAttributes,&contentBounds,&outWindow);
+ if (err != noErr)
+ fprintf(stderr,"Error while creating the window\n");
+
+ SetWindowTitleWithCFString(outWindow,CFStringCreateWithCString(NULL,name,kCFStringEncodingASCII));
+ if (err != noErr)
+ fprintf(stdout,"Error SetWindowTitleWithCFString\n");
+
+ window->window = outWindow;
+
+ err = InstallWindowEventHandler(outWindow, NewEventHandlerUPP(windowEventHandler), GetEventTypeCount(genericWindowEventHandler), genericWindowEventHandler, outWindow, NULL);
+
+ ShowWindow( outWindow );
+ result = 1;
+
+ __END__;
+ return result;
+}
+
+static pascal OSStatus windowEventHandler(EventHandlerCallRef nextHandler, EventRef theEvent, void *inUserData)
+{
+ CvWindow* window = NULL;
+ UInt32 eventKind, eventClass;
+ OSErr err = noErr;
+ int event = 0;
+ UInt32 count = 0;
+ HIPoint point = {0,0};
+ EventMouseButton eventMouseButton = 0;//FD
+ UInt32 modifiers;//FD
+
+ WindowRef theWindow = (WindowRef)inUserData;
+ if (theWindow == NULL)
+ return eventNotHandledErr;
+ window = icvWindowByHandle(theWindow);
+ if ( window == NULL)
+ return eventNotHandledErr;
+
+ eventKind = GetEventKind(theEvent);
+ eventClass = GetEventClass(theEvent);
+
+ switch (eventClass) {
+ case kEventClassMouse : {
+ switch (eventKind){
+ case kEventMouseUp :
+ case kEventMouseDown :
+ case kEventMouseMoved :
+ case kEventMouseDragged : {
+ err = CallNextEventHandler(nextHandler, theEvent);
+ if (err != eventNotHandledErr)
+ return err;
+ err = GetEventParameter(theEvent, kEventParamMouseButton, typeMouseButton, NULL, sizeof(eventMouseButton), NULL, &eventMouseButton);
+ err = GetEventParameter(theEvent, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(modifiers), NULL, &modifiers);
+ err = GetEventParameter(theEvent,kEventParamClickCount,typeUInt32,NULL,sizeof(UInt32),NULL,&count);
+ if (err == noErr){
+ if (count >1) event += 6;
+ } else {
+ event = CV_EVENT_MOUSEMOVE;
+ }
+
+ if (eventKind == kEventMouseUp)
+ event +=4;
+ if (eventKind == kEventMouseDown)
+ event +=1;
+
+ unsigned int flags = 0;
+
+ err = GetEventParameter(theEvent, kEventParamWindowMouseLocation, typeHIPoint, NULL, sizeof(point), NULL, &point);
+ if (eventKind != kEventMouseMoved){
+ switch(eventMouseButton){
+ case kEventMouseButtonPrimary:
+ if (modifiers & controlKey){
+ flags += CV_EVENT_FLAG_RBUTTON;
+ event += 1;
+ } else {
+ flags += CV_EVENT_FLAG_LBUTTON;
+ }
+ break;
+ case kEventMouseButtonSecondary:
+ flags += CV_EVENT_FLAG_RBUTTON;
+ event += 1;
+ break;
+ case kEventMouseButtonTertiary:
+ flags += CV_EVENT_FLAG_MBUTTON;
+ event += 2;
+ break;
+ }
+ }
+
+ if (modifiers&controlKey) flags += CV_EVENT_FLAG_CTRLKEY;
+ if (modifiers&shiftKey) flags += CV_EVENT_FLAG_SHIFTKEY;
+ if (modifiers& cmdKey ) flags += CV_EVENT_FLAG_ALTKEY;
+
+ if (window->on_mouse != NULL){
+ int lx,ly;
+ Rect structure, content;
+ GetWindowBounds(theWindow, kWindowStructureRgn, &structure);
+ GetWindowBounds(theWindow, kWindowContentRgn, &content);
+ lx = (int)point.x - content.left + structure.left;
+ ly = (int)point.y - window->trackbarheight - content.top + structure.top; /* minus la taille des trackbars */
+ if (window->flags & CV_WINDOW_AUTOSIZE) {//FD
+ //printf("was %d,%d\n", lx, ly);
+ /* scale the mouse coordinates */
+ lx = lx * window->imageWidth / (content.right - content.left);
+ ly = ly * window->imageHeight / (content.bottom - content.top - window->trackbarheight);
+ }
+
+ if (lx>0 && ly >0){ /* a remettre dans les coordonnées locale */
+ window->on_mouse (event, lx, ly, flags, window->on_mouse_param);
+ return noErr;
+ }
+ }
+ }
+ default : return eventNotHandledErr;
+ }
+ }
+ case kEventClassWindow : {//FD
+ switch (eventKind){
+ case kEventWindowBoundsChanged :
+ {
+ /* resize the trackbars */
+ CvTrackbar *t;
+ Rect bounds;
+ GetWindowBounds(window->window,kWindowContentRgn,&bounds);
+ for ( t = window->toolbar.first; t != 0; t = t->next )
+ SizeControl(t->trackbar,bounds.right - bounds.left - INTERWIDGETSPACE*3 - LABELWIDTH , WIDGETHEIGHT);
+ }
+ /* redraw the image */
+ icvDrawImage(window);
+ break;
+ default :
+ return eventNotHandledErr;
+ }
+ }
+ default:
+ return eventNotHandledErr;
+ }
+
+ return eventNotHandledErr;
+}
+
+OSStatus keyHandler(EventHandlerCallRef hcr, EventRef theEvent, void* inUserData)
+{
+ UInt32 eventKind;
+ UInt32 eventClass;
+ OSErr err = noErr;
+
+ eventKind = GetEventKind (theEvent);
+ eventClass = GetEventClass (theEvent);
+ err = GetEventParameter(theEvent, kEventParamKeyMacCharCodes, typeChar, NULL, sizeof(lastKey), NULL, &lastKey);
+ if (err != noErr)
+ lastKey = NO_KEY;
+
+ return noErr;
+}
+
+CV_IMPL int cvWaitKey (int maxWait)
+{
+ EventRecord theEvent;
+
+ // wait at least for one event (to allow mouse, etc. processing), exit if maxWait milliseconds passed (nullEvent)
+ UInt32 start = TickCount();
+ int iters=0;
+ do
+ {
+ // remaining time until maxWait is over
+ UInt32 wait = EventTimeToTicks (maxWait / 1000.0) - (TickCount() - start);
+ if ((int)wait <= 0)
+ {
+ if( maxWait > 0 && iters > 0 )
+ break;
+ wait = 1;
+ }
+ iters++;
+ WaitNextEvent (everyEvent, &theEvent, maxWait > 0 ? wait : kDurationForever, NULL);
+ }
+ while (lastKey == NO_KEY && theEvent.what != nullEvent);
+
+ int key = lastKey;
+ lastKey = NO_KEY;
+ return key;
+}
+
+/* End of file. */