/***************************************************************************
                            DCOPClient.java -  description
                             -------------------
    begin                : Sun Jan 27 16:22:17 2002
    copyright            : (C) 2000-2001 Lost Highway Ltd.
    email                : Richard_Dale@tipitina.demon.co.uk
    generated by         : duke@tipitina on Sun Jan 27 16:22:17 2002, using kalyptus 0.9.
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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.                                   *
 *                                                                         *
***************************************************************************/

package org.kde.koala;

import org.kde.qt.*;
import java.util.*;
import java.lang.Error;

/**

 Inter-process communication and remote procedure calls
 for KDE applications.

 This class provides IPC and RPC for KDE applications.  Usually you
 will not have to instantiate one yourself because {@link KApplication}
 contains a method to return a pointer to a DCOPClient object which
 can be used for your whole application.

 Before being able to send or receive any DCOP messages, you will have
 to attach your client object to the DCOP server, and then register
 your application with a specific name. See {@link #attach}
 and {@link #registerAs} for
 more information.

 Data to be sent should be serialized into a {@link QDataStream} which was
 initialized with the {@link byte}[] that you actually intend to send
 the data in.  An example of how you might do this:

 <pre>
   byte[] data;
   QDataStream arg(data, IO_WriteOnly);
   arg << String("This is text I am serializing");
   client.send("someApp", "someObject", "someFunction", arg);
 </pre>

 See {@link DCOPClientSignals} for signals emitted by DCOPClient.

 See {@link DCOPClientEventHandling} for event handlers to override in subclasses of DCOPClient.

 @author Preston Brown <pbrown@kde.org>, Matthias Ettrich <ettrich@kde.org>
 
 @short 
 Inter-process communication and remote procedure calls
 for KDE applications.
*/
public class DCOPClient extends QObject  {
	protected DCOPClient(Class dummy){super((Class) null);}

