From 97e8b3a2eb321884fe1e15fb584f41a38cc33d51 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Sat, 23 Mar 2019 03:24:25 +0200 Subject: qcam: Add Qt-based GUI application qcam is a sample camera GUI application based on Qt. It demonstrates integration of the Qt event loop with libcamera. The application lets the user select a camera through the GUI, and then captures a single stream from the camera and displays it in a window. Only streams in YUYV formats are supported for now. Signed-off-by: Laurent Pinchart Acked-by: Kieran Bingham Tested-by: Kieran Bingham --- src/qcam/qt_event_dispatcher.cpp | 145 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 145 insertions(+) create mode 100644 src/qcam/qt_event_dispatcher.cpp (limited to 'src/qcam/qt_event_dispatcher.cpp') diff --git a/src/qcam/qt_event_dispatcher.cpp b/src/qcam/qt_event_dispatcher.cpp new file mode 100644 index 00000000..5ba451bf --- /dev/null +++ b/src/qcam/qt_event_dispatcher.cpp @@ -0,0 +1,145 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2019, Google Inc. + * + * qt_event_dispatcher.cpp - qcam - Qt-based event dispatcher + */ + +#include + +#include +#include +#include +#include + +#include +#include + +#include "qt_event_dispatcher.h" + +using namespace libcamera; + +QtEventDispatcher::QtEventDispatcher() +{ +} + +QtEventDispatcher::~QtEventDispatcher() +{ + for (auto &it : notifiers_) { + NotifierSet &set = it.second; + delete set.read.qnotifier; + delete set.write.qnotifier; + delete set.exception.qnotifier; + } +} + +void QtEventDispatcher::registerEventNotifier(EventNotifier *notifier) +{ + NotifierSet &set = notifiers_[notifier->fd()]; + QSocketNotifier::Type qtype; + void (QtEventDispatcher::*method)(int); + NotifierPair *pair; + + switch (notifier->type()) { + case EventNotifier::Read: + default: + qtype = QSocketNotifier::Read; + method = &QtEventDispatcher::readNotifierActivated; + pair = &set.read; + break; + + case EventNotifier::Write: + qtype = QSocketNotifier::Write; + method = &QtEventDispatcher::writeNotifierActivated; + pair = &set.write; + break; + + case EventNotifier::Exception: + qtype = QSocketNotifier::Exception; + method = &QtEventDispatcher::exceptionNotifierActivated; + pair = &set.exception; + break; + } + + QSocketNotifier *qnotifier = new QSocketNotifier(notifier->fd(), qtype); + connect(qnotifier, &QSocketNotifier::activated, this, method); + pair->notifier = notifier; + pair->qnotifier = qnotifier; +} + +void QtEventDispatcher::unregisterEventNotifier(EventNotifier *notifier) +{ + NotifierSet &set = notifiers_[notifier->fd()]; + NotifierPair *pair; + + switch (notifier->type()) { + case EventNotifier::Read: + default: + pair = &set.read; + break; + + case EventNotifier::Write: + pair = &set.write; + break; + + case EventNotifier::Exception: + pair = &set.exception; + break; + } + + delete pair->qnotifier; + pair->qnotifier = nullptr; + pair->notifier = nullptr; +} + +void QtEventDispatcher::readNotifierActivated(int socket) +{ + EventNotifier *notifier = notifiers_[socket].read.notifier; + notifier->activated.emit(notifier); +} + +void QtEventDispatcher::writeNotifierActivated(int socket) +{ + EventNotifier *notifier = notifiers_[socket].write.notifier; + notifier->activated.emit(notifier); +} + +void QtEventDispatcher::exceptionNotifierActivated(int socket) +{ + EventNotifier *notifier = notifiers_[socket].exception.notifier; + notifier->activated.emit(notifier); +} + +void QtEventDispatcher::registerTimer(Timer *timer) +{ + int timerId = startTimer(timer->interval()); + timers_[timerId] = timer; + timerIds_[timer] = timerId; +} + +void QtEventDispatcher::unregisterTimer(Timer *timer) +{ + auto it = timerIds_.find(timer); + timers_.erase(it->second); + killTimer(it->second); + timerIds_.erase(it); +} + +void QtEventDispatcher::timerEvent(QTimerEvent *event) +{ + auto it = timers_.find(event->timerId()); + timerIds_.erase(it->second); + killTimer(it->first); + timers_.erase(it); +} + +void QtEventDispatcher::processEvents() +{ + std::cout << "QtEventDispatcher::processEvents() should not be called" + << std::endl; +} + +void QtEventDispatcher::interrupt() +{ + QCoreApplication::eventDispatcher()->interrupt(); +} -- cgit v1.2.1