dcop.cpp
/*****************************************************************
Copyright (c) 2000 Matthias Ettrich <ettrich@kde.org>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
******************************************************************/
// putenv() is not available on all platforms, so make sure the emulation
// wrapper is available in those cases by loading config.h!
#include <config.h>
#include <sys/types.h>
#include <pwd.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <qbuffer.h>
#include <qcolor.h>
#include <qdir.h>
#include <qfile.h>
#include <qfileinfo.h>
#include <qimage.h>
#include <qmap.h>
#include <qstringlist.h>
#include <qtextstream.h>
#include <qvariant.h>
#include "../dcopclient.h"
#include "../dcopref.h"
#include "../kdatastream.h"
#include "marshall.cpp"
#if defined Q_WS_X11
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#endif
typedef QMap<QString, QString> UserList;
static DCOPClient* dcop = 0;
static QTextStream cin_ ( stdin, IO_ReadOnly );
static QTextStream cout_( stdout, IO_WriteOnly );
static QTextStream cerr_( stderr, IO_WriteOnly );
enum Session { DefaultSession = 0, AllSessions, QuerySessions, CustomSession };
bool startsWith(const QCString &id, const char *str, int n)
{
return !n || (strncmp(id.data(), str, n) == 0);
}
bool endsWith(QCString &id, char c)
{
if (id.length() && (id[id.length()-1] == c))
{
id.truncate(id.length()-1);
return true;
}
return false;
}
void queryApplications(const QCString &filter)
{
int filterLen = filter.length();
QCStringList apps = dcop->registeredApplications();
for ( QCStringList::Iterator it = apps.begin(); it != apps.end(); ++it )
{
QCString &clientId = *it;
if ( (clientId != dcop->appId()) &&
!startsWith(clientId, "anonymous",9) &&
startsWith(clientId, filter, filterLen)
)
printf( "%s\n", clientId.data() );
}
if ( !dcop->isAttached() )
{
qWarning( "server not accessible" );
exit(1);
}
}
void queryObjects( const QCString &app, const QCString &filter )
{
int filterLen = filter.length();
bool ok = false;
bool isDefault = false;
QCStringList objs = dcop->remoteObjects( app, &ok );
for ( QCStringList::Iterator it = objs.begin(); it != objs.end(); ++it )
{
QCString &objId = *it;
if (objId == "default")
{
isDefault = true;
continue;
}
if (startsWith(objId, filter, filterLen))
{
if (isDefault)
printf( "%s (default)\n", objId.data() );
else
printf( "%s\n", objId.data() );
}
isDefault = false;
}
if ( !ok )
{
if (!dcop->isApplicationRegistered(app))
qWarning( "No such application: '%s'", app.data());
else
qWarning( "Application '%s' not accessible", app.data() );
exit(1);
}
}
void queryFunctions( const char* app, const char* obj )
{
bool ok = false;
QCStringList funcs = dcop->remoteFunctions( app, obj, &ok );
for ( QCStringList::Iterator it = funcs.begin(); it != funcs.end(); ++it ) {
printf( "%s\n", (*it).data() );
}
if ( !ok )
{
qWarning( "object '%s' in application '%s' not accessible", obj, app );
exit( 1 );
}
}
int callFunction( const char* app, const char* obj, const char* func, const QCStringList args )
{
QString f = func; // Qt is better with unicode strings, so use one.
int left = f.find( '(' );
int right = f.find( ')' );
if ( right < left )
{
qWarning( "parentheses do not match" );
return( 1 );
}
if ( left < 0 ) {
// try to get the interface from the server
bool ok = false;
QCStringList funcs = dcop->remoteFunctions( app, obj, &ok );
QCString realfunc;
if ( !ok && args.isEmpty() )
goto doit;
if ( !ok )
{
qWarning( "object not accessible" );
return( 1 );
}
for ( QCStringList::Iterator it = funcs.begin(); it != funcs.end(); ++it ) {
int l = (*it).find( '(' );
int s;
if (l > 0)
s = (*it).findRev( ' ', l);
else
s = (*it).find( ' ' );
if ( s < 0 )
s = 0;
else
s++;
if ( l > 0 && (*it).mid( s, l - s ) == func ) {
realfunc = (*it).mid( s );
const QString arguments = (*it).mid(l+1,(*it).find( ')' )-l-1);
uint a = arguments.contains(',');
if ( (a==0 && !arguments.isEmpty()) || a>0)
a++;
if ( a == args.count() )
break;
}
}
if ( realfunc.isEmpty() )
{
qWarning("no such function");
return( 1 );
}
f = realfunc;
left = f.find( '(' );
right = f.find( ')' );
}
doit:
if ( left < 0 )
f += "()";
// This may seem expensive but is done only once per invocation
// of dcop, so it should be OK.
//
//
QStringList intTypes;
intTypes << "int" << "unsigned" << "long" << "bool" ;
QStringList types;
if ( left >0 && left + 1 < right - 1) {
types = QStringList::split( ',', f.mid( left + 1, right - left - 1) );
for ( QStringList::Iterator it = types.begin(); it != types.end(); ++it ) {
QString lt = (*it).simplifyWhiteSpace();
int s = lt.find(' ');
// If there are spaces in the name, there may be two
// reasons: the parameter name is still there, ie.
// "QString URL" or it's a complicated int type, ie.
// "unsigned long long int bool".
//
//
if ( s > 0 )
{
QStringList partl = QStringList::split(' ' , lt);
// The zero'th part is -- at the very least -- a
// type part. Any trailing parts *might* be extra
// int-type keywords, or at most one may be the
// parameter name.
//
//
s=1;
while (s < static_cast<int>(partl.count()) && intTypes.contains(partl[s]))
{
s++;
}
if ( s < static_cast<int>(partl.count())-1)
{
qWarning("The argument `%s' seems syntactically wrong.",
lt.latin1());
}
if ( s == static_cast<int>(partl.count())-1)
{
partl.remove(partl.at(s));
}
lt = partl.join(" ");
lt = lt.simplifyWhiteSpace();
}
(*it) = lt;
}
QString fc = f.left( left );
fc += '(';
bool first = true;
for ( QStringList::Iterator it = types.begin(); it != types.end(); ++it ) {
if ( !first )
fc +=",";
first = false;
fc += *it;
}
fc += ')';
f = fc;
}
QByteArray data, replyData;
QCString replyType;
QDataStream arg(data, IO_WriteOnly);
uint i = 0;
for( QStringList::Iterator it = types.begin(); it != types.end(); ++it )
marshall( arg, args, i, *it );
if ( i != args.count() )
{
qWarning( "arguments do not match" );
return( 1 );
}
if ( !dcop->call( app, obj, f.latin1(), data, replyType, replyData) ) {
qWarning( "call failed");
return( 1 );
} else {
QDataStream reply(replyData, IO_ReadOnly);
if ( replyType != "void" && replyType != "ASYNC" )
{
QCString replyString = demarshal( reply, replyType );
if ( !replyString.isEmpty() )
printf( "%s\n", replyString.data() );
else
printf("\n");
}
}
return 0;
}
void showHelp( int exitCode = 0 )
{
#ifdef DCOPQUIT
cout_ << "Usage: dcopquit [options] [application]" << endl
#else
cout_ << "Usage: dcop [options] [application [object [function [arg1] [arg2] ... ] ] ]" << endl
#endif
<< "" << endl
<< "Console DCOP client" << endl
<< "" << endl
<< "Generic options:" << endl
<< " --help Show help about options" << endl
<< "" << endl
<< "Options:" << endl
<< " --pipe Call DCOP for each line read from stdin. The string '%1'" << endl
<< " will be used in the argument list as a placeholder for" << endl
<< " the substituted line." << endl
<< " For example," << endl
<< " dcop --pipe konqueror html-widget1 evalJS %1" << endl
<< " is equivalent to calling" << endl
<< " while read line ; do" << endl
<< " dcop konqueror html-widget1 evalJS \"$line\"" << endl
<< " done" << endl
<< " in bash, but because no new dcop instance has to be started" << endl
<< " for each line this is generally much faster, especially for" << endl
<< " the slower GNU dynamic linkers." << endl
<< " The '%1' placeholder cannot be used to replace e.g. the" << endl
<< " program, object or method name." << endl
<< " --user <user> Connect to the given user's DCOP server. This option will" << endl
<< " ignore the values of the environment vars $DCOPSERVER and" << endl
<< " $ICEAUTHORITY, even if they are set." << endl
<< " If the user has more than one open session, you must also" << endl
<< " use one of the --list-sessions, --session or --all-sessions" << endl
<< " command-line options." << endl
<< " --all-users Send the same DCOP call to all users with a running DCOP" << endl
<< " server. Only failed calls to existing DCOP servers will" << endl
<< " generate an error message. If no DCOP server is available" << endl
<< " at all, no error will be generated." << endl
<< " --session <ses> Send to the given KDE session. This option can only be" << endl
<< " used in combination with the --user option." << endl
<< " --all-sessions Send to all sessions found. Only works with the --user" << endl
<< " and --all-users options." << endl
<< " --list-sessions List all active KDE session for a user or all users." << endl
<< " --no-user-time Don't update the user activity timestamp in the called" << endl
<< " application (for usage in scripts running" << endl
<< " in the background)." << endl
<< endl;
exit( exitCode );
}
static UserList userList()
{
UserList result;
while( passwd* pstruct = getpwent() )
{
result[ QString::fromLocal8Bit(pstruct->pw_name) ] = QFile::decodeName(pstruct->pw_dir);
}
return result;
}
QStringList dcopSessionList( const QString &user, const QString &home )
{
if( home.isEmpty() )
{
cerr_ << "WARNING: Cannot determine home directory for user "
<< user << "!" << endl
<< "Please check permissions or set the $DCOPSERVER variable manually before" << endl
<< "calling dcop." << endl;
return QStringList();
}
QStringList result;
QFileInfo dirInfo( home );
if( !dirInfo.exists() || !dirInfo.isReadable() )
return result;
QDir d( home );
d.setFilter( QDir::Files | QDir::Hidden | QDir::NoSymLinks );
d.setNameFilter( ".DCOPserver*" );
const QFileInfoList *list = d.entryInfoList();
if( !list )
return result;
QFileInfoListIterator it( *list );
QFileInfo *fi;
while ( ( fi = it.current() ) != 0 )
{
if( fi->isReadable() )
result.append( fi->fileName() );
++it;
}
return result;
}
void sendUserTime( const char* app )
{
#if defined Q_WS_X11
static unsigned long time = 0;
if( time == 0 )
{
Display* dpy = XOpenDisplay( NULL );
if( dpy != NULL )
{
Window w = XCreateSimpleWindow( dpy, DefaultRootWindow( dpy ), 0, 0, 1, 1, 0, 0, 0 );
XSelectInput( dpy, w, PropertyChangeMask );
unsigned char data[ 1 ];
XChangeProperty( dpy, w, XA_ATOM, XA_ATOM, 8, PropModeAppend, data, 1 );
XEvent ev;
XWindowEvent( dpy, w, PropertyChangeMask, &ev );
time = ev.xproperty.time;
XDestroyWindow( dpy, w );
}
}
DCOPRef( app, "MainApplication-Interface" ).call( "updateUserTimestamp", time );
#else
// ...
#endif
}
int runDCOP( QCStringList args, UserList users, Session session,
const QString sessionName, bool readStdin, bool updateUserTime )
{
bool DCOPrefmode=false;
QCString app;
QCString objid;
QCString function;
QCStringList params;
DCOPClient *client = 0L;
int retval = 0;
if ( !args.isEmpty() && args[ 0 ].find( "DCOPRef(" ) == 0 )
{
int delimPos = args[ 0 ].findRev( ',' );
if( delimPos == -1 )
{
cerr_ << "Error: '" << args[ 0 ]
<< "' is not a valid DCOP reference." << endl;
exit( -1 );
}
app = args[ 0 ].mid( 8, delimPos-8 );
delimPos++;
objid = args[ 0 ].mid( delimPos, args[ 0 ].length()-delimPos-1 );
if( args.count() > 1 )
function = args[ 1 ];
if( args.count() > 2 )
{
params = args;
params.remove( params.begin() );
params.remove( params.begin() );
}
DCOPrefmode=true;
}
else
{
if( !args.isEmpty() )
app = args[ 0 ];
if( args.count() > 1 )
objid = args[ 1 ];
if( args.count() > 2 )
function = args[ 2 ];
if( args.count() > 3)
{
params = args;
params.remove( params.begin() );
params.remove( params.begin() );
params.remove( params.begin() );
}
}
bool firstRun = true;
UserList::Iterator it;
QStringList sessions;
bool presetDCOPServer = false;
// char *dcopStr = 0L;
QString dcopServer;
for( it = users.begin(); it != users.end() || firstRun; ++it )
{
firstRun = false;
//cout_ << "Iterating '" << it.key() << "'" << endl;
if( session == QuerySessions )
{
QStringList sessions = dcopSessionList( it.key(), it.data() );
if( sessions.isEmpty() )
{
if( users.count() <= 1 )
{
cout_ << "No active sessions";
if( !( *it ).isEmpty() )
cout_ << " for user " << *it;
cout_ << endl;
}
}
else
{
cout_ << "Active sessions ";
if( !( *it ).isEmpty() )
cout_ << "for user " << *it << " ";
cout_ << ":" << endl;
QStringList::Iterator sIt = sessions.begin();
for( ; sIt != sessions.end(); ++sIt )
cout_ << " " << *sIt << endl;
cout_ << endl;
}
continue;
}
if( getenv( "DCOPSERVER" ) )
{
sessions.append( getenv( "DCOPSERVER" ) );
presetDCOPServer = true;
}
if( users.count() > 1 || ( users.count() == 1 &&
( getenv( "DCOPSERVER" ) == 0 /*&& getenv( "DISPLAY" ) == 0*/ ) ) )
{
sessions = dcopSessionList( it.key(), it.data() );
if( sessions.isEmpty() )
{
if( users.count() > 1 )
continue;
else
{
cerr_ << "ERROR: No active KDE sessions!" << endl
<< "If you are sure there is one, please set the $DCOPSERVER variable manually" << endl
<< "before calling dcop." << endl;
exit( -1 );
}
}
else if( !sessionName.isEmpty() )
{
if( sessions.contains( sessionName ) )
{
sessions.clear();
sessions.append( sessionName );
}
else
{
cerr_ << "ERROR: The specified session doesn't exist!" << endl;
exit( -1 );
}
}
else if( sessions.count() > 1 && session != AllSessions )
{
cerr_ << "ERROR: Multiple available KDE sessions!" << endl
<< "Please specify the correct session to use with --session or use the" << endl
<< "--all-sessions option to broadcast to all sessions." << endl;
exit( -1 );
}
}
if( users.count() > 1 || ( users.count() == 1 &&
( getenv( "ICEAUTHORITY" ) == 0 || getenv( "DISPLAY" ) == 0 ) ) )
{
// Check for ICE authority file and if the file can be read by us
QString home = it.data();
QString iceFile = it.data() + "/.ICEauthority";
QFileInfo fi( iceFile );
if( iceFile.isEmpty() )
{
cerr_ << "WARNING: Cannot determine home directory for user "
<< it.key() << "!" << endl
<< "Please check permissions or set the $ICEAUTHORITY variable manually before" << endl
<< "calling dcop." << endl;
}
else if( fi.exists() )
{
if( fi.isReadable() )
{
char *envStr = strdup( ( "ICEAUTHORITY=" + iceFile ).ascii() );
putenv( envStr );
//cerr_ << "ice: " << envStr << endl;
}
else
{
cerr_ << "WARNING: ICE authority file " << iceFile
<< "is not readable by you!" << endl
<< "Please check permissions or set the $ICEAUTHORITY variable manually before" << endl
<< "calling dcop." << endl;
}
}
else
{
if( users.count() > 1 )
continue;
else
{
cerr_ << "WARNING: Cannot find ICE authority file "
<< iceFile << "!" << endl
<< "Please check permissions or set the $ICEAUTHORITY"
<< " variable manually before" << endl
<< "calling dcop." << endl;
}
}
}
// Main loop
// If users is an empty list we're calling for the currently logged
// in user. In this case we don't have a session, but still want
// to iterate the loop once.
QStringList::Iterator sIt = sessions.begin();
for( ; sIt != sessions.end() || users.isEmpty(); ++sIt )
{
if( !presetDCOPServer && !users.isEmpty() )
{
QString dcopFile = it.data() + "/" + *sIt;
QFile f( dcopFile );
if( !f.open( IO_ReadOnly ) )
{
cerr_ << "Can't open " << dcopFile << " for reading!" << endl;
exit( -1 );
}
QStringList l( QStringList::split( '\n', f.readAll() ) );
dcopServer = l.first();
if( dcopServer.isEmpty() )
{
cerr_ << "WARNING: Unable to determine DCOP server for session "
<< *sIt << "!" << endl
<< "Please check permissions or set the $DCOPSERVER variable manually before" << endl
<< "calling dcop." << endl;
exit( -1 );
}
}
delete client;
client = new DCOPClient;
if( !dcopServer.isEmpty() )
client->setServerAddress( dcopServer.ascii() );
bool success = client->attach();
if( !success )
{
cerr_ << "ERROR: Couldn't attach to DCOP server!" << endl;
retval = QMAX( retval, 1 );
if( users.isEmpty() )
break;
else
continue;
}
dcop = client;
int argscount = args.count();
if ( DCOPrefmode )
argscount++;
switch ( argscount )
{
case 0:
queryApplications("");
break;
case 1:
if (endsWith(app, '*'))
queryApplications(app);
else
queryObjects( app, "" );
break;
case 2:
if (endsWith(objid, '*'))
queryObjects(app, objid);
else
queryFunctions( app, objid );
break;
case 3:
default:
if( updateUserTime )
sendUserTime( app );
if( readStdin )
{
QCStringList::Iterator replaceArg = params.end();
QCStringList::Iterator it = params.begin();
for( ; it != params.end(); ++it )
if( *it == "%1" )
replaceArg = it;
// Read from stdin until EOF and call function for each
// read line
while ( !cin_.atEnd() )
{
QString buf = cin_.readLine();
if( replaceArg != params.end() )
*replaceArg = buf.local8Bit();
if( !buf.isNull() )
{
int res = callFunction( app, objid, function, params );
retval = QMAX( retval, res );
}
}
}
else
{
// Just call function
// cout_ << "call " << app << ", " << objid << ", " << function << ", (params)" << endl;
int res = callFunction( app, objid, function, params );
retval = QMAX( retval, res );
}
break;
}
// Another sIt++ would make the loop infinite...
if( users.isEmpty() )
break;
}
// Another it++ would make the loop infinite...
if( it == users.end() )
break;
}
return retval;
}
#ifdef Q_OS_WIN
# define main kdemain
#endif
int main( int argc, char** argv )
{
bool readStdin = false;
int numOptions = 0;
QString user;
Session session = DefaultSession;
QString sessionName;
bool updateUserTime = true;
cin_.setEncoding( QTextStream::Locale );
// Scan for command-line options first
for( int pos = 1 ; pos <= argc - 1 ; pos++ )
{
if( strcmp( argv[ pos ], "--help" ) == 0 )
showHelp( 0 );
else if( strcmp( argv[ pos ], "--pipe" ) == 0 )
{
readStdin = true;
numOptions++;
}
else if( strcmp( argv[ pos ], "--user" ) == 0 )
{
if( pos <= argc - 2 )
{
user = QString::fromLocal8Bit( argv[ pos + 1] );
numOptions +=2;
pos++;
}
else
{
cerr_ << "Missing username for '--user' option!" << endl << endl;
showHelp( -1 );
}
}
else if( strcmp( argv[ pos ], "--session" ) == 0 )
{
if( session == AllSessions )
{
cerr_ << "ERROR: --session cannot be mixed with --all-sessions!" << endl << endl;
showHelp( -1 );
}
else if( pos <= argc - 2 )
{
sessionName = QString::fromLocal8Bit( argv[ pos + 1] );
numOptions +=2;
pos++;
}
else
{
cerr_ << "Missing session name for '--session' option!" << endl << endl;
showHelp( -1 );
}
}
else if( strcmp( argv[ pos ], "--all-users" ) == 0 )
{
user = "*";
numOptions ++;
}
else if( strcmp( argv[ pos ], "--list-sessions" ) == 0 )
{
session = QuerySessions;
numOptions ++;
}
else if( strcmp( argv[ pos ], "--all-sessions" ) == 0 )
{
if( !sessionName.isEmpty() )
{
cerr_ << "ERROR: --session cannot be mixed with --all-sessions!" << endl << endl;
showHelp( -1 );
}
session = AllSessions;
numOptions ++;
}
else if( strcmp( argv[ pos ], "--no-user-time" ) == 0 )
{
updateUserTime = false;
numOptions ++;
}
else if( argv[ pos ][ 0 ] == '-' )
{
cerr_ << "Unknown command-line option '" << argv[ pos ]
<< "'." << endl << endl;
showHelp( -1 );
}
else
break; // End of options
}
argc -= numOptions;
QCStringList args;
#ifdef DCOPQUIT
if (argc > 1)
{
QCString prog = argv[ numOptions + 1 ];
if (!prog.isEmpty())
{
args.append( prog );
// Pass as-is if it ends with a wildcard
if (prog[prog.length()-1] != '*')
{
// Strip a trailing -<PID> part.
int i = prog.findRev('-');
if ((i >= 0) && prog.mid(i+1).toLong())
{
prog = prog.left(i);
}
args.append( "qt/"+prog );
args.append( "quit()" );
}
}
}
#else
for( int i = numOptions; i < argc + numOptions - 1; i++ )
args.append( argv[ i + 1 ] );
#endif
if( readStdin && args.count() < 3 )
{
cerr_ << "--pipe option only supported for function calls!" << endl << endl;
showHelp( -1 );
}
if( user == "*" && args.count() < 3 && session != QuerySessions )
{
cerr_ << "ERROR: The --all-users option is only supported for function calls!" << endl << endl;
showHelp( -1 );
}
if( session == QuerySessions && !args.isEmpty() )
{
cerr_ << "ERROR: The --list-sessions option cannot be used for actual DCOP calls!" << endl << endl;
showHelp( -1 );
}
if( session == QuerySessions && user.isEmpty() )
{
cerr_ << "ERROR: The --list-sessions option can only be used with the --user or" << endl
<< "--all-users options!" << endl << endl;
showHelp( -1 );
}
if( session != DefaultSession && session != QuerySessions &&
args.count() < 3 )
{
cerr_ << "ERROR: The --session and --all-sessions options are only supported for function" << endl
<< "calls!" << endl << endl;
showHelp( -1 );
}
UserList users;
if( user == "*" )
users = userList();
else if( !user.isEmpty() )
users[ user ] = userList()[ user ];
int retval = runDCOP( args, users, session, sessionName, readStdin, updateUserTime );
return retval;
}
// vim: set ts=8 sts=4 sw=4 noet:
DCOPRef::call
DCOPReply call(const QCString &fun)
Calls the function fun on the object referenced by this reference.
Definition: dcopref.h:417
DCOPClient::attach
bool attach()
Attaches to the DCOP server.
Definition: dcopclient.cpp:663
DCOPRef
A DCOPRef(erence) encapsulates a remote DCOP object as a triple <app,obj,type> where type is optional...
Definition: dcopref.h:278
DCOPClient
Inter-process communication and remote procedure calls for KDE applications.
Definition: dcopclient.h:68
DCOPClient::remoteObjects
QCStringList remoteObjects(const QCString &remApp, bool *ok=0)
Retrieves the list of objects of the remote application remApp.
Definition: dcopclient.cpp:1247
DCOPClient::appId
QCString appId() const
Returns the current app id or a null string if the application hasn't yet been registered.
Definition: dcopclient.cpp:995
DCOPClient::remoteFunctions
QCStringList remoteFunctions(const QCString &remApp, const QCString &remObj, bool *ok=0)
Retrieves the list of functions of the remote object remObj of application remApp.
Definition: dcopclient.cpp:1279
DCOPClient::setServerAddress
static void setServerAddress(const QCString &addr)
Sets the address of a server to use upon attaching.
Definition: dcopclient.cpp:655
DCOPClient::registeredApplications
QCStringList registeredApplications()
Retrieves the list of all currently registered applications from dcopserver.
Definition: dcopclient.cpp:1235
DCOPClient::call
bool call(const QCString &remApp, const QCString &remObj, const QCString &remFun, const QByteArray &data, QCString &replyType, QByteArray &replyData, bool useEventLoop, int timeout)
Performs a synchronous send and receive.
Definition: dcopclient.cpp:1736
DCOPClient::isAttached
bool isAttached() const
Returns whether or not the client is attached to the server.
Definition: dcopclient.cpp:908
endl
kndbgstream & endl(kndbgstream &s)
DCOPClient::isApplicationRegistered
bool isApplicationRegistered(const QCString &remApp)
Checks whether remApp is registered with the DCOP server.
Definition: dcopclient.cpp:1221

KDE Home | KDE Accessibility Home | Description of Access Keys