You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
127 lines
3.9 KiB
127 lines
3.9 KiB
/**************************************************************************** |
|
** |
|
** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). |
|
** Contact: Qt Software Information (qt-info.com) |
|
** |
|
** This file is part of a Qt Solutions component. |
|
** |
|
** Commercial Usage |
|
** Licensees holding valid Qt Solutions licenses may use this file in |
|
** accordance with the Qt Solutions Commercial License Agreement provided |
|
** with the Software or, alternatively, in accordance with the terms |
|
** contained in a written agreement between you and Nokia. |
|
** |
|
** If you are unsure which license is appropriate for your use, please |
|
** contact the sales department at qt-sales.com. |
|
** |
|
****************************************************************************/ |
|
|
|
#include <QtCore/QString> |
|
#include <Carbon/Carbon.h> |
|
|
|
#include "qtsingleapplication.h" |
|
|
|
CFStringRef qstring2cfstring(const QString &str) |
|
{ |
|
return CFStringCreateWithCharacters(0, (UniChar *)str.unicode(), str.length()); |
|
} |
|
|
|
QString cfstring2qstring(CFStringRef str) |
|
{ |
|
if(!str) |
|
return QString(); |
|
|
|
CFIndex length = CFStringGetLength(str); |
|
if(const UniChar *chars = CFStringGetCharactersPtr(str)) |
|
return QString((QChar *)chars, length); |
|
UniChar *buffer = (UniChar*)malloc(length * sizeof(UniChar)); |
|
CFStringGetCharacters(str, CFRangeMake(0, length), buffer); |
|
QString ret((QChar *)buffer, length); |
|
free(buffer); |
|
return ret; |
|
} |
|
|
|
class QtSingletonSysPrivate |
|
{ |
|
public: |
|
inline QtSingletonSysPrivate() { port = 0; } |
|
CFMessagePortRef port; |
|
}; |
|
|
|
class QtSingletonPrivate |
|
{ |
|
}; |
|
|
|
bool QtSingleApplication::isRunning() const |
|
{ |
|
CFStringRef cfstr = qstring2cfstring(id()); |
|
CFMessagePortRef myport = CFMessagePortCreateRemote(kCFAllocatorDefault, cfstr); |
|
CFRelease(cfstr); |
|
return (myport != 0); |
|
} |
|
|
|
void QtSingleApplication::sysInit() |
|
{ |
|
sysd = new QtSingletonSysPrivate; |
|
} |
|
|
|
void QtSingleApplication::sysCleanup() |
|
{ |
|
delete sysd; |
|
} |
|
|
|
CFDataRef MyCallBack(CFMessagePortRef, SInt32, CFDataRef data, void *info) |
|
{ |
|
CFIndex index = CFDataGetLength(data); |
|
const UInt8 *p = CFDataGetBytePtr(data); |
|
QByteArray ba(index, 0); |
|
for (int i = 0; i < index; ++i) |
|
ba[i] = p[i]; |
|
QString message(ba); |
|
emit static_cast<QtSingleApplication *>(info)->messageReceived(message); |
|
return 0; |
|
} |
|
|
|
void QtSingleApplication::initialize(bool activate) |
|
{ |
|
CFStringRef cfstr = qstring2cfstring(id()); |
|
CFMessagePortContext context; |
|
context.version = 0; |
|
context.info = this; |
|
context.retain = 0; |
|
context.release = 0; |
|
context.copyDescription = 0; |
|
sysd->port = CFMessagePortCreateLocal(kCFAllocatorDefault, cfstr, MyCallBack, &context, 0); |
|
CFRunLoopRef runloop = CFRunLoopGetCurrent(); |
|
if (sysd->port && runloop) { |
|
CFRunLoopSourceRef source = CFMessagePortCreateRunLoopSource(0, sysd->port, 0); |
|
if (source) |
|
CFRunLoopAddSource(runloop, source, kCFRunLoopCommonModes); |
|
CFRelease(source); |
|
} |
|
CFRelease(cfstr); |
|
if (activate) { |
|
connect(this, SIGNAL(messageReceived(const QString&)), |
|
this, SLOT(activateWindow())); |
|
} |
|
} |
|
|
|
bool QtSingleApplication::sendMessage(const QString &message, int timeout) |
|
{ |
|
CFStringRef cfstr = qstring2cfstring(id()); |
|
CFMessagePortRef myport = CFMessagePortCreateRemote(kCFAllocatorDefault, cfstr); |
|
CFRelease(cfstr); |
|
if (!myport) |
|
return false; |
|
static SInt32 msgid = 0; |
|
const QByteArray latin1Message = message.toLatin1(); |
|
CFDataRef data = CFDataCreate(0, (UInt8*)latin1Message.constData(), latin1Message.length()); |
|
CFDataRef reply = 0; |
|
SInt32 result = CFMessagePortSendRequest(myport, ++msgid, data, timeout / 1000, |
|
timeout / 1000, 0, &reply); |
|
CFRelease(data); |
|
if (reply) |
|
CFRelease(reply); |
|
return result == kCFMessagePortSuccess; |
|
|
|
}
|
|
|