Path: blob/master/modules/highgui/src/window_carbon.cpp
16337 views
/*M///////////////////////////////////////////////////////////////////////////////////////1//2// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.3//4// By downloading, copying, installing or using the software you agree to this license.5// If you do not agree to this license, do not download, install,6// copy or use the software.7//8//9// Intel License Agreement10// For Open Source Computer Vision Library11//12// Copyright (C) 2000, Intel Corporation, all rights reserved.13// Third party copyrights are property of their respective owners.14//15// Redistribution and use in source and binary forms, with or without modification,16// are permitted provided that the following conditions are met:17//18// * Redistribution's of source code must retain the above copyright notice,19// this list of conditions and the following disclaimer.20//21// * Redistribution's in binary form must reproduce the above copyright notice,22// this list of conditions and the following disclaimer in the documentation23// and/or other materials provided with the distribution.24//25// * The name of Intel Corporation may not be used to endorse or promote products26// derived from this software without specific prior written permission.27//28// This software is provided by the copyright holders and contributors "as is" and29// any express or implied warranties, including, but not limited to, the implied30// warranties of merchantability and fitness for a particular purpose are disclaimed.31// In no event shall the Intel Corporation or contributors be liable for any direct,32// indirect, incidental, special, exemplary, or consequential damages33// (including, but not limited to, procurement of substitute goods or services;34// loss of use, data, or profits; or business interruption) however caused35// and on any theory of liability, whether in contract, strict liability,36// or tort (including negligence or otherwise) arising in any way out of37// the use of this software, even if advised of the possibility of such damage.38//39//M*/4041#include "precomp.hpp"4243#include <Carbon/Carbon.h>44#include <Quicktime/Quicktime.h>//YV4546#include <unistd.h>47#include <cstdio>48#include <cmath>4950//#define MS_TO_TICKS(a) a*3/505152#define LABELWIDTH 6453#define INTERWIDGETSPACE 1654#define WIDGETHEIGHT 3255#define NO_KEY -15657struct CvWindow;5859typedef struct CvTrackbar60{61int signature;6263ControlRef trackbar;64ControlRef label;6566char* name;67CvTrackbar* next;68CvWindow* parent;69int* data;70int pos;71int maxval;72int labelSize;//Yannick Verdie73CvTrackbarCallback notify;74CvTrackbarCallback2 notify2;75void* userdata;76}77CvTrackbar;787980typedef struct CvWindow81{82int signature;8384char* name;85CvWindow* prev;86CvWindow* next;8788WindowRef window;89WindowRef oldwindow;//YV90CGImageRef imageRef;91int imageWidth;//FD92int imageHeight;//FD9394CvMat* image;95CvMat* dst_image;96int converted;97int last_key;98int flags;99int status;//YV100Ptr restoreState;//YV101102CvMouseCallback on_mouse;103void* on_mouse_param;104105struct {106int pos;107int rows;108CvTrackbar* first;109}110toolbar;111int trackbarheight;112}113CvWindow;114115static CvWindow* hg_windows = 0;116117#define Assert(exp) \118if( !(exp) ) \119{ \120printf("Assertion: %s %s: %d\n", #exp, __FILE__, __LINE__);\121assert(exp); \122}123124static int wasInitialized = 0;125static char lastKey = NO_KEY;126OSStatus keyHandler(EventHandlerCallRef hcr, EventRef theEvent, void* inUserData);127static pascal OSStatus windowEventHandler(EventHandlerCallRef nextHandler, EventRef theEvent, void *inUserData);128129static const EventTypeSpec applicationKeyboardEvents[] =130{131{ kEventClassKeyboard, kEventRawKeyDown },132};133134CV_IMPL int cvInitSystem( int argc, char** argv )135{136OSErr err = noErr;137if( !wasInitialized )138{139140hg_windows = 0;141err = InstallApplicationEventHandler(NewEventHandlerUPP( keyHandler),GetEventTypeCount(applicationKeyboardEvents),applicationKeyboardEvents,NULL,NULL);142if (err != noErr)143{144fprintf(stderr,"InstallApplicationEventHandler was not ok\n");145}146wasInitialized = 1;147}148setlocale(LC_NUMERIC,"C");149150return 0;151}152153// TODO: implement missing functionality154CV_IMPL int cvStartWindowThread()155{156return 0;157}158159static int icvCountTrackbarInWindow( const CvWindow* window)160{161CvTrackbar* trackbar = window->toolbar.first;162int count = 0;163while (trackbar != 0) {164count++;165trackbar = trackbar->next;166}167return count;168}169170static CvTrackbar* icvTrackbarByHandle( void * handle )171{172CvWindow* window = hg_windows;173CvTrackbar* trackbar = NULL;174while( window != 0 && window->window != handle) {175trackbar = window->toolbar.first;176while (trackbar != 0 && trackbar->trackbar != handle)177trackbar = trackbar->next;178if (trackbar != 0 && trackbar->trackbar == handle)179break;180window = window->next;181}182return trackbar;183}184185static CvWindow* icvWindowByHandle( void * handle )186{187CvWindow* window = hg_windows;188189while( window != 0 && window->window != handle)190window = window->next;191192return window;193}194195CV_IMPL CvWindow * icvFindWindowByName( const char* name)196{197CvWindow* window = hg_windows;198while( window != 0 && strcmp(name, window->name) != 0 )199window = window->next;200201return window;202}203204static CvTrackbar* icvFindTrackbarByName( const CvWindow* window, const char* name )205{206CvTrackbar* trackbar = window->toolbar.first;207208while (trackbar != 0 && strcmp( trackbar->name, name ) != 0)209trackbar = trackbar->next;210211return trackbar;212}213214//FD215/* draw image to frame */216static void icvDrawImage( CvWindow* window )217{218Assert( window != 0 );219if( window->imageRef == 0 ) return;220221CGContextRef myContext;222CGRect rect;223Rect portrect;224int width = window->imageWidth;225int height = window->imageHeight;226227GetWindowPortBounds(window->window, &portrect);228229if(!( window->flags & CV_WINDOW_AUTOSIZE) ) //YV230{231CGPoint origin = {0,0};232CGSize size = {portrect.right-portrect.left, portrect.bottom-portrect.top-window->trackbarheight};233rect.origin = origin; rect.size = size;234}235else236{237CGPoint origin = {0, portrect.bottom - height - window->trackbarheight};238CGSize size = {width, height};239rect.origin = origin; rect.size = size;240}241242/* 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*/243SetPortWindowPort (window->window);244QDBeginCGContext (GetWindowPort (window->window), &myContext);245CGContextSetInterpolationQuality (myContext, kCGInterpolationLow);246CGContextDrawImage(myContext,rect,window->imageRef);247CGContextFlush(myContext);// 4248QDEndCGContext (GetWindowPort(window->window), &myContext);// 5249}250251//FD252/* update imageRef */253static void icvPutImage( CvWindow* window )254{255Assert( window != 0 );256if( window->image == 0 ) return;257258CGColorSpaceRef colorspace = NULL;259CGDataProviderRef provider = NULL;260int width = window->imageWidth = window->image->cols;261int height = window->imageHeight = window->image->rows;262263colorspace = CGColorSpaceCreateDeviceRGB();264265int size = 8;266int nbChannels = 3;267268provider = CGDataProviderCreateWithData(NULL, window->image->data.ptr, width * height , NULL );269270if (window->imageRef != NULL){271CGImageRelease(window->imageRef);272window->imageRef = NULL;273}274275window->imageRef = CGImageCreate( width, height, size , size*nbChannels , window->image->step, colorspace, kCGImageAlphaNone , provider, NULL, true, kCGRenderingIntentDefault );276icvDrawImage( window );277278/* release the provider's memory */279CGDataProviderRelease( provider );280}281282static void icvUpdateWindowSize( const CvWindow* window )283{284int width = 0, height = 240;285Rect globalBounds;286287GetWindowBounds(window->window, kWindowContentRgn, &globalBounds);288289int minWidth = 320;290291if( window->image ) {292width = MAX(MAX(window->image->width, width), minWidth);293height = window->image->height;294} else295width = minWidth;296297height += window->trackbarheight;298299//height +=WIDGETHEIGHT; /* 32 pixels are spearating tracbars from the video display */300301globalBounds.right = globalBounds.left + width;302globalBounds.bottom = globalBounds.top + height;303SetWindowBounds(window->window, kWindowContentRgn, &globalBounds);304}305306static void icvDeleteWindow( CvWindow* window )307{308CvTrackbar* trackbar;309310if( window->prev )311window->prev->next = window->next;312else313hg_windows = window->next;314315if( window->next )316window->next->prev = window->prev;317318window->prev = window->next = 0;319320cvReleaseMat( &window->image );321cvReleaseMat( &window->dst_image );322323for( trackbar = window->toolbar.first; trackbar != 0; )324{325CvTrackbar* next = trackbar->next;326cvFree( (void**)&trackbar );327trackbar = next;328}329330if (window->imageRef != NULL)331CGImageRelease(window->imageRef);332333DisposeWindow (window->window);//YV334335cvFree( (void**)&window );336}337338339CV_IMPL void cvDestroyWindow( const char* name)340{341CV_FUNCNAME( "cvDestroyWindow" );342343__BEGIN__;344345CvWindow* window;346347if(!name)348CV_ERROR( CV_StsNullPtr, "NULL name string" );349350window = icvFindWindowByName( name );351if( !window )352EXIT;353354icvDeleteWindow( window );355356__END__;357}358359360CV_IMPL void cvDestroyAllWindows( void )361{362while( hg_windows )363{364CvWindow* window = hg_windows;365icvDeleteWindow( window );366}367}368369370CV_IMPL void cvShowImage( const char* name, const CvArr* arr)371{372CV_FUNCNAME( "cvShowImage" );373374__BEGIN__;375376CvWindow* window;377int origin = 0;378int resize = 0;379CvMat stub, *image;380381if( !name )382CV_ERROR( CV_StsNullPtr, "NULL name" );383384window = icvFindWindowByName(name);385if(!window)386{387cvNamedWindow(name, 1);388window = icvFindWindowByName(name);389}390391if( !window || !arr )392EXIT; // keep silence here.393394if( CV_IS_IMAGE_HDR( arr ))395origin = ((IplImage*)arr)->origin;396397CV_CALL( image = cvGetMat( arr, &stub ));398399/*400if( !window->image )401cvResizeWindow( name, image->cols, image->rows );402*/403404if( window->image &&405!CV_ARE_SIZES_EQ(window->image, image) ) {406if ( ! (window->flags & CV_WINDOW_AUTOSIZE) )//FD407resize = 1;408cvReleaseMat( &window->image );409}410411if( !window->image ) {412resize = 1;//FD413window->image = cvCreateMat( image->rows, image->cols, CV_8UC3 );414}415416cvConvertImage( image, window->image, (origin != 0 ? CV_CVTIMG_FLIP : 0) + CV_CVTIMG_SWAP_RB );417icvPutImage( window );418if ( resize )//FD419icvUpdateWindowSize( window );420421__END__;422}423424CV_IMPL void cvResizeWindow( const char* name, int width, int height)425{426CV_FUNCNAME( "cvResizeWindow" );427428__BEGIN__;429430CvWindow* window;431//CvTrackbar* trackbar;432433if( !name )434CV_ERROR( CV_StsNullPtr, "NULL name" );435436window = icvFindWindowByName(name);437if(!window)438EXIT;439440SizeWindow(window->window, width, height, true);441442__END__;443}444445CV_IMPL void cvMoveWindow( const char* name, int x, int y)446{447CV_FUNCNAME( "cvMoveWindow" );448449__BEGIN__;450451CvWindow* window;452//CvTrackbar* trackbar;453454if( !name )455CV_ERROR( CV_StsNullPtr, "NULL name" );456457window = icvFindWindowByName(name);458if(!window)459EXIT;460461MoveWindow(window->window, x, y, true);462463__END__;464}465466void TrackbarActionProcPtr (ControlRef theControl, ControlPartCode partCode)467{468CvTrackbar * trackbar = icvTrackbarByHandle (theControl);469470if (trackbar == NULL)471{472fprintf(stderr,"Error getting trackbar\n");473return;474}475else476{477int pos = GetControl32BitValue (theControl);478if ( trackbar->data )479*trackbar->data = pos;480if ( trackbar->notify )481trackbar->notify(pos);482else if ( trackbar->notify2 )483trackbar->notify2(pos, trackbar->userdata);484485//--------YV---------------------------486CFStringEncoding encoding = kCFStringEncodingASCII;487CFAllocatorRef alloc_default = kCFAllocatorDefault; // = NULL;488489char valueinchar[20];490sprintf(valueinchar, " (%d)", *trackbar->data);491492// create an empty CFMutableString493CFIndex maxLength = 256;494CFMutableStringRef cfstring = CFStringCreateMutable(alloc_default,maxLength);495496// append some c strings into it.497CFStringAppendCString(cfstring,trackbar->name,encoding);498CFStringAppendCString(cfstring,valueinchar,encoding);499500SetControlData(trackbar->label, kControlEntireControl,kControlStaticTextCFStringTag, sizeof(cfstring), &cfstring);501DrawControls(trackbar->parent->window);502//-----------------------------------------503}504}505506507static int icvCreateTrackbar (const char* trackbar_name,508const char* window_name,509int* val, int count,510CvTrackbarCallback on_notify,511CvTrackbarCallback2 on_notify2,512void* userdata)513{514int result = 0;515516CV_FUNCNAME( "icvCreateTrackbar" );517__BEGIN__;518519/*char slider_name[32];*/520CvWindow* window = 0;521CvTrackbar* trackbar = 0;522Rect stboundsRect;523ControlRef outControl;524ControlRef stoutControl;525Rect bounds;526527if( !window_name || !trackbar_name )528CV_ERROR( CV_StsNullPtr, "NULL window or trackbar name" );529530if( count <= 0 )531CV_ERROR( CV_StsOutOfRange, "Bad trackbar maximal value" );532533window = icvFindWindowByName(window_name);534if( !window )535EXIT;536537trackbar = icvFindTrackbarByName(window,trackbar_name);538if( !trackbar )539{540int len = strlen(trackbar_name);541trackbar = (CvTrackbar*)cvAlloc(sizeof(CvTrackbar) + len + 1);542memset( trackbar, 0, sizeof(*trackbar));543trackbar->signature = CV_TRACKBAR_MAGIC_VAL;544trackbar->name = (char*)(trackbar+1);545memcpy( trackbar->name, trackbar_name, len + 1 );546trackbar->parent = window;547trackbar->next = window->toolbar.first;548window->toolbar.first = trackbar;549550if( val )551{552int value = *val;553if( value < 0 )554value = 0;555if( value > count )556value = count;557trackbar->pos = value;558trackbar->data = val;559}560561trackbar->maxval = count;562563//----------- YV ----------------------564//get nb of digits565int nbDigit = 0;566while((count/=10)>10){567nbDigit++;568}569570//pad size maxvalue in pixel571Point qdSize;572char valueinchar[strlen(trackbar_name)+1 +1 +1+nbDigit+1];//length+\n +space +(+nbDigit+)573sprintf(valueinchar, "%s (%d)",trackbar_name, trackbar->maxval);574SInt16 baseline;575CFStringRef text = CFStringCreateWithCString(NULL,valueinchar,kCFStringEncodingASCII);576GetThemeTextDimensions( text, kThemeCurrentPortFont, kThemeStateActive, false, &qdSize, &baseline );577trackbar->labelSize = qdSize.h;578//--------------------------------------579580int c = icvCountTrackbarInWindow(window);581582GetWindowBounds(window->window,kWindowContentRgn,&bounds);583584stboundsRect.top = (INTERWIDGETSPACE +WIDGETHEIGHT)* (c-1)+INTERWIDGETSPACE;585stboundsRect.left = INTERWIDGETSPACE;586stboundsRect.bottom = stboundsRect.top + WIDGETHEIGHT;587stboundsRect.right = stboundsRect.left+LABELWIDTH;588589//fprintf(stdout,"create trackabar bounds (%d %d %d %d)\n",stboundsRect.top,stboundsRect.left,stboundsRect.bottom,stboundsRect.right);590//----------- YV ----------------------591sprintf(valueinchar, "%s (%d)",trackbar_name, trackbar->pos);592CreateStaticTextControl (window->window,&stboundsRect,CFStringCreateWithCString(NULL,valueinchar,kCFStringEncodingASCII),NULL,&stoutControl);593//--------------------------------------594595stboundsRect.top = (INTERWIDGETSPACE +WIDGETHEIGHT)* (c-1)+INTERWIDGETSPACE;596stboundsRect.left = INTERWIDGETSPACE*2+LABELWIDTH;597stboundsRect.bottom = stboundsRect.top + WIDGETHEIGHT;598stboundsRect.right = bounds.right-INTERWIDGETSPACE;599600CreateSliderControl (window->window,&stboundsRect, trackbar->pos,0,trackbar->maxval,kControlSliderLiveFeedback,0,true,NewControlActionUPP(TrackbarActionProcPtr),&outControl);601602bounds.bottom += INTERWIDGETSPACE + WIDGETHEIGHT;603SetControlVisibility (outControl,true,true);604SetControlVisibility (stoutControl,true,true);605606trackbar->trackbar = outControl;607trackbar->label = stoutControl;608if (c == 1)609window->trackbarheight = INTERWIDGETSPACE*2 + WIDGETHEIGHT;610else611window->trackbarheight += INTERWIDGETSPACE + WIDGETHEIGHT;612icvUpdateWindowSize( window );613}614615trackbar->notify = on_notify;616trackbar->notify2 = on_notify2;617trackbar->userdata = userdata;618619result = 1;620621__END__;622return result;623}624625626CV_IMPL int cvCreateTrackbar (const char* trackbar_name,627const char* window_name,628int* val, int count,629CvTrackbarCallback on_notify)630{631return icvCreateTrackbar(trackbar_name, window_name, val, count, on_notify, 0, 0);632}633634635CV_IMPL int cvCreateTrackbar2(const char* trackbar_name,636const char* window_name,637int* val, int count,638CvTrackbarCallback2 on_notify2,639void* userdata)640{641return icvCreateTrackbar(trackbar_name, window_name, val,642count, 0, on_notify2, userdata);643}644645646CV_IMPL void647cvSetMouseCallback( const char* name, CvMouseCallback function, void* info)648{649CvWindow* window = icvFindWindowByName( name );650if (window != NULL)651{652window->on_mouse = function;653window->on_mouse_param = info;654}655else656{657fprintf(stdout,"Error with cvSetMouseCallback. Window not found : %s\n",name);658}659}660661CV_IMPL int cvGetTrackbarPos( const char* trackbar_name, const char* window_name )662{663int pos = -1;664665CV_FUNCNAME( "cvGetTrackbarPos" );666667__BEGIN__;668669CvWindow* window;670CvTrackbar* trackbar = 0;671672if( trackbar_name == 0 || window_name == 0 )673CV_ERROR( CV_StsNullPtr, "NULL trackbar or window name" );674675window = icvFindWindowByName( window_name );676if( window )677trackbar = icvFindTrackbarByName( window, trackbar_name );678679if( trackbar )680pos = trackbar->pos;681682__END__;683684return pos;685}686687CV_IMPL void cvSetTrackbarPos(const char* trackbar_name, const char* window_name, int pos)688{689CV_FUNCNAME( "cvSetTrackbarPos" );690691__BEGIN__;692693CvWindow* window;694CvTrackbar* trackbar = 0;695696if( trackbar_name == 0 || window_name == 0 )697CV_ERROR( CV_StsNullPtr, "NULL trackbar or window name" );698699window = icvFindWindowByName( window_name );700if( window )701trackbar = icvFindTrackbarByName( window, trackbar_name );702703if( trackbar )704{705if( pos < 0 )706pos = 0;707708if( pos > trackbar->maxval )709pos = trackbar->maxval;710711// Set new value and redraw the trackbar712SetControlValue( trackbar->trackbar, pos );713Draw1Control( trackbar->trackbar );714}715716__END__;717return ;718}719720CvRect cvGetWindowRect_CARBON(const char* name)721{722CvRect result = cvRect(-1, -1, -1, -1);723724CV_FUNCNAME( "cvGetWindowRect_QT" );725726__BEGIN__;727728CvWindow* window;729730if(!name)731CV_ERROR( CV_StsNullPtr, "NULL name string" );732733window = icvFindWindowByName( name );734if( !window )735CV_ERROR( CV_StsNullPtr, "NULL window" );736737738Rect portrect;739GetWindowPortBounds(window->window, &portrect);740LocalToGlobal(&topLeft(portrect));741LocalToGlobal(&botRight(portrect));742if(!( window->flags & CV_WINDOW_AUTOSIZE) )743{744result = cvRect(portrect.left, portrect.top, portrect.right-portrect.left,745portrect.bottom-portrect.top-window->trackbarheight);746}747else748{749result = cvRect(portrect.left, portrect.bottom - height - window->trackbarheight,750window->imageWidth, window->imageHeight);751}752753__END__;754return result;755}756757CV_IMPL void* cvGetWindowHandle( const char* name )758{759WindowRef result = 0;760761__BEGIN__;762763CvWindow* window;764window = icvFindWindowByName( name );765if (window != NULL)766result = window->window;767else768result = NULL;769770__END__;771772return result;773}774775776CV_IMPL const char* cvGetWindowName( void* window_handle )777{778const char* window_name = "";779780CV_FUNCNAME( "cvGetWindowName" );781782__BEGIN__;783784CvWindow* window;785786if( window_handle == 0 )787CV_ERROR( CV_StsNullPtr, "NULL window" );788window = icvWindowByHandle(window_handle );789if( window )790window_name = window->name;791792__END__;793794return window_name;795}796797double cvGetModeWindow_CARBON(const char* name)//YV798{799double result = -1;800801CV_FUNCNAME( "cvGetModeWindow_QT" );802803__BEGIN__;804805CvWindow* window;806807if(!name)808CV_ERROR( CV_StsNullPtr, "NULL name string" );809810window = icvFindWindowByName( name );811if( !window )812CV_ERROR( CV_StsNullPtr, "NULL window" );813814result = window->status;815816__END__;817return result;818}819820void cvSetModeWindow_CARBON( const char* name, double prop_value)//Yannick Verdie821{822OSStatus err = noErr;823824825CV_FUNCNAME( "cvSetModeWindow_QT" );826827__BEGIN__;828829CvWindow* window;830831if(!name)832CV_ERROR( CV_StsNullPtr, "NULL name string" );833834window = icvFindWindowByName( name );835if( !window )836CV_ERROR( CV_StsNullPtr, "NULL window" );837838if(window->flags & CV_WINDOW_AUTOSIZE)//if the flag CV_WINDOW_AUTOSIZE is set839EXIT;840841if (window->status==CV_WINDOW_FULLSCREEN && prop_value==CV_WINDOW_NORMAL)842{843err = EndFullScreen(window->restoreState,0);844if (err != noErr)845fprintf(stdout,"Error EndFullScreen\n");846window->window = window->oldwindow;847ShowWindow( window->window );848849window->status=CV_WINDOW_NORMAL;850EXIT;851}852853if (window->status==CV_WINDOW_NORMAL && prop_value==CV_WINDOW_FULLSCREEN)854{855GDHandle device;856err = GetWindowGreatestAreaDevice(window->window, kWindowTitleBarRgn, &device, NULL);857if (err != noErr)858fprintf(stdout,"Error GetWindowGreatestAreaDevice\n");859860HideWindow(window->window);861window->oldwindow = window->window;862err = BeginFullScreen(&(window->restoreState), device, 0, 0, &window->window, 0, fullScreenAllowEvents | fullScreenDontSwitchMonitorResolution);863if (err != noErr)864fprintf(stdout,"Error BeginFullScreen\n");865866window->status=CV_WINDOW_FULLSCREEN;867EXIT;868}869870__END__;871}872873void cv::setWindowTitle(const String& winname, const String& title)874{875CvWindow* window = icvFindWindowByName(winname.c_str());876877if (!window)878{879namedWindow(winname);880window = icvFindWindowByName(winname.c_str());881}882883if (!window)884CV_Error(Error::StsNullPtr, "NULL window");885886if (noErr != SetWindowTitleWithCFString(window->window, CFStringCreateWithCString(NULL, title.c_str(), kCFStringEncodingASCII)))887CV_Error_(Error::StsError, ("Failed to set \"%s\" window title to \"%s\"", winname.c_str(), title.c_str()));888}889890CV_IMPL int cvNamedWindow( const char* name, int flags )891{892int result = 0;893CV_FUNCNAME( "cvNamedWindow" );894if (!wasInitialized)895cvInitSystem(0, NULL);896897// to be able to display a window, we need to be a 'faceful' application898// http://lists.apple.com/archives/carbon-dev/2005/Jun/msg01414.html899static bool switched_to_faceful = false;900if (! switched_to_faceful)901{902ProcessSerialNumber psn = { 0, kCurrentProcess };903OSStatus ret = TransformProcessType (&psn, kProcessTransformToForegroundApplication );904905if (ret == noErr)906{907SetFrontProcess( &psn );908switched_to_faceful = true;909}910else911{912fprintf(stderr, "Failed to transform process type: %d\n", (int) ret);913fflush (stderr);914}915}916917__BEGIN__;918919WindowRef outWindow = NULL;920OSStatus err = noErr;921Rect contentBounds = {100,100,320,440};922923CvWindow* window;924UInt wAttributes = 0;925926int len;927928const EventTypeSpec genericWindowEventHandler[] = {929{ kEventClassMouse, kEventMouseMoved},930{ kEventClassMouse, kEventMouseDragged},931{ kEventClassMouse, kEventMouseUp},932{ kEventClassMouse, kEventMouseDown},933{ kEventClassWindow, kEventWindowClose },934{ kEventClassWindow, kEventWindowBoundsChanged }//FD935};936937if( !name )938CV_ERROR( CV_StsNullPtr, "NULL name string" );939940if( icvFindWindowByName( name ) != 0 ){941result = 1;942EXIT;943}944len = strlen(name);945CV_CALL( window = (CvWindow*)cvAlloc(sizeof(CvWindow) + len + 1));946memset( window, 0, sizeof(*window));947window->name = (char*)(window + 1);948memcpy( window->name, name, len + 1 );949window->flags = flags;950window->status = CV_WINDOW_NORMAL;//YV951window->signature = CV_WINDOW_MAGIC_VAL;952window->image = 0;953window->last_key = 0;954window->on_mouse = 0;955window->on_mouse_param = 0;956957window->next = hg_windows;958window->prev = 0;959if( hg_windows )960hg_windows->prev = window;961hg_windows = window;962wAttributes = kWindowStandardDocumentAttributes | kWindowStandardHandlerAttribute | kWindowLiveResizeAttribute;963964965if (window->flags & CV_WINDOW_AUTOSIZE)//Yannick verdie, remove the handler at the bottom-right position of the window in AUTORESIZE mode966{967wAttributes = 0;968wAttributes = kWindowCloseBoxAttribute | kWindowFullZoomAttribute | kWindowCollapseBoxAttribute | kWindowStandardHandlerAttribute | kWindowLiveResizeAttribute;969}970971err = CreateNewWindow ( kDocumentWindowClass,wAttributes,&contentBounds,&outWindow);972if (err != noErr)973fprintf(stderr,"Error while creating the window\n");974975SetWindowTitleWithCFString(outWindow,CFStringCreateWithCString(NULL,name,kCFStringEncodingASCII));976if (err != noErr)977fprintf(stdout,"Error SetWindowTitleWithCFString\n");978979window->window = outWindow;980window->oldwindow = 0;//YV981982err = InstallWindowEventHandler(outWindow, NewEventHandlerUPP(windowEventHandler), GetEventTypeCount(genericWindowEventHandler), genericWindowEventHandler, outWindow, NULL);983984ShowWindow( outWindow );985result = 1;986987__END__;988return result;989}990991static pascal OSStatus windowEventHandler(EventHandlerCallRef nextHandler, EventRef theEvent, void *inUserData)992{993CvWindow* window = NULL;994UInt32 eventKind, eventClass;995OSErr err = noErr;996int event = 0;997UInt32 count = 0;998HIPoint point = {0,0};999EventMouseButton eventMouseButton = 0;//FD1000UInt32 modifiers;//FD10011002WindowRef theWindow = (WindowRef)inUserData;1003if (theWindow == NULL)1004return eventNotHandledErr;1005window = icvWindowByHandle(theWindow);1006if ( window == NULL)1007return eventNotHandledErr;10081009eventKind = GetEventKind(theEvent);1010eventClass = GetEventClass(theEvent);10111012switch (eventClass) {1013case kEventClassMouse : {1014switch (eventKind){1015case kEventMouseUp :1016case kEventMouseDown :1017case kEventMouseMoved :1018case kEventMouseDragged : {1019err = CallNextEventHandler(nextHandler, theEvent);1020if (err != eventNotHandledErr)1021return err;1022err = GetEventParameter(theEvent, kEventParamMouseButton, typeMouseButton, NULL, sizeof(eventMouseButton), NULL, &eventMouseButton);1023err = GetEventParameter(theEvent, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(modifiers), NULL, &modifiers);1024err = GetEventParameter(theEvent,kEventParamClickCount,typeUInt32,NULL,sizeof(UInt32),NULL,&count);1025if (err == noErr){1026if (count >1) event += 6;1027} else {1028event = CV_EVENT_MOUSEMOVE;1029}10301031if (eventKind == kEventMouseUp)1032event +=4;1033if (eventKind == kEventMouseDown)1034event +=1;10351036unsigned int flags = 0;10371038err = GetEventParameter(theEvent, kEventParamWindowMouseLocation, typeHIPoint, NULL, sizeof(point), NULL, &point);1039if (eventKind != kEventMouseMoved){1040switch(eventMouseButton){1041case kEventMouseButtonPrimary:1042if (modifiers & controlKey){1043flags += CV_EVENT_FLAG_RBUTTON;1044event += 1;1045} else {1046flags += CV_EVENT_FLAG_LBUTTON;1047}1048break;1049case kEventMouseButtonSecondary:1050flags += CV_EVENT_FLAG_RBUTTON;1051event += 1;1052break;1053case kEventMouseButtonTertiary:1054flags += CV_EVENT_FLAG_MBUTTON;1055event += 2;1056break;1057}1058}10591060if (modifiers&controlKey) flags += CV_EVENT_FLAG_CTRLKEY;1061if (modifiers&shiftKey) flags += CV_EVENT_FLAG_SHIFTKEY;1062if (modifiers& cmdKey ) flags += CV_EVENT_FLAG_ALTKEY;10631064if (window->on_mouse != NULL){1065int lx,ly;1066Rect structure, content;1067GetWindowBounds(theWindow, kWindowStructureRgn, &structure);1068GetWindowBounds(theWindow, kWindowContentRgn, &content);1069lx = (int)point.x - content.left + structure.left;1070ly = (int)point.y - window->trackbarheight - content.top + structure.top;1071if (window->flags & CV_WINDOW_AUTOSIZE) {//FD1072//printf("was %d,%d\n", lx, ly);1073/* scale the mouse coordinates */1074lx = lx * window->imageWidth / (content.right - content.left);1075ly = ly * window->imageHeight / (content.bottom - content.top - window->trackbarheight);1076}10771078if (lx>0 && ly >0){1079window->on_mouse (event, lx, ly, flags, window->on_mouse_param);1080return noErr;1081}1082}1083}1084default : return eventNotHandledErr;1085}1086}1087case kEventClassWindow : {//FD1088switch (eventKind){1089case kEventWindowBoundsChanged :1090{1091/* resize the trackbars */1092CvTrackbar *t;1093Rect bounds;1094GetWindowBounds(window->window,kWindowContentRgn,&bounds);1095for ( t = window->toolbar.first; t != 0; t = t->next )1096SizeControl(t->trackbar,bounds.right - bounds.left - INTERWIDGETSPACE*3 - LABELWIDTH , WIDGETHEIGHT);1097}1098/* redraw the image */1099icvDrawImage(window);1100break;1101default :1102return eventNotHandledErr;1103}1104}1105default:1106return eventNotHandledErr;1107}11081109return eventNotHandledErr;1110}11111112OSStatus keyHandler(EventHandlerCallRef hcr, EventRef theEvent, void* inUserData)1113{1114UInt32 eventKind;1115UInt32 eventClass;1116OSErr err = noErr;11171118eventKind = GetEventKind (theEvent);1119eventClass = GetEventClass (theEvent);1120err = GetEventParameter(theEvent, kEventParamKeyMacCharCodes, typeChar, NULL, sizeof(lastKey), NULL, &lastKey);1121if (err != noErr)1122lastKey = NO_KEY;11231124return noErr;1125}11261127CV_IMPL int cvWaitKey (int maxWait)1128{1129EventRecord theEvent;11301131// wait at least for one event (to allow mouse, etc. processing), exit if maxWait milliseconds passed (nullEvent)1132UInt32 start = TickCount();1133int iters=0;1134do1135{1136// remaining time until maxWait is over1137UInt32 wait = EventTimeToTicks (maxWait / 1000.0) - (TickCount() - start);1138if ((int)wait <= 0)1139{1140if( maxWait > 0 && iters > 0 )1141break;1142wait = 1;1143}1144iters++;1145WaitNextEvent (everyEvent, &theEvent, maxWait > 0 ? wait : kDurationForever, NULL);1146}1147while (lastKey == NO_KEY && theEvent.what != nullEvent);11481149int key = lastKey;1150lastKey = NO_KEY;1151return key;1152}11531154/* End of file. */115511561157