summaryrefslogtreecommitdiff
path: root/src/qcam/qt_event_dispatcher.cpp
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>2019-03-23 03:24:25 +0200
committerLaurent Pinchart <laurent.pinchart@ideasonboard.com>2019-03-29 17:09:46 +0200
commit97e8b3a2eb321884fe1e15fb584f41a38cc33d51 (patch)
tree3ed93b2504e4fcdc3511bcf956f43ad84a558d0f /src/qcam/qt_event_dispatcher.cpp
parentffef90a1c1f1990581d8fbc22193bfc766d23d3b (diff)
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 <laurent.pinchart@ideasonboard.com> Acked-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Tested-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Diffstat (limited to 'src/qcam/qt_event_dispatcher.cpp')
-rw-r--r--src/qcam/qt_event_dispatcher.cpp145
1 files changed, 145 insertions, 0 deletions
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 <iostream>
+
+#include <QAbstractEventDispatcher>
+#include <QCoreApplication>
+#include <QSocketNotifier>
+#include <QTimerEvent>
+
+#include <libcamera/event_notifier.h>
+#include <libcamera/timer.h>
+
+#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();
+}