summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLubos Lunak <l.lunak@ suse.cz>2006-03-15 14:46:02 +0000
committerLubos Lunak <l.lunak@ suse.cz>2006-03-15 14:46:02 +0000
commitabaf1823ae29cd333c53a80f56ca98f412b6c7c3 (patch)
treeabe8fb5d9468105458c85f1ebdf56c95da9a3a35
parent42973bd25b205abd97eedd63687c4179b6fede43 (diff)
Some silly attempt at C bindings docs.
-rw-r--r--portland/dapi/BUILD1
-rw-r--r--portland/dapi/doc/API.txt9
-rw-r--r--portland/dapi/doc/C-API.txt214
-rw-r--r--portland/dapi/doc/C-HOWTO.txt204
-rw-r--r--portland/dapi/lib/callbacks.c2
-rw-r--r--portland/dapi/lib/callbacks.h2
-rw-r--r--portland/dapi/tests/test_callbacks.c2
7 files changed, 431 insertions, 3 deletions
diff --git a/portland/dapi/BUILD b/portland/dapi/BUILD
index 7383cf6..46c9fdd 100644
--- a/portland/dapi/BUILD
+++ b/portland/dapi/BUILD
@@ -8,6 +8,7 @@ cd kde
make -f Makefile.cvs
./configure
make
+make install
If you have a serious problem with the -Werror flag, edit configure.ac
and kde/configure.in.in (sorry, but plain C accepts unbelievable nonsense
diff --git a/portland/dapi/doc/API.txt b/portland/dapi/doc/API.txt
index 536180d..bc73023 100644
--- a/portland/dapi/doc/API.txt
+++ b/portland/dapi/doc/API.txt
@@ -1,3 +1,12 @@
+==============================================================================
+ Description of the API
+==============================================================================
+
+This file is a complete list and description of all API calls. It doesn't
+contain any information specific to any language bindings.
+
+
+
Conventions:
============
diff --git a/portland/dapi/doc/C-API.txt b/portland/dapi/doc/C-API.txt
new file mode 100644
index 0000000..cb16ff7
--- /dev/null
+++ b/portland/dapi/doc/C-API.txt
@@ -0,0 +1,214 @@
+==============================================================================
+ Description of C API bindings
+==============================================================================
+
+This file contains information specific to the C bindings. Refer to the generic
+API documentation for information that is not specific to C bindings. See also
+C-HOWTO.txt .
+
+
+
+
+Data types
+==========
+
+
+C allows only a limited set of data types. Types from the abstract API that
+are not available in C are used as follows:
+
+bool - int with values 1 for true and 0 for false
+
+string - char* NUL-terminated string; calls that return char* allocate it dynamically
+and the caller must deallocate it by calling free()
+
+arrays ( int[], string[] ) - intarr, stringarr (see below)
+
+windowinfo - DapiWindowInfo (see below)
+
+
+DapiConnection
+--------------
+
+Opaque data type that contains all internal data. Most calls require it
+as the first argument.
+
+
+DapiWindowInfo
+--------------
+
+Some call require information about a window related to the call. This structure
+holds data about such window. Call dapi_windowInfoInitWindow() to fill in the info
+or use the convenience _Window functions.
+
+
+void dapi_windowInfoInitWindow( DapiWindowInfo* winfo, long window )
+--------------------------------------------------------------------
+
+Initializes DapiWindowInfo with data about given window.
+
+winfo: DapiWindowInfo data structure to initialize
+window: Window handle (as used with X Window System)
+
+
+void dapi_freeWindowInfo( DapiWindowInfo winfo )
+------------------------------------------------
+
+Frees DapiWindowInfo structure data.
+
+winfo: DapiWindowInfo data structure to free data from.
+
+
+intarr
+------
+
+A structure representing an integer array.
+typedef struct
+ {
+ int count;
+ int* data;
+ } intarr;
+'count' is number of elements, 'data' is array of elements.
+
+
+void dapi_freeintarr( intarr arr )
+----------------------------------
+
+Convenience function that frees dynamically allocated data from intarr.
+All DAPI functions that return intarr allocate the data dynamically
+and the caller must free it.
+
+
+stringarr
+---------
+
+A structure representing a string array.
+typedef struct
+ {
+ int count;
+ char** data;
+ } stringarr;
+'count' is number of elements, 'data' is array of char* strings.
+
+
+void dapi_freestringarr( stringarr arr )
+----------------------------------------
+
+Convenience function that frees dynamically allocated data from stringarr.
+All DAPI functions that return stringarr allocate the data dynamically
+and the caller must free it.
+
+
+
+
+
+
+Utility functions
+=================
+
+
+DapiConnection* dapi_connect( void )
+------------------------------------
+
+Tries to connect to a running backend daemon.
+
+Returns: NULL if failed, opaque connection handle if success.
+
+
+DapiConnection* dapi_connectAndInit( void )
+-------------------------------------------
+
+Convenience function that calls dapi_connect() and if successful
+also performs initialization by calling dapi_Init() (see later).
+
+
+DapiConnection* dapi_namedConnect( const char* name )
+-----------------------------------------------------
+
+Tries to connect to a named fallback daemon.
+
+name: name of the fallback daemon
+Returns: NULL if failed, opaque connection handle if success.
+
+
+DapiConnection* dapi_namedConnectAndInit( const char* name )
+------------------------------------------------------------
+
+Convenience function that calls dapi_namedConnect() and if successful
+also performs initialization by calling dapi_Init() (see later).
+
+
+void dapi_close( DapiConnection* conn )
+---------------------------------------
+
+Closes a connection to a backend daemon.
+
+conn: Opaque connection handle.
+
+
+int dapi_socket( DapiConnection* conn )
+---------------------------------------
+
+Returns a file descriptor that can be used with system functions such as select()
+to watch activity.
+
+conn: Opaque connection handle.
+Returns: file descriptor
+
+
+void dapi_processData( DapiConnection* conn )
+---------------------------------------------
+
+Processes pending incoming data on the connection socket.
+
+conn: Opaque connection handle.
+
+
+int dapi_readCommand( DapiConnection* conn, int* comm, int* seq )
+-----------------------------------------------------------------
+
+Reads a command header of the next incoming command request/reply.
+
+conn: Opaque connection handle.
+comm: Id number of the incomming command.
+seq: Sequence number of the incoming command.
+Returns: 1 if successful, 0 if failure
+
+
+TBD:
+typedef void (*DapiGenericCallback)( DapiConnection* conn, int command, int seq );
+DapiGenericCallback dapi_setGenericCallback( DapiConnection* conn, DapiGenericCallback callback );
+void dapi_genericCallback( DapiConnection* conn, int command, int seq );
+
+
+
+
+
+
+Calls functions
+===============
+
+
+There are several ways to invoke the API calls. For call XYZ there is:
+
+- lowlevel dapi_writeCommandXYZ(), dapi_readReplyXYZ() calls that write a command
+ request resp. read a command reply.
+
+ dapi_writeCommandXYZ() writes a command header and all command arguments and
+ returns either 0 if failure or sequence number of the command. Each command request
+ has a specific sequence number assigned and is used to identify replies.
+
+ dapi_readCommandXYZ() reads all reply arguments. It doesn't read command header,
+ dapi_readCommand() must be called first to identify a command. Returns 1 if success
+ or 0 if failure.
+
+ Include file dapi/comm_generated.h contains all function prototypes.
+
+- blocking dapi_XYZ() call that writes a command request and waits for a reply.
+ Include file dapi/calls_generated.h contains all function prototypes.
+
+- non-blocking dapi_callbackXYZ() call that writes a command and invokes the passed
+ callback when a reply comes.
+
+ dapi_callbackXYZ() returns a sequence number if success or 0 if failure
+
+ Include file dapi/callbacks_generated.h contains all function prototypes.
diff --git a/portland/dapi/doc/C-HOWTO.txt b/portland/dapi/doc/C-HOWTO.txt
new file mode 100644
index 0000000..3425377
--- /dev/null
+++ b/portland/dapi/doc/C-HOWTO.txt
@@ -0,0 +1,204 @@
+==============================================================================
+ C API bindings HOWTO
+==============================================================================
+
+This file contains HOWTO information specific to the C bindings. Refer to the generic
+API documentation for information that is not specific to C bindings and to
+C-API.txt for description of C bindings.
+
+
+Note: Most test programs in tests/ can be also used as examples.
+
+
+Linking with the library
+========================
+
+
+Use #include <dapi/headerfile.h> and add proper include path flags for the compiler
+if necessary.
+
+Add -ldapi and proper library path flags for the linker if necessary.
+
+
+
+Handling the DAPI connection
+============================
+
+
+Before using any API calls it is necessary to initialize the DAPI connection first.
+
+static DapiConnection* my_dapi_connection = NULL;
+...
+int initializeDapi()
+ {
+ my_dapi_connection = dapi_connectAndInit();
+ if( my_dapi_connection == NULL )
+ return 0; /* oops, failure */
+ return 1;
+ }
+
+If you want to do more than just perform a simple blocking call, you need to watch
+the connection for activity. Use dapi_socket() to get the file descriptor to watch
+and call dapi_processData().
+
+void mainloop()
+ {
+ fd_set in;
+ FD_ZERO( &in );
+ ... all file descriptors the app wants to watch
+ FD_SET( dapi_socket( my_dapi_connection ), &in );
+ ... select() call here
+ if( FD_ISSET( dapi_socket( my_dapi_connection ), &in ))
+ dapi_processData( my_dapi_connection );
+ ...
+ }
+
+Closing of the connection is done using dapi_close();
+
+
+
+Blocking calls
+==============
+
+
+For blocking calls, just simply call the matching API function. For example, to open
+URL in a browser:
+
+int openURL( const char* url )
+ {
+ if( dapi_OpenUrl_Window( my_dapi_connection, url, XWINDOW_HANDLE( toplevel_widget )))
+ return 1;
+ ... failure
+ }
+
+
+OpenUrl call needs a toplevel window in which the request originated (to handle properly
+window relations and focus). It is strongly discouraged to omit this information.
+If the application has no window at all, use 0. Note a convenience _Window function is
+used instead of DapiWindowInfo and dapi_windowInfoInitWindow().
+
+
+Functions are responsible for freeing resources allocated by the call. For example
+when converting KDE's media:/ URL to a local file:
+
+void handle_media_url( const char* url )
+ {
+ char* local;
+ /* convert to local file, don't allow download to a temporary file */
+ local = dapi_LocalFile_Window( my_dapi_connection, url, NULL, 0, XWINDOW_HANDLE( toplevel_widget ));
+ if( local != NULL ) /* success */
+ {
+ handle_local_file( local );
+ free( local );
+ return;
+ }
+ }
+
+
+Callbacks
+=========
+
+
+Some calls such as downloading a remote file to a temporary local file may take long time
+and as such should be processed asynchronously. It is possible to do so using the lowlevel
+dapi_read/write function or using callbacks.
+
+int start_downloading_remote_url( const char* url )
+ {
+ int seq = dapi_callbackLocalFile_Window( my_dapi_connection, url, NULL, 1, XWINDOW_HANDLE( toplevel_widget ),
+ download_remote_url_callback );
+ if( seq != 0 )
+ return seq;
+ ... failure
+ }
+
+void download_remote_url_callback( DapiConnection* conn, int seq, const char* result )
+ {
+ /* if this callback is used for more calls, use seq and the value returned from dapi_callbackLocalFile_Window
+ to identify matching command and reply */
+ if( result[ 0 ] != '\0' )
+ ... success
+ else
+ ... failed to download
+ }
+
+
+NOTE: Callbacks should not deallocate any of its arguments, callback handling will perform this
+automatically after the callback returns.
+
+
+Fallbacks
+=========
+
+
+API calls may fail for various reasons: No backend daemon is running or it doesn't implement
+the required functionality.
+
+No backend daemon running
+-------------------------
+
+A backend daemon should be provided by the desktop environment in which the application is running.
+If dapi_connectAndInit() call fails, it is most probably because the daemon is not available.
+In such case the application may consider shipping its own fallback daemon.
+
+
+int initializeDapi()
+ {
+ my_dapi_connection = dapi_connectAndInit();
+ if( my_dapi_connection == NULL )
+ { /* failure, try a fallback */
+ run_fallback_daemon();
+ my_dapi_connection = dapi_namedConnectAndInit( "MyAppFooInc" );
+ if( my_dapi_connection == NULL )
+ return 0; /* still no luck */
+ }
+ return 1;
+ }
+
+This approach allows silently expecting all following calls to succeed and not caring about fallback
+code at all. (NOTE: still experimental, not sure if it's worth it)
+
+The provided generic daemon accepts --dapiname argument that specifies the fallback name it should
+use. In this specific case run_fallback_daemon() could run "dapi_generic --dapiname MyAppFooInc".
+
+
+Some functionality not available
+--------------------------------
+
+It is possible to query functionality provided by the backend daemon.
+
+int is_openurl_supported()
+ {
+ intarr capabilities;
+ int i;
+ if( dapi_Capabilities( conn, &capabilities ))
+ {
+ int has_openurl = 0;
+ for( i = 0;
+ i < capabilities.count;
+ ++i )
+ {
+ if( capabilities.data[ i ] == DAPI_COMMAND_OPENURL )
+ has_openurl = 1;
+ }
+ }
+ return has_openurl;
+ }
+
+See dapi/comm_generated.h for list of command ids (DAPI_COMMAND_MAILTO for MailTo call etc.)
+
+Applications may perform one Capabilities call after initializing connection and query for all
+required functionality. If they don't find it available they may as well close this connection
+and use a fallback daemon in order to expect all calls to succeed.
+
+
+Fallback code
+-------------
+
+Another approach is to just initialize connection and test for failure after every call.
+
+void openURL( const char* url )
+ {
+ if( !dapi_OpenUrl_Window( my_dapi_connection, url, XWINDOW_HANDLE( toplevel_widget )))
+ openInHardcodedBrowser( url );
+ }
diff --git a/portland/dapi/lib/callbacks.c b/portland/dapi/lib/callbacks.c
index 2ac8f47..62f402d 100644
--- a/portland/dapi/lib/callbacks.c
+++ b/portland/dapi/lib/callbacks.c
@@ -14,7 +14,7 @@ DapiGenericCallback dapi_setGenericCallback( DapiConnection* conn, DapiGenericCa
return ret;
}
-void dapi_processCallbacks( DapiConnection* conn )
+void dapi_processData( DapiConnection* conn )
{
while( dapi_hasData( conn ))
{
diff --git a/portland/dapi/lib/callbacks.h b/portland/dapi/lib/callbacks.h
index 81f8c01..333ee82 100644
--- a/portland/dapi/lib/callbacks.h
+++ b/portland/dapi/lib/callbacks.h
@@ -13,7 +13,7 @@ typedef void (*DapiGenericCallback)( DapiConnection* conn, int command, int seq
DapiGenericCallback dapi_setGenericCallback( DapiConnection* conn, DapiGenericCallback callback );
-void dapi_processCallbacks( DapiConnection* conn );
+void dapi_processData( DapiConnection* conn );
void dapi_genericCallback( DapiConnection* conn, int command, int seq );
diff --git a/portland/dapi/tests/test_callbacks.c b/portland/dapi/tests/test_callbacks.c
index c682a54..6f4cd40 100644
--- a/portland/dapi/tests/test_callbacks.c
+++ b/portland/dapi/tests/test_callbacks.c
@@ -24,7 +24,7 @@ int main()
seq = dapi_callbackButtonOrder( conn, callback );
printf( "Order call2: %d\n", seq );
sleep( 1 ); /* give time to process */
- dapi_processCallbacks( conn );
+ dapi_processData( conn );
dapi_close( conn );
return 0;
}