Home | History | Annotate | Download | only in src
      1 /*M///////////////////////////////////////////////////////////////////////////////////////
      2 //
      3 //  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
      4 //
      5 //  By downloading, copying, installing or using the software you agree to this license.
      6 //  If you do not agree to this license, do not download, install,
      7 //  copy or use the software.
      8 //
      9 //
     10 //                        Intel License Agreement
     11 //                For Open Source Computer Vision Library
     12 //
     13 // Copyright (C) 2000, Intel Corporation, all rights reserved.
     14 // Third party copyrights are property of their respective owners.
     15 //
     16 // Redistribution and use in source and binary forms, with or without modification,
     17 // are permitted provided that the following conditions are met:
     18 //
     19 //   * Redistribution's of source code must retain the above copyright notice,
     20 //     this list of conditions and the following disclaimer.
     21 //
     22 //   * Redistribution's in binary form must reproduce the above copyright notice,
     23 //     this list of conditions and the following disclaimer in the documentation
     24 //     and/or other materials provided with the distribution.
     25 //
     26 //   * The name of Intel Corporation may not be used to endorse or promote products
     27 //     derived from this software without specific prior written permission.
     28 //
     29 // This software is provided by the copyright holders and contributors "as is" and
     30 // any express or implied warranties, including, but not limited to, the implied
     31 // warranties of merchantability and fitness for a particular purpose are disclaimed.
     32 // In no event shall the Intel Corporation or contributors be liable for any direct,
     33 // indirect, incidental, special, exemplary, or consequential damages
     34 // (including, but not limited to, procurement of substitute goods or services;
     35 // loss of use, data, or profits; or business interruption) however caused
     36 // and on any theory of liability, whether in contract, strict liability,
     37 // or tort (including negligence or otherwise) arising in any way out of
     38 // the use of this software, even if advised of the possibility of such damage.
     39 //
     40 //M*/
     41 
     42 #include "precomp.hpp"
     43 
     44 #include <Carbon/Carbon.h>
     45 #include <Quicktime/Quicktime.h>//YV
     46 
     47 #include <unistd.h>
     48 #include <cstdio>
     49 #include <cmath>
     50 
     51 //#define MS_TO_TICKS(a) a*3/50
     52 
     53 #define LABELWIDTH 64
     54 #define INTERWIDGETSPACE 16
     55 #define WIDGETHEIGHT 32
     56 #define NO_KEY -1
     57 
     58 struct CvWindow;
     59 
     60 typedef struct CvTrackbar
     61 {
     62     int signature;
     63 
     64     ControlRef trackbar;
     65     ControlRef label;
     66 
     67     char* name;
     68     CvTrackbar* next;
     69     CvWindow* parent;
     70     int* data;
     71     int pos;
     72     int maxval;
     73     int labelSize;//Yannick Verdie
     74     CvTrackbarCallback notify;
     75     CvTrackbarCallback2 notify2;
     76     void* userdata;
     77 }
     78 CvTrackbar;
     79 
     80 
     81 typedef struct CvWindow
     82 {
     83     int signature;
     84 
     85     char* name;
     86     CvWindow* prev;
     87     CvWindow* next;
     88 
     89     WindowRef window;
     90     WindowRef oldwindow;//YV
     91     CGImageRef imageRef;
     92     int imageWidth;//FD
     93     int imageHeight;//FD
     94 
     95     CvMat* image;
     96     CvMat* dst_image;
     97     int converted;
     98     int last_key;
     99     int flags;
    100     int status;//YV
    101     Ptr restoreState;//YV
    102 
    103     CvMouseCallback on_mouse;
    104     void* on_mouse_param;
    105 
    106     struct {
    107         int pos;
    108         int rows;
    109         CvTrackbar* first;
    110     }
    111     toolbar;
    112     int trackbarheight;
    113 }
    114 CvWindow;
    115 
    116 static CvWindow* hg_windows = 0;
    117 
    118 #define Assert(exp)                                             \
    119 if( !(exp) )                                                    \
    120 {                                                               \
    121     printf("Assertion: %s  %s: %d\n", #exp, __FILE__, __LINE__);\
    122     assert(exp);                                                \
    123 }
    124 
    125 static int wasInitialized = 0;
    126 static char lastKey = NO_KEY;
    127 OSStatus keyHandler(EventHandlerCallRef hcr, EventRef theEvent, void* inUserData);
    128 static pascal OSStatus windowEventHandler(EventHandlerCallRef nextHandler, EventRef theEvent, void *inUserData);
    129 
    130 static const EventTypeSpec applicationKeyboardEvents[] =
    131 {
    132     { kEventClassKeyboard, kEventRawKeyDown },
    133 };
    134 
    135 CV_IMPL int cvInitSystem( int argc, char** argv )
    136 {
    137     OSErr err = noErr;
    138     if( !wasInitialized )
    139     {
    140 
    141         hg_windows = 0;
    142         err = InstallApplicationEventHandler(NewEventHandlerUPP( keyHandler),GetEventTypeCount(applicationKeyboardEvents),applicationKeyboardEvents,NULL,NULL);
    143         if (err != noErr)
    144         {
    145              fprintf(stderr,"InstallApplicationEventHandler was not ok\n");
    146         }
    147         wasInitialized = 1;
    148     }
    149     setlocale(LC_NUMERIC,"C");
    150 
    151     return 0;
    152 }
    153 
    154 // TODO: implement missing functionality
    155 CV_IMPL int cvStartWindowThread()
    156 {
    157     return 0;
    158 }
    159 
    160 static int icvCountTrackbarInWindow( const CvWindow* window)
    161 {
    162     CvTrackbar* trackbar = window->toolbar.first;
    163     int count = 0;
    164     while (trackbar != 0) {
    165         count++;
    166         trackbar = trackbar->next;
    167     }
    168     return count;
    169 }
    170 
    171 static CvTrackbar* icvTrackbarByHandle( void * handle )
    172 {
    173     CvWindow* window = hg_windows;
    174     CvTrackbar* trackbar = NULL;
    175     while( window != 0 && window->window != handle) {
    176         trackbar = window->toolbar.first;
    177         while (trackbar != 0 && trackbar->trackbar != handle)
    178             trackbar = trackbar->next;
    179         if (trackbar != 0 && trackbar->trackbar == handle)
    180             break;
    181         window = window->next;
    182     }
    183     return trackbar;
    184 }
    185 
    186 static CvWindow* icvWindowByHandle( void * handle )
    187 {
    188     CvWindow* window = hg_windows;
    189 
    190     while( window != 0 && window->window != handle)
    191         window = window->next;
    192 
    193     return window;
    194 }
    195 
    196 CV_IMPL CvWindow * icvFindWindowByName( const char* name)
    197 {
    198     CvWindow* window = hg_windows;
    199     while( window != 0 && strcmp(name, window->name) != 0 )
    200         window = window->next;
    201 
    202     return window;
    203 }
    204 
    205 static CvTrackbar* icvFindTrackbarByName( const CvWindow* window, const char* name )
    206 {
    207     CvTrackbar* trackbar = window->toolbar.first;
    208 
    209     while (trackbar != 0 && strcmp( trackbar->name, name ) != 0)
    210         trackbar = trackbar->next;
    211 
    212     return trackbar;
    213 }
    214 
    215 //FD
    216 /* draw image to frame */
    217 static void icvDrawImage( CvWindow* window )
    218 {
    219     Assert( window != 0 );
    220     if( window->imageRef == 0 ) return;
    221 
    222     CGContextRef myContext;
    223     CGRect rect;
    224     Rect portrect;
    225     int width = window->imageWidth;
    226     int height = window->imageHeight;
    227 
    228         GetWindowPortBounds(window->window, &portrect);
    229 
    230     if(!( window->flags & CV_WINDOW_AUTOSIZE) ) //YV
    231     {
    232         CGPoint origin = {0,0};
    233         CGSize size = {portrect.right-portrect.left, portrect.bottom-portrect.top-window->trackbarheight};
    234         rect.origin = origin; rect.size = size;
    235     }
    236     else
    237     {
    238         CGPoint origin = {0, portrect.bottom - height - window->trackbarheight};
    239         CGSize size = {width, height};
    240         rect.origin = origin; rect.size = size;
    241     }
    242 
    243     /* 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*/
    244     SetPortWindowPort (window->window);
    245     QDBeginCGContext (GetWindowPort (window->window), &myContext);
    246     CGContextSetInterpolationQuality (myContext, kCGInterpolationLow);
    247     CGContextDrawImage(myContext,rect,window->imageRef);
    248     CGContextFlush(myContext);// 4
    249     QDEndCGContext (GetWindowPort(window->window), &myContext);// 5
    250 }
    251 
    252 //FD
    253 /* update imageRef */
    254 static void icvPutImage( CvWindow* window )
    255 {
    256     Assert( window != 0 );
    257     if( window->image == 0 ) return;
    258 
    259     CGColorSpaceRef colorspace = NULL;
    260     CGDataProviderRef provider = NULL;
    261     int width = window->imageWidth = window->image->cols;
    262     int height = window->imageHeight = window->image->rows;
    263 
    264     colorspace = CGColorSpaceCreateDeviceRGB();
    265 
    266     int size = 8;
    267     int nbChannels = 3;
    268 
    269     provider = CGDataProviderCreateWithData(NULL, window->image->data.ptr, width * height , NULL );
    270 
    271     if (window->imageRef != NULL){
    272         CGImageRelease(window->imageRef);
    273         window->imageRef = NULL;
    274     }
    275 
    276     window->imageRef = CGImageCreate( width, height, size , size*nbChannels , window->image->step, colorspace,  kCGImageAlphaNone , provider, NULL, true, kCGRenderingIntentDefault );
    277     icvDrawImage( window );
    278 
    279     /* release the provider's memory */
    280     CGDataProviderRelease( provider );
    281 }
    282 
    283 static void icvUpdateWindowSize( const CvWindow* window )
    284 {
    285     int width = 0, height = 240; /* init  al taille de base de l'image*/
    286     Rect globalBounds;
    287 
    288     GetWindowBounds(window->window, kWindowContentRgn, &globalBounds);
    289 
    290     int minWidth = 320;
    291 
    292     if( window->image ) {
    293         width = MAX(MAX(window->image->width, width), minWidth);
    294         height = window->image->height;
    295     } else
    296         width = minWidth;
    297 
    298     height += window->trackbarheight;
    299 
    300     //height +=WIDGETHEIGHT; /* 32 pixels are spearating tracbars from the video display */
    301 
    302     globalBounds.right = globalBounds.left + width;
    303     globalBounds.bottom = globalBounds.top + height;
    304     SetWindowBounds(window->window, kWindowContentRgn, &globalBounds);
    305 }
    306 
    307 static void icvDeleteWindow( CvWindow* window )
    308 {
    309     CvTrackbar* trackbar;
    310 
    311     if( window->prev )
    312         window->prev->next = window->next;
    313     else
    314         hg_windows = window->next;
    315 
    316     if( window->next )
    317         window->next->prev = window->prev;
    318 
    319     window->prev = window->next = 0;
    320 
    321     cvReleaseMat( &window->image );
    322     cvReleaseMat( &window->dst_image );
    323 
    324     for( trackbar = window->toolbar.first; trackbar != 0; )
    325     {
    326         CvTrackbar* next = trackbar->next;
    327         cvFree( (void**)&trackbar );
    328         trackbar = next;
    329     }
    330 
    331     if (window->imageRef != NULL)
    332         CGImageRelease(window->imageRef);
    333 
    334     DisposeWindow (window->window);//YV
    335 
    336     cvFree( (void**)&window );
    337 }
    338 
    339 
    340 CV_IMPL void cvDestroyWindow( const char* name)
    341 {
    342     CV_FUNCNAME( "cvDestroyWindow" );
    343 
    344     __BEGIN__;
    345 
    346     CvWindow* window;
    347 
    348     if(!name)
    349         CV_ERROR( CV_StsNullPtr, "NULL name string" );
    350 
    351     window = icvFindWindowByName( name );
    352     if( !window )
    353         EXIT;
    354 
    355     icvDeleteWindow( window );
    356 
    357     __END__;
    358 }
    359 
    360 
    361 CV_IMPL void cvDestroyAllWindows( void )
    362 {
    363     while( hg_windows )
    364     {
    365         CvWindow* window = hg_windows;
    366         icvDeleteWindow( window );
    367     }
    368 }
    369 
    370 
    371 CV_IMPL void cvShowImage( const char* name, const CvArr* arr)
    372 {
    373     CV_FUNCNAME( "cvShowImage" );
    374 
    375     __BEGIN__;
    376 
    377     CvWindow* window;
    378     int origin = 0;
    379     int resize = 0;
    380     CvMat stub, *image;
    381 
    382     if( !name )
    383         CV_ERROR( CV_StsNullPtr, "NULL name" );
    384 
    385     window = icvFindWindowByName(name);
    386     if(!window)
    387     {
    388         cvNamedWindow(name, 1);
    389         window = icvFindWindowByName(name);
    390     }
    391 
    392     if( !window || !arr )
    393         EXIT; // keep silence here.
    394 
    395     if( CV_IS_IMAGE_HDR( arr ))
    396         origin = ((IplImage*)arr)->origin;
    397 
    398     CV_CALL( image = cvGetMat( arr, &stub ));
    399 
    400     /*
    401      if( !window->image )
    402      cvResizeWindow( name, image->cols, image->rows );
    403      */
    404 
    405     if( window->image &&
    406         !CV_ARE_SIZES_EQ(window->image, image) ) {
    407         if ( ! (window->flags & CV_WINDOW_AUTOSIZE) )//FD
    408             resize = 1;
    409         cvReleaseMat( &window->image );
    410     }
    411 
    412     if( !window->image ) {
    413         resize = 1;//FD
    414         window->image = cvCreateMat( image->rows, image->cols, CV_8UC3 );
    415     }
    416 
    417     cvConvertImage( image, window->image, (origin != 0 ? CV_CVTIMG_FLIP : 0) + CV_CVTIMG_SWAP_RB );
    418     icvPutImage( window );
    419     if ( resize )//FD
    420         icvUpdateWindowSize( window );
    421 
    422     __END__;
    423 }
    424 
    425 CV_IMPL void cvResizeWindow( const char* name, int width, int height)
    426 {
    427     CV_FUNCNAME( "cvResizeWindow" );
    428 
    429     __BEGIN__;
    430 
    431     CvWindow* window;
    432     //CvTrackbar* trackbar;
    433 
    434     if( !name )
    435         CV_ERROR( CV_StsNullPtr, "NULL name" );
    436 
    437     window = icvFindWindowByName(name);
    438     if(!window)
    439         EXIT;
    440 
    441     SizeWindow(window->window, width, height, true);
    442 
    443     __END__;
    444 }
    445 
    446 CV_IMPL void cvMoveWindow( const char* name, int x, int y)
    447 {
    448     CV_FUNCNAME( "cvMoveWindow" );
    449 
    450     __BEGIN__;
    451 
    452     CvWindow* window;
    453     //CvTrackbar* trackbar;
    454 
    455     if( !name )
    456         CV_ERROR( CV_StsNullPtr, "NULL name" );
    457 
    458     window = icvFindWindowByName(name);
    459     if(!window)
    460         EXIT;
    461 
    462     MoveWindow(window->window, x, y, true);
    463 
    464     __END__;
    465 }
    466 
    467 void TrackbarActionProcPtr (ControlRef theControl, ControlPartCode partCode)
    468 {
    469     CvTrackbar * trackbar = icvTrackbarByHandle (theControl);
    470 
    471     if (trackbar == NULL)
    472     {
    473         fprintf(stderr,"Error getting trackbar\n");
    474         return;
    475     }
    476     else
    477     {
    478         int pos = GetControl32BitValue (theControl);
    479         if ( trackbar->data )
    480             *trackbar->data = pos;
    481         if ( trackbar->notify )
    482             trackbar->notify(pos);
    483         else if ( trackbar->notify2 )
    484             trackbar->notify2(pos, trackbar->userdata);
    485 
    486         //--------YV---------------------------
    487         CFStringEncoding encoding = kCFStringEncodingASCII;
    488         CFAllocatorRef alloc_default = kCFAllocatorDefault;  // = NULL;
    489 
    490         char valueinchar[20];
    491         sprintf(valueinchar, " (%d)",  *trackbar->data);
    492 
    493         // create an empty CFMutableString
    494         CFIndex maxLength = 256;
    495         CFMutableStringRef cfstring = CFStringCreateMutable(alloc_default,maxLength);
    496 
    497         // append some c strings into it.
    498         CFStringAppendCString(cfstring,trackbar->name,encoding);
    499         CFStringAppendCString(cfstring,valueinchar,encoding);
    500 
    501         SetControlData(trackbar->label, kControlEntireControl,kControlStaticTextCFStringTag, sizeof(cfstring), &cfstring);
    502         DrawControls(trackbar->parent->window);
    503         //-----------------------------------------
    504     }
    505 }
    506 
    507 
    508 static int icvCreateTrackbar (const char* trackbar_name,
    509                               const char* window_name,
    510                               int* val, int count,
    511                               CvTrackbarCallback on_notify,
    512                               CvTrackbarCallback2 on_notify2,
    513                               void* userdata)
    514 {
    515     int result = 0;
    516 
    517     CV_FUNCNAME( "icvCreateTrackbar" );
    518     __BEGIN__;
    519 
    520     /*char slider_name[32];*/
    521     CvWindow* window = 0;
    522     CvTrackbar* trackbar = 0;
    523     Rect  stboundsRect;
    524     ControlRef outControl;
    525     ControlRef stoutControl;
    526     Rect bounds;
    527 
    528     if( !window_name || !trackbar_name )
    529         CV_ERROR( CV_StsNullPtr, "NULL window or trackbar name" );
    530 
    531     if( count <= 0 )
    532         CV_ERROR( CV_StsOutOfRange, "Bad trackbar maximal value" );
    533 
    534     window = icvFindWindowByName(window_name);
    535     if( !window )
    536         EXIT;
    537 
    538     trackbar = icvFindTrackbarByName(window,trackbar_name);
    539     if( !trackbar )
    540     {
    541         int len = strlen(trackbar_name);
    542         trackbar = (CvTrackbar*)cvAlloc(sizeof(CvTrackbar) + len + 1);
    543         memset( trackbar, 0, sizeof(*trackbar));
    544         trackbar->signature = CV_TRACKBAR_MAGIC_VAL;
    545         trackbar->name = (char*)(trackbar+1);
    546         memcpy( trackbar->name, trackbar_name, len + 1 );
    547         trackbar->parent = window;
    548         trackbar->next = window->toolbar.first;
    549         window->toolbar.first = trackbar;
    550 
    551         if( val )
    552         {
    553             int value = *val;
    554             if( value < 0 )
    555                 value = 0;
    556             if( value > count )
    557                 value = count;
    558             trackbar->pos = value;
    559             trackbar->data = val;
    560         }
    561 
    562         trackbar->maxval = count;
    563 
    564         //----------- YV ----------------------
    565         //get nb of digits
    566         int nbDigit = 0;
    567         while((count/=10)>10){
    568             nbDigit++;
    569         }
    570 
    571         //pad size maxvalue in pixel
    572         Point	qdSize;
    573         char valueinchar[strlen(trackbar_name)+1 +1 +1+nbDigit+1];//length+\n +space +(+nbDigit+)
    574         sprintf(valueinchar, "%s (%d)",trackbar_name, trackbar->maxval);
    575         SInt16	baseline;
    576         CFStringRef text = CFStringCreateWithCString(NULL,valueinchar,kCFStringEncodingASCII);
    577         GetThemeTextDimensions( text, kThemeCurrentPortFont, kThemeStateActive, false, &qdSize, &baseline );
    578         trackbar->labelSize = qdSize.h;
    579         //--------------------------------------
    580 
    581         int c = icvCountTrackbarInWindow(window);
    582 
    583         GetWindowBounds(window->window,kWindowContentRgn,&bounds);
    584 
    585         stboundsRect.top = (INTERWIDGETSPACE +WIDGETHEIGHT)* (c-1)+INTERWIDGETSPACE;
    586         stboundsRect.left = INTERWIDGETSPACE;
    587         stboundsRect.bottom = stboundsRect.top + WIDGETHEIGHT;
    588         stboundsRect.right = stboundsRect.left+LABELWIDTH;
    589 
    590         //fprintf(stdout,"create trackabar bounds (%d %d %d %d)\n",stboundsRect.top,stboundsRect.left,stboundsRect.bottom,stboundsRect.right);
    591      //----------- YV ----------------------
    592      sprintf(valueinchar, "%s (%d)",trackbar_name, trackbar->pos);
    593         CreateStaticTextControl (window->window,&stboundsRect,CFStringCreateWithCString(NULL,valueinchar,kCFStringEncodingASCII),NULL,&stoutControl);
    594         //--------------------------------------
    595 
    596         stboundsRect.top = (INTERWIDGETSPACE +WIDGETHEIGHT)* (c-1)+INTERWIDGETSPACE;
    597         stboundsRect.left = INTERWIDGETSPACE*2+LABELWIDTH;
    598         stboundsRect.bottom = stboundsRect.top + WIDGETHEIGHT;
    599         stboundsRect.right =  bounds.right-INTERWIDGETSPACE;
    600 
    601         CreateSliderControl (window->window,&stboundsRect, trackbar->pos,0,trackbar->maxval,kControlSliderLiveFeedback,0,true,NewControlActionUPP(TrackbarActionProcPtr),&outControl);
    602 
    603         bounds.bottom += INTERWIDGETSPACE + WIDGETHEIGHT;
    604         SetControlVisibility (outControl,true,true);
    605         SetControlVisibility (stoutControl,true,true);
    606 
    607         trackbar->trackbar = outControl;
    608         trackbar->label = stoutControl;
    609         if (c == 1)
    610             window->trackbarheight = INTERWIDGETSPACE*2 + WIDGETHEIGHT;
    611         else
    612             window->trackbarheight += INTERWIDGETSPACE + WIDGETHEIGHT;
    613         icvUpdateWindowSize( window );
    614     }
    615 
    616     trackbar->notify = on_notify;
    617     trackbar->notify2 = on_notify2;
    618     trackbar->userdata = userdata;
    619 
    620     result = 1;
    621 
    622     __END__;
    623     return result;
    624 }
    625 
    626 
    627 CV_IMPL int cvCreateTrackbar (const char* trackbar_name,
    628                               const char* window_name,
    629                               int* val, int count,
    630                               CvTrackbarCallback on_notify)
    631 {
    632     return icvCreateTrackbar(trackbar_name, window_name, val, count, on_notify, 0, 0);
    633 }
    634 
    635 
    636 CV_IMPL int cvCreateTrackbar2(const char* trackbar_name,
    637                               const char* window_name,
    638                               int* val, int count,
    639                               CvTrackbarCallback2 on_notify2,
    640                               void* userdata)
    641 {
    642     return icvCreateTrackbar(trackbar_name, window_name, val,
    643                              count, 0, on_notify2, userdata);
    644 }
    645 
    646 
    647 CV_IMPL void
    648 cvSetMouseCallback( const char* name, CvMouseCallback function, void* info)
    649 {
    650     CvWindow* window = icvFindWindowByName( name );
    651     if (window != NULL)
    652     {
    653         window->on_mouse = function;
    654         window->on_mouse_param = info;
    655     }
    656     else
    657     {
    658         fprintf(stdout,"Error with cvSetMouseCallback. Window not found : %s\n",name);
    659     }
    660 }
    661 
    662  CV_IMPL int cvGetTrackbarPos( const char* trackbar_name, const char* window_name )
    663 {
    664     int pos = -1;
    665 
    666     CV_FUNCNAME( "cvGetTrackbarPos" );
    667 
    668     __BEGIN__;
    669 
    670     CvWindow* window;
    671     CvTrackbar* trackbar = 0;
    672 
    673     if( trackbar_name == 0 || window_name == 0 )
    674         CV_ERROR( CV_StsNullPtr, "NULL trackbar or window name" );
    675 
    676     window = icvFindWindowByName( window_name );
    677     if( window )
    678         trackbar = icvFindTrackbarByName( window, trackbar_name );
    679 
    680     if( trackbar )
    681         pos = trackbar->pos;
    682 
    683     __END__;
    684 
    685     return pos;
    686 }
    687 
    688 CV_IMPL void cvSetTrackbarPos(const char* trackbar_name, const char* window_name, int pos)
    689 {
    690    CV_FUNCNAME( "cvSetTrackbarPos" );
    691 
    692     __BEGIN__;
    693 
    694     CvWindow* window;
    695     CvTrackbar* trackbar = 0;
    696 
    697     if( trackbar_name == 0 || window_name == 0 )
    698         CV_ERROR( CV_StsNullPtr, "NULL trackbar or window name" );
    699 
    700     window = icvFindWindowByName( window_name );
    701     if( window )
    702         trackbar = icvFindTrackbarByName( window, trackbar_name );
    703 
    704     if( trackbar )
    705     {
    706         if( pos < 0 )
    707             pos = 0;
    708 
    709         if( pos > trackbar->maxval )
    710             pos = trackbar->maxval;
    711 
    712     // Set new value and redraw the trackbar
    713     SetControlValue( trackbar->trackbar, pos );
    714     Draw1Control( trackbar->trackbar );
    715     }
    716 
    717     __END__;
    718     return ;
    719 }
    720 
    721 CV_IMPL void* cvGetWindowHandle( const char* name )
    722 {
    723     WindowRef result = 0;
    724 
    725     __BEGIN__;
    726 
    727     CvWindow* window;
    728     window = icvFindWindowByName( name );
    729     if (window != NULL)
    730         result = window->window;
    731     else
    732         result = NULL;
    733 
    734     __END__;
    735 
    736     return result;
    737 }
    738 
    739 
    740 CV_IMPL const char* cvGetWindowName( void* window_handle )
    741 {
    742     const char* window_name = "";
    743 
    744     CV_FUNCNAME( "cvGetWindowName" );
    745 
    746     __BEGIN__;
    747 
    748     CvWindow* window;
    749 
    750     if( window_handle == 0 )
    751         CV_ERROR( CV_StsNullPtr, "NULL window" );
    752     window = icvWindowByHandle(window_handle );
    753     if( window )
    754         window_name = window->name;
    755 
    756     __END__;
    757 
    758     return window_name;
    759 }
    760 
    761 double cvGetModeWindow_CARBON(const char* name)//YV
    762 {
    763     double result = -1;
    764 
    765     CV_FUNCNAME( "cvGetModeWindow_QT" );
    766 
    767     __BEGIN__;
    768 
    769     CvWindow* window;
    770 
    771     if(!name)
    772         CV_ERROR( CV_StsNullPtr, "NULL name string" );
    773 
    774     window = icvFindWindowByName( name );
    775     if( !window )
    776         CV_ERROR( CV_StsNullPtr, "NULL window" );
    777 
    778     result = window->status;
    779 
    780     __END__;
    781     return result;
    782 }
    783 
    784 void cvSetModeWindow_CARBON( const char* name, double prop_value)//Yannick Verdie
    785 {
    786     OSStatus err = noErr;
    787 
    788 
    789     CV_FUNCNAME( "cvSetModeWindow_QT" );
    790 
    791     __BEGIN__;
    792 
    793     CvWindow* window;
    794 
    795     if(!name)
    796         CV_ERROR( CV_StsNullPtr, "NULL name string" );
    797 
    798     window = icvFindWindowByName( name );
    799     if( !window )
    800         CV_ERROR( CV_StsNullPtr, "NULL window" );
    801 
    802     if(window->flags & CV_WINDOW_AUTOSIZE)//if the flag CV_WINDOW_AUTOSIZE is set
    803         EXIT;
    804 
    805     if (window->status==CV_WINDOW_FULLSCREEN && prop_value==CV_WINDOW_NORMAL)
    806     {
    807         err = EndFullScreen(window->restoreState,0);
    808         if (err != noErr)
    809             fprintf(stdout,"Error EndFullScreen\n");
    810         window->window = window->oldwindow;
    811         ShowWindow( window->window );
    812 
    813         window->status=CV_WINDOW_NORMAL;
    814         EXIT;
    815     }
    816 
    817     if (window->status==CV_WINDOW_NORMAL && prop_value==CV_WINDOW_FULLSCREEN)
    818     {
    819         GDHandle device;
    820         err = GetWindowGreatestAreaDevice(window->window, kWindowTitleBarRgn, &device, NULL);
    821         if (err != noErr)
    822             fprintf(stdout,"Error GetWindowGreatestAreaDevice\n");
    823 
    824         HideWindow(window->window);
    825         window->oldwindow = window->window;
    826         err = BeginFullScreen(&(window->restoreState), device, 0, 0, &window->window, 0, fullScreenAllowEvents | fullScreenDontSwitchMonitorResolution);
    827         if (err != noErr)
    828             fprintf(stdout,"Error BeginFullScreen\n");
    829 
    830         window->status=CV_WINDOW_FULLSCREEN;
    831         EXIT;
    832     }
    833 
    834     __END__;
    835 }
    836 
    837 void cv::setWindowTitle(const String& winname, const String& title)
    838 {
    839     CvWindow* window = icvFindWindowByName(winname.c_str());
    840 
    841     if (!window)
    842     {
    843         namedWindow(winname);
    844         window = icvFindWindowByName(winname.c_str());
    845     }
    846 
    847     if (!window)
    848         CV_Error(Error::StsNullPtr, "NULL window");
    849 
    850     if (noErr != SetWindowTitleWithCFString(window->window, CFStringCreateWithCString(NULL, title.c_str(), kCFStringEncodingASCII)))
    851         CV_Error_(Error::StsError, ("Failed to set \"%s\" window title to \"%s\"", winname.c_str(), title.c_str()));
    852 }
    853 
    854 CV_IMPL int cvNamedWindow( const char* name, int flags )
    855 {
    856     int result = 0;
    857     CV_FUNCNAME( "cvNamedWindow" );
    858     if (!wasInitialized)
    859         cvInitSystem(0, NULL);
    860 
    861     // to be able to display a window, we need to be a 'faceful' application
    862     // http://lists.apple.com/archives/carbon-dev/2005/Jun/msg01414.html
    863     static bool switched_to_faceful = false;
    864     if (! switched_to_faceful)
    865     {
    866         ProcessSerialNumber psn = { 0, kCurrentProcess };
    867         OSStatus ret = TransformProcessType (&psn, kProcessTransformToForegroundApplication );
    868 
    869         if (ret == noErr)
    870         {
    871             SetFrontProcess( &psn );
    872             switched_to_faceful = true;
    873         }
    874         else
    875         {
    876             fprintf(stderr, "Failed to tranform process type: %d\n", (int) ret);
    877             fflush (stderr);
    878         }
    879     }
    880 
    881     __BEGIN__;
    882 
    883     WindowRef       outWindow = NULL;
    884     OSStatus              err = noErr;
    885     Rect        contentBounds = {100,100,320,440};
    886 
    887     CvWindow* window;
    888     UInt wAttributes = 0;
    889 
    890     int len;
    891 
    892     const EventTypeSpec genericWindowEventHandler[] = {
    893         { kEventClassMouse, kEventMouseMoved},
    894         { kEventClassMouse, kEventMouseDragged},
    895         { kEventClassMouse, kEventMouseUp},
    896         { kEventClassMouse, kEventMouseDown},
    897         { kEventClassWindow, kEventWindowClose },
    898         { kEventClassWindow, kEventWindowBoundsChanged }//FD
    899     };
    900 
    901     if( !name )
    902         CV_ERROR( CV_StsNullPtr, "NULL name string" );
    903 
    904     if( icvFindWindowByName( name ) != 0 ){
    905         result = 1;
    906         EXIT;
    907     }
    908     len = strlen(name);
    909     CV_CALL( window = (CvWindow*)cvAlloc(sizeof(CvWindow) + len + 1));
    910     memset( window, 0, sizeof(*window));
    911     window->name = (char*)(window + 1);
    912     memcpy( window->name, name, len + 1 );
    913     window->flags = flags;
    914     window->status = CV_WINDOW_NORMAL;//YV
    915     window->signature = CV_WINDOW_MAGIC_VAL;
    916     window->image = 0;
    917     window->last_key = 0;
    918     window->on_mouse = 0;
    919     window->on_mouse_param = 0;
    920 
    921     window->next = hg_windows;
    922     window->prev = 0;
    923     if( hg_windows )
    924         hg_windows->prev = window;
    925     hg_windows = window;
    926     wAttributes =  kWindowStandardDocumentAttributes | kWindowStandardHandlerAttribute | kWindowLiveResizeAttribute;
    927 
    928 
    929     if (window->flags & CV_WINDOW_AUTOSIZE)//Yannick verdie, remove the handler at the bottom-right position of the window in AUTORESIZE mode
    930     {
    931     wAttributes = 0;
    932     wAttributes = kWindowCloseBoxAttribute | kWindowFullZoomAttribute | kWindowCollapseBoxAttribute | kWindowStandardHandlerAttribute  |  kWindowLiveResizeAttribute;
    933     }
    934 
    935     err = CreateNewWindow ( kDocumentWindowClass,wAttributes,&contentBounds,&outWindow);
    936     if (err != noErr)
    937         fprintf(stderr,"Error while creating the window\n");
    938 
    939     SetWindowTitleWithCFString(outWindow,CFStringCreateWithCString(NULL,name,kCFStringEncodingASCII));
    940     if (err != noErr)
    941         fprintf(stdout,"Error SetWindowTitleWithCFString\n");
    942 
    943     window->window = outWindow;
    944     window->oldwindow = 0;//YV
    945 
    946     err = InstallWindowEventHandler(outWindow, NewEventHandlerUPP(windowEventHandler), GetEventTypeCount(genericWindowEventHandler), genericWindowEventHandler, outWindow, NULL);
    947 
    948     ShowWindow( outWindow );
    949     result = 1;
    950 
    951     __END__;
    952     return result;
    953 }
    954 
    955 static pascal OSStatus windowEventHandler(EventHandlerCallRef nextHandler, EventRef theEvent, void *inUserData)
    956 {
    957     CvWindow* window = NULL;
    958     UInt32 eventKind, eventClass;
    959     OSErr err = noErr;
    960     int event = 0;
    961     UInt32 count = 0;
    962     HIPoint point = {0,0};
    963     EventMouseButton eventMouseButton = 0;//FD
    964     UInt32 modifiers;//FD
    965 
    966     WindowRef theWindow = (WindowRef)inUserData;
    967     if (theWindow == NULL)
    968         return eventNotHandledErr;
    969     window = icvWindowByHandle(theWindow);
    970     if ( window == NULL)
    971         return eventNotHandledErr;
    972 
    973     eventKind = GetEventKind(theEvent);
    974     eventClass = GetEventClass(theEvent);
    975 
    976     switch (eventClass) {
    977     case kEventClassMouse : {
    978         switch (eventKind){
    979         case kEventMouseUp :
    980         case kEventMouseDown :
    981         case kEventMouseMoved :
    982         case kEventMouseDragged : {
    983             err = CallNextEventHandler(nextHandler, theEvent);
    984             if (err != eventNotHandledErr)
    985                 return err;
    986             err = GetEventParameter(theEvent, kEventParamMouseButton, typeMouseButton, NULL, sizeof(eventMouseButton), NULL, &eventMouseButton);
    987             err = GetEventParameter(theEvent, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(modifiers), NULL, &modifiers);
    988             err = GetEventParameter(theEvent,kEventParamClickCount,typeUInt32,NULL,sizeof(UInt32),NULL,&count);
    989             if (err == noErr){
    990                 if (count >1) event += 6;
    991             } else {
    992                 event = CV_EVENT_MOUSEMOVE;
    993             }
    994 
    995             if (eventKind == kEventMouseUp)
    996                 event +=4;
    997             if (eventKind == kEventMouseDown)
    998                 event +=1;
    999 
   1000             unsigned int flags = 0;
   1001 
   1002             err = GetEventParameter(theEvent, kEventParamWindowMouseLocation, typeHIPoint, NULL, sizeof(point), NULL, &point);
   1003             if (eventKind != kEventMouseMoved){
   1004                 switch(eventMouseButton){
   1005                     case kEventMouseButtonPrimary:
   1006                         if (modifiers & controlKey){
   1007                             flags += CV_EVENT_FLAG_RBUTTON;
   1008                             event += 1;
   1009                         } else {
   1010                             flags += CV_EVENT_FLAG_LBUTTON;
   1011                         }
   1012                         break;
   1013                     case kEventMouseButtonSecondary:
   1014                         flags += CV_EVENT_FLAG_RBUTTON;
   1015                         event += 1;
   1016                         break;
   1017                     case kEventMouseButtonTertiary:
   1018                         flags += CV_EVENT_FLAG_MBUTTON;
   1019                         event += 2;
   1020                         break;
   1021                 }
   1022             }
   1023 
   1024             if (modifiers&controlKey) flags += CV_EVENT_FLAG_CTRLKEY;
   1025             if (modifiers&shiftKey)   flags += CV_EVENT_FLAG_SHIFTKEY;
   1026             if (modifiers& cmdKey )   flags += CV_EVENT_FLAG_ALTKEY;
   1027 
   1028             if (window->on_mouse != NULL){
   1029                 int lx,ly;
   1030                 Rect structure, content;
   1031                 GetWindowBounds(theWindow, kWindowStructureRgn, &structure);
   1032                 GetWindowBounds(theWindow, kWindowContentRgn, &content);
   1033                 lx = (int)point.x - content.left + structure.left;
   1034                 ly = (int)point.y - window->trackbarheight  - content.top + structure.top; /* minus la taille des trackbars */
   1035                 if (window->flags & CV_WINDOW_AUTOSIZE) {//FD
   1036                                                          //printf("was %d,%d\n", lx, ly);
   1037                     /* scale the mouse coordinates */
   1038                     lx = lx * window->imageWidth / (content.right - content.left);
   1039                     ly = ly * window->imageHeight / (content.bottom - content.top - window->trackbarheight);
   1040                 }
   1041 
   1042                 if (lx>0 && ly >0){ /* a remettre dans les coordonnes locale */
   1043                     window->on_mouse (event, lx, ly, flags, window->on_mouse_param);
   1044                     return noErr;
   1045                 }
   1046             }
   1047         }
   1048         default : return eventNotHandledErr;
   1049         }
   1050     }
   1051     case kEventClassWindow : {//FD
   1052         switch (eventKind){
   1053         case kEventWindowBoundsChanged :
   1054         {
   1055             /* resize the trackbars */
   1056             CvTrackbar *t;
   1057             Rect bounds;
   1058             GetWindowBounds(window->window,kWindowContentRgn,&bounds);
   1059             for ( t = window->toolbar.first; t != 0; t = t->next )
   1060                 SizeControl(t->trackbar,bounds.right - bounds.left - INTERWIDGETSPACE*3 - LABELWIDTH , WIDGETHEIGHT);
   1061         }
   1062             /* redraw the image */
   1063             icvDrawImage(window);
   1064             break;
   1065         default :
   1066             return eventNotHandledErr;
   1067         }
   1068     }
   1069     default:
   1070         return eventNotHandledErr;
   1071     }
   1072 
   1073     return eventNotHandledErr;
   1074 }
   1075 
   1076 OSStatus keyHandler(EventHandlerCallRef hcr, EventRef theEvent, void* inUserData)
   1077 {
   1078     UInt32 eventKind;
   1079     UInt32 eventClass;
   1080     OSErr  err        = noErr;
   1081 
   1082     eventKind  = GetEventKind     (theEvent);
   1083     eventClass = GetEventClass    (theEvent);
   1084     err        = GetEventParameter(theEvent, kEventParamKeyMacCharCodes, typeChar, NULL, sizeof(lastKey), NULL, &lastKey);
   1085     if (err != noErr)
   1086         lastKey = NO_KEY;
   1087 
   1088     return noErr;
   1089 }
   1090 
   1091 CV_IMPL int cvWaitKey (int maxWait)
   1092 {
   1093     EventRecord theEvent;
   1094 
   1095     // wait at least for one event (to allow mouse, etc. processing), exit if maxWait milliseconds passed (nullEvent)
   1096     UInt32 start = TickCount();
   1097     int iters=0;
   1098     do
   1099     {
   1100         // remaining time until maxWait is over
   1101         UInt32 wait = EventTimeToTicks (maxWait / 1000.0) - (TickCount() - start);
   1102         if ((int)wait <= 0)
   1103         {
   1104             if( maxWait > 0 && iters > 0 )
   1105                 break;
   1106             wait = 1;
   1107         }
   1108         iters++;
   1109         WaitNextEvent (everyEvent, &theEvent, maxWait > 0 ? wait : kDurationForever, NULL);
   1110     }
   1111     while (lastKey == NO_KEY  &&  theEvent.what != nullEvent);
   1112 
   1113     int key = lastKey;
   1114     lastKey = NO_KEY;
   1115     return key;
   1116 }
   1117 
   1118 /* End of file. */
   1119