@@ -49,6 +49,43 @@ public:
}
};
+/**
+ * \brief Custom QEvent to signal hotplug or unplug
+ */
+class HotplugEvent : public QEvent
+{
+public:
+ enum PLUGEVENT {
+ HOTPLUG,
+ UNPLUG
+ };
+
+ HotplugEvent(std::shared_ptr<Camera> camera, PLUGEVENT event)
+ : QEvent(type())
+ {
+ camera_ = camera;
+ plugEvent_ = event;
+ }
+
+ ~HotplugEvent()
+ {
+ camera_.reset();
+ }
+
+ static Type type()
+ {
+ static int type = QEvent::registerEventType();
+ return static_cast<Type>(type);
+ }
+
+ PLUGEVENT getHotplugEvent() { return plugEvent_; }
+ Camera *getCamera() { return camera_.get(); }
+
+private:
+ std::shared_ptr<Camera> camera_;
+ PLUGEVENT plugEvent_;
+};
+
MainWindow::MainWindow(CameraManager *cm, const OptionsParser::Options &options)
: saveRaw_(nullptr), options_(options), cm_(cm), allocator_(nullptr),
isCapturing_(false), captureRaw_(false)
@@ -71,6 +108,10 @@ MainWindow::MainWindow(CameraManager *cm, const OptionsParser::Options &options)
setCentralWidget(viewfinder_);
adjustSize();
+ /* Hotplug/unplug support */
+ cm_->cameraAdded.connect(this, &MainWindow::addNewCamera);
+ cm_->cameraRemoved.connect(this, &MainWindow::removeCamera);
+
/* Open the camera and start capture. */
ret = openCamera();
if (ret < 0) {
@@ -95,6 +136,9 @@ bool MainWindow::event(QEvent *e)
if (e->type() == CaptureEvent::type()) {
processCapture();
return true;
+ } else if (e->type() == HotplugEvent::type()) {
+ processHotplug(static_cast<HotplugEvent *>(e));
+ return true;
}
return QMainWindow::event(e);
@@ -525,6 +569,45 @@ void MainWindow::stopCapture()
setWindowTitle(title_);
}
+/* -----------------------------------------------------------------------------
+ * Camera hotplugging support
+ */
+
+void MainWindow::processHotplug(HotplugEvent *e)
+{
+ Camera *camera = e->getCamera();
+ HotplugEvent::PLUGEVENT event = e->getHotplugEvent();
+
+ if (event == HotplugEvent::PLUGEVENT::HOTPLUG) {
+ cameraCombo_->addItem(QString::fromStdString(camera->name()));
+ } else if (event == HotplugEvent::PLUGEVENT::UNPLUG) {
+ int camIndex = cameraCombo_->findText(QString::fromStdString(camera->name()));
+
+ /* Check if the currently-streaming camera is removed. */
+ if (camera == camera_.get()) {
+ toggleCapture(false);
+ cameraCombo_->setCurrentIndex(0);
+ }
+ cameraCombo_->removeItem(camIndex);
+ }
+}
+
+void MainWindow::addNewCamera(std::shared_ptr<Camera> camera)
+{
+ qInfo() << "Adding new camera:" << camera->name().c_str();
+ QCoreApplication::postEvent(this,
+ new HotplugEvent(std::move(camera),
+ HotplugEvent::PLUGEVENT::HOTPLUG));
+}
+
+void MainWindow::removeCamera(std::shared_ptr<Camera> camera)
+{
+ qInfo() << "Removing camera:" << camera->name().c_str();
+ QCoreApplication::postEvent(this,
+ new HotplugEvent(std::move(camera),
+ HotplugEvent::PLUGEVENT::UNPLUG));
+}
+
/* -----------------------------------------------------------------------------
* Image Save
*/
@@ -32,6 +32,8 @@ using namespace libcamera;
class QAction;
class QComboBox;
+class HotplugEvent;
+
enum {
OptCamera = 'c',
OptHelp = 'h',
@@ -87,8 +89,12 @@ private:
int startCapture();
void stopCapture();
+ void addNewCamera(std::shared_ptr<Camera> camera);
+ void removeCamera(std::shared_ptr<Camera> camera);
+
void requestComplete(Request *request);
void processCapture();
+ void processHotplug(HotplugEvent *e);
void processViewfinder(FrameBuffer *buffer);
/* UI elements */
Signed-off-by: Umang Jain <email@uajain.com> --- src/qcam/main_window.cpp | 83 ++++++++++++++++++++++++++++++++++++++++ src/qcam/main_window.h | 6 +++ 2 files changed, 89 insertions(+)