/*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 "precomp.hpp" #include #include //YV #include #include #include //#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; int labelSize;//Yannick Verdie CvTrackbarCallback notify; CvTrackbarCallback2 notify2; void* userdata; } CvTrackbar; typedef struct CvWindow { int signature; char* name; CvWindow* prev; CvWindow* next; WindowRef window; WindowRef oldwindow;//YV CGImageRef imageRef; int imageWidth;//FD int imageHeight;//FD CvMat* image; CvMat* dst_image; int converted; int last_key; int flags; int status;//YV Ptr restoreState;//YV 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) ) //YV { 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); DisposeWindow (window->window);//YV 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); //--------YV--------------------------- CFStringEncoding encoding = kCFStringEncodingASCII; CFAllocatorRef alloc_default = kCFAllocatorDefault; // = NULL; char valueinchar[20]; sprintf(valueinchar, " (%d)", *trackbar->data); // create an empty CFMutableString CFIndex maxLength = 256; CFMutableStringRef cfstring = CFStringCreateMutable(alloc_default,maxLength); // append some c strings into it. CFStringAppendCString(cfstring,trackbar->name,encoding); CFStringAppendCString(cfstring,valueinchar,encoding); SetControlData(trackbar->label, kControlEntireControl,kControlStaticTextCFStringTag, sizeof(cfstring), &cfstring); DrawControls(trackbar->parent->window); //----------------------------------------- } } 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; //----------- YV ---------------------- //get nb of digits int nbDigit = 0; while((count/=10)>10){ nbDigit++; } //pad size maxvalue in pixel Point qdSize; char valueinchar[strlen(trackbar_name)+1 +1 +1+nbDigit+1];//lenght+\n +space +(+nbDigit+) sprintf(valueinchar, "%s (%d)",trackbar_name, trackbar->maxval); SInt16 baseline; CFStringRef text = CFStringCreateWithCString(NULL,valueinchar,kCFStringEncodingASCII); GetThemeTextDimensions( text, kThemeCurrentPortFont, kThemeStateActive, false, &qdSize, &baseline ); trackbar->labelSize = qdSize.h; //-------------------------------------- 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); //----------- YV ---------------------- sprintf(valueinchar, "%s (%d)",trackbar_name, trackbar->pos); CreateStaticTextControl (window->window,&stboundsRect,CFStringCreateWithCString(NULL,valueinchar,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; } double cvGetModeWindow_CARBON(const char* name)//YV { double result = -1; CV_FUNCNAME( "cvGetModeWindow_QT" ); __BEGIN__; CvWindow* window; if(!name) CV_ERROR( CV_StsNullPtr, "NULL name string" ); window = icvFindWindowByName( name ); if( !window ) CV_ERROR( CV_StsNullPtr, "NULL window" ); result = window->status; __END__; return result; } void cvSetModeWindow_CARBON( const char* name, double prop_value)//Yannick Verdie { OSStatus err = noErr; CV_FUNCNAME( "cvSetModeWindow_QT" ); __BEGIN__; CvWindow* window; if(!name) CV_ERROR( CV_StsNullPtr, "NULL name string" ); window = icvFindWindowByName( name ); if( !window ) CV_ERROR( CV_StsNullPtr, "NULL window" ); if(window->flags & CV_WINDOW_AUTOSIZE)//if the flag CV_WINDOW_AUTOSIZE is set EXIT; if (window->status==CV_WINDOW_FULLSCREEN && prop_value==CV_WINDOW_NORMAL) { err = EndFullScreen(window->restoreState,0); if (err != noErr) fprintf(stdout,"Error EndFullScreen\n"); window->window = window->oldwindow; ShowWindow( window->window ); window->status=CV_WINDOW_NORMAL; EXIT; } if (window->status==CV_WINDOW_NORMAL && prop_value==CV_WINDOW_FULLSCREEN) { GDHandle device; err = GetWindowGreatestAreaDevice(window->window, kWindowTitleBarRgn, &device, NULL); if (err != noErr) fprintf(stdout,"Error GetWindowGreatestAreaDevice\n"); HideWindow(window->window); window->oldwindow = window->window; err = BeginFullScreen(&(window->restoreState), device, 0, 0, &window->window, 0, fullScreenAllowEvents | fullScreenDontSwitchMonitorResolution); if (err != noErr) fprintf(stdout,"Error BeginFullScreen\n"); window->status=CV_WINDOW_FULLSCREEN; EXIT; } __END__; } 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->status = CV_WINDOW_NORMAL;//YV 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; if (window->flags & CV_WINDOW_AUTOSIZE)//Yannick verdie, remove the handler at the bottom-right position of the window in AUTORESIZE mode { wAttributes = 0; wAttributes = kWindowCloseBoxAttribute | kWindowFullZoomAttribute | kWindowCollapseBoxAttribute | 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; window->oldwindow = 0;//YV 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. */