reorder defined checks according to cmake file
[platform/upstream/opencv.git] / modules / highgui / src / window.cpp
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 #include "backend.hpp"
44
45 #include "opencv2/core/opengl.hpp"
46 #include "opencv2/core/utils/logger.hpp"
47
48 // in later times, use this file as a dispatcher to implementations like cvcap.cpp
49
50
51 using namespace cv;
52 using namespace cv::highgui_backend;
53
54 namespace cv {
55
56 Mutex& getWindowMutex()
57 {
58     static Mutex* g_window_mutex = new Mutex();
59     return *g_window_mutex;
60 }
61
62 namespace impl {
63
64 typedef std::map<std::string, highgui_backend::UIWindowBase::Ptr> WindowsMap_t;
65 static WindowsMap_t& getWindowsMap()
66 {
67     static WindowsMap_t g_windowsMap;
68     return g_windowsMap;
69 }
70
71 static std::shared_ptr<UIWindow> findWindow_(const std::string& name)
72 {
73     cv::AutoLock lock(cv::getWindowMutex());
74     auto& windowsMap = getWindowsMap();
75     auto i = windowsMap.find(name);
76     if (i != windowsMap.end())
77     {
78         const auto& ui_base = i->second;
79         if (ui_base)
80         {
81             if (!ui_base->isActive())
82             {
83                 windowsMap.erase(i);
84                 return std::shared_ptr<UIWindow>();
85             }
86             auto window = std::dynamic_pointer_cast<UIWindow>(ui_base);
87             return window;
88         }
89     }
90     return std::shared_ptr<UIWindow>();
91 }
92
93 static void cleanupTrackbarCallbacksWithData_();  // forward declaration
94
95 static void cleanupClosedWindows_()
96 {
97     cv::AutoLock lock(cv::getWindowMutex());
98     auto& windowsMap = getWindowsMap();
99     for (auto it = windowsMap.begin(); it != windowsMap.end();)
100     {
101         const auto& ui_base = it->second;
102         bool erase = (!ui_base || !ui_base->isActive());
103         if (erase)
104         {
105             it = windowsMap.erase(it);
106         }
107         else
108         {
109             ++it;
110         }
111     }
112
113     cleanupTrackbarCallbacksWithData_();
114 }
115
116 // Just to support deprecated API, to be removed
117 struct TrackbarCallbackWithData
118 {
119     std::weak_ptr<UITrackbar> trackbar_;
120     int* data_;
121     TrackbarCallback callback_;
122     void* userdata_;
123
124     TrackbarCallbackWithData(int* data, TrackbarCallback callback, void* userdata)
125         : data_(data)
126         , callback_(callback), userdata_(userdata)
127     {
128         // trackbar_ is initialized separatelly
129     }
130
131     ~TrackbarCallbackWithData()
132     {
133         CV_LOG_DEBUG(NULL, "UI/Trackbar: Cleanup deprecated TrackbarCallbackWithData");
134     }
135
136     void onChange(int pos)
137     {
138         if (data_)
139             *data_ = pos;
140         if (callback_)
141             callback_(pos, userdata_);
142     }
143
144     static void onChangeCallback(int pos, void* userdata)
145     {
146         TrackbarCallbackWithData* thiz = (TrackbarCallbackWithData*)userdata;
147         CV_Assert(thiz);
148         return thiz->onChange(pos);
149     }
150 };
151
152 typedef std::vector< std::shared_ptr<TrackbarCallbackWithData> > TrackbarCallbacksWithData_t;
153 static TrackbarCallbacksWithData_t& getTrackbarCallbacksWithData()
154 {
155     static TrackbarCallbacksWithData_t g_trackbarCallbacksWithData;
156     return g_trackbarCallbacksWithData;
157 }
158
159 static void cleanupTrackbarCallbacksWithData_()
160 {
161     cv::AutoLock lock(cv::getWindowMutex());
162     auto& callbacks = getTrackbarCallbacksWithData();
163     for (auto it = callbacks.begin(); it != callbacks.end();)
164     {
165         const auto& cb = *it;
166         bool erase = (!cb || cb->trackbar_.expired());
167         if (erase)
168         {
169             it = callbacks.erase(it);
170         }
171         else
172         {
173             ++it;
174         }
175     }
176 }
177
178 }}  // namespace cv::impl
179
180 using namespace cv::impl;
181
182 #if defined(OPENCV_HIGHGUI_WITHOUT_BUILTIN_BACKEND) && defined(ENABLE_PLUGINS)
183 static void deprecateNotFoundNoOpBehavior()
184 {
185     CV_LOG_ONCE_WARNING(NULL, "This no-op behavior is deprecated. Future versions of OpenCV will trigger exception in this case");
186 }
187 #define CV_NOT_FOUND_DEPRECATION deprecateNotFoundNoOpBehavior()
188 #endif
189
190 CV_IMPL void cvSetWindowProperty(const char* name, int prop_id, double prop_value)
191 {
192     CV_TRACE_FUNCTION();
193     CV_Assert(name);
194
195     {
196         auto window = findWindow_(name);
197         if (window)
198         {
199             /*bool res = */window->setProperty(prop_id, prop_value);
200             return;
201         }
202     }
203
204 #if defined(OPENCV_HIGHGUI_WITHOUT_BUILTIN_BACKEND) && defined(ENABLE_PLUGINS)
205     auto backend = getCurrentUIBackend();
206     if (backend)
207     {
208         CV_LOG_WARNING(NULL, "Can't find window with name: '" << name << "'. Do nothing");
209         CV_NOT_FOUND_DEPRECATION;
210     }
211     else
212     {
213         CV_LOG_WARNING(NULL, "No UI backends available. Use OPENCV_LOG_LEVEL=DEBUG for investigation");
214     }
215     return;
216 #else
217     switch(prop_id)
218     {
219     //change between fullscreen or not.
220     case CV_WND_PROP_FULLSCREEN:
221
222         if (prop_value != CV_WINDOW_NORMAL && prop_value != CV_WINDOW_FULLSCREEN)  // bad argument
223             break;
224
225         #if defined (HAVE_QT)
226             cvSetModeWindow_QT(name,prop_value);
227         #elif defined(HAVE_WIN32UI)
228             cvSetModeWindow_W32(name,prop_value);
229         #elif defined (HAVE_GTK)
230             cvSetModeWindow_GTK(name,prop_value);
231         #elif defined (HAVE_COCOA)
232             cvSetModeWindow_COCOA(name,prop_value);
233         #elif defined (WINRT)
234             cvSetModeWindow_WinRT(name, prop_value);
235         #endif
236
237     break;
238
239     case CV_WND_PROP_AUTOSIZE:
240         #if defined (HAVE_QT)
241             cvSetPropWindow_QT(name,prop_value);
242         #endif
243     break;
244
245     case CV_WND_PROP_ASPECTRATIO:
246         #if defined (HAVE_QT)
247             cvSetRatioWindow_QT(name,prop_value);
248         #endif
249     break;
250
251     case cv::WND_PROP_TOPMOST:
252         #if defined (HAVE_QT)
253             // nothing
254         #elif defined(HAVE_WIN32UI)
255             cvSetPropTopmost_W32(name, (prop_value != 0 ? true : false));
256         #elif defined(HAVE_COCOA)
257             cvSetPropTopmost_COCOA(name, (prop_value != 0 ? true : false));
258         #endif
259     break;
260
261     case cv::WND_PROP_VSYNC:
262         #if defined (HAVE_QT)
263             // nothing
264         #elif defined (HAVE_WIN32UI)
265             cvSetPropVsync_W32(name, (prop_value != 0));
266         #else
267             // not implemented yet for other toolkits
268         #endif
269     break;
270
271     default:;
272     }
273 #endif
274 }
275
276 /* return -1 if error */
277 CV_IMPL double cvGetWindowProperty(const char* name, int prop_id)
278 {
279     CV_TRACE_FUNCTION();
280     CV_Assert(name);
281
282     {
283         auto window = findWindow_(name);
284         if (window)
285         {
286             double v = window->getProperty(prop_id);
287             if (cvIsNaN(v))
288                 return -1;
289             return v;
290         }
291     }
292
293 #if defined(OPENCV_HIGHGUI_WITHOUT_BUILTIN_BACKEND) && defined(ENABLE_PLUGINS)
294     auto backend = getCurrentUIBackend();
295     if (backend)
296     {
297         CV_LOG_WARNING(NULL, "Can't find window with name: '" << name << "'. Do nothing");
298         CV_NOT_FOUND_DEPRECATION;
299     }
300     else
301     {
302         CV_LOG_WARNING(NULL, "No UI backends available. Use OPENCV_LOG_LEVEL=DEBUG for investigation");
303     }
304     return -1;
305 #else
306     switch(prop_id)
307     {
308     case CV_WND_PROP_FULLSCREEN:
309
310         #if defined (HAVE_QT)
311             return cvGetModeWindow_QT(name);
312         #elif defined(HAVE_WIN32UI)
313             return cvGetModeWindow_W32(name);
314         #elif defined (HAVE_GTK)
315             return cvGetModeWindow_GTK(name);
316         #elif defined (HAVE_COCOA)
317             return cvGetModeWindow_COCOA(name);
318         #elif defined (WINRT)
319             return cvGetModeWindow_WinRT(name);
320         #else
321             return -1;
322         #endif
323     break;
324
325     case CV_WND_PROP_AUTOSIZE:
326
327         #if defined (HAVE_QT)
328             return cvGetPropWindow_QT(name);
329         #elif defined(HAVE_WIN32UI)
330             return cvGetPropWindowAutoSize_W32(name);
331         #elif defined (HAVE_GTK)
332             return cvGetPropWindowAutoSize_GTK(name);
333         #else
334             return -1;
335         #endif
336     break;
337
338     case CV_WND_PROP_ASPECTRATIO:
339
340         #if defined (HAVE_QT)
341             return cvGetRatioWindow_QT(name);
342         #elif defined(HAVE_WIN32UI)
343             return cvGetRatioWindow_W32(name);
344         #elif defined (HAVE_GTK)
345             return cvGetRatioWindow_GTK(name);
346         #else
347             return -1;
348         #endif
349     break;
350
351     case CV_WND_PROP_OPENGL:
352
353         #if defined (HAVE_QT)
354             return cvGetOpenGlProp_QT(name);
355         #elif defined(HAVE_WIN32UI)
356             return cvGetOpenGlProp_W32(name);
357         #elif defined (HAVE_GTK)
358             return cvGetOpenGlProp_GTK(name);
359         #else
360             return -1;
361         #endif
362     break;
363
364     case CV_WND_PROP_VISIBLE:
365         #if defined (HAVE_QT)
366             return cvGetPropVisible_QT(name);
367         #elif defined(HAVE_WIN32UI)
368             return cvGetPropVisible_W32(name);
369         #else
370             return -1;
371         #endif
372     break;
373
374     case cv::WND_PROP_TOPMOST:
375         #if defined (HAVE_QT)
376             return -1;
377         #elif defined(HAVE_WIN32UI)
378             return cvGetPropTopmost_W32(name);
379         #elif defined(HAVE_COCOA)
380             return cvGetPropTopmost_COCOA(name);
381         #else
382             return -1;
383         #endif
384     break;
385
386     case cv::WND_PROP_VSYNC:
387         #if defined (HAVE_QT)
388             return -1;
389         #elif defined (HAVE_WIN32UI)
390             return cvGetPropVsync_W32(name);
391         #else
392             return -1;
393         #endif
394     break;
395
396     default:
397         return -1;
398     }
399 #endif
400 }
401
402 cv::Rect cvGetWindowImageRect(const char* name)
403 {
404     CV_TRACE_FUNCTION();
405     CV_Assert(name);
406
407     {
408         auto window = findWindow_(name);
409         if (window)
410         {
411             return window->getImageRect();
412         }
413     }
414
415 #if defined(OPENCV_HIGHGUI_WITHOUT_BUILTIN_BACKEND) && defined(ENABLE_PLUGINS)
416     auto backend = getCurrentUIBackend();
417     if (backend)
418     {
419         CV_LOG_WARNING(NULL, "Can't find window with name: '" << name << "'. Do nothing");
420         CV_NOT_FOUND_DEPRECATION;
421     }
422     else
423     {
424         CV_LOG_WARNING(NULL, "No UI backends available. Use OPENCV_LOG_LEVEL=DEBUG for investigation");
425     }
426     return Rect(-1, -1, -1, -1);
427 #else
428
429     #if defined (HAVE_QT)
430         return cvGetWindowRect_QT(name);
431     #elif defined(HAVE_WIN32UI)
432         return cvGetWindowRect_W32(name);
433     #elif defined (HAVE_GTK)
434         return cvGetWindowRect_GTK(name);
435     #elif defined (HAVE_COCOA)
436         return cvGetWindowRect_COCOA(name);
437     #else
438         return Rect(-1, -1, -1, -1);
439     #endif
440
441 #endif
442 }
443
444 cv::Rect cv::getWindowImageRect(const String& winname)
445 {
446     CV_TRACE_FUNCTION();
447     return cvGetWindowImageRect(winname.c_str());
448 }
449
450 void cv::namedWindow( const String& winname, int flags )
451 {
452     CV_TRACE_FUNCTION();
453     CV_Assert(!winname.empty());
454
455     {
456         cv::AutoLock lock(cv::getWindowMutex());
457         cleanupClosedWindows_();
458         auto& windowsMap = getWindowsMap();
459         auto i = windowsMap.find(winname);
460         if (i != windowsMap.end())
461         {
462             auto ui_base = i->second;
463             if (ui_base)
464             {
465                 auto window = std::dynamic_pointer_cast<UIWindow>(ui_base);
466                 if (!window)
467                 {
468                     CV_LOG_ERROR(NULL, "OpenCV/UI: Can't create window: '" << winname << "'");
469                 }
470                 return;
471             }
472         }
473         auto backend = getCurrentUIBackend();
474         if (backend)
475         {
476             auto window = backend->createWindow(winname, flags);
477             if (!window)
478             {
479                 CV_LOG_ERROR(NULL, "OpenCV/UI: Can't create window: '" << winname << "'");
480                 return;
481             }
482             windowsMap.emplace(winname, window);
483             return;
484         }
485     }
486
487     cvNamedWindow( winname.c_str(), flags );
488 }
489
490 void cv::destroyWindow( const String& winname )
491 {
492     CV_TRACE_FUNCTION();
493
494     {
495         auto window = findWindow_(winname);
496         if (window)
497         {
498             window->destroy();
499             cleanupClosedWindows_();
500             return;
501         }
502     }
503
504     cvDestroyWindow( winname.c_str() );
505 }
506
507 void cv::destroyAllWindows()
508 {
509     CV_TRACE_FUNCTION();
510
511     {
512         cv::AutoLock lock(cv::getWindowMutex());
513         auto backend = getCurrentUIBackend();
514         if (backend)
515         {
516             backend->destroyAllWindows();
517             cleanupClosedWindows_();
518             return;
519         }
520     }
521
522     cvDestroyAllWindows();
523 }
524
525 void cv::resizeWindow( const String& winname, int width, int height )
526 {
527     CV_TRACE_FUNCTION();
528
529     {
530         auto window = findWindow_(winname);
531         if (window)
532         {
533             return window->resize(width, height);
534         }
535     }
536
537 #if defined(OPENCV_HIGHGUI_WITHOUT_BUILTIN_BACKEND) && defined(ENABLE_PLUGINS)
538     auto backend = getCurrentUIBackend();
539     if (backend)
540     {
541         CV_LOG_WARNING(NULL, "Can't find window with name: '" << winname << "'. Do nothing");
542         CV_NOT_FOUND_DEPRECATION;
543     }
544     else
545     {
546         CV_LOG_WARNING(NULL, "No UI backends available. Use OPENCV_LOG_LEVEL=DEBUG for investigation");
547     }
548     return;
549 #else
550     cvResizeWindow( winname.c_str(), width, height );
551 #endif
552 }
553
554 void cv::resizeWindow(const String& winname, const cv::Size& size)
555 {
556    CV_TRACE_FUNCTION();
557    cvResizeWindow(winname.c_str(), size.width, size.height);
558 }
559
560 void cv::moveWindow( const String& winname, int x, int y )
561 {
562     CV_TRACE_FUNCTION();
563
564     {
565         auto window = findWindow_(winname);
566         if (window)
567         {
568             return window->move(x, y);
569         }
570     }
571
572 #if defined(OPENCV_HIGHGUI_WITHOUT_BUILTIN_BACKEND) && defined(ENABLE_PLUGINS)
573     auto backend = getCurrentUIBackend();
574     if (backend)
575     {
576         CV_LOG_WARNING(NULL, "Can't find window with name: '" << winname << "'. Do nothing");
577         CV_NOT_FOUND_DEPRECATION;
578     }
579     else
580     {
581         CV_LOG_WARNING(NULL, "No UI backends available. Use OPENCV_LOG_LEVEL=DEBUG for investigation");
582     }
583     return;
584 #else
585     cvMoveWindow( winname.c_str(), x, y );
586 #endif
587 }
588
589 void cv::setWindowProperty(const String& winname, int prop_id, double prop_value)
590 {
591     CV_TRACE_FUNCTION();
592     cvSetWindowProperty( winname.c_str(), prop_id, prop_value);
593 }
594
595 double cv::getWindowProperty(const String& winname, int prop_id)
596 {
597     CV_TRACE_FUNCTION();
598     return cvGetWindowProperty(winname.c_str(), prop_id);
599 }
600
601 int cv::waitKeyEx(int delay)
602 {
603     CV_TRACE_FUNCTION();
604
605     {
606         cv::AutoLock lock(cv::getWindowMutex());
607         auto backend = getCurrentUIBackend();
608         if (backend)
609         {
610             return backend->waitKeyEx(delay);
611         }
612     }
613
614     return cvWaitKey(delay);
615 }
616
617 int cv::waitKey(int delay)
618 {
619     CV_TRACE_FUNCTION();
620     int code = waitKeyEx(delay);
621 #ifndef WINRT
622     static int use_legacy = -1;
623     if (use_legacy < 0)
624     {
625         use_legacy = getenv("OPENCV_LEGACY_WAITKEY") != NULL ? 1 : 0;
626     }
627     if (use_legacy > 0)
628         return code;
629 #endif
630     return (code != -1) ? (code & 0xff) : -1;
631 }
632
633 #if defined(HAVE_QT) || (defined (WINRT) && !defined (WINRT_8_0)) || \
634     !defined(HAVE_WIN32UI) && (defined(HAVE_GTK) || defined(HAVE_COCOA))
635 // pollKey() fallback implementation
636 int cv::pollKey()
637 {
638     CV_TRACE_FUNCTION();
639
640     {
641         cv::AutoLock lock(cv::getWindowMutex());
642         auto backend = getCurrentUIBackend();
643         if (backend)
644         {
645             return backend->pollKey();
646         }
647     }
648
649     // fallback. please implement a proper polling function
650     return cvWaitKey(1);
651 }
652 #elif defined(HAVE_WIN32UI)
653 // pollKey() implemented in window_w32.cpp
654 #endif
655
656 int cv::createTrackbar(const String& trackbarName, const String& winName,
657                    int* value, int count, TrackbarCallback callback,
658                    void* userdata)
659 {
660     CV_TRACE_FUNCTION();
661
662     CV_LOG_IF_WARNING(NULL, value, "UI/Trackbar(" << trackbarName << "@" << winName << "): Using 'value' pointer is unsafe and deprecated. Use NULL as value pointer. "
663             "To fetch trackbar value setup callback.");
664
665     {
666         cv::AutoLock lock(cv::getWindowMutex());
667         auto window = findWindow_(winName);
668         if (window)
669         {
670             if (value)
671             {
672                 auto cb = std::make_shared<TrackbarCallbackWithData>(value, callback, userdata);
673                 auto trackbar = window->createTrackbar(trackbarName, count, TrackbarCallbackWithData::onChangeCallback, cb.get());
674                 if (!trackbar)
675                 {
676                     CV_LOG_ERROR(NULL, "OpenCV/UI: Can't create trackbar: '" << trackbarName << "'@'" << winName << "'");
677                     return 0;
678                 }
679                 cb->trackbar_ = trackbar;
680                 getTrackbarCallbacksWithData().emplace_back(cb);
681                 getWindowsMap().emplace(trackbar->getID(), trackbar);
682                 trackbar->setPos(*value);
683                 return 1;
684             }
685             else
686             {
687                 auto trackbar = window->createTrackbar(trackbarName, count, callback, userdata);
688                 if (!trackbar)
689                 {
690                     CV_LOG_ERROR(NULL, "OpenCV/UI: Can't create trackbar: '" << trackbarName << "'@'" << winName << "'");
691                     return 0;
692                 }
693                 getWindowsMap().emplace(trackbar->getID(), trackbar);
694                 return 1;
695             }
696         }
697     }
698
699 #if defined(OPENCV_HIGHGUI_WITHOUT_BUILTIN_BACKEND) && defined(ENABLE_PLUGINS)
700     auto backend = getCurrentUIBackend();
701     if (backend)
702     {
703         CV_LOG_WARNING(NULL, "Can't find window with name: '" << winName << "'. Do nothing");
704         CV_NOT_FOUND_DEPRECATION;
705     }
706     else
707     {
708         CV_LOG_WARNING(NULL, "No UI backends available. Use OPENCV_LOG_LEVEL=DEBUG for investigation");
709     }
710     return 0;
711 #else
712     return cvCreateTrackbar2(trackbarName.c_str(), winName.c_str(),
713                              value, count, callback, userdata);
714 #endif
715 }
716
717 void cv::setTrackbarPos( const String& trackbarName, const String& winName, int value )
718 {
719     CV_TRACE_FUNCTION();
720
721     {
722         cv::AutoLock lock(cv::getWindowMutex());
723         auto window = findWindow_(winName);
724         if (window)
725         {
726             auto trackbar = window->findTrackbar(trackbarName);
727             CV_Assert(trackbar);
728             return trackbar->setPos(value);
729         }
730     }
731
732 #if defined(OPENCV_HIGHGUI_WITHOUT_BUILTIN_BACKEND) && defined(ENABLE_PLUGINS)
733     auto backend = getCurrentUIBackend();
734     if (backend)
735     {
736         CV_LOG_WARNING(NULL, "Can't find window with name: '" << winName << "'. Do nothing");
737         CV_NOT_FOUND_DEPRECATION;
738     }
739     else
740     {
741         CV_LOG_WARNING(NULL, "No UI backends available. Use OPENCV_LOG_LEVEL=DEBUG for investigation");
742     }
743     return;
744 #else
745     cvSetTrackbarPos(trackbarName.c_str(), winName.c_str(), value );
746 #endif
747 }
748
749 void cv::setTrackbarMax(const String& trackbarName, const String& winName, int maxval)
750 {
751     CV_TRACE_FUNCTION();
752
753     {
754         cv::AutoLock lock(cv::getWindowMutex());
755         auto window = findWindow_(winName);
756         if (window)
757         {
758             auto trackbar = window->findTrackbar(trackbarName);
759             CV_Assert(trackbar);
760             Range old_range = trackbar->getRange();
761             Range range(std::min(old_range.start, maxval), maxval);
762             return trackbar->setRange(range);
763         }
764     }
765
766 #if defined(OPENCV_HIGHGUI_WITHOUT_BUILTIN_BACKEND) && defined(ENABLE_PLUGINS)
767     auto backend = getCurrentUIBackend();
768     if (backend)
769     {
770         CV_LOG_WARNING(NULL, "Can't find window with name: '" << winName << "'. Do nothing");
771         CV_NOT_FOUND_DEPRECATION;
772     }
773     else
774     {
775         CV_LOG_WARNING(NULL, "No UI backends available. Use OPENCV_LOG_LEVEL=DEBUG for investigation");
776     }
777     return;
778 #else
779     cvSetTrackbarMax(trackbarName.c_str(), winName.c_str(), maxval);
780 #endif
781 }
782
783 void cv::setTrackbarMin(const String& trackbarName, const String& winName, int minval)
784 {
785     CV_TRACE_FUNCTION();
786
787     {
788         cv::AutoLock lock(cv::getWindowMutex());
789         auto window = findWindow_(winName);
790         if (window)
791         {
792             auto trackbar = window->findTrackbar(trackbarName);
793             CV_Assert(trackbar);
794             Range old_range = trackbar->getRange();
795             Range range(minval, std::max(minval, old_range.end));
796             return trackbar->setRange(range);
797         }
798     }
799
800 #if defined(OPENCV_HIGHGUI_WITHOUT_BUILTIN_BACKEND) && defined(ENABLE_PLUGINS)
801     auto backend = getCurrentUIBackend();
802     if (backend)
803     {
804         CV_LOG_WARNING(NULL, "Can't find window with name: '" << winName << "'. Do nothing");
805         CV_NOT_FOUND_DEPRECATION;
806     }
807     else
808     {
809         CV_LOG_WARNING(NULL, "No UI backends available. Use OPENCV_LOG_LEVEL=DEBUG for investigation");
810     }
811     return;
812 #else
813     cvSetTrackbarMin(trackbarName.c_str(), winName.c_str(), minval);
814 #endif
815 }
816
817 int cv::getTrackbarPos( const String& trackbarName, const String& winName )
818 {
819     CV_TRACE_FUNCTION();
820
821     {
822         cv::AutoLock lock(cv::getWindowMutex());
823         auto window = findWindow_(winName);
824         if (window)
825         {
826             auto trackbar = window->findTrackbar(trackbarName);
827             CV_Assert(trackbar);
828             return trackbar->getPos();
829         }
830     }
831
832 #if defined(OPENCV_HIGHGUI_WITHOUT_BUILTIN_BACKEND) && defined(ENABLE_PLUGINS)
833     auto backend = getCurrentUIBackend();
834     if (backend)
835     {
836         CV_LOG_WARNING(NULL, "Can't find window with name: '" << winName << "'. Do nothing");
837         CV_NOT_FOUND_DEPRECATION;
838     }
839     else
840     {
841         CV_LOG_WARNING(NULL, "No UI backends available. Use OPENCV_LOG_LEVEL=DEBUG for investigation");
842     }
843     return -1;
844 #else
845     return cvGetTrackbarPos(trackbarName.c_str(), winName.c_str());
846 #endif
847 }
848
849 void cv::setMouseCallback( const String& windowName, MouseCallback onMouse, void* param)
850 {
851     CV_TRACE_FUNCTION();
852
853     {
854         cv::AutoLock lock(cv::getWindowMutex());
855         auto window = findWindow_(windowName);
856         if (window)
857         {
858             return window->setMouseCallback(onMouse, param);
859         }
860     }
861
862 #if defined(OPENCV_HIGHGUI_WITHOUT_BUILTIN_BACKEND) && defined(ENABLE_PLUGINS)
863     auto backend = getCurrentUIBackend();
864     if (backend)
865     {
866         CV_LOG_WARNING(NULL, "Can't find window with name: '" << windowName << "'. Do nothing");
867         CV_NOT_FOUND_DEPRECATION;
868     }
869     else
870     {
871         CV_LOG_WARNING(NULL, "No UI backends available. Use OPENCV_LOG_LEVEL=DEBUG for investigation");
872     }
873     return;
874 #else
875     cvSetMouseCallback(windowName.c_str(), onMouse, param);
876 #endif
877 }
878
879 int cv::getMouseWheelDelta( int flags )
880 {
881     CV_TRACE_FUNCTION();
882     return CV_GET_WHEEL_DELTA(flags);
883 }
884
885 int cv::startWindowThread()
886 {
887     CV_TRACE_FUNCTION();
888     return cvStartWindowThread();
889 }
890
891 // OpenGL support
892
893 void cv::setOpenGlDrawCallback(const String& name, OpenGlDrawCallback callback, void* userdata)
894 {
895     CV_TRACE_FUNCTION();
896     cvSetOpenGlDrawCallback(name.c_str(), callback, userdata);
897 }
898
899 void cv::setOpenGlContext(const String& windowName)
900 {
901     CV_TRACE_FUNCTION();
902     cvSetOpenGlContext(windowName.c_str());
903 }
904
905 void cv::updateWindow(const String& windowName)
906 {
907     CV_TRACE_FUNCTION();
908     cvUpdateWindow(windowName.c_str());
909 }
910
911 #ifdef HAVE_OPENGL
912 namespace
913 {
914     std::map<cv::String, cv::ogl::Texture2D> wndTexs;
915     std::map<cv::String, cv::ogl::Texture2D> ownWndTexs;
916     std::map<cv::String, cv::ogl::Buffer> ownWndBufs;
917
918     void glDrawTextureCallback(void* userdata)
919     {
920         cv::ogl::Texture2D* texObj = static_cast<cv::ogl::Texture2D*>(userdata);
921
922         cv::ogl::render(*texObj);
923     }
924 }
925 #endif // HAVE_OPENGL
926
927 void cv::imshow( const String& winname, InputArray _img )
928 {
929     CV_TRACE_FUNCTION();
930
931     {
932         cv::AutoLock lock(cv::getWindowMutex());
933         cleanupClosedWindows_();
934         auto& windowsMap = getWindowsMap();
935         auto i = windowsMap.find(winname);
936         if (i != windowsMap.end())
937         {
938             auto ui_base = i->second;
939             if (ui_base)
940             {
941                 auto window = std::dynamic_pointer_cast<UIWindow>(ui_base);
942                 if (!window)
943                 {
944                     CV_LOG_ERROR(NULL, "OpenCV/UI: invalid window name: '" << winname << "'");
945                 }
946                 return window->imshow(_img);
947             }
948         }
949         auto backend = getCurrentUIBackend();
950         if (backend)
951         {
952             auto window = backend->createWindow(winname, WINDOW_NORMAL);
953             if (!window)
954             {
955                 CV_LOG_ERROR(NULL, "OpenCV/UI: Can't create window: '" << winname << "'");
956                 return;
957             }
958             windowsMap.emplace(winname, window);
959             return window->imshow(_img);
960         }
961     }
962
963     const Size size = _img.size();
964 #ifndef HAVE_OPENGL
965     CV_Assert(size.width>0 && size.height>0);
966     {
967         Mat img = _img.getMat();
968         CvMat c_img = cvMat(img);
969         cvShowImage(winname.c_str(), &c_img);
970     }
971 #else
972     const double useGl = getWindowProperty(winname, WND_PROP_OPENGL);
973     CV_Assert(size.width>0 && size.height>0);
974
975     if (useGl <= 0)
976     {
977         Mat img = _img.getMat();
978         CvMat c_img = cvMat(img);
979         cvShowImage(winname.c_str(), &c_img);
980     }
981     else
982     {
983         const double autoSize = getWindowProperty(winname, WND_PROP_AUTOSIZE);
984
985         if (autoSize > 0)
986         {
987             resizeWindow(winname, size.width, size.height);
988         }
989
990         setOpenGlContext(winname);
991
992         cv::ogl::Texture2D& tex = ownWndTexs[winname];
993
994         if (_img.kind() == _InputArray::CUDA_GPU_MAT)
995         {
996             cv::ogl::Buffer& buf = ownWndBufs[winname];
997             buf.copyFrom(_img);
998             buf.setAutoRelease(false);
999
1000             tex.copyFrom(buf);
1001             tex.setAutoRelease(false);
1002         }
1003         else
1004         {
1005             tex.copyFrom(_img);
1006         }
1007
1008         tex.setAutoRelease(false);
1009
1010         setOpenGlDrawCallback(winname, glDrawTextureCallback, &tex);
1011
1012         updateWindow(winname);
1013     }
1014 #endif
1015 }
1016
1017 void cv::imshow(const String& winname, const ogl::Texture2D& _tex)
1018 {
1019     CV_TRACE_FUNCTION();
1020 #ifndef HAVE_OPENGL
1021     CV_UNUSED(winname);
1022     CV_UNUSED(_tex);
1023     CV_Error(cv::Error::OpenGlNotSupported, "The library is compiled without OpenGL support");
1024 #else
1025     const double useGl = getWindowProperty(winname, WND_PROP_OPENGL);
1026
1027     if (useGl <= 0)
1028     {
1029         CV_Error(cv::Error::OpenGlNotSupported, "The window was created without OpenGL context");
1030     }
1031     else
1032     {
1033         const double autoSize = getWindowProperty(winname, WND_PROP_AUTOSIZE);
1034
1035         if (autoSize > 0)
1036         {
1037             Size size = _tex.size();
1038             resizeWindow(winname, size.width, size.height);
1039         }
1040
1041         setOpenGlContext(winname);
1042
1043         cv::ogl::Texture2D& tex = wndTexs[winname];
1044
1045         tex = _tex;
1046
1047         tex.setAutoRelease(false);
1048
1049         setOpenGlDrawCallback(winname, glDrawTextureCallback, &tex);
1050
1051         updateWindow(winname);
1052     }
1053 #endif
1054 }
1055
1056 // Without OpenGL
1057
1058 #ifndef HAVE_OPENGL
1059
1060 CV_IMPL void cvSetOpenGlDrawCallback(const char*, CvOpenGlDrawCallback, void*)
1061 {
1062     CV_Error(CV_OpenGlNotSupported, "The library is compiled without OpenGL support");
1063 }
1064
1065 CV_IMPL void cvSetOpenGlContext(const char*)
1066 {
1067     CV_Error(CV_OpenGlNotSupported, "The library is compiled without OpenGL support");
1068 }
1069
1070 CV_IMPL void cvUpdateWindow(const char*)
1071 {
1072     CV_Error(CV_OpenGlNotSupported, "The library is compiled without OpenGL support");
1073 }
1074
1075 #endif // !HAVE_OPENGL
1076
1077 #if defined (HAVE_QT)
1078
1079 cv::QtFont cv::fontQt(const String& nameFont, int pointSize, Scalar color, int weight, int style, int spacing)
1080 {
1081     CvFont f = cvFontQt(nameFont.c_str(), pointSize, cvScalar(color), weight, style, spacing);
1082     void* pf = &f; // to suppress strict-aliasing
1083     return *(cv::QtFont*)pf;
1084 }
1085
1086 void cv::addText( const Mat& img, const String& text, Point org, const QtFont& font)
1087 {
1088     CvMat _img = cvMat(img);
1089     cvAddText( &_img, text.c_str(), cvPoint(org), (CvFont*)&font);
1090 }
1091
1092 void cv::addText( const Mat& img, const String& text, Point org, const String& nameFont,
1093         int pointSize, Scalar color, int weight, int style, int spacing)
1094 {
1095     CvFont f = cvFontQt(nameFont.c_str(), pointSize, cvScalar(color), weight, style, spacing);
1096     CvMat _img = cvMat(img);
1097     cvAddText( &_img, text.c_str(), cvPoint(org), &f);
1098 }
1099
1100 void cv::displayStatusBar(const String& name,  const String& text, int delayms)
1101 {
1102     cvDisplayStatusBar(name.c_str(),text.c_str(), delayms);
1103 }
1104
1105 void cv::displayOverlay(const String& name,  const String& text, int delayms)
1106 {
1107     cvDisplayOverlay(name.c_str(),text.c_str(), delayms);
1108 }
1109
1110 int cv::startLoop(int (*pt2Func)(int argc, char *argv[]), int argc, char* argv[])
1111 {
1112     return cvStartLoop(pt2Func, argc, argv);
1113 }
1114
1115 void cv::stopLoop()
1116 {
1117     cvStopLoop();
1118 }
1119
1120 void cv::saveWindowParameters(const String& windowName)
1121 {
1122     cvSaveWindowParameters(windowName.c_str());
1123 }
1124
1125 void cv::loadWindowParameters(const String& windowName)
1126 {
1127     cvLoadWindowParameters(windowName.c_str());
1128 }
1129
1130 int cv::createButton(const String& button_name, ButtonCallback on_change, void* userdata, int button_type , bool initial_button_state  )
1131 {
1132     return cvCreateButton(button_name.c_str(), on_change, userdata, button_type , initial_button_state );
1133 }
1134
1135 #else
1136
1137 static const char* NO_QT_ERR_MSG = "The library is compiled without QT support";
1138
1139 cv::QtFont cv::fontQt(const String&, int, Scalar, int,  int, int)
1140 {
1141     CV_Error(CV_StsNotImplemented, NO_QT_ERR_MSG);
1142 }
1143
1144 void cv::addText( const Mat&, const String&, Point, const QtFont&)
1145 {
1146     CV_Error(CV_StsNotImplemented, NO_QT_ERR_MSG);
1147 }
1148
1149 void cv::addText(const Mat&, const String&, Point, const String&, int, Scalar, int, int, int)
1150 {
1151     CV_Error(CV_StsNotImplemented, NO_QT_ERR_MSG);
1152 }
1153
1154 void cv::displayStatusBar(const String&,  const String&, int)
1155 {
1156     CV_Error(CV_StsNotImplemented, NO_QT_ERR_MSG);
1157 }
1158
1159 void cv::displayOverlay(const String&,  const String&, int )
1160 {
1161     CV_Error(CV_StsNotImplemented, NO_QT_ERR_MSG);
1162 }
1163
1164 int cv::startLoop(int (*)(int argc, char *argv[]), int , char**)
1165 {
1166     CV_Error(CV_StsNotImplemented, NO_QT_ERR_MSG);
1167 }
1168
1169 void cv::stopLoop()
1170 {
1171     CV_Error(CV_StsNotImplemented, NO_QT_ERR_MSG);
1172 }
1173
1174 void cv::saveWindowParameters(const String&)
1175 {
1176     CV_Error(CV_StsNotImplemented, NO_QT_ERR_MSG);
1177 }
1178
1179 void cv::loadWindowParameters(const String&)
1180 {
1181     CV_Error(CV_StsNotImplemented, NO_QT_ERR_MSG);
1182 }
1183
1184 int cv::createButton(const String&, ButtonCallback, void*, int , bool )
1185 {
1186     CV_Error(CV_StsNotImplemented, NO_QT_ERR_MSG);
1187 }
1188
1189 #endif
1190
1191 #if   defined (HAVE_WIN32UI)  // see window_w32.cpp
1192 #elif defined (HAVE_GTK)      // see window_gtk.cpp
1193 #elif defined (HAVE_COCOA)    // see window_cocoa.mm
1194 #elif defined (HAVE_QT)       // see window_QT.cpp
1195 #elif defined (WINRT) && !defined (WINRT_8_0) // see window_winrt.cpp
1196
1197 #else
1198
1199 // No windowing system present at compile time ;-(
1200 //
1201 // We will build place holders that don't break the API but give an error
1202 // at runtime. This way people can choose to replace an installed HighGUI
1203 // version with a more capable one without a need to recompile dependent
1204 // applications or libraries.
1205
1206 void cv::setWindowTitle(const String&, const String&)
1207 {
1208     CV_Error(Error::StsNotImplemented, "The function is not implemented. "
1209         "Rebuild the library with Windows, GTK+ 2.x or Cocoa support. "
1210         "If you are on Ubuntu or Debian, install libgtk2.0-dev and pkg-config, then re-run cmake or configure script");
1211 }
1212
1213 #define CV_NO_GUI_ERROR(funcname) \
1214     cv::error(cv::Error::StsError, \
1215     "The function is not implemented. " \
1216     "Rebuild the library with Windows, GTK+ 2.x or Cocoa support. "\
1217     "If you are on Ubuntu or Debian, install libgtk2.0-dev and pkg-config, then re-run cmake or configure script", \
1218     funcname, __FILE__, __LINE__)
1219
1220
1221 CV_IMPL int cvNamedWindow( const char*, int )
1222 {
1223     CV_NO_GUI_ERROR("cvNamedWindow");
1224 }
1225
1226 CV_IMPL void cvDestroyWindow( const char* )
1227 {
1228     CV_NO_GUI_ERROR( "cvDestroyWindow" );
1229 }
1230
1231 CV_IMPL void
1232 cvDestroyAllWindows( void )
1233 {
1234     CV_NO_GUI_ERROR( "cvDestroyAllWindows" );
1235 }
1236
1237 CV_IMPL void
1238 cvShowImage( const char*, const CvArr* )
1239 {
1240     CV_NO_GUI_ERROR( "cvShowImage" );
1241 }
1242
1243 CV_IMPL void cvResizeWindow( const char*, int, int )
1244 {
1245     CV_NO_GUI_ERROR( "cvResizeWindow" );
1246 }
1247
1248 CV_IMPL void cvMoveWindow( const char*, int, int )
1249 {
1250     CV_NO_GUI_ERROR( "cvMoveWindow" );
1251 }
1252
1253 CV_IMPL int
1254 cvCreateTrackbar( const char*, const char*,
1255                   int*, int, CvTrackbarCallback )
1256 {
1257     CV_NO_GUI_ERROR( "cvCreateTrackbar" );
1258 }
1259
1260 CV_IMPL int
1261 cvCreateTrackbar2( const char* /*trackbar_name*/, const char* /*window_name*/,
1262                    int* /*val*/, int /*count*/, CvTrackbarCallback2 /*on_notify2*/,
1263                    void* /*userdata*/ )
1264 {
1265     CV_NO_GUI_ERROR( "cvCreateTrackbar2" );
1266 }
1267
1268 CV_IMPL void
1269 cvSetMouseCallback( const char*, CvMouseCallback, void* )
1270 {
1271     CV_NO_GUI_ERROR( "cvSetMouseCallback" );
1272 }
1273
1274 CV_IMPL int cvGetTrackbarPos( const char*, const char* )
1275 {
1276     CV_NO_GUI_ERROR( "cvGetTrackbarPos" );
1277 }
1278
1279 CV_IMPL void cvSetTrackbarPos( const char*, const char*, int )
1280 {
1281     CV_NO_GUI_ERROR( "cvSetTrackbarPos" );
1282 }
1283
1284 CV_IMPL void cvSetTrackbarMax(const char*, const char*, int)
1285 {
1286     CV_NO_GUI_ERROR( "cvSetTrackbarMax" );
1287 }
1288
1289 CV_IMPL void cvSetTrackbarMin(const char*, const char*, int)
1290 {
1291     CV_NO_GUI_ERROR( "cvSetTrackbarMin" );
1292 }
1293
1294 CV_IMPL void* cvGetWindowHandle( const char* )
1295 {
1296     CV_NO_GUI_ERROR( "cvGetWindowHandle" );
1297 }
1298
1299 CV_IMPL const char* cvGetWindowName( void* )
1300 {
1301     CV_NO_GUI_ERROR( "cvGetWindowName" );
1302 }
1303
1304 CV_IMPL int cvWaitKey( int )
1305 {
1306     CV_NO_GUI_ERROR( "cvWaitKey" );
1307 }
1308
1309 CV_IMPL int cvInitSystem( int , char** )
1310 {
1311
1312     CV_NO_GUI_ERROR( "cvInitSystem" );
1313 }
1314
1315 CV_IMPL int cvStartWindowThread()
1316 {
1317
1318     CV_NO_GUI_ERROR( "cvStartWindowThread" );
1319 }
1320
1321 //-------- Qt ---------
1322 CV_IMPL void cvAddText( const CvArr*, const char*, CvPoint , CvFont* )
1323 {
1324     CV_NO_GUI_ERROR("cvAddText");
1325 }
1326
1327 CV_IMPL void cvDisplayStatusBar(const char* , const char* , int )
1328 {
1329     CV_NO_GUI_ERROR("cvDisplayStatusBar");
1330 }
1331
1332 CV_IMPL void cvDisplayOverlay(const char* , const char* , int )
1333 {
1334     CV_NO_GUI_ERROR("cvNamedWindow");
1335 }
1336
1337 CV_IMPL int cvStartLoop(int (*)(int argc, char *argv[]), int , char* argv[])
1338 {
1339     CV_UNUSED(argv);
1340     CV_NO_GUI_ERROR("cvStartLoop");
1341 }
1342
1343 CV_IMPL void cvStopLoop()
1344 {
1345     CV_NO_GUI_ERROR("cvStopLoop");
1346 }
1347
1348 CV_IMPL void cvSaveWindowParameters(const char* )
1349 {
1350     CV_NO_GUI_ERROR("cvSaveWindowParameters");
1351 }
1352
1353 // CV_IMPL void cvLoadWindowParameterss(const char* name)
1354 // {
1355 //     CV_NO_GUI_ERROR("cvLoadWindowParameters");
1356 // }
1357
1358 CV_IMPL int cvCreateButton(const char*, void (*)(int, void*), void*, int, int)
1359 {
1360     CV_NO_GUI_ERROR("cvCreateButton");
1361 }
1362
1363 int cv::pollKey()
1364 {
1365     CV_NO_GUI_ERROR("cv::pollKey()");
1366 }
1367
1368 #endif
1369
1370 /* End of file. */