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 
cvInitSystem(int argc,char ** argv)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
cvStartWindowThread()155 CV_IMPL int cvStartWindowThread()
156 {
157     return 0;
158 }
159 
icvCountTrackbarInWindow(const CvWindow * window)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 
icvTrackbarByHandle(void * handle)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 
icvWindowByHandle(void * handle)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 
icvFindWindowByName(const char * name)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 
icvFindTrackbarByName(const CvWindow * window,const char * name)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 */
icvDrawImage(CvWindow * window)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 */
icvPutImage(CvWindow * window)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 
icvUpdateWindowSize(const CvWindow * window)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 
icvDeleteWindow(CvWindow * window)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 
cvDestroyWindow(const char * name)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 
cvDestroyAllWindows(void)361 CV_IMPL void cvDestroyAllWindows( void )
362 {
363     while( hg_windows )
364     {
365         CvWindow* window = hg_windows;
366         icvDeleteWindow( window );
367     }
368 }
369 
370 
cvShowImage(const char * name,const CvArr * arr)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 
cvResizeWindow(const char * name,int width,int height)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 
cvMoveWindow(const char * name,int x,int y)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 
TrackbarActionProcPtr(ControlRef theControl,ControlPartCode partCode)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 
icvCreateTrackbar(const char * trackbar_name,const char * window_name,int * val,int count,CvTrackbarCallback on_notify,CvTrackbarCallback2 on_notify2,void * userdata)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 
cvCreateTrackbar(const char * trackbar_name,const char * window_name,int * val,int count,CvTrackbarCallback on_notify)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 
cvCreateTrackbar2(const char * trackbar_name,const char * window_name,int * val,int count,CvTrackbarCallback2 on_notify2,void * userdata)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
cvSetMouseCallback(const char * name,CvMouseCallback function,void * info)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 
cvGetTrackbarPos(const char * trackbar_name,const char * window_name)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 
cvSetTrackbarPos(const char * trackbar_name,const char * window_name,int pos)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 
cvGetWindowHandle(const char * name)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 
cvGetWindowName(void * window_handle)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 
cvGetModeWindow_CARBON(const char * name)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 
cvSetModeWindow_CARBON(const char * name,double prop_value)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 
setWindowTitle(const String & winname,const String & title)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 
cvNamedWindow(const char * name,int flags)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 
windowEventHandler(EventHandlerCallRef nextHandler,EventRef theEvent,void * inUserData)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 coordonnées 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 
keyHandler(EventHandlerCallRef hcr,EventRef theEvent,void * inUserData)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 
cvWaitKey(int maxWait)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