README for the DD++ library - version 1.2 ========================================= By: Harry Danilevsky and Andrew Renalds Description ----------- The DD++ library is a C++ wrapper for the Motif 1.2 drag and drop preregister protocol. Its unique design not only provides a simple interface to drag and drop but also allows the movement of objects through the X server. This is done by separating the widget associated with the drag/drop site from the data that gets manipulated. The data type class, called Draggable, provides an interface to the data conversion and data transfer functions in the form of memory stream based persistence. A programmer must derive a class from this base class and override the saveOn(), restoreFrom(), and atomName() functions. Several examples are provided (DraggableString, DraggableInt, and DraggableDouble) in the include directory. Frequently used data types can be included in the DD++ library. To create a drag site with all the default Motif properties, a programmer simply needs to instantiate the DragSite class with the widget which will be the drag site. A data type can then be assigned to the drag site via the objectToDrag() method. An example of a class derived from DragSite, called SpecificDragSite, is also provided in the include directory. This class provides additional visual functionality such as drag-over and drag-under effects. Since a drop site can accept more than one data type, a programmer must first instantiate a DropTargetList class for a drop site. For each data type a drop site will accept, a class must be derived from the DropTarget class overriding the receive() method. This method is called when a successful drop occurs for a particular data type. An object of each class derived from DropTarget is then added to the drop targets list of valid data types via the append() method. In the same way, a data type may be removed from this list via the remove() method. A more detailed description of this library can be found in issue 12 of The X Resource journal. Compilation ----------- To compile libDD++.a and test examples: - Look into makefile and modify (if necessary ) environment variables according to your directory structure. - Type 'make'. This will build lib/libDD++.a and example programs in test subdirectory. - Type 'make install'. libDD++.a will be installed in LIBINSTALLDIR and the DD++ include directory will be created in INCINSTALLDIR. This package is known to compile with: 1. GNU's g++ version 2.4.1 under SunOS 4.1.3, Motif 1.2.1 2. Lucid's lcc version 3.2 under SunOS 4.1.3, Motif 1.2.1 3. Sun CC under Solaris 2.3, Motif 1.2.1 4. SGI C++ compiler under IRIX 5.2 , Motif 1.2.3 5. GNU's g++ version 2.6 under AIX If you compile and run it on other platforms, please let us know. Changes in version 1.1 ---------------------- A new class has been added (XPixmap) to be able to handle pixmaps as well as bitmaps. The library can be compiled with or without the HAVE_XPMLIB flag depending upon whether or not you have libxpm.a. A new example has also been added (DropTrash) showing how simple it is to create drop sites which have fancy visual effects. Changes in version 1.2 ---------------------- Previous versions used SLList (single-linked list) class from GNU libg++ library. This was the primary reason for releasing DD++ under the terms of Gnu Public License. GPL (as well as GLPL) are notorious for being a source of great confusion. It is especially disliked by people developing non-PD software. To eliminate this problem version 1.2 is no longer relying on libg++ and is now released under simple copyright terms (see file COPYRIGHT). Bug Fixes: Memory leaks eliminated (we used purify 3.0 do detect them). There are still memory leaks but they originate internally in Motif/Xlib and we don't have control over them. In previous versions it was not possible to override DragSite::actionName() and DragSite::dragKey() methods. Even though they were declared virtual they were in fact called from within DragSite ctor which of course used base class implementation. In version 1.2 actionName has become a char* data member of the DragSite class. You may specify your action name in DragSite ctor ; if you don't, the default action name "StartDrag" will be used. You may also specify in DragSite ctor whether you want the default key translation (Btn2 for copy, Shift-Btn2 for move and Shift-Ctl-Btn2 for link). If you create a DragSite with setDefaultDragKeys=False, you can either set key translation in your resource file(this is more in X spirit) or overload DragSite::dragKey() method in your derived class, construct an instance of the derived class and then call setDragKeys() method for it. Most likely you wouldn't want to do anything and rely on default behavior but we just didn't want to be blamed for "not providing enough flexibility" :-) New Feature: XDR-based streams. You may decide to use XDR-based streams instead of 'traditional' iostream-based. For instance if your Draggable object contains floating-point data and you are dragging it between applications running on different platforms then you can't reliably transfer floating-point data via iostream without losing precision (you'd have to write double onto a stream in string format and then read it back). An example of such Draggable object may be a graph structure containing coordinate pairs. XDR-based streams (DDistream and DDostream) are designed such that their interface is very similar to iostream's. The major practical difference is in operator >> for char*. In case of iostream operators <<(istream&, char*) and >>(ostream, char*) are not symmetrical. If a character string contains a whitespace or end-of-line character and you write it out using operator<<, you can't read it back with operator>> (only initial portion - till whitespace - will be read); you have to use getline() method. Xdr on the other hand has its own storing mechanism which automatically stores object size for arrays and strings. Thus for XDR-based streams getline() method is not needed. Moreover, you can read from DDistream into NULL pointer and memory will be allocated automatically (you are responsible for deleting it). The DD++ implementation of XDR-based streams is not general (these are memory-based streams) because DD++ doesn't need file or socket based streams. If you choose to use XDR-based streams you'll have to uncomment a line in the makefile which defines DD_USE_XDR variable. If your system C library doesn't contain Xdr implementation you'll also need to set XDRLIB. Xdr implementation is part of publically available tirpc package. Xdr header files containing ANSI-style function prototypes are included in include/rpc directory. saveTo() and restoreFrom() methods now work with o_stream/i_stream which are typedef'd to ostream/istream or DDostream/DDistream, depending on whether DD_USE_XDR is defined. Because of lack of available equipment XDR feature has not been excessively tested and should be considered beta or even alpha. If you decide to use it we'd like to hear about your experience (no matter how bad it might be :-). Harry Danilevsky hdanilev@fnbc.com Andrew Renalds renalds@fnbc.com