00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
#include <qobjectlist.h>
00027
#include <qmetaobject.h>
00028
#include <qvariant.h>
00029
#include <qtimer.h>
00030
#include <qintdict.h>
00031
#include <qeventloop.h>
00032
00033
00034
#include "config.h"
00035
00036
#include <config.h>
00037
#include <dcopref.h>
00038
00039
#include <sys/time.h>
00040
#include <sys/types.h>
00041
#include <sys/stat.h>
00042
#include <sys/file.h>
00043
#include <sys/socket.h>
00044
00045
#include <ctype.h>
00046
#include <unistd.h>
00047
#include <stdlib.h>
00048
#include <assert.h>
00049
#include <string.h>
00050
00051
#ifndef QT_CLEAN_NAMESPACE
00052
#define QT_CLEAN_NAMESPACE
00053
#endif
00054
#include <qguardedptr.h>
00055
#include <qtextstream.h>
00056
#include <qfile.h>
00057
#include <qdir.h>
00058
#include <qapplication.h>
00059
#include <qsocketnotifier.h>
00060
#include <qregexp.h>
00061
00062
#include <private/qucomextra_p.h>
00063
00064
#include <dcopglobal.h>
00065
#include <dcopclient.h>
00066
#include <dcopobject.h>
00067
00068
#if defined Q_WS_X11 && ! defined K_WS_QTONLY
00069
#include <X11/Xmd.h>
00070
#endif
00071
extern "C" {
00072
#ifdef Q_OS_UNIX
00073
#include <KDE-ICE/ICElib.h>
00074
#include <KDE-ICE/ICEutil.h>
00075
#include <KDE-ICE/ICEmsg.h>
00076
#include <KDE-ICE/ICEproto.h>
00077
#endif
00078
}
00079
00080
00081
00082
extern QMap<QCString, DCOPObject *> * kde_dcopObjMap;
00083
00084
00085
00086
00087
typedef QAsciiDict<DCOPClient> client_map_t;
00088
static client_map_t *DCOPClient_CliMap = 0;
00089
00090
static
00091 client_map_t *cliMap()
00092 {
00093
if (!DCOPClient_CliMap)
00094 DCOPClient_CliMap =
new client_map_t;
00095
return DCOPClient_CliMap;
00096 }
00097
00098 DCOPClient *
DCOPClient::findLocalClient(
const QCString &_appId )
00099 {
00100
return cliMap()->find(_appId.data());
00101 }
00102
00103
static
00104
void registerLocalClient(
const QCString &_appId,
DCOPClient *client )
00105 {
00106 cliMap()->replace(_appId.data(), client);
00107 }
00108
00109
static
00110
void unregisterLocalClient(
const QCString &_appId )
00111 {
00112 client_map_t *map = cliMap();
00113 map->remove(_appId.data());
00114 }
00116
00117
template class QPtrList<DCOPObjectProxy>;
00118
template class QPtrList<DCOPClientTransaction>;
00119
#ifdef Q_OS_UNIX
00120
template class QPtrList<_IceConn>;
00121
#endif
00122
00123
struct DCOPClientMessage
00124 {
00125
int opcode;
00126
#ifdef Q_OS_UNIX
00127
CARD32
key;
00128
#endif
00129
QByteArray data;
00130 };
00131
00132
class DCOPClient::ReplyStruct
00133 {
00134
public:
00135
enum ReplyStatus { Pending, Ok, Failed };
00136 ReplyStruct() {
00137 status = Pending;
00138 replyType = 0;
00139 replyData = 0;
00140 replyId = -1;
00141 transactionId = -1;
00142 replyObject = 0;
00143 }
00144 ReplyStatus status;
00145
QCString* replyType;
00146
QByteArray* replyData;
00147
int replyId;
00148 Q_INT32 transactionId;
00149
QCString calledApp;
00150
QGuardedPtr<QObject> replyObject;
00151
QCString replySlot;
00152 };
00153
00154
class DCOPClientPrivate
00155 {
00156
public:
00157
DCOPClient *parent;
00158
QCString appId;
00159
#ifdef Q_OS_UNIX
00160
IceConn iceConn;
00161
#endif
00162
int majorOpcode;
00163
00164
int majorVersion, minorVersion;
00165
00166
static const char* serverAddr;
00167
QSocketNotifier *notifier;
00168
bool non_blocking_call_lock;
00169
bool registered;
00170
bool foreign_server;
00171
bool accept_calls;
00172
bool accept_calls_override;
00173
bool qt_bridge_enabled;
00174
00175
QCString senderId;
00176
QCString objId;
00177
QCString function;
00178
00179
QCString defaultObject;
00180
QPtrList<DCOPClientTransaction> *transactionList;
00181
bool transaction;
00182 Q_INT32 transactionId;
00183
int opcode;
00184
00185
#ifdef Q_OS_UNIX
00186
00187
00188
00189
00190
00191 CARD32
key;
00192 CARD32 currentKey;
00193 CARD32 currentKeySaved;
00194
#endif
00195
00196
QTimer postMessageTimer;
00197
QPtrList<DCOPClientMessage> messages;
00198
00199
QPtrList<DCOPClient::ReplyStruct> pendingReplies;
00200
QPtrList<DCOPClient::ReplyStruct> asyncReplyQueue;
00201
00202
struct LocalTransactionResult
00203 {
00204
QCString replyType;
00205
QByteArray replyData;
00206 };
00207
00208
QIntDict<LocalTransactionResult> localTransActionList;
00209
00210
QTimer eventLoopTimer;
00211 };
00212
00213
class DCOPClientTransaction
00214 {
00215
public:
00216 Q_INT32
id;
00217
#ifdef Q_OS_UNIX
00218
CARD32
key;
00219
#endif
00220
QCString senderId;
00221 };
00222
00223 QCString DCOPClient::iceauthPath()
00224 {
00225
QCString path = ::getenv(
"PATH");
00226
if (path.isEmpty())
00227 path =
"/bin:/usr/bin";
00228 path +=
":/usr/bin/X11:/usr/X11/bin:/usr/X11R6/bin";
00229
QCString fPath = strtok(path.data(),
":\b");
00230
while (!fPath.isNull())
00231 {
00232 fPath +=
"/iceauth";
00233
if (access(fPath.data(), X_OK) == 0)
00234 {
00235
return fPath;
00236 }
00237
00238 fPath = strtok(NULL,
":\b");
00239 }
00240
return 0;
00241 }
00242
00243
static QCString dcopServerFile(
const QCString &hostname,
bool old)
00244 {
00245
QCString fName = ::getenv(
"DCOPAUTHORITY");
00246
if (!old && !fName.isEmpty())
00247
return fName;
00248
00249 fName = ::getenv(
"HOME");
00250
if (fName.isEmpty())
00251 {
00252 fprintf(stderr,
"Aborting. $HOME is not set.\n");
00253 exit(1);
00254 }
00255
#ifdef Q_WS_X11
00256
QCString disp = getenv(
"DISPLAY");
00257
#elif defined(Q_WS_QWS)
00258
QCString disp = getenv(
"QWS_DISPLAY");
00259
#else
00260
QCString disp;
00261
#endif
00262
if (disp.isEmpty())
00263 disp =
"NODISPLAY";
00264
00265
int i;
00266
if((i = disp.findRev(
'.')) > disp.findRev(KPATH_SEPARATOR) && i >= 0)
00267 disp.truncate(i);
00268
00269
if (!old)
00270 {
00271
while( (i = disp.find(KPATH_SEPARATOR)) >= 0)
00272 disp[i] =
'_';
00273 }
00274
00275 fName +=
"/.DCOPserver_";
00276
if (hostname.isEmpty())
00277 {
00278
char hostName[256];
00279 hostName[0] =
'\0';
00280
if (gethostname(hostName,
sizeof(hostName)))
00281 {
00282 fName +=
"localhost";
00283 }
00284
else
00285 {
00286 hostName[
sizeof(hostName)-1] =
'\0';
00287 fName += hostName;
00288 }
00289 }
00290
else
00291 {
00292 fName += hostname;
00293 }
00294 fName +=
"_"+disp;
00295
return fName;
00296 }
00297
00298
00299
00300 QCString DCOPClient::dcopServerFile(
const QCString &hostname)
00301 {
00302 return ::dcopServerFile(hostname,
false);
00303 }
00304
00305
00306
00307 QCString DCOPClient::dcopServerFileOld(
const QCString &hostname)
00308 {
00309 return ::dcopServerFile(hostname,
true);
00310 }
00311
00312
00313
const char* DCOPClientPrivate::serverAddr = 0;
00314
00315
#ifdef Q_OS_UNIX
00316
static void DCOPProcessInternal( DCOPClientPrivate *d,
int opcode, CARD32 key,
const QByteArray& dataReceived,
bool canPost );
00317
#endif
00318
00319
void DCOPClient::handleAsyncReply(ReplyStruct *replyStruct)
00320 {
00321
if (replyStruct->replyObject)
00322 {
00323 QObject::connect(
this, SIGNAL(callBack(
int,
const QCString&,
const QByteArray &)),
00324 replyStruct->replyObject, replyStruct->replySlot);
00325 emit callBack(replyStruct->replyId, *(replyStruct->replyType), *(replyStruct->replyData));
00326 QObject::disconnect(
this, SIGNAL(callBack(
int,
const QCString&,
const QByteArray &)),
00327 replyStruct->replyObject, replyStruct->replySlot);
00328 }
00329
delete replyStruct;
00330 }
00331
00332
#ifdef Q_OS_UNIX
00333
00336
static void DCOPProcessMessage(IceConn iceConn, IcePointer clientObject,
00337
int opcode,
unsigned long length, Bool ,
00338 IceReplyWaitInfo *replyWait,
00339 Bool *replyWaitRet)
00340 {
00341 DCOPMsg *pMsg = 0;
00342 DCOPClientPrivate *d = static_cast<DCOPClientPrivate *>(clientObject);
00343 DCOPClient::ReplyStruct *replyStruct = replyWait ? static_cast<DCOPClient::ReplyStruct*>(replyWait->reply) : 0;
00344
00345 IceReadMessageHeader(iceConn,
sizeof(DCOPMsg), DCOPMsg, pMsg);
00346 CARD32
key = pMsg->key;
00347
if ( d->key == 0 )
00348 d->key =
key;
00349
00350
QByteArray dataReceived( length );
00351 IceReadData(iceConn, length, dataReceived.data() );
00352
00353 d->opcode = opcode;
00354
switch (opcode ) {
00355
00356
case DCOPReplyFailed:
00357
if ( replyStruct ) {
00358 replyStruct->status = DCOPClient::ReplyStruct::Failed;
00359 replyStruct->transactionId = 0;
00360 *replyWaitRet = True;
00361
return;
00362 }
else {
00363 qWarning(
"Very strange! got a DCOPReplyFailed opcode, but we were not waiting for a reply!");
00364
return;
00365 }
00366
case DCOPReply:
00367
if ( replyStruct ) {
00368
QByteArray* b = replyStruct->replyData;
00369
QCString* t = replyStruct->replyType;
00370 replyStruct->status = DCOPClient::ReplyStruct::Ok;
00371 replyStruct->transactionId = 0;
00372
00373
QCString calledApp, app;
00374
QDataStream ds( dataReceived, IO_ReadOnly );
00375 ds >> calledApp >> app >> *t >> *b;
00376
00377 *replyWaitRet = True;
00378
return;
00379 }
else {
00380 qWarning(
"Very strange! got a DCOPReply opcode, but we were not waiting for a reply!");
00381
return;
00382 }
00383
case DCOPReplyWait:
00384
if ( replyStruct ) {
00385
QCString calledApp, app;
00386 Q_INT32
id;
00387
QDataStream ds( dataReceived, IO_ReadOnly );
00388 ds >> calledApp >> app >>
id;
00389 replyStruct->transactionId =
id;
00390 replyStruct->calledApp = calledApp;
00391 d->pendingReplies.append(replyStruct);
00392 *replyWaitRet = True;
00393
return;
00394 }
else {
00395 qWarning(
"Very strange! got a DCOPReplyWait opcode, but we were not waiting for a reply!");
00396
return;
00397 }
00398
case DCOPReplyDelayed:
00399 {
00400
QDataStream ds( dataReceived, IO_ReadOnly );
00401
QCString calledApp, app;
00402 Q_INT32
id;
00403
00404 ds >> calledApp >> app >>
id;
00405
if (replyStruct && (
id == replyStruct->transactionId) && (calledApp == replyStruct->calledApp))
00406 {
00407 *replyWaitRet = True;
00408 }
00409
00410
for(DCOPClient::ReplyStruct *rs = d->pendingReplies.first(); rs;
00411 rs = d->pendingReplies.next())
00412 {
00413
if ((rs->transactionId ==
id) && (rs->calledApp == calledApp))
00414 {
00415 d->pendingReplies.remove();
00416
QByteArray* b = rs->replyData;
00417
QCString* t = rs->replyType;
00418 ds >> *t >> *b;
00419
00420 rs->status = DCOPClient::ReplyStruct::Ok;
00421 rs->transactionId = 0;
00422
if (!rs->replySlot.isEmpty())
00423 {
00424 d->parent->handleAsyncReply(rs);
00425 }
00426
return;
00427 }
00428 }
00429 }
00430 qWarning(
"Very strange! got a DCOPReplyDelayed opcode, but we were not waiting for a reply!");
00431
return;
00432
case DCOPCall:
00433
case DCOPFind:
00434
case DCOPSend:
00435 DCOPProcessInternal( d, opcode, key, dataReceived,
true );
00436 }
00437 }
00438
#endif
00439
00440
void DCOPClient::processPostedMessagesInternal()
00441 {
00442
#ifdef Q_OS_UNIX
00443
if ( d->messages.isEmpty() )
00444
return;
00445
QPtrListIterator<DCOPClientMessage> it (d->messages );
00446 DCOPClientMessage* msg ;
00447
while ( ( msg = it.current() ) ) {
00448 ++it;
00449
if ( d->currentKey && msg->key != d->currentKey )
00450
continue;
00451 d->messages.removeRef( msg );
00452 d->opcode = msg->opcode;
00453 DCOPProcessInternal( d, msg->opcode, msg->key, msg->data,
false );
00454
delete msg;
00455 }
00456
if ( !d->messages.isEmpty() )
00457 d->postMessageTimer.start( 100,
true );
00458
#endif
00459
}
00460
00461
#ifdef Q_OS_UNIX
00462
00465
void DCOPProcessInternal( DCOPClientPrivate *d,
int opcode, CARD32 key,
const QByteArray& dataReceived,
bool canPost )
00466 {
00467
if (!d->accept_calls && (opcode == DCOPSend))
00468
return;
00469
00470 IceConn iceConn = d->iceConn;
00471 DCOPMsg *pMsg = 0;
00472
DCOPClient *c = d->parent;
00473
QDataStream ds( dataReceived, IO_ReadOnly );
00474
00475
QCString fromApp;
00476 ds >> fromApp;
00477
if (fromApp.isEmpty())
00478
return;
00479
00480
if (!d->accept_calls)
00481 {
00482
QByteArray reply;
00483
QDataStream replyStream( reply, IO_WriteOnly );
00484
00485 replyStream << d->appId << fromApp;
00486 IceGetHeader( iceConn, d->majorOpcode, DCOPReplyFailed,
00487
sizeof(DCOPMsg), DCOPMsg, pMsg );
00488
int datalen = reply.size();
00489 pMsg->key =
key;
00490 pMsg->length += datalen;
00491 IceSendData( iceConn, datalen, const_cast<char *>(reply.data()));
00492
return;
00493 }
00494
00495
QCString app, objId, fun;
00496
QByteArray data;
00497 ds >> app >> objId >> fun >> data;
00498 d->senderId = fromApp;
00499 d->objId = objId;
00500 d->function = fun;
00501
00502
00503
00504
if ( canPost && d->currentKey &&
key != d->currentKey ) {
00505 DCOPClientMessage* msg =
new DCOPClientMessage;
00506 msg->opcode = opcode;
00507 msg->key =
key;
00508 msg->data = dataReceived;
00509 d->messages.append( msg );
00510 d->postMessageTimer.start( 0,
true );
00511
return;
00512 }
00513
00514 d->objId = objId;
00515 d->function = fun;
00516
00517
QCString replyType;
00518
QByteArray replyData;
00519
bool b;
00520 CARD32 oldCurrentKey = d->currentKey;
00521
if ( opcode != DCOPSend )
00522 d->currentKey =
key;
00523
00524
if ( opcode == DCOPFind )
00525 b = c->
find(app, objId, fun, data, replyType, replyData );
00526
else
00527 b = c->
receive( app, objId, fun, data, replyType, replyData );
00528
00529
00530
if ( opcode == DCOPSend )
00531
return;
00532
00533
if ((d->currentKey ==
key) || (oldCurrentKey != 2))
00534 d->currentKey = oldCurrentKey;
00535
00536
QByteArray reply;
00537
QDataStream replyStream( reply, IO_WriteOnly );
00538
00539 Q_INT32
id = c->
transactionId();
00540
if (
id) {
00541
00542 replyStream << d->appId << fromApp <<
id;
00543
00544 IceGetHeader( iceConn, d->majorOpcode, DCOPReplyWait,
00545
sizeof(DCOPMsg), DCOPMsg, pMsg );
00546 pMsg->key =
key;
00547 pMsg->length += reply.size();
00548 IceSendData( iceConn, reply.size(), const_cast<char *>(reply.data()));
00549
return;
00550 }
00551
00552
if ( !b ) {
00553
00554
00555 replyStream << d->appId << fromApp;
00556 IceGetHeader( iceConn, d->majorOpcode, DCOPReplyFailed,
00557
sizeof(DCOPMsg), DCOPMsg, pMsg );
00558
int datalen = reply.size();
00559 pMsg->key =
key;
00560 pMsg->length += datalen;
00561 IceSendData( iceConn, datalen, const_cast<char *>(reply.data()));
00562
return;
00563 }
00564
00565
00566 replyStream << d->appId << fromApp << replyType << replyData.size();
00567
00568
00569
00570 IceGetHeader( iceConn, d->majorOpcode,
DCOPReply,
00571
sizeof(DCOPMsg), DCOPMsg, pMsg );
00572
int datalen = reply.size() + replyData.size();
00573 pMsg->key =
key;
00574 pMsg->length += datalen;
00575
00576
00577 IceSendData( iceConn, reply.size(), const_cast<char *>(reply.data()));
00578 IceSendData( iceConn, replyData.size(), const_cast<char *>(replyData.data()));
00579 }
00580
00581
00582
00583
static IcePoVersionRec DCOPClientVersions[] = {
00584 { DCOPVersionMajor, DCOPVersionMinor, DCOPProcessMessage }
00585 };
00586
#endif
00587
00588
00589
static DCOPClient* dcop_main_client = 0;
00590
00591 DCOPClient*
DCOPClient::mainClient()
00592 {
00593
return dcop_main_client;
00594 }
00595
00596 void DCOPClient::setMainClient(
DCOPClient* client )
00597 {
00598 dcop_main_client = client;
00599 }
00600
00601
00602 DCOPClient::DCOPClient()
00603 {
00604 d =
new DCOPClientPrivate;
00605 d->parent =
this;
00606
#ifdef Q_OS_UNIX
00607
d->iceConn = 0L;
00608 d->key = 0;
00609 d->currentKey = 0;
00610
#endif
00611
d->majorOpcode = 0;
00612 d->appId = 0;
00613 d->notifier = 0L;
00614 d->non_blocking_call_lock =
false;
00615 d->registered =
false;
00616 d->foreign_server =
true;
00617 d->accept_calls =
true;
00618 d->accept_calls_override =
false;
00619 d->qt_bridge_enabled =
true;
00620 d->transactionList = 0L;
00621 d->transactionId = 0;
00622 QObject::connect( &d->postMessageTimer, SIGNAL( timeout() ),
this, SLOT( processPostedMessagesInternal() ) );
00623 QObject::connect( &d->eventLoopTimer, SIGNAL( timeout() ),
this, SLOT( eventLoopTimeout() ) );
00624
00625
if ( !
mainClient() )
00626
setMainClient(
this );
00627 }
00628
00629 DCOPClient::~DCOPClient()
00630 {
00631
#ifdef DCOPCLIENT_DEBUG
00632
qWarning(
"d->messages.count() = %d", d->messages.count());
00633
QPtrListIterator<DCOPClientMessage> it (d->messages );
00634 DCOPClientMessage* msg ;
00635
while ( ( msg = it.current() ) ) {
00636 ++it;
00637 d->messages.removeRef( msg );
00638 qWarning(
"DROPPING UNHANDLED DCOP MESSAGE:");
00639 qWarning(
" opcode = %d key = %d", msg->opcode, msg->key);
00640
QDataStream ds( msg->data, IO_ReadOnly );
00641
00642
QCString fromApp, app, objId, fun;
00643 ds >> fromApp >> app >> objId >> fun;
00644 qWarning(
" from = %s", fromApp.data());
00645 qWarning(
" to = %s / %s / %s", app.data(), objId.data(), fun.data());
00646
delete msg;
00647 }
00648
#endif
00649
#ifdef Q_OS_UNIX
00650
if (d->iceConn)
00651
if (IceConnectionStatus(d->iceConn) == IceConnectAccepted)
00652
detach();
00653
#endif
00654
00655
if (d->registered)
00656 unregisterLocalClient( d->appId );
00657
00658
delete d->notifier;
00659
delete d->transactionList;
00660 d->messages.setAutoDelete(
true);
00661
delete d;
00662
00663
if (
mainClient() ==
this )
00664
setMainClient( 0 );
00665 }
00666
00667 void DCOPClient::setServerAddress(
const QCString &addr)
00668 {
00669
QCString env =
"DCOPSERVER=" + addr;
00670 putenv(strdup(env.data()));
00671
delete [] DCOPClientPrivate::serverAddr;
00672 DCOPClientPrivate::serverAddr = qstrdup( addr.data() );
00673 }
00674
00675 bool DCOPClient::attach()
00676 {
00677
if (!attachInternal(
true ))
00678
if (!attachInternal(
true ))
00679
return false;
00680
return true;
00681 }
00682
00683
void DCOPClient::bindToApp()
00684 {
00685
00686
00687
if (qApp) {
00688
if ( d->notifier )
00689
delete d->notifier;
00690 d->notifier =
new QSocketNotifier(
socket(),
00691 QSocketNotifier::Read, 0, 0);
00692 QObject::connect(d->notifier, SIGNAL(activated(
int)),
00693 SLOT(processSocketData(
int)));
00694 }
00695 }
00696
00697 void DCOPClient::suspend()
00698 {
00699 assert(d->notifier);
00700 d->notifier->setEnabled(
false);
00701 }
00702
00703 void DCOPClient::resume()
00704 {
00705 assert(d->notifier);
00706 d->notifier->setEnabled(
true);
00707 }
00708
00709 bool DCOPClient::isSuspended()
const
00710
{
00711
#if defined(Q_WS_WIN) || defined(Q_WS_MAC) //TODO: REMOVE
00712
if (!d->notifier)
00713
return false;
00714
#endif
00715
return !d->notifier->isEnabled();
00716 }
00717
00718
#ifdef SO_PEERCRED
00719
00720
static bool peerIsUs(
int sockfd)
00721 {
00722
struct ucred cred;
00723 socklen_t siz =
sizeof(cred);
00724
if (getsockopt(sockfd, SOL_SOCKET, SO_PEERCRED, &cred, &siz) != 0)
00725
return false;
00726
return (cred.uid == getuid());
00727 }
00728
#else
00729
00730
static bool isServerSocketOwnedByUser(
const char*server)
00731 {
00732
if (strncmp(server,
"local/", 6) != 0)
00733
return false;
00734
const char *path = strchr(server, KPATH_SEPARATOR);
00735
if (!path)
00736
return false;
00737 path++;
00738
00739
struct stat stat_buf;
00740
if (stat(path, &stat_buf) != 0)
00741
return false;
00742
00743
return (stat_buf.st_uid == getuid());
00744 }
00745
#endif
00746
00747
00748
bool DCOPClient::attachInternal(
bool registerAsAnonymous )
00749 {
00750
#ifdef Q_OS_UNIX
00751
char errBuf[1024];
00752
00753
if (
isAttached() )
00754
detach();
00755
00756
if ((d->majorOpcode = IceRegisterForProtocolSetup(const_cast<char *>(
"DCOP"),
00757 const_cast<char *>(DCOPVendorString),
00758 const_cast<char *>(DCOPReleaseString),
00759 1, DCOPClientVersions,
00760 DCOPAuthCount,
00761 const_cast<char **>(DCOPAuthNames),
00762 DCOPClientAuthProcs, 0L)) < 0) {
00763 emit
attachFailed(QString::fromLatin1(
"Communications could not be established." ));
00764
return false;
00765 }
00766
00767
bool bClearServerAddr =
false;
00768
00769
if (!d->serverAddr) {
00770
00771
00772
QString dcopSrv;
00773 dcopSrv = ::getenv(
"DCOPSERVER");
00774
if (dcopSrv.isEmpty()) {
00775
QString fName = dcopServerFile();
00776
QFile f(fName);
00777
if (!f.open(IO_ReadOnly)) {
00778 emit attachFailed(QString::fromLatin1(
"Could not read network connection list.\n" )+fName);
00779
return false;
00780 }
00781
int size = QMIN( 1024, f.size() );
00782
QCString contents( size+1 );
00783
if ( f.readBlock( contents.data(), size ) != size )
00784 {
00785 qDebug(
"Error reading from %s, didn't read the expected %d bytes", fName.latin1(), size);
00786
00787 }
00788 contents[size] =
'\0';
00789
int pos = contents.find(
'\n');
00790
if ( pos == -1 )
00791 {
00792 qDebug(
"Only one line in dcopserver file !: %s", contents.data());
00793 dcopSrv = QString::fromLatin1(contents);
00794 }
00795
else
00796 {
00797 dcopSrv = QString::fromLatin1(contents.left( pos ));
00798
00799
00800
00801 }
00802 }
00803 d->serverAddr = qstrdup( const_cast<char *>(dcopSrv.latin1()) );
00804 bClearServerAddr =
true;
00805 }
00806
00807
if ((d->iceConn = IceOpenConnection(const_cast<char*>(d->serverAddr),
00808 static_cast<IcePointer>(
this), False, d->majorOpcode,
00809
sizeof(errBuf), errBuf)) == 0L) {
00810 qDebug(
"DCOPClient::attachInternal. Attach failed %s", errBuf ? errBuf :
"");
00811 d->iceConn = 0;
00812
if (bClearServerAddr) {
00813
delete [] d->serverAddr;
00814 d->serverAddr = 0;
00815 }
00816 emit attachFailed(QString::fromLatin1( errBuf ));
00817
return false;
00818 }
00819
00820 IceSetShutdownNegotiation(d->iceConn, False);
00821
00822
int setupstat;
00823
char* vendor = 0;
00824
char* release = 0;
00825 setupstat = IceProtocolSetup(d->iceConn, d->majorOpcode,
00826 static_cast<IcePointer>(d),
00827 False,
00828 &(d->majorVersion), &(d->minorVersion),
00829 &(vendor), &(release), 1024, errBuf);
00830
if (vendor) free(vendor);
00831
if (release) free(release);
00832
00833
if (setupstat == IceProtocolSetupFailure ||
00834 setupstat == IceProtocolSetupIOError) {
00835 IceCloseConnection(d->iceConn);
00836 d->iceConn = 0;
00837
if (bClearServerAddr) {
00838
delete [] d->serverAddr;
00839 d->serverAddr = 0;
00840 }
00841 emit attachFailed(QString::fromLatin1( errBuf ));
00842
return false;
00843 }
else if (setupstat == IceProtocolAlreadyActive) {
00844
if (bClearServerAddr) {
00845
delete [] d->serverAddr;
00846 d->serverAddr = 0;
00847 }
00848
00849 emit attachFailed(QString::fromLatin1(
"internal error in IceOpenConnection" ));
00850
return false;
00851 }
00852
00853
00854
if (IceConnectionStatus(d->iceConn) != IceConnectAccepted) {
00855
if (bClearServerAddr) {
00856
delete [] d->serverAddr;
00857 d->serverAddr = 0;
00858 }
00859 emit attachFailed(QString::fromLatin1(
"DCOP server did not accept the connection." ));
00860
return false;
00861 }
00862
00863
#ifdef SO_PEERCRED
00864
d->foreign_server = !peerIsUs(
socket());
00865
#else
00866
d->foreign_server = !isServerSocketOwnedByUser(d->serverAddr);
00867
#endif
00868
if (!d->accept_calls_override)
00869 d->accept_calls = !d->foreign_server;
00870
00871 bindToApp();
00872
00873
if ( registerAsAnonymous )
00874
registerAs(
"anonymous",
true );
00875
00876
return true;
00877
#else
00878
return false;
00879
#endif
00880
}
00881
00882
00883 bool DCOPClient::detach()
00884 {
00885
#ifdef Q_OS_UNIX
00886
int status;
00887
00888
if (d->iceConn) {
00889 IceProtocolShutdown(d->iceConn, d->majorOpcode);
00890 status = IceCloseConnection(d->iceConn);
00891
if (status != IceClosedNow)
00892
return false;
00893
else
00894 d->iceConn = 0L;
00895 }
00896
00897
if (d->registered)
00898 unregisterLocalClient(d->appId);
00899
00900
delete d->notifier;
00901 d->notifier = 0L;
00902 d->registered =
false;
00903 d->foreign_server =
true;
00904
return true;
00905
#else
00906
return false;
00907
#endif
00908
}
00909
00910 bool DCOPClient::isAttached()
const
00911
{
00912
#ifdef Q_OS_UNIX
00913
if (!d->iceConn)
00914
return false;
00915
00916
return (IceConnectionStatus(d->iceConn) == IceConnectAccepted);
00917
#else
00918
return false;
00919
#endif
00920
}
00921
00922 bool DCOPClient::isAttachedToForeignServer()
const
00923
{
00924
return isAttached() && d->foreign_server;
00925 }
00926
00927 bool DCOPClient::acceptCalls()
const
00928
{
00929
return isAttached() && d->accept_calls;
00930 }
00931
00932 void DCOPClient::setAcceptCalls(
bool b)
00933 {
00934 d->accept_calls = b;
00935 d->accept_calls_override =
true;
00936 }
00937
00938 bool DCOPClient::qtBridgeEnabled()
00939 {
00940
return d->qt_bridge_enabled;
00941 }
00942
00943 void DCOPClient::setQtBridgeEnabled(
bool b)
00944 {
00945 d->qt_bridge_enabled = b;
00946 }
00947
00948 QCString DCOPClient::registerAs(
const QCString &appId,
bool addPID )
00949 {
00950
QCString result;
00951
00952
QCString _appId = appId;
00953
00954
if (addPID) {
00955
QCString pid;
00956 pid.sprintf(
"-%d", getpid());
00957 _appId = _appId + pid;
00958 }
00959
00960
if( d->appId == _appId )
00961
return d->appId;
00962
00963
#if 0 // no need to detach, dcopserver can handle renaming
00964
00965
if (
isRegistered() ) {
00966
detach();
00967 }
00968
#endif
00969
00970
if ( !
isAttached() ) {
00971
if (!attachInternal(
false ))
00972
if (!attachInternal(
false ))
00973
return result;
00974 }
00975
00976
00977
QCString replyType;
00978
QByteArray data, replyData;
00979
QDataStream arg( data, IO_WriteOnly );
00980 arg << _appId;
00981
if (
call(
"DCOPServer",
"",
"registerAs(QCString)", data, replyType, replyData ) ) {
00982
QDataStream reply( replyData, IO_ReadOnly );
00983 reply >> result;
00984 }
00985
00986 d->appId = result;
00987 d->registered = !result.isNull();
00988
00989
if (d->registered)
00990 registerLocalClient( d->appId,
this );
00991
00992
return result;
00993 }
00994
00995 bool DCOPClient::isRegistered()
const
00996
{
00997
return d->registered;
00998 }
00999
01000
01001 QCString DCOPClient::appId()
const
01002
{
01003
return d->appId;
01004 }
01005
01006
01007 int DCOPClient::socket()
const
01008
{
01009
#ifdef Q_OS_UNIX
01010
if (d->iceConn)
01011
return IceConnectionNumber(d->iceConn);
01012
#endif //Q_OS_UNIX
01013
return 0;
01014 }
01015
01016
static inline bool isIdentChar(
char x )
01017 {
01018
return x ==
'_' || (x >=
'0' && x <=
'9') ||
01019 (x >=
'a' && x <= 'z') || (x >=
'A' && x <=
'Z');
01020 }
01021
01022 QCString DCOPClient::normalizeFunctionSignature(
const QCString& fun ) {
01023
if ( fun.isEmpty() )
01024
return fun.copy();
01025
QCString result( fun.size() );
01026
char *from = fun.data();
01027
char *to = result.data();
01028
char *first = to;
01029
char last = 0;
01030
while (
true ) {
01031
while ( *from && isspace(*from) )
01032 from++;
01033
if ( last && isIdentChar( last ) && isIdentChar( *from ) )
01034 *to++ = 0x20;
01035
while ( *from && !isspace(*from) ) {
01036 last = *from++;
01037 *to++ = last;
01038 }
01039
if ( !*from )
01040
break;
01041 }
01042
if ( to > first && *(to-1) == 0x20 )
01043 to--;
01044 *to =
'\0';
01045 result.resize( (
int)((
long)to - (
long)result.data()) + 1 );
01046
return result;
01047 }
01048
01049
01050 QCString DCOPClient::senderId()
const
01051
{
01052
return d->senderId;
01053 }
01054
01055
01056 bool DCOPClient::send(
const QCString &remApp,
const QCString &remObjId,
01057
const QCString &remFun,
const QByteArray &data)
01058 {
01059
#ifdef Q_OS_UNIX
01060
if (remApp.isEmpty())
01061
return false;
01062
DCOPClient *localClient =
findLocalClient( remApp );
01063
01064
if ( localClient ) {
01065
bool saveTransaction = d->transaction;
01066 Q_INT32 saveTransactionId = d->transactionId;
01067
QCString saveSenderId = d->senderId;
01068
01069 d->senderId = 0;
01070
QCString replyType;
01071
QByteArray replyData;
01072 (
void) localClient->
receive( remApp, remObjId, remFun, data, replyType, replyData );
01073
01074 d->transaction = saveTransaction;
01075 d->transactionId = saveTransactionId;
01076 d->senderId = saveSenderId;
01077
01078
01079
01080
01081
return true;
01082 }
01083
01084
if ( !
isAttached() )
01085
return false;
01086
01087
01088 DCOPMsg *pMsg;
01089
01090
QByteArray ba;
01091
QDataStream ds(ba, IO_WriteOnly);
01092 ds << d->appId << remApp << remObjId <<
normalizeFunctionSignature(remFun) << data.size();
01093
01094 IceGetHeader(d->iceConn, d->majorOpcode, DCOPSend,
01095
sizeof(DCOPMsg), DCOPMsg, pMsg);
01096
01097 pMsg->key = 1;
01098
int datalen = ba.size() + data.size();
01099 pMsg->length += datalen;
01100
01101 IceSendData( d->iceConn, ba.size(), const_cast<char *>(ba.data()) );
01102 IceSendData( d->iceConn, data.size(), const_cast<char *>(data.data()) );
01103
01104
01105
01106
if (IceConnectionStatus(d->iceConn) == IceConnectAccepted)
01107
return true;
01108
#endif //Q_OS_UNIX
01109
return false;
01110 }
01111
01112 bool DCOPClient::send(
const QCString &remApp,
const QCString &remObjId,
01113
const QCString &remFun,
const QString &data)
01114 {
01115
QByteArray ba;
01116
QDataStream ds(ba, IO_WriteOnly);
01117 ds << data;
01118
return send(remApp, remObjId, remFun, ba);
01119 }
01120
01121 bool DCOPClient::findObject(
const QCString &remApp,
const QCString &remObj,
01122
const QCString &remFun,
const QByteArray &data,
01123
QCString &foundApp,
QCString &foundObj,
01124
bool useEventLoop)
01125 {
01126
return findObject( remApp, remObj, remFun, data, foundApp, foundObj, useEventLoop, -1 );
01127 }
01128
01129 bool DCOPClient::findObject(
const QCString &remApp,
const QCString &remObj,
01130
const QCString &remFun,
const QByteArray &data,
01131
QCString &foundApp,
QCString &foundObj,
01132
bool useEventLoop,
int timeout)
01133 {
01134
QCStringList appList;
01135
QCString app = remApp;
01136
if (app.isEmpty())
01137 app =
"*";
01138
01139 foundApp = 0;
01140 foundObj = 0;
01141
01142
if (app[app.length()-1] ==
'*')
01143 {
01144
01145
01146
01147
int len = app.length()-1;
01148
QCStringList apps=
registeredApplications();
01149
for( QCStringList::ConstIterator it = apps.begin();
01150 it != apps.end();
01151 ++it)
01152 {
01153
if ( strncmp( (*it).data(), app.data(), len) == 0)
01154 appList.append(*it);
01155 }
01156 }
01157
else
01158 {
01159 appList.append(app);
01160 }
01161
01162
01163
for(
int phase=1; phase <= 2; phase++)
01164 {
01165
for( QCStringList::ConstIterator it = appList.begin();
01166 it != appList.end();
01167 ++it)
01168 {
01169
QCString remApp = *it;
01170
QCString replyType;
01171
QByteArray replyData;
01172
bool result =
false;
01173
DCOPClient *localClient =
findLocalClient( remApp );
01174
01175
if ( (phase == 1) && localClient ) {
01176
01177
bool saveTransaction = d->transaction;
01178 Q_INT32 saveTransactionId = d->transactionId;
01179
QCString saveSenderId = d->senderId;
01180
01181 d->senderId = 0;
01182 result = localClient->
find( remApp, remObj, remFun, data, replyType, replyData );
01183
01184 Q_INT32
id = localClient->
transactionId();
01185
if (
id) {
01186
01187
do {
01188 QApplication::eventLoop()->processEvents( QEventLoop::WaitForMore);
01189 }
while( !localClient->
isLocalTransactionFinished(
id, replyType, replyData));
01190 result =
true;
01191 }
01192 d->transaction = saveTransaction;
01193 d->transactionId = saveTransactionId;
01194 d->senderId = saveSenderId;
01195 }
01196
else if ((phase == 2) && !localClient)
01197 {
01198
01199 result = callInternal(remApp, remObj, remFun, data,
01200 replyType, replyData, useEventLoop, timeout, DCOPFind);
01201 }
01202
01203
if (result)
01204 {
01205
if (replyType ==
"DCOPRef")
01206 {
01207
DCOPRef ref;
01208
QDataStream reply( replyData, IO_ReadOnly );
01209 reply >> ref;
01210
01211
if (ref.app() == remApp)
01212 {
01213
01214 foundApp = ref.app();
01215 foundObj = ref.object();
01216
return true;
01217 }
01218 }
01219 }
01220 }
01221 }
01222
return false;
01223 }
01224
01225 bool DCOPClient::process(
const QCString &,
const QByteArray &,
01226
QCString&,
QByteArray &)
01227 {
01228
return false;
01229 }
01230
01231 bool DCOPClient::isApplicationRegistered(
const QCString& remApp)
01232 {
01233
QCString replyType;
01234
QByteArray data, replyData;
01235
QDataStream arg( data, IO_WriteOnly );
01236 arg << remApp;
01237
int result =
false;
01238
if (
call(
"DCOPServer",
"",
"isApplicationRegistered(QCString)", data, replyType, replyData ) ) {
01239
QDataStream reply( replyData, IO_ReadOnly );
01240 reply >> result;
01241 }
01242
return result;
01243 }
01244
01245 QCStringList DCOPClient::registeredApplications()
01246 {
01247
QCString replyType;
01248
QByteArray data, replyData;
01249
QCStringList result;
01250
if (
call(
"DCOPServer",
"",
"registeredApplications()", data, replyType, replyData ) ) {
01251
QDataStream reply( replyData, IO_ReadOnly );
01252 reply >> result;
01253 }
01254
return result;
01255 }
01256
01257 QCStringList DCOPClient::remoteObjects(
const QCString& remApp,
bool *ok )
01258 {
01259
QCString replyType;
01260
QByteArray data, replyData;
01261
QCStringList result;
01262
if ( ok )
01263 *ok =
false;
01264
if (
call( remApp,
"DCOPClient",
"objects()", data, replyType, replyData ) ) {
01265
QDataStream reply( replyData, IO_ReadOnly );
01266 reply >> result;
01267
if ( ok )
01268 *ok =
true;
01269 }
01270
return result;
01271 }
01272
01273 QCStringList DCOPClient::remoteInterfaces(
const QCString& remApp,
const QCString& remObj,
bool *ok )
01274 {
01275
QCString replyType;
01276
QByteArray data, replyData;
01277
QCStringList result;
01278
if ( ok )
01279 *ok =
false;
01280
if (
call( remApp, remObj,
"interfaces()", data, replyType, replyData ) && replyType ==
"QCStringList") {
01281
QDataStream reply( replyData, IO_ReadOnly );
01282 reply >> result;
01283
if ( ok )
01284 *ok =
true;
01285 }
01286
return result;
01287 }
01288
01289 QCStringList DCOPClient::remoteFunctions(
const QCString& remApp,
const QCString& remObj,
bool *ok )
01290 {
01291
QCString replyType;
01292
QByteArray data, replyData;
01293
QCStringList result;
01294
if ( ok )
01295 *ok =
false;
01296
if (
call( remApp, remObj,
"functions()", data, replyType, replyData ) && replyType ==
"QCStringList") {
01297
QDataStream reply( replyData, IO_ReadOnly );
01298 reply >> result;
01299
if ( ok )
01300 *ok =
true;
01301 }
01302
return result;
01303 }
01304
01305 void DCOPClient::setNotifications(
bool enabled)
01306 {
01307
QByteArray data;
01308
QDataStream ds(data, IO_WriteOnly);
01309 ds << static_cast<Q_INT8>(enabled);
01310
01311
QCString replyType;
01312
QByteArray reply;
01313
if (!
call(
"DCOPServer",
"",
"setNotifications( bool )", data, replyType, reply))
01314 qWarning(
"I couldn't enable notifications at the dcopserver!");
01315 }
01316
01317 void DCOPClient::setDaemonMode(
bool daemonMode )
01318 {
01319
QByteArray data;
01320
QDataStream ds(data, IO_WriteOnly);
01321 ds << static_cast<Q_INT8>( daemonMode );
01322
01323
QCString replyType;
01324
QByteArray reply;
01325
if (!
call(
"DCOPServer",
"",
"setDaemonMode(bool)", data, replyType, reply))
01326 qWarning(
"I couldn't enable daemon mode at the dcopserver!");
01327 }
01328
01329
01330
01331
01332
01333
01334
01335
01336
static void fillQtObjects(
QCStringList& l,
QObject* o,
QCString path )
01337 {
01338
if ( !path.isEmpty() )
01339 path +=
'/';
01340
01341
int unnamed = 0;
01342
const QObjectList *list = o ? o->children() :
QObject::objectTrees();
01343
if ( list ) {
01344 QObjectListIt it( *list );
01345
QObject *obj;
01346
while ( (obj=it.current()) ) {
01347 ++it;
01348
QCString n = obj->name();
01349
if ( n ==
"unnamed" || n.isEmpty() )
01350 {
01351 n.sprintf(
"%p", (
void *) obj);
01352 n =
QString(
"unnamed%1(%2, %3)").arg(++unnamed).arg(obj->className()).arg(n).latin1();
01353 }
01354
QCString fn = path + n;
01355 l.append( fn );
01356
if ( obj->children() )
01357 fillQtObjects( l, obj, fn );
01358 }
01359 }
01360 }
01361
01362
namespace
01363
{
01364
struct O
01365 {
01366 O(): o(0) {}
01367 O (
const QCString& str,
QObject* obj ):s(str), o(obj){}
01368
QCString s;
01369
QObject* o;
01370 };
01371 }
01372
01373
static void fillQtObjectsEx(
QValueList<O>& l,
QObject* o,
QCString path )
01374 {
01375
if ( !path.isEmpty() )
01376 path +=
'/';
01377
01378
int unnamed = 0;
01379
const QObjectList *list = o ? o->children() :
QObject::objectTrees();
01380
if ( list ) {
01381 QObjectListIt it( *list );
01382
QObject *obj;
01383
while ( (obj=it.current()) ) {
01384 ++it;
01385
QCString n = obj->name();
01386
if ( n ==
"unnamed" || n.isEmpty() )
01387 {
01388 n.sprintf(
"%p", (
void *) obj);
01389 n =
QString(
"unnamed%1(%2, %3)").arg(++unnamed).arg(obj->className()).arg(n).latin1();
01390 }
01391
QCString fn = path + n;
01392 l.append( O( fn, obj ) );
01393
if ( obj->children() )
01394 fillQtObjectsEx( l, obj, fn );
01395 }
01396 }
01397 }
01398
01399
01400
static QObject* findQtObject(
QCString id )
01401 {
01402
QRegExp expr(
id );
01403
QValueList<O> l;
01404 fillQtObjectsEx( l, 0,
"qt" );
01405
01406
QObject* firstContains = 0L;
01407
for (
QValueList<O>::ConstIterator it = l.begin(); it != l.end(); ++it ) {
01408
if ( (*it).s ==
id )
01409
return (*it).o;
01410
if ( !firstContains && (*it).s.contains( expr ) ) {
01411 firstContains = (*it).o;
01412 }
01413 }
01414
return firstContains;
01415 }
01416
01417
static QCStringList findQtObjects(
QCString id )
01418 {
01419
QRegExp expr(
id );
01420
QValueList<O> l;
01421 fillQtObjectsEx( l, 0,
"qt" );
01422
QCStringList result;
01423
for (
QValueList<O>::ConstIterator it = l.begin(); it != l.end(); ++it ) {
01424
if ( (*it).s.contains( expr ) )
01425 result << (*it).s;
01426 }
01427
return result;
01428 }
01429
01430
static bool receiveQtObject(
const QCString &objId,
const QCString &fun,
const QByteArray &data,
01431
QCString& replyType,
QByteArray &replyData)
01432 {
01433
if ( objId ==
"qt" ) {
01434
if ( fun ==
"interfaces()" ) {
01435 replyType =
"QCStringList";
01436
QDataStream reply( replyData, IO_WriteOnly );
01437
QCStringList l;
01438 l <<
"DCOPObject";
01439 l <<
"Qt";
01440 reply << l;
01441
return true;
01442 }
else if ( fun ==
"functions()" ) {
01443 replyType =
"QCStringList";
01444
QDataStream reply( replyData, IO_WriteOnly );
01445
QCStringList l;
01446 l <<
"QCStringList functions()";
01447 l <<
"QCStringList interfaces()";
01448 l <<
"QCStringList objects()";
01449 l <<
"QCStringList find(QCString)";
01450 reply << l;
01451
return true;
01452 }
else if ( fun ==
"objects()" ) {
01453 replyType =
"QCStringList";
01454
QDataStream reply( replyData, IO_WriteOnly );
01455
QCStringList l;
01456 fillQtObjects( l, 0,
"qt" );
01457 reply << l;
01458
return true;
01459 }
else if ( fun ==
"find(QCString)" ) {
01460
QDataStream ds( data, IO_ReadOnly );
01461
QCString id;
01462 ds >>
id ;
01463 replyType =
"QCStringList";
01464
QDataStream reply( replyData, IO_WriteOnly );
01465 reply << findQtObjects(
id ) ;
01466
return true;
01467 }
01468 }
else if ( objId.left(3) ==
"qt/" ) {
01469
QObject* o = findQtObject( objId );
01470
if ( !o )
01471
return false;
01472
if ( fun ==
"functions()" ) {
01473 replyType =
"QCStringList";
01474
QDataStream reply( replyData, IO_WriteOnly );
01475
QCStringList l;
01476 l <<
"QCStringList functions()";
01477 l <<
"QCStringList interfaces()";
01478 l <<
"QCStringList properties()";
01479 l <<
"bool setProperty(QCString,QVariant)";
01480 l <<
"QVariant property(QCString)";
01481
QStrList lst = o->metaObject()->slotNames(
true );
01482
int i = 0;
01483
for (
QPtrListIterator<char> it( lst ); it.current(); ++it ) {
01484
if ( o->metaObject()->slot( i++,
true )->access != QMetaData::Public )
01485
continue;
01486
QCString slot = it.current();
01487
if ( slot.contains(
"()" ) ) {
01488 slot.prepend(
"void ");
01489 l << slot;
01490 }
01491 }
01492 reply << l;
01493
return true;
01494 }
else if ( fun ==
"interfaces()" ) {
01495 replyType =
"QCStringList";
01496
QDataStream reply( replyData, IO_WriteOnly );
01497
QCStringList l;
01498
QMetaObject *meta = o->metaObject();
01499
while ( meta ) {
01500 l.prepend( meta->
className() );
01501 meta = meta->
superClass();
01502 }
01503 reply << l;
01504
return true;
01505 }
else if ( fun ==
"properties()" ) {
01506 replyType =
"QCStringList";
01507
QDataStream reply( replyData, IO_WriteOnly );
01508
QCStringList l;
01509
QStrList lst = o->metaObject()->propertyNames(
true );
01510
for (
QPtrListIterator<char> it( lst ); it.current(); ++it ) {
01511
QMetaObject *mo = o->metaObject();
01512
const QMetaProperty* p = mo->
property( mo->findProperty( it.current(),
true ),
true );
01513
if ( !p )
01514
continue;
01515
QCString prop = p->type();
01516 prop +=
' ';
01517 prop += p->name();
01518
if ( !p->writable() )
01519 prop +=
" readonly";
01520 l << prop;
01521 }
01522 reply << l;
01523
return true;
01524 }
else if ( fun ==
"property(QCString)" ) {
01525 replyType =
"QVariant";
01526
QDataStream ds( data, IO_ReadOnly );
01527
QCString name;
01528 ds >>
name ;
01529
QVariant result = o->property( name );
01530
QDataStream reply( replyData, IO_WriteOnly );
01531 reply << result;
01532
return true;
01533 }
else if ( fun ==
"setProperty(QCString,QVariant)" ) {
01534
QDataStream ds( data, IO_ReadOnly );
01535
QCString name;
01536
QVariant value;
01537 ds >>
name >> value;
01538 replyType =
"bool";
01539
QDataStream reply( replyData, IO_WriteOnly );
01540 reply << (Q_INT8) o->setProperty( name, value );
01541
return true;
01542 }
else {
01543
int slot = o->metaObject()->findSlot( fun,
true );
01544
if ( slot != -1 ) {
01545 replyType =
"void";
01546 QUObject uo[ 1 ];
01547 o->qt_invoke( slot, uo );
01548
return true;
01549 }
01550 }
01551
01552
01553 }
01554
return false;
01555 }
01556
01557
01558
01559
01560
01561
01562
01563
01564
bool DCOPClient::receive(
const QCString &,
const QCString &objId,
01565
const QCString &fun,
const QByteArray &data,
01566
QCString& replyType,
QByteArray &replyData)
01567 {
01568 d->transaction =
false;
01569
if ( objId ==
"DCOPClient" ) {
01570
if ( fun ==
"objects()" ) {
01571 replyType =
"QCStringList";
01572
QDataStream reply( replyData, IO_WriteOnly );
01573
QCStringList l;
01574
if (d->qt_bridge_enabled)
01575 {
01576 l <<
"qt";
01577 }
01578
if ( kde_dcopObjMap ) {
01579
QMap<QCString, DCOPObject *>::ConstIterator it( kde_dcopObjMap->begin());
01580
for (; it != kde_dcopObjMap->end(); ++it) {
01581
if ( !it.key().isEmpty() ) {
01582
if ( it.key() == d->defaultObject )
01583 l <<
"default";
01584 l << it.key();
01585 }
01586 }
01587 }
01588 reply << l;
01589
return true;
01590 }
01591 }
01592
01593
if ( objId.isEmpty() || objId ==
"DCOPClient" ) {
01594
if ( fun ==
"applicationRegistered(QCString)" ) {
01595
QDataStream ds( data, IO_ReadOnly );
01596
QCString r;
01597 ds >> r;
01598 emit
applicationRegistered( r );
01599
return true;
01600 }
else if ( fun ==
"applicationRemoved(QCString)" ) {
01601
QDataStream ds( data, IO_ReadOnly );
01602
QCString r;
01603 ds >> r;
01604 emit
applicationRemoved( r );
01605
return true;
01606 }
01607
01608
if (
process( fun, data, replyType, replyData ) )
01609
return true;
01610
01611
01612 }
else if (d->qt_bridge_enabled &&
01613 (objId ==
"qt" || objId.left(3) ==
"qt/") ) {
01614
return receiveQtObject( objId, fun, data, replyType, replyData );
01615 }
01616
01617
if ( objId.isEmpty() || objId ==
"default" ) {
01618
if ( !d->defaultObject.isEmpty() &&
DCOPObject::hasObject( d->defaultObject ) ) {
01619
DCOPObject *objPtr =
DCOPObject::find( d->defaultObject );
01620 objPtr->
setCallingDcopClient(
this);
01621
if (objPtr->
process(fun, data, replyType, replyData))
01622
return true;
01623 }
01624
01625
01626 }
01627
01628
if (!objId.isEmpty() && objId[objId.length()-1] ==
'*') {
01629
01630
01631
QPtrList<DCOPObject> matchList =
01632
DCOPObject::match(objId.left(objId.length()-1));
01633
for (
DCOPObject *objPtr = matchList.first();
01634 objPtr != 0L; objPtr = matchList.next()) {
01635 objPtr->
setCallingDcopClient(
this);
01636
if (!objPtr->
process(fun, data, replyType, replyData))
01637
return false;
01638 }
01639
return true;
01640 }
else if (!
DCOPObject::hasObject(objId)) {
01641
if ( DCOPObjectProxy::proxies ) {
01642
for (
QPtrListIterator<DCOPObjectProxy> it( *DCOPObjectProxy::proxies ); it.current(); ++it ) {
01643
01644
if ( it.current()->process( objId, fun, data, replyType, replyData ) )
01645
return true;
01646 }
01647 }
01648
return false;
01649
01650 }
else {
01651
DCOPObject *objPtr =
DCOPObject::find(objId);
01652 objPtr->
setCallingDcopClient(
this);
01653
if (!objPtr->
process(fun, data, replyType, replyData)) {
01654
01655
return false;
01656 }
01657 }
01658
01659
return true;
01660 }
01661
01662
01663
01664
01665
static bool findResultOk(
QCString &replyType,
QByteArray &replyData)
01666 {
01667 Q_INT8 success;
01668
if (replyType !=
"bool")
return false;
01669
01670
QDataStream reply( replyData, IO_ReadOnly );
01671 reply >> success;
01672
01673
if (!success)
return false;
01674
return true;
01675 }
01676
01677
01678
01679
static bool findSuccess(
const QCString &app,
const QCString objId,
QCString &replyType,
QByteArray &replyData)
01680 {
01681
DCOPRef ref(app, objId);
01682 replyType =
"DCOPRef";
01683
01684 replyData =
QByteArray();
01685
QDataStream final_reply( replyData, IO_WriteOnly );
01686 final_reply << ref;
01687
return true;
01688 }
01689
01690
01691
bool DCOPClient::find(
const QCString &app,
const QCString &objId,
01692
const QCString &fun,
const QByteArray &data,
01693
QCString& replyType,
QByteArray &replyData)
01694 {
01695 d->transaction =
false;
01696
if ( !app.isEmpty() && app != d->appId && app[app.length()-1] !=
'*') {
01697 qWarning(
"WEIRD! we somehow received a DCOP message w/a different appId");
01698
return false;
01699 }
01700
01701
if (objId.isEmpty() || objId[objId.length()-1] !=
'*')
01702 {
01703
if (fun.isEmpty())
01704 {
01705
if (objId.isEmpty() ||
DCOPObject::hasObject(objId))
01706
return findSuccess(app, objId, replyType, replyData);
01707
return false;
01708 }
01709
01710
if (receive(app, objId, fun, data, replyType, replyData))
01711 {
01712
if (findResultOk(replyType, replyData))
01713
return findSuccess(app, objId, replyType, replyData);
01714 }
01715 }
01716
else {
01717
01718
01719
QPtrList<DCOPObject> matchList =
01720
DCOPObject::match(objId.left(objId.length()-1));
01721
for (
DCOPObject *objPtr = matchList.first();
01722 objPtr != 0L; objPtr = matchList.next())
01723 {
01724 replyType = 0;
01725 replyData =
QByteArray();
01726
if (fun.isEmpty())
01727
return findSuccess(app, objPtr->
objId(), replyType, replyData);
01728 objPtr->
setCallingDcopClient(
this);
01729
if (objPtr->
process(fun, data, replyType, replyData))
01730
if (findResultOk(replyType, replyData))
01731
return findSuccess(app, objPtr->
objId(), replyType, replyData);
01732 }
01733 }
01734
return false;
01735 }
01736
01737
01738 bool DCOPClient::call(
const QCString &remApp,
const QCString &remObjId,
01739
const QCString &remFun,
const QByteArray &data,
01740
QCString& replyType,
QByteArray &replyData,
01741
bool useEventLoop)
01742 {
01743
return call( remApp, remObjId, remFun, data, replyType, replyData, useEventLoop, -1 );
01744 }
01745
01746 bool DCOPClient::call(
const QCString &remApp,
const QCString &remObjId,
01747
const QCString &remFun,
const QByteArray &data,
01748
QCString& replyType,
QByteArray &replyData,
01749
bool useEventLoop,
int timeout)
01750 {
01751
if (remApp.isEmpty())
01752
return false;
01753
DCOPClient *localClient =
findLocalClient( remApp );
01754
01755
if ( localClient ) {
01756
bool saveTransaction = d->transaction;
01757 Q_INT32 saveTransactionId = d->transactionId;
01758
QCString saveSenderId = d->senderId;
01759
01760 d->senderId = 0;
01761
bool b = localClient->
receive( remApp, remObjId, remFun, data, replyType, replyData );
01762
01763 Q_INT32
id = localClient->
transactionId();
01764
if (
id) {
01765
01766
do {
01767 QApplication::eventLoop()->processEvents( QEventLoop::WaitForMore);
01768 }
while( !localClient->
isLocalTransactionFinished(
id, replyType, replyData));
01769 b =
true;
01770 }
01771 d->transaction = saveTransaction;
01772 d->transactionId = saveTransactionId;
01773 d->senderId = saveSenderId;
01774
return b;
01775 }
01776
01777
return callInternal(remApp, remObjId, remFun, data,
01778 replyType, replyData, useEventLoop, timeout, DCOPCall);
01779 }
01780
01781
void DCOPClient::asyncReplyReady()
01782 {
01783
while( d->asyncReplyQueue.count() )
01784 {
01785 ReplyStruct *replyStruct = d->asyncReplyQueue.take(0);
01786 handleAsyncReply(replyStruct);
01787 }
01788 }
01789
01790 int DCOPClient::callAsync(
const QCString &remApp,
const QCString &remObjId,
01791
const QCString &remFun,
const QByteArray &data,
01792
QObject *callBackObj,
const char *callBackSlot)
01793 {
01794
QCString replyType;
01795
QByteArray replyData;
01796
01797 ReplyStruct *replyStruct =
new ReplyStruct;
01798 replyStruct->replyType =
new QCString;
01799 replyStruct->replyData =
new QByteArray;
01800 replyStruct->replyObject = callBackObj;
01801 replyStruct->replySlot = callBackSlot;
01802 replyStruct->replyId = ++d->transactionId;
01803
if (d->transactionId < 0)
01804 d->transactionId = 0;
01805
01806
bool b = callInternal(remApp, remObjId, remFun, data,
01807 replyStruct,
false, -1, DCOPCall);
01808
if (!b)
01809 {
01810
delete replyStruct->replyType;
01811
delete replyStruct->replyData;
01812
delete replyStruct;
01813
return 0;
01814 }
01815
01816
if (replyStruct->transactionId == 0)
01817 {
01818
01819 QTimer::singleShot(0,
this, SLOT(asyncReplyReady()));
01820 d->asyncReplyQueue.append(replyStruct);
01821 }
01822
01823
return replyStruct->replyId;
01824 }
01825
01826
bool DCOPClient::callInternal(
const QCString &remApp,
const QCString &remObjId,
01827
const QCString &remFun,
const QByteArray &data,
01828
QCString& replyType,
QByteArray &replyData,
01829
bool useEventLoop,
int timeout,
int minor_opcode)
01830 {
01831
#ifdef Q_OS_UNIX
01832
ReplyStruct replyStruct;
01833 replyStruct.replyType = &replyType;
01834 replyStruct.replyData = &replyData;
01835
return callInternal(remApp, remObjId, remFun, data, &replyStruct, useEventLoop, timeout, minor_opcode);
01836
#else
01837
return false;
01838
#endif
01839
}
01840
01841
bool DCOPClient::callInternal(
const QCString &remApp,
const QCString &remObjId,
01842
const QCString &remFun,
const QByteArray &data,
01843 ReplyStruct *replyStruct,
01844
bool useEventLoop,
int timeout,
int minor_opcode)
01845 {
01846
#ifdef Q_OS_UNIX
01847
if ( !
isAttached() )
01848
return false;
01849
01850 DCOPMsg *pMsg;
01851
01852 CARD32 oldCurrentKey = d->currentKey;
01853
if ( !d->currentKey )
01854 d->currentKey = d->key;
01855
01856
QByteArray ba;
01857
QDataStream ds(ba, IO_WriteOnly);
01858 ds << d->appId << remApp << remObjId <<
normalizeFunctionSignature(remFun) << data.size();
01859
01860 IceGetHeader(d->iceConn, d->majorOpcode, minor_opcode,
01861
sizeof(DCOPMsg), DCOPMsg, pMsg);
01862
01863 pMsg->key = d->currentKey;
01864
int datalen = ba.size() + data.size();
01865 pMsg->length += datalen;
01866
01867
01868
01869 IceSendData(d->iceConn, ba.size(), const_cast<char *>(ba.data()));
01870 IceSendData(d->iceConn, data.size(), const_cast<char *>(data.data()));
01871
01872
if (IceConnectionStatus(d->iceConn) != IceConnectAccepted)
01873
return false;
01874
01875 IceFlush (d->iceConn);
01876
01877 IceReplyWaitInfo waitInfo;
01878 waitInfo.sequence_of_request = IceLastSentSequenceNumber(d->iceConn);
01879 waitInfo.major_opcode_of_request = d->majorOpcode;
01880 waitInfo.minor_opcode_of_request = minor_opcode;
01881
01882 replyStruct->transactionId = -1;
01883 waitInfo.reply = static_cast<IcePointer>(replyStruct);
01884
01885 Bool readyRet = False;
01886 IceProcessMessagesStatus s;
01887
01888 timeval time_start;
01889
int time_left = -1;
01890
if( timeout >= 0 )
01891 {
01892 gettimeofday( &time_start, NULL );
01893 time_left = timeout;
01894 }
01895
for(;;) {
01896
bool checkMessages =
true;
01897
if ( useEventLoop
01898 ? d->notifier != NULL
01899 : timeout >= 0 ) {
01900
const int guiTimeout = 100;
01901 checkMessages =
false;
01902
01903
int msecs = useEventLoop
01904 ? guiTimeout
01905 : time_left;
01906 fd_set fds;
01907
struct timeval tv;
01908 FD_ZERO( &fds );
01909 FD_SET(
socket(), &fds );
01910 tv.tv_sec = msecs / 1000;
01911 tv.tv_usec = (msecs % 1000) * 1000;
01912
if ( select(
socket() + 1, &fds, 0, 0, &tv ) <= 0 ) {
01913
if( useEventLoop && (timeout < 0 || time_left > guiTimeout)) {
01914
01915
01916
bool old_lock = d->non_blocking_call_lock;
01917
if ( !old_lock ) {
01918 d->non_blocking_call_lock =
true;
01919 emit
blockUserInput(
true );
01920 }
01921
if( timeout >= 0 )
01922 d->eventLoopTimer.start(time_left - guiTimeout,
true);
01923 qApp->enter_loop();
01924 d->eventLoopTimer.stop();
01925
if ( !old_lock ) {
01926 d->non_blocking_call_lock =
false;
01927 emit
blockUserInput(
false );
01928 }
01929 }
01930 }
01931
else
01932 {
01933 checkMessages =
true;
01934 }
01935 }
01936
if (!d->iceConn)
01937
return false;
01938
01939
if( replyStruct->transactionId != -1 )
01940 {
01941
if (replyStruct->transactionId == 0)
01942
break;
01943
if (!replyStruct->replySlot.isEmpty())
01944
break;
01945 }
01946
01947
if( checkMessages ) {
01948 s = IceProcessMessages(d->iceConn, &waitInfo,
01949 &readyRet);
01950
if (s == IceProcessMessagesIOError) {
01951
detach();
01952 d->currentKey = oldCurrentKey;
01953
return false;
01954 }
01955 }
01956
01957
if( replyStruct->transactionId != -1 )
01958 {
01959
if (replyStruct->transactionId == 0)
01960
break;
01961
if (!replyStruct->replySlot.isEmpty())
01962
break;
01963 }
01964
01965
if( timeout < 0 )
01966
continue;
01967 timeval time_now;
01968 gettimeofday( &time_now, NULL );
01969 time_left = timeout -
01970 ((time_now.tv_sec - time_start.tv_sec) * 1000) -
01971 ((time_now.tv_usec - time_start.tv_usec) / 1000);
01972
if( time_left <= 0)
01973 {
01974
if (useEventLoop)
01975 {
01976
01977 time_left = 0;
01978 useEventLoop =
false;
01979
continue;
01980 }
01981 *(replyStruct->replyType) =
QCString();
01982 *(replyStruct->replyData) =
QByteArray();
01983 replyStruct->status = ReplyStruct::Failed;
01984
break;
01985 }
01986 }
01987
01988
01989
if ( d->non_blocking_call_lock ) {
01990 qApp->exit_loop();
01991 }
01992
01993 d->currentKey = oldCurrentKey;
01994
return replyStruct->status != ReplyStruct::Failed;
01995
#else
01996
return false;
01997
#endif
01998
}
01999
02000
void DCOPClient::eventLoopTimeout()
02001 {
02002 qApp->exit_loop();
02003 }
02004
02005 void DCOPClient::processSocketData(
int fd)
02006 {
02007
#ifdef Q_OS_UNIX
02008
02009 fd_set fds;
02010 timeval timeout;
02011 timeout.tv_sec = 0;
02012 timeout.tv_usec = 0;
02013 FD_ZERO(&fds);
02014 FD_SET(fd, &fds);
02015
int result = select(fd+1, &fds, 0, 0, &timeout);
02016
if (result == 0)
02017
return;
02018
02019
if ( d->non_blocking_call_lock ) {
02020 qApp->exit_loop();
02021
return;
02022 }
02023
02024
if (!d->iceConn) {
02025 d->notifier->deleteLater();
02026 d->notifier = 0;
02027 qWarning(
"received an error processing data from the DCOP server!");
02028
return;
02029 }
02030
02031 IceProcessMessagesStatus s = IceProcessMessages(d->iceConn, 0, 0);
02032
02033
if (s == IceProcessMessagesIOError) {
02034
detach();
02035 qWarning(
"received an error processing data from the DCOP server!");
02036
return;
02037 }
02038
#endif //Q_OS_UNIX
02039
}
02040
02041 void DCOPClient::setDefaultObject(
const QCString& objId )
02042 {
02043 d->defaultObject = objId;
02044 }
02045
02046
02047 QCString DCOPClient::defaultObject()
const
02048
{
02049
return d->defaultObject;
02050 }
02051
02052
bool
02053 DCOPClient::isLocalTransactionFinished(Q_INT32
id,
QCString &replyType,
QByteArray &replyData)
02054 {
02055 DCOPClientPrivate::LocalTransactionResult *result = d->localTransActionList.take(
id);
02056
if (!result)
02057
return false;
02058
02059 replyType = result->replyType;
02060 replyData = result->replyData;
02061
delete result;
02062
02063
return true;
02064 }
02065
02066 DCOPClientTransaction *
02067 DCOPClient::beginTransaction()
02068 {
02069
if (d->opcode == DCOPSend)
02070
return 0;
02071
if (!d->transactionList)
02072 d->transactionList =
new QPtrList<DCOPClientTransaction>;
02073
02074 d->transaction =
true;
02075 DCOPClientTransaction *trans =
new DCOPClientTransaction();
02076 trans->senderId = d->senderId;
02077 trans->id = ++d->transactionId;
02078
if (d->transactionId < 0)
02079 d->transactionId = 0;
02080
#ifdef Q_OS_UNIX
02081
trans->key = d->currentKey;
02082
#endif
02083
02084 d->transactionList->append( trans );
02085
02086
return trans;
02087 }
02088
02089 Q_INT32
02090 DCOPClient::transactionId()
const
02091
{
02092
if (d->transaction)
02093
return d->transactionId;
02094
else
02095
return 0;
02096 }
02097
02098
void
02099 DCOPClient::endTransaction( DCOPClientTransaction *trans,
QCString& replyType,
02100
QByteArray &replyData)
02101 {
02102
if ( !trans )
02103
return;
02104
02105
if ( !
isAttached() )
02106
return;
02107
02108
if ( !d->transactionList) {
02109 qWarning(
"Transaction unknown: No pending transactions!");
02110
return;
02111 }
02112
02113
if ( !d->transactionList->removeRef( trans ) ) {
02114 qWarning(
"Transaction unknown: Not on list of pending transactions!");
02115
return;
02116 }
02117
02118
if (trans->senderId.isEmpty())
02119 {
02120
02121 DCOPClientPrivate::LocalTransactionResult *result =
new DCOPClientPrivate::LocalTransactionResult();
02122 result->replyType = replyType;
02123 result->replyData = replyData;
02124
02125 d->localTransActionList.insert(trans->id, result);
02126
02127
delete trans;
02128
02129
return;
02130 }
02131
02132
#ifdef Q_OS_UNIX
02133
DCOPMsg *pMsg;
02134
02135
QByteArray ba;
02136
QDataStream ds(ba, IO_WriteOnly);
02137 ds << d->appId << trans->senderId << trans->id << replyType << replyData;
02138
02139 IceGetHeader(d->iceConn, d->majorOpcode, DCOPReplyDelayed,
02140
sizeof(DCOPMsg), DCOPMsg, pMsg);
02141 pMsg->key = trans->key;
02142 pMsg->length += ba.size();
02143
02144 IceSendData( d->iceConn, ba.size(), const_cast<char *>(ba.data()) );
02145
#endif
02146
02147
delete trans;
02148 }
02149
02150
void
02151 DCOPClient::emitDCOPSignal(
const QCString &object,
const QCString &signal,
const QByteArray &data)
02152 {
02153
02154
send(
"DCOPServer",
"emit", object+
"#"+normalizeFunctionSignature(signal), data);
02155 }
02156
02157
void
02158 DCOPClient::emitDCOPSignal(
const QCString &signal,
const QByteArray &data)
02159 {
02160 emitDCOPSignal(0, signal, data);
02161 }
02162
02163
bool
02164 DCOPClient::connectDCOPSignal(
const QCString &sender,
const QCString &senderObj,
02165
const QCString &signal,
02166
const QCString &receiverObj,
const QCString &slot,
bool Volatile)
02167 {
02168
QCString replyType;
02169
QByteArray data, replyData;
02170 Q_INT8 iVolatile = Volatile ? 1 : 0;
02171
02172
QDataStream args(data, IO_WriteOnly );
02173 args << sender << senderObj << normalizeFunctionSignature(signal) << receiverObj << normalizeFunctionSignature(slot) << iVolatile;
02174
02175
if (!
call(
"DCOPServer", 0,
02176
"connectSignal(QCString,QCString,QCString,QCString,QCString,bool)",
02177 data, replyType, replyData))
02178 {
02179
return false;
02180 }
02181
02182
if (replyType !=
"bool")
02183
return false;
02184
02185
QDataStream reply(replyData, IO_ReadOnly );
02186 Q_INT8 result;
02187 reply >> result;
02188
return (result != 0);
02189 }
02190
02191
bool
02192 DCOPClient::connectDCOPSignal(
const QCString &sender,
const QCString &signal,
02193
const QCString &receiverObj,
const QCString &slot,
bool Volatile)
02194 {
02195
return connectDCOPSignal( sender, 0, signal, receiverObj, slot, Volatile);
02196 }
02197
02198
bool
02199 DCOPClient::disconnectDCOPSignal(
const QCString &sender,
const QCString &senderObj,
02200
const QCString &signal,
02201
const QCString &receiverObj,
const QCString &slot)
02202 {
02203
QCString replyType;
02204
QByteArray data, replyData;
02205
02206
QDataStream args(data, IO_WriteOnly );
02207 args << sender << senderObj << normalizeFunctionSignature(signal) << receiverObj << normalizeFunctionSignature(slot);
02208
02209
if (!
call(
"DCOPServer", 0,
02210
"disconnectSignal(QCString,QCString,QCString,QCString,QCString)",
02211 data, replyType, replyData))
02212 {
02213
return false;
02214 }
02215
02216
if (replyType !=
"bool")
02217
return false;
02218
02219
QDataStream reply(replyData, IO_ReadOnly );
02220 Q_INT8 result;
02221 reply >> result;
02222
return (result != 0);
02223 }
02224
02225
bool
02226 DCOPClient::disconnectDCOPSignal(
const QCString &sender,
const QCString &signal,
02227
const QCString &receiverObj,
const QCString &slot)
02228 {
02229
return disconnectDCOPSignal( sender, 0, signal, receiverObj, slot);
02230 }
02231
02232
void
02233 DCOPClient::setPriorityCall(
bool b)
02234 {
02235
#ifdef Q_OS_UNIX
02236
if (b)
02237 {
02238
if (d->currentKey == 2)
02239
return;
02240 d->currentKeySaved = d->currentKey;
02241 d->currentKey = 2;
02242 }
02243
else
02244 {
02245
if (d->currentKey != 2)
02246
return;
02247 d->currentKey = d->currentKeySaved;
02248
if ( !d->messages.isEmpty() )
02249 d->postMessageTimer.start( 0,
true );
02250 }
02251
#endif
02252
}
02253
02254
02255
02256
void
02257 DCOPClient::emergencyClose()
02258 {
02259
QPtrList<DCOPClient> list;
02260 client_map_t *map = DCOPClient_CliMap;
02261
if (!map)
return;
02262
QAsciiDictIterator<DCOPClient> it(*map);
02263
while(it.current()) {
02264 list.removeRef(it.current());
02265 list.append(it.current());
02266 ++it;
02267 }
02268
#ifdef Q_OS_UNIX
02269
for(
DCOPClient *cl = list.first(); cl; cl = list.next())
02270 {
02271
if (cl->
d->iceConn) {
02272 IceProtocolShutdown(cl->
d->iceConn, cl->
d->majorOpcode);
02273 IceCloseConnection(cl->
d->iceConn);
02274 cl->
d->iceConn = 0L;
02275 }
02276 }
02277
#endif
02278
}
02279
02280
const char *
02281 DCOPClient::postMortemSender()
02282 {
02283
if (!dcop_main_client)
02284
return "";
02285
if (dcop_main_client->
d->senderId.isEmpty())
02286
return "";
02287
return dcop_main_client->
d->senderId.data();
02288 }
02289
02290
const char *
02291 DCOPClient::postMortemObject()
02292 {
02293
if (!dcop_main_client)
02294
return "";
02295
return dcop_main_client->
d->objId.data();
02296 }
02297
const char *
02298 DCOPClient::postMortemFunction()
02299 {
02300
if (!dcop_main_client)
02301
return "";
02302
return dcop_main_client->
d->function.data();
02303 }
02304
02305
void DCOPClient::virtual_hook(
int,
void* )
02306 { }
02307
02308
#include <dcopclient.moc>
02309