From fe39094b08f6cc2cf2b99e61db34004e89ab2cc4 Mon Sep 17 00:00:00 2001 From: Edric Milaret Date: Tue, 4 Aug 2015 13:41:03 -0400 Subject: [PATCH] uri: register ring protocol - This commit enforce that only one instance of Ring can run. Ring window now show if it was minimized or hidden when attempting to launch again. - Ring will be launched or shown on ring: protocol use and call the provided uri. (e.g. test ring link ) - Register ring protocol in Windows registry at install time as we need administrator elevation. Issue: #78588 Issue: #78589 Change-Id: I7645d8a3154ce1c91a91bfac21c330add9a03fcc --- RingWinClient.pro | 5 +++++ main.cpp | 56 ++++++++++++++++++++++++++++++++++++++++++++++- mainwindow.cpp | 15 +++++++++++++ mainwindow.h | 3 +++ ring.nsi | 5 +++++ shmclient.cpp | 53 ++++++++++++++++++++++++++++++++++++++++++++ shmclient.h | 38 ++++++++++++++++++++++++++++++++ 7 files changed, 174 insertions(+), 1 deletion(-) create mode 100644 shmclient.cpp create mode 100644 shmclient.h diff --git a/RingWinClient.pro b/RingWinClient.pro index db4bb20..3d1f2f3 100644 --- a/RingWinClient.pro +++ b/RingWinClient.pro @@ -105,6 +105,11 @@ HEADERS += mainwindow.h \ qualitydialog.h \ ringthemeutils.h +contains(DEFINES, URI_PROTOCOL) { + HEADERS += shmclient.h + SOURCES += shmclient.cpp +} + FORMS += mainwindow.ui \ callwidget.ui \ configurationwidget.ui \ diff --git a/main.cpp b/main.cpp index e2f8880..583e913 100644 --- a/main.cpp +++ b/main.cpp @@ -25,16 +25,21 @@ #include "media/video.h" #include "media/text.h" #include "media/file.h" -#include + #include #include #include + #ifdef Q_OS_WIN32 #include #endif +#ifdef URI_PROTOCOL +#include "shmclient.h" +#endif + REGISTER_MEDIA(); void @@ -62,13 +67,46 @@ main(int argc, char *argv[]) QApplication a(argc, argv); auto startMinimized = false; + QString uri = ""; for (auto string : QCoreApplication::arguments()) { if (string == "-m" || string == "--minimized") startMinimized = true; if (string == "-d" || string == "--debug") Console(); + if (string.startsWith("ring:")) { + uri = string; + } + } + +#ifdef URI_PROTOCOL + QSharedMemory* shm = new QSharedMemory("RingShm"); + QSystemSemaphore* sem = new QSystemSemaphore("RingSem", 0); + + if (not shm->create(1024)) { + if (not uri.isEmpty()) { + shm->attach(); + shm->lock(); + char *to = (char*) shm->data(); + QChar *data = uri.data(); + while (!data->isNull()) + { + memset(to, data->toLatin1(), 1); + ++data; + ++to; + } + memset(to, 0, 1); //null terminator + shm->unlock(); + } + sem->release(); + + delete shm; + exit(EXIT_SUCCESS); } + //Client listening to shm event + memset((char*)shm->data(), 0, shm->size()); + ShmClient* shmClient = new ShmClient(shm, sem); +#endif QTranslator qtTranslator; qtTranslator.load("qt_" + QLocale::system().name(), @@ -100,6 +138,11 @@ main(int argc, char *argv[]) MainWindow w; + if (not uri.isEmpty()) { + startMinimized = false; + w.onRingEvent(uri); + } + if (not startMinimized) w.show(); else @@ -107,5 +150,16 @@ main(int argc, char *argv[]) w.createThumbBar(); +#ifdef URI_PROTOCOL + QObject::connect(shmClient, SIGNAL(RingEvent(QString)), &w, SLOT(onRingEvent(QString))); + + QObject::connect(&a, &QApplication::aboutToQuit, [&a, &shmClient, &shm, &sem]() { + shmClient->terminate(); + delete shmClient; + delete shm; + delete sem; + }); +#endif + return a.exec(); } diff --git a/mainwindow.cpp b/mainwindow.cpp index 31541ca..2b2bae3 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -37,6 +37,10 @@ #include "winsparkle.h" #endif +#include "callmodel.h" + +#include + MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow), @@ -116,6 +120,17 @@ MainWindow::~MainWindow() delete navStack_; } +void +MainWindow::onRingEvent(const QString &uri) +{ + this->showNormal(); + if (not uri.isEmpty()) { + auto outCall = CallModel::instance().dialingCall(); + outCall->setDialNumber(uri); + outCall->performAction(Call::Action::ACCEPT); + } +} + bool MainWindow::nativeEvent(const QByteArray &eventType, void *message, long *result) { diff --git a/mainwindow.h b/mainwindow.h index f40b837..2cc0a21 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -46,6 +46,9 @@ public: protected: bool nativeEvent(const QByteArray &eventType, void *message, long *result); +public slots: + void onRingEvent(const QString& uri); + private slots: void trayActivated(QSystemTrayIcon::ActivationReason reason); void onIncomingCall(Call *call); diff --git a/ring.nsi b/ring.nsi index 18f31f8..3261df4 100644 --- a/ring.nsi +++ b/ring.nsi @@ -110,6 +110,11 @@ section "install" ${GetSize} "$INSTDIR" "/S=0K" $0 $1 $2 IntFmt $0 "0x%08X" $0 WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${COMPANYNAME} ${APPNAME}" "EstimatedSize" "$0" + + # Write ring protocol in registry + WriteRegStr HKCR "ring" "URL Protocol" "$\"$\"" + WriteRegStr HKCR "ring\DefaultIcon" "" "$\"$INSTDIR\Ring.exe,1$\"" + WriteRegStr HKCR "ring\shell\open\command" "" "$\"$INSTDIR\Ring.exe$\" $\"%1$\"" sectionEnd # Uninstaller diff --git a/shmclient.cpp b/shmclient.cpp new file mode 100644 index 0000000..c175fb1 --- /dev/null +++ b/shmclient.cpp @@ -0,0 +1,53 @@ +/*************************************************************************** + * Copyright (C) 2016 by Savoir-faire Linux * + * Author: Edric Ladent Milaret * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 3 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + **************************************************************************/ + +#include "shmclient.h" + +#include + +ShmClient::ShmClient(QSharedMemory* shm, QSystemSemaphore *sem) : + shm_(shm), + sem_(sem) +{ + start(); +} + +void ShmClient::run() +{ + while (true) { + + sem_->acquire(); + + shm_->lock(); + + char const *from = (char const*)shm_->data(); + + QString uri = ""; + QTextStream stream(&uri); + + while (from && *from) + { + stream << *from; + ++from; + } + + shm_->unlock(); + + emit RingEvent(uri); + } +} diff --git a/shmclient.h b/shmclient.h new file mode 100644 index 0000000..bfbae32 --- /dev/null +++ b/shmclient.h @@ -0,0 +1,38 @@ +/*************************************************************************** + * Copyright (C) 2016 by Savoir-faire Linux * + * Author: Edric Ladent Milaret * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 3 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + **************************************************************************/ + +#pragma once + +#include +#include +#include + +class ShmClient : public QThread +{ + Q_OBJECT +public: + ShmClient(QSharedMemory* shm, QSystemSemaphore* sem); + void run(); + +private: + QSharedMemory* shm_; + QSystemSemaphore* sem_; + +signals: + void RingEvent(const QString& uri = ""); +}; -- GitLab