1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40#include "qvideowidget_p.h"
41#include "qpaintervideosurface_p.h"
42
43#include <qmediaobject.h>
44#include <qmediaservice.h>
45#include <qvideowindowcontrol.h>
46#include <qvideowidgetcontrol.h>
47
48#include <qvideorenderercontrol.h>
49#include <qvideosurfaceformat.h>
50#include <qpainter.h>
51
52#include <qapplication.h>
53#include <qevent.h>
54#include <qboxlayout.h>
55#include <qnamespace.h>
56
57#include <qwindow.h>
58#include <private/qhighdpiscaling_p.h>
59
60#ifdef Q_OS_WIN
61#include <QtCore/qt_windows.h>
62#endif
63
64using namespace Qt;
65
66QT_BEGIN_NAMESPACE
67
68QVideoWidgetControlBackend::QVideoWidgetControlBackend(
69 QMediaService *service, QVideoWidgetControl *control, QWidget *widget)
70 : m_service(service)
71 , m_widgetControl(control)
72{
73 connect(sender: control, SIGNAL(brightnessChanged(int)), receiver: widget, SLOT(_q_brightnessChanged(int)));
74 connect(sender: control, SIGNAL(contrastChanged(int)), receiver: widget, SLOT(_q_contrastChanged(int)));
75 connect(sender: control, SIGNAL(hueChanged(int)), receiver: widget, SLOT(_q_hueChanged(int)));
76 connect(sender: control, SIGNAL(saturationChanged(int)), receiver: widget, SLOT(_q_saturationChanged(int)));
77 connect(sender: control, SIGNAL(fullScreenChanged(bool)), receiver: widget, SLOT(_q_fullScreenChanged(bool)));
78
79 QBoxLayout *layout = new QVBoxLayout;
80 layout->setContentsMargins(left: 0, top: 0, right: 0, bottom: 0);
81 layout->setSpacing(0);
82
83 QWidget *videoWidget = control->videoWidget();
84 videoWidget->setMouseTracking(widget->hasMouseTracking());
85 layout->addWidget(videoWidget);
86
87 widget->setLayout(layout);
88}
89
90void QVideoWidgetControlBackend::releaseControl()
91{
92 m_service->releaseControl(control: m_widgetControl);
93}
94
95void QVideoWidgetControlBackend::setBrightness(int brightness)
96{
97 m_widgetControl->setBrightness(brightness);
98}
99
100void QVideoWidgetControlBackend::setContrast(int contrast)
101{
102 m_widgetControl->setContrast(contrast);
103}
104
105void QVideoWidgetControlBackend::setHue(int hue)
106{
107 m_widgetControl->setHue(hue);
108}
109
110void QVideoWidgetControlBackend::setSaturation(int saturation)
111{
112 m_widgetControl->setSaturation(saturation);
113}
114
115void QVideoWidgetControlBackend::setFullScreen(bool fullScreen)
116{
117 m_widgetControl->setFullScreen(fullScreen);
118}
119
120
121Qt::AspectRatioMode QVideoWidgetControlBackend::aspectRatioMode() const
122{
123 return m_widgetControl->aspectRatioMode();
124}
125
126void QVideoWidgetControlBackend::setAspectRatioMode(Qt::AspectRatioMode mode)
127{
128 m_widgetControl->setAspectRatioMode(mode);
129}
130
131QRendererVideoWidgetBackend::QRendererVideoWidgetBackend(
132 QMediaService *service, QVideoRendererControl *control, QWidget *widget)
133 : m_service(service)
134 , m_rendererControl(control)
135 , m_widget(widget)
136 , m_surface(new QPainterVideoSurface)
137 , m_aspectRatioMode(Qt::KeepAspectRatio)
138 , m_updatePaintDevice(true)
139{
140 connect(sender: this, SIGNAL(brightnessChanged(int)), receiver: m_widget, SLOT(_q_brightnessChanged(int)));
141 connect(sender: this, SIGNAL(contrastChanged(int)), receiver: m_widget, SLOT(_q_contrastChanged(int)));
142 connect(sender: this, SIGNAL(hueChanged(int)), receiver: m_widget, SLOT(_q_hueChanged(int)));
143 connect(sender: this, SIGNAL(saturationChanged(int)), receiver: m_widget, SLOT(_q_saturationChanged(int)));
144 connect(sender: m_surface, SIGNAL(frameChanged()), receiver: this, SLOT(frameChanged()));
145 connect(sender: m_surface, SIGNAL(surfaceFormatChanged(QVideoSurfaceFormat)),
146 receiver: this, SLOT(formatChanged(QVideoSurfaceFormat)));
147
148 if (m_rendererControl)
149 m_rendererControl->setSurface(m_surface);
150}
151
152QRendererVideoWidgetBackend::~QRendererVideoWidgetBackend()
153{
154 delete m_surface;
155}
156
157QAbstractVideoSurface *QRendererVideoWidgetBackend::videoSurface() const
158{
159 return m_surface;
160}
161
162void QRendererVideoWidgetBackend::releaseControl()
163{
164 if (m_service && m_rendererControl)
165 m_service->releaseControl(control: m_rendererControl);
166}
167
168void QRendererVideoWidgetBackend::clearSurface()
169{
170 if (m_rendererControl)
171 m_rendererControl->setSurface(0);
172}
173
174void QRendererVideoWidgetBackend::setBrightness(int brightness)
175{
176 m_surface->setBrightness(brightness);
177
178 emit brightnessChanged(brightness);
179}
180
181void QRendererVideoWidgetBackend::setContrast(int contrast)
182{
183 m_surface->setContrast(contrast);
184
185 emit contrastChanged(contrast);
186}
187
188void QRendererVideoWidgetBackend::setHue(int hue)
189{
190 m_surface->setHue(hue);
191
192 emit hueChanged(hue);
193}
194
195void QRendererVideoWidgetBackend::setSaturation(int saturation)
196{
197 m_surface->setSaturation(saturation);
198
199 emit saturationChanged(saturation);
200}
201
202Qt::AspectRatioMode QRendererVideoWidgetBackend::aspectRatioMode() const
203{
204 return m_aspectRatioMode;
205}
206
207void QRendererVideoWidgetBackend::setAspectRatioMode(Qt::AspectRatioMode mode)
208{
209 m_aspectRatioMode = mode;
210
211 m_widget->updateGeometry();
212}
213
214void QRendererVideoWidgetBackend::setFullScreen(bool)
215{
216}
217
218QSize QRendererVideoWidgetBackend::sizeHint() const
219{
220 return m_surface->surfaceFormat().sizeHint();
221}
222
223void QRendererVideoWidgetBackend::showEvent()
224{
225}
226
227void QRendererVideoWidgetBackend::hideEvent(QHideEvent *)
228{
229#if QT_CONFIG(opengl)
230 m_updatePaintDevice = true;
231#endif
232}
233
234void QRendererVideoWidgetBackend::resizeEvent(QResizeEvent *)
235{
236 updateRects();
237}
238
239void QRendererVideoWidgetBackend::moveEvent(QMoveEvent *)
240{
241}
242
243void QRendererVideoWidgetBackend::paintEvent(QPaintEvent *event)
244{
245 QPainter painter(m_widget);
246
247 if (m_widget->testAttribute(attribute: Qt::WA_OpaquePaintEvent)) {
248 QRegion borderRegion = event->region();
249 borderRegion = borderRegion.subtracted(r: m_boundingRect);
250
251 QBrush brush = m_widget->palette().window();
252
253 for (const QRect &r : borderRegion)
254 painter.fillRect(r, brush);
255 }
256
257 if (m_surface->isActive() && m_boundingRect.intersects(r: event->rect())) {
258 m_surface->paint(painter: &painter, target: m_boundingRect, source: m_sourceRect);
259
260 m_surface->setReady(true);
261 } else {
262#if QT_CONFIG(opengl)
263 if (m_updatePaintDevice && (painter.paintEngine()->type() == QPaintEngine::OpenGL
264 || painter.paintEngine()->type() == QPaintEngine::OpenGL2)) {
265 m_updatePaintDevice = false;
266
267 m_surface->updateGLContext();
268 if (m_surface->supportedShaderTypes() & QPainterVideoSurface::GlslShader) {
269 m_surface->setShaderType(QPainterVideoSurface::GlslShader);
270 } else {
271 m_surface->setShaderType(QPainterVideoSurface::FragmentProgramShader);
272 }
273 }
274#endif
275 }
276
277}
278
279void QRendererVideoWidgetBackend::formatChanged(const QVideoSurfaceFormat &format)
280{
281 m_nativeSize = format.sizeHint();
282
283 updateRects();
284
285 m_widget->updateGeometry();
286 m_widget->update();
287}
288
289void QRendererVideoWidgetBackend::frameChanged()
290{
291 m_widget->update(m_boundingRect);
292}
293
294void QRendererVideoWidgetBackend::updateRects()
295{
296 QRect rect = m_widget->rect();
297
298 if (m_nativeSize.isEmpty()) {
299 m_boundingRect = QRect();
300 } else if (m_aspectRatioMode == Qt::IgnoreAspectRatio) {
301 m_boundingRect = rect;
302 m_sourceRect = QRectF(0, 0, 1, 1);
303 } else if (m_aspectRatioMode == Qt::KeepAspectRatio) {
304 QSize size = m_nativeSize;
305 size.scale(s: rect.size(), mode: Qt::KeepAspectRatio);
306
307 m_boundingRect = QRect(0, 0, size.width(), size.height());
308 m_boundingRect.moveCenter(p: rect.center());
309
310 m_sourceRect = QRectF(0, 0, 1, 1);
311 } else if (m_aspectRatioMode == Qt::KeepAspectRatioByExpanding) {
312 m_boundingRect = rect;
313
314 QSizeF size = rect.size();
315 size.scale(s: m_nativeSize, mode: Qt::KeepAspectRatio);
316
317 m_sourceRect = QRectF(
318 0, 0, size.width() / m_nativeSize.width(), size.height() / m_nativeSize.height());
319 m_sourceRect.moveCenter(p: QPointF(0.5, 0.5));
320 }
321}
322
323QWindowVideoWidgetBackend::QWindowVideoWidgetBackend(
324 QMediaService *service, QVideoWindowControl *control, QWidget *widget)
325 : m_service(service)
326 , m_windowControl(control)
327 , m_widget(widget)
328{
329 connect(sender: control, SIGNAL(brightnessChanged(int)), receiver: m_widget, SLOT(_q_brightnessChanged(int)));
330 connect(sender: control, SIGNAL(contrastChanged(int)), receiver: m_widget, SLOT(_q_contrastChanged(int)));
331 connect(sender: control, SIGNAL(hueChanged(int)), receiver: m_widget, SLOT(_q_hueChanged(int)));
332 connect(sender: control, SIGNAL(saturationChanged(int)), receiver: m_widget, SLOT(_q_saturationChanged(int)));
333 connect(sender: control, SIGNAL(fullScreenChanged(bool)), receiver: m_widget, SLOT(_q_fullScreenChanged(bool)));
334 connect(sender: control, SIGNAL(nativeSizeChanged()), receiver: m_widget, SLOT(_q_dimensionsChanged()));
335
336 control->setWinId(widget->winId());
337#if defined(Q_OS_WIN)
338 // Disable updates to avoid flickering while resizing/moving.
339 m_widget->setUpdatesEnabled(false);
340#endif
341}
342
343QWindowVideoWidgetBackend::~QWindowVideoWidgetBackend()
344{
345}
346
347void QWindowVideoWidgetBackend::releaseControl()
348{
349 m_service->releaseControl(control: m_windowControl);
350}
351
352void QWindowVideoWidgetBackend::setBrightness(int brightness)
353{
354 m_windowControl->setBrightness(brightness);
355}
356
357void QWindowVideoWidgetBackend::setContrast(int contrast)
358{
359 m_windowControl->setContrast(contrast);
360}
361
362void QWindowVideoWidgetBackend::setHue(int hue)
363{
364 m_windowControl->setHue(hue);
365}
366
367void QWindowVideoWidgetBackend::setSaturation(int saturation)
368{
369 m_windowControl->setSaturation(saturation);
370}
371
372void QWindowVideoWidgetBackend::setFullScreen(bool fullScreen)
373{
374 m_windowControl->setFullScreen(fullScreen);
375}
376
377Qt::AspectRatioMode QWindowVideoWidgetBackend::aspectRatioMode() const
378{
379 return m_windowControl->aspectRatioMode();
380}
381
382void QWindowVideoWidgetBackend::setAspectRatioMode(Qt::AspectRatioMode mode)
383{
384 m_windowControl->setAspectRatioMode(mode);
385}
386
387QSize QWindowVideoWidgetBackend::sizeHint() const
388{
389 return m_windowControl->nativeSize();
390}
391
392void QWindowVideoWidgetBackend::updateDisplayRect()
393{
394 QRect rect = m_widget->rect();
395 if (QHighDpiScaling::isActive()) {
396 const qreal factor = QHighDpiScaling::factor(context: m_widget->windowHandle());
397 if (!qFuzzyCompare(p1: factor, p2: qreal(1))) {
398 rect = QRectF(QPointF(rect.topLeft()) * factor,
399 QSizeF(rect.size()) * factor).toRect();
400 }
401 }
402 m_windowControl->setDisplayRect(rect);
403}
404
405void QWindowVideoWidgetBackend::showEvent()
406{
407 m_windowControl->setWinId(m_widget->winId());
408 updateDisplayRect();
409
410#if defined(Q_OS_WIN)
411 m_windowControl->repaint();
412#endif
413}
414
415void QWindowVideoWidgetBackend::hideEvent(QHideEvent *)
416{
417}
418
419void QWindowVideoWidgetBackend::moveEvent(QMoveEvent *)
420{
421 updateDisplayRect();
422}
423
424void QWindowVideoWidgetBackend::resizeEvent(QResizeEvent *)
425{
426 updateDisplayRect();
427}
428
429void QWindowVideoWidgetBackend::paintEvent(QPaintEvent *event)
430{
431 if (m_widget->testAttribute(attribute: Qt::WA_OpaquePaintEvent)) {
432 QPainter painter(m_widget);
433
434 painter.fillRect(event->rect(), m_widget->palette().window());
435 }
436
437 m_windowControl->repaint();
438
439 event->accept();
440}
441
442void QVideoWidgetPrivate::setCurrentControl(QVideoWidgetControlInterface *control)
443{
444 if (currentControl != control) {
445 currentControl = control;
446
447 currentControl->setBrightness(brightness);
448 currentControl->setContrast(contrast);
449 currentControl->setHue(hue);
450 currentControl->setSaturation(saturation);
451 currentControl->setAspectRatioMode(aspectRatioMode);
452 }
453}
454
455void QVideoWidgetPrivate::clearService()
456{
457 if (service) {
458 QObject::disconnect(sender: service, SIGNAL(destroyed()), receiver: q_func(), SLOT(_q_serviceDestroyed()));
459
460 if (widgetBackend) {
461 QLayout *layout = q_func()->layout();
462
463 for (QLayoutItem *item = layout->takeAt(index: 0); item; item = layout->takeAt(index: 0)) {
464 item->widget()->setParent(0);
465 delete item;
466 }
467 delete layout;
468
469 widgetBackend->releaseControl();
470
471 delete widgetBackend;
472 widgetBackend = 0;
473 } else if (rendererBackend) {
474 rendererBackend->clearSurface();
475 rendererBackend->releaseControl();
476
477 delete rendererBackend;
478 rendererBackend = 0;
479 } else if (windowBackend) {
480 windowBackend->releaseControl();
481
482 delete windowBackend;
483 windowBackend = 0;
484 }
485
486 currentBackend = 0;
487 currentControl = 0;
488 service = 0;
489 }
490}
491
492bool QVideoWidgetPrivate::createWidgetBackend()
493{
494 if (QMediaControl *control = service->requestControl(QVideoWidgetControl_iid)) {
495 if (QVideoWidgetControl *widgetControl = qobject_cast<QVideoWidgetControl *>(object: control)) {
496 widgetBackend = new QVideoWidgetControlBackend(service, widgetControl, q_func());
497
498 setCurrentControl(widgetBackend);
499
500 return true;
501 }
502 service->releaseControl(control);
503 }
504 return false;
505}
506
507bool QVideoWidgetPrivate::createWindowBackend()
508{
509 if (QMediaControl *control = service->requestControl(QVideoWindowControl_iid)) {
510 if (QVideoWindowControl *windowControl = qobject_cast<QVideoWindowControl *>(object: control)) {
511 windowBackend = new QWindowVideoWidgetBackend(service, windowControl, q_func());
512 currentBackend = windowBackend;
513
514 setCurrentControl(windowBackend);
515
516 return true;
517 }
518 service->releaseControl(control);
519 }
520 return false;
521}
522
523bool QVideoWidgetPrivate::createRendererBackend()
524{
525 QMediaControl *control = service
526 ? service->requestControl(QVideoRendererControl_iid)
527 : nullptr;
528 rendererBackend = new QRendererVideoWidgetBackend(service,
529 qobject_cast<QVideoRendererControl *>(object: control), q_func());
530 currentBackend = rendererBackend;
531 setCurrentControl(rendererBackend);
532
533 return !service || (service && control);
534}
535
536void QVideoWidgetPrivate::_q_serviceDestroyed()
537{
538 if (widgetBackend)
539 delete q_func()->layout();
540
541 delete widgetBackend;
542 delete windowBackend;
543 delete rendererBackend;
544
545 widgetBackend = 0;
546 windowBackend = 0;
547 rendererBackend = 0;
548 currentControl = 0;
549 currentBackend = 0;
550 service = 0;
551}
552
553void QVideoWidgetPrivate::_q_brightnessChanged(int b)
554{
555 if (b != brightness)
556 emit q_func()->brightnessChanged(brightness: brightness = b);
557}
558
559void QVideoWidgetPrivate::_q_contrastChanged(int c)
560{
561 if (c != contrast)
562 emit q_func()->contrastChanged(contrast: contrast = c);
563}
564
565void QVideoWidgetPrivate::_q_hueChanged(int h)
566{
567 if (h != hue)
568 emit q_func()->hueChanged(hue: hue = h);
569}
570
571void QVideoWidgetPrivate::_q_saturationChanged(int s)
572{
573 if (s != saturation)
574 emit q_func()->saturationChanged(saturation: saturation = s);
575}
576
577
578void QVideoWidgetPrivate::_q_fullScreenChanged(bool fullScreen)
579{
580 if (!fullScreen && q_func()->isFullScreen())
581 q_func()->showNormal();
582}
583
584void QVideoWidgetPrivate::_q_dimensionsChanged()
585{
586 q_func()->updateGeometry();
587 q_func()->update();
588}
589
590/*!
591 \class QVideoWidget
592
593
594 \brief The QVideoWidget class provides a widget which presents video
595 produced by a media object.
596 \ingroup multimedia
597 \inmodule QtMultimediaWidgets
598
599 Attaching a QVideoWidget to a QMediaObject allows it to display the
600 video or image output of that media object. A QVideoWidget is attached
601 to media object by passing a pointer to the QMediaObject in its
602 constructor, and detached by destroying the QVideoWidget.
603
604 \snippet multimedia-snippets/video.cpp Video widget
605
606 \b {Note}: Only a single display output can be attached to a media
607 object at one time.
608
609 \sa QMediaObject, QMediaPlayer, QGraphicsVideoItem
610*/
611
612/*!
613 Constructs a new video widget.
614
615 The \a parent is passed to QWidget.
616*/
617QVideoWidget::QVideoWidget(QWidget *parent)
618 : QWidget(parent, {})
619 , d_ptr(new QVideoWidgetPrivate)
620{
621 d_ptr->q_ptr = this;
622}
623
624/*!
625 \internal
626*/
627QVideoWidget::QVideoWidget(QVideoWidgetPrivate &dd, QWidget *parent)
628 : QWidget(parent, {})
629 , d_ptr(&dd)
630{
631 d_ptr->q_ptr = this;
632
633 QPalette palette = QWidget::palette();
634 palette.setColor(acr: QPalette::Window, acolor: Qt::black);
635 setPalette(palette);
636}
637
638/*!
639 Destroys a video widget.
640*/
641QVideoWidget::~QVideoWidget()
642{
643 d_ptr->clearService();
644
645 delete d_ptr;
646}
647
648/*!
649 \property QVideoWidget::mediaObject
650 \brief the media object which provides the video displayed by a widget.
651*/
652
653QMediaObject *QVideoWidget::mediaObject() const
654{
655 return d_func()->mediaObject;
656}
657
658/*!
659 \internal
660*/
661bool QVideoWidget::setMediaObject(QMediaObject *object)
662{
663 Q_D(QVideoWidget);
664
665 if (object == d->mediaObject)
666 return true;
667
668 d->clearService();
669
670 d->mediaObject = object;
671
672 if (d->mediaObject)
673 d->service = d->mediaObject->service();
674
675 if (d->service) {
676 if (d->createWidgetBackend()) {
677 // Nothing to do here.
678 } else if ((!window() || !window()->testAttribute(attribute: Qt::WA_DontShowOnScreen))
679 && d->createWindowBackend()) {
680 if (isVisible())
681 d->windowBackend->showEvent();
682 } else if (d->createRendererBackend()) {
683 if (isVisible())
684 d->rendererBackend->showEvent();
685 } else {
686 d->service = 0;
687 d->mediaObject = 0;
688
689 return false;
690 }
691
692 connect(asender: d->service, SIGNAL(destroyed()), SLOT(_q_serviceDestroyed()));
693 } else {
694 d->mediaObject = 0;
695
696 return false;
697 }
698
699 return true;
700}
701
702/*!
703 \since 5.15
704 \property QVideoWidget::videoSurface
705 \brief Returns the underlaying video surface that can render video frames
706 to the current widget.
707 This property is never \c nullptr.
708 Example of how to render video frames to QVideoWidget:
709 \snippet multimedia-snippets/video.cpp Widget Surface
710 \sa QMediaPlayer::setVideoOutput
711*/
712
713QAbstractVideoSurface *QVideoWidget::videoSurface() const
714{
715 auto d = const_cast<QVideoWidgetPrivate *>(d_func());
716
717 if (!d->rendererBackend) {
718 d->clearService();
719 d->createRendererBackend();
720 }
721
722 return d->rendererBackend->videoSurface();
723}
724
725/*!
726 \property QVideoWidget::aspectRatioMode
727 \brief how video is scaled with respect to its aspect ratio.
728*/
729
730Qt::AspectRatioMode QVideoWidget::aspectRatioMode() const
731{
732 return d_func()->aspectRatioMode;
733}
734
735void QVideoWidget::setAspectRatioMode(Qt::AspectRatioMode mode)
736{
737 Q_D(QVideoWidget);
738
739 if (d->currentControl) {
740 d->currentControl->setAspectRatioMode(mode);
741 d->aspectRatioMode = d->currentControl->aspectRatioMode();
742 } else {
743 d->aspectRatioMode = mode;
744 }
745}
746
747/*!
748 \property QVideoWidget::fullScreen
749 \brief whether video display is confined to a window or is fullScreen.
750*/
751
752void QVideoWidget::setFullScreen(bool fullScreen)
753{
754 Q_D(QVideoWidget);
755
756 Qt::WindowFlags flags = windowFlags();
757
758 if (fullScreen) {
759 d->nonFullScreenFlags = flags & (Qt::Window | Qt::SubWindow);
760 flags |= Qt::Window;
761 flags &= ~Qt::SubWindow;
762 setWindowFlags(flags);
763
764 showFullScreen();
765 } else {
766 flags &= ~(Qt::Window | Qt::SubWindow); //clear the flags...
767 flags |= d->nonFullScreenFlags; //then we reset the flags (window and subwindow)
768 setWindowFlags(flags);
769
770 showNormal();
771 }
772}
773
774/*!
775 \fn QVideoWidget::fullScreenChanged(bool fullScreen)
776
777 Signals that the \a fullScreen mode of a video widget has changed.
778
779 \sa isFullScreen()
780*/
781
782/*!
783 \property QVideoWidget::brightness
784 \brief an adjustment to the brightness of displayed video.
785
786 Valid brightness values range between -100 and 100, the default is 0.
787*/
788
789int QVideoWidget::brightness() const
790{
791 return d_func()->brightness;
792}
793
794void QVideoWidget::setBrightness(int brightness)
795{
796 Q_D(QVideoWidget);
797
798 int boundedBrightness = qBound(min: -100, val: brightness, max: 100);
799
800 if (d->currentControl)
801 d->currentControl->setBrightness(boundedBrightness);
802 else if (d->brightness != boundedBrightness)
803 emit brightnessChanged(brightness: d->brightness = boundedBrightness);
804}
805
806/*!
807 \fn QVideoWidget::brightnessChanged(int brightness)
808
809 Signals that a video widgets's \a brightness adjustment has changed.
810
811 \sa brightness()
812*/
813
814/*!
815 \property QVideoWidget::contrast
816 \brief an adjustment to the contrast of displayed video.
817
818 Valid contrast values range between -100 and 100, the default is 0.
819
820*/
821
822int QVideoWidget::contrast() const
823{
824 return d_func()->contrast;
825}
826
827void QVideoWidget::setContrast(int contrast)
828{
829 Q_D(QVideoWidget);
830
831 int boundedContrast = qBound(min: -100, val: contrast, max: 100);
832
833 if (d->currentControl)
834 d->currentControl->setContrast(boundedContrast);
835 else if (d->contrast != boundedContrast)
836 emit contrastChanged(contrast: d->contrast = boundedContrast);
837}
838
839/*!
840 \fn QVideoWidget::contrastChanged(int contrast)
841
842 Signals that a video widgets's \a contrast adjustment has changed.
843
844 \sa contrast()
845*/
846
847/*!
848 \property QVideoWidget::hue
849 \brief an adjustment to the hue of displayed video.
850
851 Valid hue values range between -100 and 100, the default is 0.
852*/
853
854int QVideoWidget::hue() const
855{
856 return d_func()->hue;
857}
858
859void QVideoWidget::setHue(int hue)
860{
861 Q_D(QVideoWidget);
862
863 int boundedHue = qBound(min: -100, val: hue, max: 100);
864
865 if (d->currentControl)
866 d->currentControl->setHue(boundedHue);
867 else if (d->hue != boundedHue)
868 emit hueChanged(hue: d->hue = boundedHue);
869}
870
871/*!
872 \fn QVideoWidget::hueChanged(int hue)
873
874 Signals that a video widgets's \a hue has changed.
875
876 \sa hue()
877*/
878
879/*!
880 \property QVideoWidget::saturation
881 \brief an adjustment to the saturation of displayed video.
882
883 Valid saturation values range between -100 and 100, the default is 0.
884*/
885
886int QVideoWidget::saturation() const
887{
888 return d_func()->saturation;
889}
890
891void QVideoWidget::setSaturation(int saturation)
892{
893 Q_D(QVideoWidget);
894
895 int boundedSaturation = qBound(min: -100, val: saturation, max: 100);
896
897 if (d->currentControl)
898 d->currentControl->setSaturation(boundedSaturation);
899 else if (d->saturation != boundedSaturation)
900 emit saturationChanged(saturation: d->saturation = boundedSaturation);
901
902}
903
904/*!
905 \fn QVideoWidget::saturationChanged(int saturation)
906
907 Signals that a video widgets's \a saturation has changed.
908
909 \sa saturation()
910*/
911
912/*!
913 Returns the size hint for the current back end,
914 if there is one, or else the size hint from QWidget.
915 */
916QSize QVideoWidget::sizeHint() const
917{
918 Q_D(const QVideoWidget);
919
920 if (d->currentBackend)
921 return d->currentBackend->sizeHint();
922 else
923 return QWidget::sizeHint();
924
925
926}
927
928/*!
929 \reimp
930 Current event \a event.
931 Returns the value of the baseclass QWidget::event(QEvent *event) function.
932*/
933bool QVideoWidget::event(QEvent *event)
934{
935 Q_D(QVideoWidget);
936
937 if (event->type() == QEvent::WindowStateChange) {
938 if (windowState() & Qt::WindowFullScreen) {
939 if (d->currentControl)
940 d->currentControl->setFullScreen(true);
941
942 if (!d->wasFullScreen)
943 emit fullScreenChanged(fullScreen: d->wasFullScreen = true);
944 } else {
945 if (d->currentControl)
946 d->currentControl->setFullScreen(false);
947
948 if (d->wasFullScreen)
949 emit fullScreenChanged(fullScreen: d->wasFullScreen = false);
950 }
951 }
952 return QWidget::event(event);
953}
954
955/*!
956 \reimp
957 Handles the show \a event.
958 */
959void QVideoWidget::showEvent(QShowEvent *event)
960{
961 Q_D(QVideoWidget);
962
963 QWidget::showEvent(event);
964
965 // The window backend won't work for re-directed windows so use the renderer backend instead.
966 if (d->windowBackend && window()->testAttribute(attribute: Qt::WA_DontShowOnScreen)) {
967 d->windowBackend->releaseControl();
968
969 delete d->windowBackend;
970 d->windowBackend = 0;
971
972 d->createRendererBackend();
973 }
974
975 if (d->currentBackend)
976 d->currentBackend->showEvent();
977}
978
979/*!
980 \reimp
981 Handles the hide \a event.
982*/
983void QVideoWidget::hideEvent(QHideEvent *event)
984{
985 Q_D(QVideoWidget);
986
987 if (d->currentBackend)
988 d->currentBackend->hideEvent(event);
989
990 QWidget::hideEvent(event);
991}
992
993/*!
994 \reimp
995 Handles the resize \a event.
996 */
997void QVideoWidget::resizeEvent(QResizeEvent *event)
998{
999 Q_D(QVideoWidget);
1000
1001 QWidget::resizeEvent(event);
1002
1003 if (d->currentBackend)
1004 d->currentBackend->resizeEvent(event);
1005}
1006
1007/*!
1008 \reimp
1009 Handles the move \a event.
1010 */
1011void QVideoWidget::moveEvent(QMoveEvent *event)
1012{
1013 Q_D(QVideoWidget);
1014
1015 if (d->currentBackend)
1016 d->currentBackend->moveEvent(event);
1017}
1018
1019/*!
1020 \reimp
1021 Handles the paint \a event.
1022 */
1023void QVideoWidget::paintEvent(QPaintEvent *event)
1024{
1025 Q_D(QVideoWidget);
1026
1027 if (d->currentBackend) {
1028 d->currentBackend->paintEvent(event);
1029 } else if (testAttribute(attribute: Qt::WA_OpaquePaintEvent)) {
1030 QPainter painter(this);
1031
1032 painter.fillRect(event->rect(), palette().window());
1033 }
1034}
1035
1036#if defined(Q_OS_WIN)
1037# if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
1038bool QVideoWidget::nativeEvent(const QByteArray &eventType, void *message, qintptr *result)
1039# else
1040bool QVideoWidget::nativeEvent(const QByteArray &eventType, void *message, long *result)
1041# endif
1042{
1043 Q_D(QVideoWidget);
1044 Q_UNUSED(eventType);
1045 Q_UNUSED(result);
1046
1047 MSG *mes = reinterpret_cast<MSG *>(message);
1048 if (mes->message == WM_PAINT || mes->message == WM_ERASEBKGND) {
1049 if (d->windowBackend)
1050 d->windowBackend->showEvent();
1051 }
1052
1053 return false;
1054}
1055#endif
1056
1057QT_END_NAMESPACE
1058
1059#include "moc_qvideowidget.cpp"
1060#include "moc_qvideowidget_p.cpp"
1061

source code of qtmultimedia/src/multimediawidgets/qvideowidget.cpp