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