2011-04-14 17:59:51 -04:00
|
|
|
/****************************************************************
|
|
|
|
* RetroShare is distributed under the following license:
|
|
|
|
*
|
|
|
|
* Copyright (C) 2006, 2007 crypton
|
|
|
|
*
|
|
|
|
* 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 2
|
|
|
|
* 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, write to the Free Software
|
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
|
|
* Boston, MA 02110-1301, USA.
|
|
|
|
****************************************************************/
|
|
|
|
|
|
|
|
#include <QCoreApplication>
|
|
|
|
#include <QMessageBox>
|
|
|
|
#include <QIcon>
|
|
|
|
#include <iostream>
|
|
|
|
|
|
|
|
#include <retroshare/rsinit.h>
|
|
|
|
|
|
|
|
#include "EventReceiver.h"
|
2012-03-10 18:39:42 -05:00
|
|
|
#include "gui/MainWindow.h"
|
2011-04-14 17:59:51 -04:00
|
|
|
#include "gui/RetroShareLink.h"
|
|
|
|
|
|
|
|
#ifdef WINDOWS_SYS
|
|
|
|
#include <windows.h>
|
|
|
|
#define OP_RETROSHARELINK 12000
|
|
|
|
#endif
|
|
|
|
|
|
|
|
struct SharedMemoryInfo
|
|
|
|
{
|
|
|
|
#ifdef WINDOWS_SYS
|
|
|
|
/* Store handle of the event window */
|
|
|
|
WId wid;
|
|
|
|
#else
|
|
|
|
long dummy;
|
|
|
|
#endif
|
|
|
|
};
|
|
|
|
|
|
|
|
EventReceiver::EventReceiver()
|
|
|
|
{
|
|
|
|
#ifdef WINDOWS_SYS
|
|
|
|
setWindowTitle("RetroShare EventReceiver");
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* Build unique name for the running instance */
|
|
|
|
QString name = QString("RetroShare-%1::EventReceiver").arg(QCoreApplication::applicationDirPath());
|
2011-04-18 18:15:24 -04:00
|
|
|
sharedMemory.setKey(name);
|
2011-04-14 17:59:51 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
EventReceiver::~EventReceiver()
|
|
|
|
{
|
2011-04-18 18:15:24 -04:00
|
|
|
sharedMemory.detach();
|
2011-04-14 17:59:51 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
bool EventReceiver::start()
|
|
|
|
{
|
2011-04-18 18:15:24 -04:00
|
|
|
if (!sharedMemory.create(sizeof(SharedMemoryInfo))) {
|
|
|
|
std::cerr << "EventReceiver::start() Cannot create shared memory !" << sharedMemory.errorString().toStdString() << std::endl;
|
2011-04-14 17:59:51 -04:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool result = true;
|
|
|
|
|
2011-04-18 18:15:24 -04:00
|
|
|
if (sharedMemory.lock()) {
|
|
|
|
SharedMemoryInfo *info = (SharedMemoryInfo*) sharedMemory.data();
|
2011-04-14 17:59:51 -04:00
|
|
|
if (info) {
|
|
|
|
#ifdef WINDOWS_SYS
|
|
|
|
info->wid = winId();
|
|
|
|
#else
|
|
|
|
info->dummy = 0;
|
|
|
|
#endif
|
|
|
|
} else {
|
|
|
|
result = false;
|
|
|
|
std::cerr << "EventReceiver::start() Shared memory returns a NULL pointer!" << std::endl;
|
|
|
|
}
|
|
|
|
|
2011-04-18 18:15:24 -04:00
|
|
|
sharedMemory.unlock();
|
2011-04-14 17:59:51 -04:00
|
|
|
} else {
|
|
|
|
result = false;
|
|
|
|
std::cerr << "EventReceiver::start() Cannot lock shared memory !" << std::endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool EventReceiver::sendRetroShareLink(const QString& link)
|
|
|
|
{
|
2011-04-18 18:15:24 -04:00
|
|
|
if (!sharedMemory.attach()) {
|
2011-04-14 17:59:51 -04:00
|
|
|
/* No running instance found */
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool result = true;
|
|
|
|
|
2011-04-18 18:15:24 -04:00
|
|
|
if (sharedMemory.lock()) {
|
|
|
|
SharedMemoryInfo *info = (SharedMemoryInfo*) sharedMemory.data();
|
2011-04-14 17:59:51 -04:00
|
|
|
if (info) {
|
|
|
|
#ifdef WINDOWS_SYS
|
|
|
|
if (info->wid) {
|
2011-10-08 13:49:06 -04:00
|
|
|
QByteArray linkData(link.toUtf8());
|
2011-04-14 17:59:51 -04:00
|
|
|
|
|
|
|
COPYDATASTRUCT send;
|
|
|
|
send.dwData = OP_RETROSHARELINK;
|
2011-04-18 18:15:24 -04:00
|
|
|
send.cbData = link.length() * sizeof(char);
|
2011-04-14 17:59:51 -04:00
|
|
|
send.lpData = (void*) linkData.constData();
|
|
|
|
|
|
|
|
SendMessage((HWND) info->wid, WM_COPYDATA, (WPARAM) 0, (LPARAM) (PCOPYDATASTRUCT) &send);
|
|
|
|
} else {
|
|
|
|
result = false;
|
|
|
|
}
|
|
|
|
#else
|
2011-08-12 10:06:29 -04:00
|
|
|
Q_UNUSED(link);
|
|
|
|
|
2011-04-14 17:59:51 -04:00
|
|
|
QMessageBox mb(QMessageBox::Critical, "RetroShare", QObject::tr("Start with a RetroShare link is only supported for Windows."), QMessageBox::Ok);
|
|
|
|
mb.setWindowIcon(QIcon(":/images/rstray3.png"));
|
|
|
|
mb.exec();
|
|
|
|
|
|
|
|
result = false;
|
|
|
|
#endif
|
|
|
|
} else {
|
|
|
|
result = false;
|
|
|
|
std::cerr << "EventReceiver::sendRetroShareLink() Cannot lock shared memory !" << std::endl;
|
|
|
|
}
|
|
|
|
|
2011-04-18 18:15:24 -04:00
|
|
|
sharedMemory.unlock();
|
2011-04-14 17:59:51 -04:00
|
|
|
} else {
|
|
|
|
result = false;
|
|
|
|
std::cerr << "EventReceiver::start() Cannot lock shared memory !" << std::endl;
|
|
|
|
}
|
|
|
|
|
2011-04-18 18:15:24 -04:00
|
|
|
sharedMemory.detach();
|
2011-04-14 17:59:51 -04:00
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef WINDOWS_SYS
|
|
|
|
bool EventReceiver::winEvent(MSG* message, long* result)
|
|
|
|
{
|
|
|
|
if (message->message == WM_COPYDATA ) {
|
|
|
|
/* Extract the struct from lParam */
|
|
|
|
COPYDATASTRUCT *data = (COPYDATASTRUCT*) message->lParam;
|
|
|
|
|
|
|
|
if (data && data->dwData == OP_RETROSHARELINK) {
|
2011-10-08 13:49:06 -04:00
|
|
|
received(QString::fromUtf8((const char*) data->lpData, data->cbData));
|
2011-04-14 17:59:51 -04:00
|
|
|
|
|
|
|
/* Keep the event from Qt */
|
|
|
|
*result = 0;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Give the event to Qt */
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2012-03-10 18:39:42 -05:00
|
|
|
#ifdef WINDOWS_SYS
|
|
|
|
//void SetForegroundWindowInternal(HWND hWnd)
|
|
|
|
//{
|
|
|
|
// if (!::IsWindow(hWnd)) return;
|
|
|
|
|
|
|
|
// // relation time of SetForegroundWindow lock
|
|
|
|
// DWORD lockTimeOut = 0;
|
|
|
|
// HWND hCurrWnd = ::GetForegroundWindow();
|
|
|
|
// DWORD dwThisTID = ::GetCurrentThreadId(),
|
|
|
|
// dwCurrTID = ::GetWindowThreadProcessId(hCurrWnd,0);
|
|
|
|
|
|
|
|
// // we need to bypass some limitations from Microsoft :)
|
|
|
|
// if (dwThisTID != dwCurrTID) {
|
|
|
|
// ::AttachThreadInput(dwThisTID, dwCurrTID, TRUE);
|
|
|
|
|
|
|
|
// ::SystemParametersInfo(SPI_GETFOREGROUNDLOCKTIMEOUT,0,&lockTimeOut,0);
|
|
|
|
// ::SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT,0,0,SPIF_SENDWININICHANGE | SPIF_UPDATEINIFILE);
|
|
|
|
|
|
|
|
// ::AllowSetForegroundWindow(ASFW_ANY);
|
|
|
|
// }
|
|
|
|
|
|
|
|
// ::SetForegroundWindow(hWnd);
|
|
|
|
|
|
|
|
// if(dwThisTID != dwCurrTID) {
|
|
|
|
// ::SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT,0,(PVOID)lockTimeOut,SPIF_SENDWININICHANGE | SPIF_UPDATEINIFILE);
|
|
|
|
// ::AttachThreadInput(dwThisTID, dwCurrTID, FALSE);
|
|
|
|
// }
|
|
|
|
//}
|
|
|
|
|
|
|
|
void SetForegroundWindowInternal(HWND hWnd)
|
|
|
|
{
|
|
|
|
if (!::IsWindow(hWnd)) return;
|
|
|
|
|
|
|
|
BYTE keyState[256] = {0};
|
|
|
|
// to unlock SetForegroundWindow we need to imitate Alt pressing
|
|
|
|
if (::GetKeyboardState((LPBYTE)&keyState)) {
|
|
|
|
if(!(keyState[VK_MENU] & 0x80)) {
|
|
|
|
::keybd_event(VK_MENU, 0, KEYEVENTF_EXTENDEDKEY | 0, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
::SetForegroundWindow(hWnd);
|
|
|
|
|
|
|
|
if (::GetKeyboardState((LPBYTE)&keyState)) {
|
|
|
|
if(!(keyState[VK_MENU] & 0x80)) {
|
|
|
|
::keybd_event(VK_MENU, 0, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2011-04-14 17:59:51 -04:00
|
|
|
void EventReceiver::received(const QString &url)
|
|
|
|
{
|
|
|
|
RetroShareLink link(url);
|
|
|
|
if (link.valid()) {
|
2012-03-10 18:39:42 -05:00
|
|
|
MainWindow *window = MainWindow::getInstance();
|
|
|
|
if (window) {
|
|
|
|
window->show();
|
|
|
|
window->raise();
|
|
|
|
|
|
|
|
#ifdef WINDOWS_SYS
|
|
|
|
SetForegroundWindowInternal(window->winId());
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2011-04-14 17:59:51 -04:00
|
|
|
emit linkReceived(link.toUrl());
|
|
|
|
}
|
|
|
|
}
|