diff --git a/RingWinClient.pro b/RingWinClient.pro index db4bb203a35e5313a67f49aaccd29291b2324bfd..3d1f2f3cef8878e18d89cb5716520c9d3cebf1b8 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 e2f88806fed0a4248984a9886830adac2598f934..583e913ffbe68cf9a871ac7d5bfe285ac6e4fe2d 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 31541cae1723588ca9bee507d6556a864b119f73..2b2bae3016b692a72ec061f44a6fc242a37d03b7 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 f40b837a53c49729da335d0e03b517a262d8770f..2cc0a21107ad7ee28729e66aa0c9fe3432f1ad8b 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 18f31f887d5162b6d27906a28862a00f938c4f19..3261df4e98d23d3370a47947d750f98dbd749a93 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 0000000000000000000000000000000000000000..c175fb190ecc02e094d1b1183e65d433f16e50dd --- /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 0000000000000000000000000000000000000000..bfbae32a0f0ce3a91b606cd9d820673c9409ade7 --- /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 = ""); +};