	private native void newDCOPClient();

/** 
 Constructs a new DCOP client, but does not attach to any server.  
*/
	public DCOPClient() {
		super((Class) null);
		newDCOPClient();
	}

/** 
 Cleans up any open connections and dynamic data.
   
*/
	protected native void finalize() throws InternalError;
	public native void dispose();
	public native boolean isDisposed();

/** 
 Attaches to the DCOP server.

 If the connection was already attached,
 the connection will be re-established with the current server address.

 Naturally, only attached application can use DCOP services.

 If a {@link QApplication} object exists then client registers itself as
 {@link QApplication#name} + "-" + <pid>.
 If no {@link QApplication} object exists the client registers itself as
 "anonymous".

 If you want to register differently, you should use {@link #registerAs}
 instead.

*/
	public native boolean attach();

/** 

 Internal function for {@link KUniqueApplication} to register the {@link DCOPClient}
 with the application in case the application didn't exist at the
 time the {@link DCOPClient} was created.
   
*/
	public native void bindToApp();

/** 
 Detaches from the DCOP server.
   
*/
	public native boolean detach();

/** 
 Returns whether or not the client is attached to the server.
   
*/
	public native boolean isAttached();

/** 
 Returns whether the client is attached to a server owned by
 another user.
   
*/
	public native boolean isAttachedToForeignServer();

/** 
 Returns whether the client handles incoming calls.
   
*/
	public native boolean acceptCalls();

/** 
 Specify whether the client should accept incoming calls.
 By default clients accept incoming calls, but not when connected
 to a foreign server.
   
*/
	public native void setAcceptCalls( boolean b);

/** 
 Registers at the DCOP server.

 If the application was already registered,
 the registration will be re-done with the new {@link appId}.

 <code>appId</code> is a <code>unique</code> application/program id that the server
 will use to associate requests with. If there is already an application
 registered with the same name, the server will add a number to the
 id to unify it. If <code>addPID</code> is true, the PID of the current process
 will be added to id.

 Registration is necessary if you want to allow other clients to talk
 to you.  They can do so using your <code>appId</code> as first parameter
 for {@link #send} or {@link #call}. If you just want to talk to
  other clients, you
 do not need to register at the server. In that case {@link #attach} is
 enough.
 It will implicitly register you as "anonymous".

*/
	public native String registerAs( String appId, boolean addPID);

/** 
 Returns whether or not the client is registered at the server.
   
*/
	public native boolean isRegistered();

/** 
 Returns the current app id or a null string if the application
 hasn't yet been registered.
   
*/
	public native String appId();

/** 

*/
	public native int socket();

/** 
 Temporarily suspends processing of DCOP events.
 This can be usefull if you need to show e.g. a dialog before
 your application is ready to accept DCOP requests. Normally the
 dialog would start an event loop and in this event loop DCOP
 requests will be handled.

 Be aware that not responding to DCOP requests may cause other
 programs that want to communicate with your application, to hang.
   
*/
	public native void suspend();

/** 
 Resumes the processing of DCOP events.
 See {@link #suspend}.
   
*/
	public native void resume();

/** 
 Sends a data block to the server.

*/
	public native boolean send( String remApp, String remObj, String remFun, byte[] data);

/** 
 This function acts exactly the same as the above, but the data
 parameter can be specified as a {@link String} for convenience.
   
*/
	public native boolean send( String remApp, String remObj, String remFun, String data);

/** 
 Performs a synchronous send and receive.

  The parameters are the same as for send, with the exception of
  another {@link byte}[] being provided for results to be
  (optionally) returned in.

 A call blocks the application until the process receives the
 answer.

 If <code>useEventLoop</code> is true, a local event loop will be started after
 1/10th of a second in order to keep the user interface updated
 (by processing paint events and such) until an answer is received.

*/
	public native boolean call( String remApp, String remObj, String remFun, byte[] data, String replyType, byte[] replyData, boolean useEventLoop);
	public native boolean call( String remApp, String remObj, String remFun, byte[] data, String replyType, byte[] replyData);

/** 
 Searches for an object which matches a criteria.

 findObject calls <code>remFun</code> in the applications and objects identified
 by <code>remApp</code> and <code>remObj</code> until <code>remFun</code> returns true. The name of
 the application and object that returned true are returned in
 <code>foundApp</code> and <code>foundObj</code> respectively.

 If <code>remFun</code> is empty a default function is called in the object
 which always returns <code>true.</code>

 A findObject blocks the application until the process receives the
 answer.

 If <code>useEventLoop</code> is true, a local event loop will be started after
 1/10th of a second in order to keep the user interface updated
 (by processing paint events and such) until an answer is received.

*/
	public native boolean findObject( String remApp, String remObj, String remFun, byte[] data, String foundApp, String foundObj, boolean useEventLoop);
	public native boolean findObject( String remApp, String remObj, String remFun, byte[] data, String foundApp, String foundObj);

/** 
 Emits <code>signal</code> as DCOP signal from object <code>object</code> with <code>data</code> as
 arguments.
   
*/
	public native void emitDCOPSignal( String object, String signal, byte[] data);
	public native void emitDCOPSignal( String signal, byte[] data);

/** 
 Connects to a DCOP signal.

*/
	public native boolean connectDCOPSignal( String sender, String senderObj, String signal, String receiverObj, String slot, boolean Volatile);
	public native boolean connectDCOPSignal( String sender, String signal, String receiverObj, String slot, boolean Volatile);

/** 
 Disconnects a DCOP signal.

 A special case is when both sender & signal are empty. In this
 case all connections related to <code>receiverObj</code> in the current client
 are disconnected. (Both connections from as well as to this object!)

*/
	public native boolean disconnectDCOPSignal( String sender, String senderObj, String signal, String receiverObj, String slot);
	public native boolean disconnectDCOPSignal( String sender, String signal, String receiverObj, String slot);

/** 
 Reimplement this function to handle app-wide function calls unassociated w/an object.

 Note that <code>fun</code> is normalized. See {@link #normalizeFunctionSignature}.

 If you do not want to reimplement this function for whatever reason,
 you can also use a default object  or a {@link DCOPObjectProxy}.

*/
	public native boolean process( String fun, byte[] data, String replyType, byte[] replyData);

/** 
 Delays the reply of the current function call
 until {@link #endTransaction} is called.

 This allows a server to queue requests.

 Note: Should be called from inside {@link #process} only!
   
*/
//	public native DCOPClientTransaction beginTransaction();

/** 
 Sends the delayed reply of a function call.
   
*/
//	public native void endTransaction( DCOPClientTransaction arg1, String replyType, byte[] replyData);

/** 
 Test whether the current function call is delayed.

 Note: Should be called from inside {@link #process} only!

*/
	public native int transactionId();

/** 
 Checks whether <code>remApp</code> is registered with the {@link DCOPServer}.

*/
	public native boolean isApplicationRegistered( String remApp);

/** 
 Retrieves the list of all currently registered applications
 from dcopserver.
   
*/
	public native ArrayList registeredApplications();

/** 
 Retrieves the list of objects of the remote application <code>remApp.</code>
   
*/
	public native ArrayList remoteObjects( String remApp, int[] ok);

/** 
 Retrieves the list of interfaces of the remote object <code>remObj</code>
 of application <code>remApp.</code>
  
*/
	public native ArrayList remoteInterfaces( String remApp, String remObj, int[] ok);

/** 
 Retrieves the list of functions of the remote object <code>remObj</code>
 of application <code>remApp</code>
  
*/
	public native ArrayList remoteFunctions( String remApp, String remObj, int[] ok);

/** 
 Receives a DCOPSend or DCOPCall message from the server.

   
*/
	public native boolean receive( String app, String obj, String fun, byte[] data, String replyType, byte[] replyData);

/** 
 Receives a <code>DCOPFind</code> message from the server.

   
*/
	public native boolean find( String app, String obj, String fun, byte[] data, String replyType, byte[] replyData);

/** 
 Returns the <code>appId</code> of the last application that talked to us.
   
*/
	public native String senderId();

/** 
 Installs object <code>objId</code> as application-wide default object.

 All app-wide messages that have not been processed by the dcopclient
 will be send further to <code>objId.</code>
    
*/
	public native void setDefaultObject( String objId);

/** 
 Returns the current default object or an empty string if no object is
 installed as default object.

 A default object receives application-wide messages that have not
 been processed by the DCOPClient itself.
     
*/
	public native String defaultObject();

/** 
 Enables / disables the {@link #applicationRegistered} /
 {@link #applicationRemoved} signals.
 Note that a counter is maintained about how often this method
 was called. If this method is called twice with <code>enabled</code> set to
 true, notifications will be enabled until it was called with
 <code>enabled</code> set to false as often.

 They are disabled by default.  
*/
	public native void setNotifications( boolean enabled);

/** 
 Tells the dcopserver to treat the client as daemon client, not
 as regular client.
 If the number of regular clients drops down to zero, the
 dcopserver will emit a KDE termination signal after 10
 seconds.
   
*/
	public native void setDaemonMode( boolean daemonMode);

/** 
 Sets the address of a server to use upon attaching.

 If no server address is ever specified, attach will try its best to
 find the server anyway.
   
*/
	public static native void setServerAddress( String addr);

/** 
 Normalizes the function signature <code>fun.</code>

 A normalized signature doesn't contain any unnecessary whitespace
 anymore. The remaining whitespace consists of single blanks only (0x20).

 Example for a normalized signature:
 <pre>
   "someFunction(String,int)"
 </pre>

 When using {@link #send} or {@link #call}, normalization is done
 automatically for you.

   
*/
	public static native String normalizeFunctionSignature( String fun);

/** 
 Returns the application's main dcop client. The main client can
 be used by objects that do not have any specific access to a dcop
 client. In KDE applications, the main client usually is the same
 as KAppliction.dcopClient().
   
*/
	public static native DCOPClient mainClient();

/** 
 Sets the application's main dcop client. The main client can
 be used by objects that do not have any specific access to a dcop
 client. In KDE applications, the main client usually is the same
 as KAppliction.dcopClient().
   
*/
	public static native void setMainClient( DCOPClient arg1);

/** 

    
*/
	public static native void emergencyClose();

/** 

 Provides information about the last DCOP call for debugging purposes.
    
*/
	public static native String postMortemSender();
	public static native String postMortemObject();
	public static native String postMortemFunction();

/** 
 File with information how to reach the dcopserver.

*/
	public static native String dcopServerFile( String hostname);

/** 
 For backwards compatibility with KDE 2.x
    
*/
	public static native String dcopServerFileOld( String hostname);
	protected native void processSocketData( int socknum);
}
