Most applications which write data files should be compatible with other applications. For example, applications will want to be able to import data, i.e. open a file written by another application and translate its data into a format the application can use. However, writing code to open another application's file and translate it into your own application's format can be difficult. Any application that wanted to properly support file-importing would have to provide a great many of these utilities. Furthermore, there would be a lot of duplicated effort; one application's routine for importing a particular file format would be much like another's. Applications would have similar problems exporting data, i.e. writing their data in another application's format.
The Impex (Import/Export) Library, along with specific translation libraries, solves these problems. They automatically translate files from non-GEOS formats into the Metafile (i.e. Clipboard) format and back. Applications just need to include the Import and Export objects; once they do this, importing and exporting data is just like using the Clipboard. Furthermore, extending the Impex Library to handle new formats is easy. All you have to do is write a new translation library for that one format and put the library in the SP_IMPORT_EXPORT_DRIVERS standard path. All applications which use the Impex objects will then be able to use that new format. Developers can write their own translation libraries; however, few will need to do this, since GEOS provides libraries for the most popular formats.
The Impex library currently supports import and export of text and graphic files. Geoworks is planning on extending it to allow the import and export of spreadsheet and font files as well. When these capabilities are available, they will be just like the already-supported text and graphic import and export.
1 Impex Basics
1.1 The Impex Objects
1.2 How the Impex Objects Work
2 Using Impex
2.1 Common Impex Concepts
2.2 The ImportControl Object
2.3 The ExportControl Object
3 Writing Translation Libraries
3.1 How Translation Libraries Work
3.2 Intermediate Formats
The Impex library provides a uniform way of importing data from files written by non-GEOS applications, and of exporting data to files written in these formats. It also saves coding time. Every outside format needs a single translation library, which translates between the Metafile format and the format for that specific library. The Impex objects provide all the necessary user interface (though the libraries and applications can add more), and also do all necessary interaction with the translation libraries.
In order to import data, an application will need to have an ImportControl object. Similarly, in order to export data, an application will need an ExportControl. Most applications that produce data files will want to use both of these objects.
Some applications will create a new GEOS file for imported data; others will add it into the current document, as if they were pasting data from the clipboard. Similarly, some applications will export the entire current document; others will export only the current selection, if any. This is left entirely to the discretion of the application.
There are two Impex objects which applications need to know about: ImportControl and ExportControl. These objects are both subclassed off of
ImportExportClass
, which provides some functionality needed for both objects; however, all this functionality is internal, so you can ignore this class. (No one should ever create an ImportExport object, and it has no instance data which applications may set.)
ImportExportClass
is itself subclassed from
GenControlClass
; therefore, ImportControl and ExportControl objects inherit all the functionality of controllers.
Applications will generally have one ImportControl and one ExportControl object. Applications may put these in different places; for example, some will place both of these on the File menu, while others may put them in the "Open" or "Save As" dialog boxes. Applications should decide this based on how they think the user will be using the import and export capabilities.
The ImportControl and ExportControl objects communicate with the application by sending messages. The ImportControl object sends a message to its recipient near the end of the Import process, when it has translated a file into a VM chain for the application to copy. The ExportControl object sends a message near the beginning of the export process, instructing the application to create a VM chain for the application to export. In both cases the message sent and the recipient are set by the application. Most applications will have the messages sent to their process arguments; however, applications which use the object model of document control may want to have the messages sent to the target object.
The Impex objects manage the user interface for importing and exporting data. They also open and create the appropriate files when necessary. If a user wants to import a file, the Import object lets the user select a source file and format. The import object will then call an appropriate library to translate the source file into a VM chain in the clipboard (i.e. MetaFile) format. At this point, it sends a message to the application, passing the handle of the VM chain. Similarly, when the user wants to export data, the Export object first lets the user select a name and format for the destination file. The Export object then sends a message to the application requesting a source VM chain in the Metafile format. The Export object then calls the appropriate translation library, which translates the MetaFile into a corresponding DOS file in the specified format.
It may help to give a blow-by-blow example. Let's suppose someone is using FooPaint, a graphics program for GEOS. FooPaint uses both the ImportControl and ExportControl objects to let the user import and export graphics. The user wants to import a graphic file written by BazDraw, a non-GEOS application. The user activates the "Import" trigger. The following things happen:
ImpexImportExportCompleted()
utility routine. This routine sends an appropriate acknowledgment message to the ImportControl object. The ImportControl destroys the temporary VM file.Note that almost all of this takes place without any action by the application. The only thing the application has to do is copy data from the VM chain to its own file, translating from the Metafile format to its own format. This is exactly what the application does whenever it pastes data from the clipboard; thus, applications which use the clipboard already have almost everything they need to use the Impex objects.
Exporting data is almost the same as importing it. The application is sent a message at the beginning of the operation, asking the application to write a VM chain in the Metafile format. The ExportControl will already have created a temporary VM file for the application to use; the application just has to allocate a chain in it and fill it with the appropriate information. The ExportControl presents a dialog box to the user, letting the user select a name, format, and location for the exported file; it then starts up the appropriate translation library to write the file.
The Impex objects are easy to use. Essentially, an application has to declare two objects and handle a single message from each of them. Applications which can use the clipboard already have most of the code they will need to use the Impex objects.
There are certain concepts and structures which are used by both of the Impex objects. Applications which use the Impex objects will have to be familiar with them.
ImpexDataClasses
The Impex objects are designed to translate into a few specific formats. These formats are known collectively as the
Metafile
formats. These formats (except for the "font" format) are identical to the standard "Clipboard Item Formats" described in the Clipboard chapter. When an application uses the Impex objects, it has to specify what types of data it is prepared to import or export.
It does this by setting an
ImpexDataClasses
record in both the ImportControl and the ExportControl objects.
ImpexDataClasses
has the following fields:
Every translation library translates a DOS file into a VM chain in one of these four formats, and vice versa. When an application declares an Impex object, it specifies what formats should be supported for that application. The user will be allowed to choose translation libraries which translate to or from a supported Metafile format.
ImpexTranslationParams
The Import and Export objects have to pass information to the application and the translation libraries. The same sort of information gets passed in many situations; for example, the objects often have to pass the
VMFileHandle
and
VMBlockHandle
which specify the VM chain. For simplicity, the Impex objects just pass a pointer to a
ImpexTranslationParams
structure when they send messages to the translation libraries or the application. The library or application takes the appropriate action, changing the
ImpexTranslationParams
structure as necessary; it then sends a response message, which takes a pointer to the same
ImpexTranslationParams
.
ImpexTranslationParams
has the following structure:
typedef struct { optr ITP_impexOD; Message ITP_returnMsg; ImpexDataClasses ITP_dataClass; VMFileHandle ITP_transferVMFile; VMBlockHandle ITP_transferVMChain; dword ITP_internal; ManufacturerID ITP_manufacturerID; ClipboardFormat ITP_clipboardFormat; } ImpexTranslationParams;
ITP_impexOD
_returnMsg
ImpexTranslationParams
.
The application should just pass the pointer to the
ImpexTranslationParams
to the routine
ImpexImportExportCompleted()
; this routine will send the appropriate notification message.
_dataClass
ImpexDataClasses
record. Exactly one of the flags will be set, indicating what sort of Metafile format is being used.
ITP_transferVMFile
VMFileHandle
of the transfer file. The transfer file is automatically created and destroyed by an Impex object.
_transferVMChain
VMBlockHandle
of the first block in the transfer VM chain. In Import operations, the translation library creates the VM chain in the transfer file; in Export operations, the application creates it. The chain will be freed when the Impex object destroys the transfer VM file. For information about creating VM chains, see the VM chapter.
ITP_internal
This field is for internal use by the Impex objects. You should not change it.
ITP_manufacturerID
This field contains the manufacturer ID which should be used for the Metafile data; see the Clipboard chapter.
ITP_clipboardFormat
The meaning of each field can change, depending on the circumstances. For example, when the ImportControl sends its message to the application, the ITP
_transferVMChain
field will contain the handle of a VM chain containing the imported data. In contrast, when the ExportControl sends its message, ITP
_transferVMChain
contains a null handle; the application should allocate a VM chain, fill it with data, and write the
VMBlockHandle
of the chain to this field. When a field has a special meaning, the documentation will explain it.
Applications which use the Impex library will generally have a single ImportControl object. This object is usually a child of the File menu; however, applications may put it wherever they want. They should also place it on the application object's GAGCNLT_SELF_LOAD_OPTIONS General Change Notification list. Applications should disable this object (with MSG_GEN_SET_NOT_ENABLED) whenever they are not prepared to accept imported data; for example, some applications will choose to disable file importing whenever they are unable to open a new document.
The ImportControl object is subclassed from
GenControlClass
(by way of
ImportExportClass
, as noted above). It thus has all the functionality of that class. It also has a few instance data fields of its own; they are shown in ImportControlClass Instance Data.
Code Display 16-1 ImportControlClass Instance Data
/* ICI_attrs is a word-length record which stores attribute information for the * ImportControl object. It has only one flag, ICA_IGNORE_INPUT. */ @instance ImportControlAttrs ICI_attrs = 0;
/* ICI_dataClasses is a word-length record which indicates what Metafile formats * are supported by the application. The application must set this field. */ @instance ImpexDataClasses ICI_dataClasses = 0;
/* ICI_destination and ICI_message indicate what message should be sent when the * ImportControl object has finished importing a file. The application must set * these fields. The message must take a single argument, namely a pointer to an * ImpexTranslationParams structure in ss:bp (on the stack). */ @instance optr ICI_destination; @instance word ICI_message;
/* Applications may wish to add their own UI objects to the Import dialog box. * They can do so by defining a generic tree (the top object of which must be not * "usable"), and putting an optr to the top object in ATTR_IMPORT_CONTROL_APP_UI. */ @vardata optr ATTR_IMPORT_CONTROL_APP_UI;
/* Controller features flags */ typedef ByteFlags ImportControlFeatures; #define IMPORTCF_BASIC 0x01
typedef ByteFlags ImportControlToolboxFeatures; #define IMPORTCTF_DIALOG_BOX 0x01
ImportControlAttrs, MSG_IMPORT_CONTROL_GET_ATTRS, MSG_IMPORT_CONTROL_SET_ATTRS
ICI
_attrs
is a word-length record of type
ImportControlAttrs
. This record contains only one flag:
To find out the current setting of this field, send
MSG_IMPORT_CONTROL_GET_ATTRS
to the ImportControl. To change this field, send MSG_IMPORT_CONTROL_SET_ATTRS to the ImportControl.
ImportControlAttrs MSG_IMPORT_CONTROL_GET_ATTRS();
This message retrieves the current setting of the ImportControl's ICI
_attrs
field.
Source: Unrestricted.
Destination: Any ImportControl object.
Return: The ImportControl's ICI
_attrs
field.
Interception: This message should not be intercepted.
void MSG_IMPORT_CONTROL_SET_ATTRS( ImportControlAttrs attrs);
This message changes the current settings of an ImportControl's ICI
_attrs
field.
Source: Unrestricted.
Destination: Any ImportControl object.
Parameters:
attrs
The new settings for the ICI
_attrs
field.
Interception: This message should not be intercepted.
MSG_IMPORT_CONTROL_GET_DATA_CLASSES, MSG_IMPORT_CONTROL_SET_DATA_CLASSES
When you declare an Import object, you must specify what kind of Metafiles your application is prepared to accept. You do this by setting the value of the ICI
_dataClasses
field. This field is a word-length record of type
ImpexDataClasses
(described in ImpexTranslationParams). If (for example) only the IDC_TEXT bit is set, the ImportControl will use only those import libraries which produce text Metafile output. More than one bit may be set; when the ImportControl sends its notification, it will tell the application what type of data is being imported.
To find out the current settings of the ICI
_dataClasses
field, send MSG_IMPORT_CONTROL_GET_DATA_CLASSES. To change the settings of this field, send MSG_IMPORT_CONTROL_SET_DATA_CLASSES.
ImpexDataClasses MSG_IMPORT_CONTROL_GET_DATA_CLASSES();
This message retrieves the current setting of the ImportControl's ICI
_dataClasses
field. This tells you what kind of data can be imported.
Source: Unrestricted.
Destination: Any ImportControl object.
Return: The ImportControl's ICI
_dataClasses
field.
Interception: This message should not be intercepted.
void MSG_IMPORT_CONTROL_SET_DATA_CLASSES( ImpexDataClasses dataClass);
This message changes the current settings of an ImportControl's ICI
_dataClasses
field.
Source: Unrestricted.
Destination: Any ImportControl object.
Parameters:
dataClass
The new settings for the ICI
_dataClasses
field.
Interception: This message should not be intercepted.
MSG_IMPORT_CONTROL_GET_ACTION, MSG_IMPORT_CONTROL_SET_ACTION, ImpexImportExportCompleted()
The ImportControl does most of its work transparently to the application. It interacts with the rest of the application only when the user has selected a file to import and the appropriate translation library has produced a VM chain. At this point the ImportControl sends a notification message to the application. The application responds by copying the data from the VM chain and sending back an acknowledgment message. The ImportControl can then destroy the temporary VM transfer file.
The application determines what message will be sent, and to what object, by setting the ICI
_destination
and ICI
_message
fields. Whatever object will receive the message should define an appropriate message.
The ImportControl will send this message with a single parameter:
itp
, a pointer to an
ImpexTranslationParams
structure (see ImpexTranslationParams). The fields of the structure have the following meanings in this case:
ITP_impexOD
_returnMsg
MSG_IMPORT_CONTROL_IMPORT_COMPLETE.
_dataClass
ImpexDataClasses
record with one flag set. This flag indicates what type of Metafile has been prepared.
_transferVMFile
VMFileHandle
of the temporary transfer file.
_transferVMChain
VMBlockHandle
of the lead block in the VM chain containing the imported data.
_internal
The recipient of the message should take any appropriate action; usually this entails copying the data from the VM chain, as if it were pasting data from the Clipboard. When the application is finished, it should call
ImpexImportExportCompleted()
. This routine takes one parameter, namely the
itp
pointer which was passed to the object. (The
ImpexTranslationParams
structure should not have been changed.)
ImpexImportExportCompleted()
reads the appropriate message and destination from the
ImpexTranslationParams
and sends the proper acknowledgment message (which in this case is
MSG_IMPORT_CONTROL_IMPORT_COMPLETE
).
Applications which use the object model of document control will often set ICI
_destination
to TO_APP_TARGET; this will make it send its messages to the target object. The application can find out the ImportControl's action by sending it
MSG_IMPORT_CONTROL_GET_ACTION
. The application can change the ImportControl's action by sending it
MSG_IMPORT_CONTROL_SET_ACTION
.
void MSG_IMPORT_CONTROL_GET_ACTION( ImpexAction * retValue);
This message retrieves the values of an ImportControl's ICI
_destination
and ICI
_message
fields. These fields indicate what action the ImportControl will take when it is finished preparing a file for import.
Source: Unrestricted.
Destination: Any ImportControl object.
Parameters:
retValue
A pointer to an
ImpexAction
structure.
Return: The value of ICI
_message
(i.e. the message sent by the ImportControl).
recipient
ImpexAction
structure describing the message sent.Interception: This message should not be intercepted.
Structures: The message and recipient are written to an
ImpexAction
structure:
typedef struct { word message; /* message sent */ word unused; optr destOD; /* Destination of message */ } ImpexAction;
void MSG_IMPORT_CONTROL_SET_ACTION( optr destOD, /* Send messages to this object. */ word ICImsg); /* Send this message to the above recipient. */
This message changes the values of an ImportControl's ICI
_destination
and ICI
_message
fields. These fields indicate what action the ImportControl will take when it is finished preparing a file for import.
Source: Unrestricted.
Destination: Any ImportControl object.
Parameters:
destOD
Set ICI
_destination
to this value.
ICImsg
_message
to this value.Interception: This message should not be intercepted.
When the user selects the "Import" trigger or tool, the Import controller brings up a dialog box. The application can, if it wishes, add UI objects to this box. It does so by defining a tree of generic objects (the top object of which must be set "not usable"). It must place an optr to the top object in the tree in ATTR_IMPORT_CONTROL_APP_UI. When the ImportControl builds the dialog box, it will add that optr as one of the children in the tree and set it "usable".
Applications which use the Impex library will generally have a single ExportControl object. This object is usually a child of the File menu; however, applications may put it wherever they want. They should also place it on the application object's GAGCNLT_SELF_LOAD_OPTIONS GCN list. Applications should disable this object (with MSG_GEN_SET_NOT_ENABLED) whenever they are not able to prepare data for export; for example, some applications will choose to disable file exporting whenever the "Cut" and "Copy" functions are disabled.
The ExportControl object is subclassed from
GenControlClass
(by way of
ImportExportClass
, as noted above). It thus has all the functionality of that class. It also has a few instance data fields of its own; they are shown in ExportControlClass Instance Data.
Code Display 16-2 ExportControlClass Instance Data
/* ECI_attrs is a word-length record which stores attribute information for the * ImportControl object. It has only one flag, ECA_IGNORE_INPUT. */ @instance ExportControlAttrs ECI_attrs = 0;
/* ECI_dataClasses is a word-length record which indicates what Metafile formats * are supported by the application. The application must set this field. */ @instance ImpexDataClasses ECI_dataClasses = 0;
/* ECI_destination and ECI_message indicate what message should be sent when the * ExportControl object is preparing to export a file. The application must set * these fields. The message must take a single argument, namely a pointer to an * ImpexTranslationParams structure in ss:bp (on the stack). */ @instance optr ECI_destination; @instance word ECI_message;
/* Applications may wish to add their own UI objects to the Export dialog box. * They can do so by defining a generic tree (the top object of which must be not * "usable"), and putting an optr to the top object in ATTR_EXPORT_CONTROL_APP_UI. */ @vardata optr ATTR_EXPORT_CONTROL_APP_UI;
/* Controller features flags */ typedef ByteFlags ExportControlFeatures; #define EXPORTCF_BASIC 0x01
typedef ByteFlags ExportControlToolboxFeatures; #define EXPORTCTF_DIALOG_BOX 0x01
ExportControlAttrs, MSG_EXPORT_CONTROL_GET_ATTRS, MSG_EXPORT_CONTROL_SET_ATTRS
ECI
_attrs
is a word-length record of type
ExportControlAttrs
. This record contains only one flag:
To find out the current setting of this field, send
MSG_EXPORT_CONTROL_GET_ATTRS
to the ImportControl. To change this field, send MSG_EXPORT_CONTROL_SET_ATTRS to the ImportControl.
ExportControlAttrs MSG_EXPORT_CONTROL_GET_ATTRS();
This message retrieves the current setting of the ExportControl's ECI
_attrs
field.
Source: Unrestricted.
Destination: Any ExportControl object.
Return: The ExportControl's ECI
_attrs
field.
Interception: This message should not be intercepted.
void MSG_EXPORT_CONTROL_SET_ATTRS( ExportControlAttrs attrs);
This message changes the current settings of an ExportControl's ECI
_attrs
field.
Source: Unrestricted.
Destination: Any ExportControl object.
Parameters:
attrs
The new settings for the ECI
_attrs
field.
Interception: This message should not be intercepted.
MSG_EXPORT_CONTROL_GET_DATA_CLASSES, MSG_EXPORT_CONTROL_SET_DATA_CLASSES
When you declare an Export object, you must specify what kind of Metafiles your application is able to create. You do this by setting the value of the ECI
_dataClasses
field. This field is a word-length record of type
ImpexDataClasses
(described in ImpexTranslationParams). If (for example) only the IDC_TEXT bit is set, the ExportControl will use only those export libraries which expect text Metafile input. More than one bit may be set; when the ExportControl sends its notification, it will tell the application what type of data it expects to export.
To find out the current settings of the ECI
_dataClasses
field, send MSG_EXPORT_CONTROL_GET_DATA_CLASSES. To change the settings of this field, send MSG_EXPORT_CONTROL_SET_DATA_CLASSES.
ImpexDataClasses MSG_EXPORT_CONTROL_GET_DATA_CLASSES();
This message retrieves the current setting of the ExportControl's ECI
_dataClasses
field. This tells you what kind of data can be exported.
Source: Unrestricted.
Destination: Any ExportControl object.
Return: The ExportControl's ECI
_dataClasses
field.
Interception: This message should not be intercepted.
void MSG_EXPORT_CONTROL_SET_DATA_CLASSES( ImpexDataClasses dataClasses);
This message changes the current settings of an ExportControl's ECI
_dataClasses
field.
Source: Unrestricted.
Destination: Any ExportControl object.
Parameters:
dataClasses
The new settings for the ECI
_dataClasses
field.
Interception: This message should not be intercepted.
MSG_EXPORT_CONTROL_GET_ACTION, MSG_EXPORT_CONTROL_SET_ACTION
The ExportControl does most of its work transparently to the application. It interacts with the rest of the application after the user selects the name, location, and format of the exported file. At this point the ExportControl creates a temporary transfer file and sends a notification message to the application; the notification message passes the file handle and the format expected. The application responds by creating a VM chain in the transfer file and filling it with the data to export, formatted in the appropriate Metafile format. The ExportControl can then call the translation library to create the output file.
The application determines what notification message will be sent, and to what object, by setting the ECI
_destination
and ECI
_message
fields. Whatever object will receive the message should define an appropriate message.
The ExportControl will send this message with a single parameter:
itp
, a pointer to an
ImpexTranslationParams
structure. The fields of the structure have the following meanings in this situation:
ITP_impexOD
_returnMsg
MSG_EXPORT_CONTROL_EXPORT_COMPLETE.
_dataClass
ImpexDataClasses
record with one flag set. This flag indicates what type of Metafile should be prepared.
_transferVMFile
VMFileHandle
of the temporary transfer file.
_transferVMChain
VMBlockHandle
of the head of the chain to this field. If the application fails for any reason, it should leave this field as a null handle.
_internal
The recipient of the message should take any appropriate action; usually this entails translating the current selection into the Metafile format and writing it to a VM chain. When the application is finished, it should call
ImpexImportExportCompleted()
. This routine will send the appropriate acknowledgment message to the ExportControl object (in this case,
MSG_EXPORT_CONTROL_EXPORT_COMPLETE
). This routine takes one parameter, namely the
itp
pointer which was passed to the object. The ITP
_transferVMChain
field of the
ImpexTranslationParams
structure should be set to the handle of the head block in the VM chain. If the application was unable to prepare the data for export, it should clear this field.
The ExportControl object will have created a temporary file for the application to use. This file will be entirely empty when the application gets it. The ExportControl will ignore everything in the file except for the VM chain indicated by ITP
_transferVMChain
; thus, an application can feel free to allocate blocks in the VM file for scratch space. The ExportControl will destroy the file when the translation library has finished preparing the output file.
Applications which use the object model of document control will often set ECI
_destination
to TO_APP_TARGET; this will make it send its messages to the target object. The application can find out the ExportControl's action by sending it
MSG_EXPORT_CONTROL_GET_ACTION
. The application can change the ExportControl's action by sending it
MSG_EXPORT_CONTROL_SET_ACTION
.
void MSG_EXPORT_CONTROL_GET_ACTION( ObjectState * retValue);
This message retrieves the values of an ExportControl's ECI
_destination
and ECI
_message
fields. These fields indicate what action the ExportControl will take when it needs to have data prepared for export.
Source: Unrestricted.
Destination: Any ImportControl object.
Parameters:
retValue
A pointer to an
ObjectState
structure.
Return: The value of ICI
_message
(i.e. the message sent by the ExportControl).
recipient
ObjectState
structure describing the message sent.Interception: This message should not be intercepted.
Structures: The message and recipient are written to an
ObjectState
structure:
typedef struct { int notUsed; word message; /* Message sent */ optr destOD; /* Destination of message */ } ObjectState;
void MSG_EXPORT_CONTROL_SET_ACTION( optr destOD, /* Send messages to this object. */ word ECImsg); /* Send this message to the above recipient. */
This message changes the values of an ExportControl's ECI
_destination
and ECI
_message
fields. These fields indicate what action the ExportControl will take when it is finished preparing a file for export.
Source: Unrestricted.
Destination: Any ExportControl object.
Parameters:
recipient
Set ECI
_destination
to this value.
message
_message
to this value.Interception: This message should not be intercepted.
When the user selects the "Export" trigger or tool, the Export controller brings up a dialog box. The application can, if it wishes, add UI objects to this box. It does so by defining a tree of generic objects (the top object of which must be set "not usable"). It must place an optr to the top object in the tree in ATTR_EXPORT_CONTROL_APP_UI. When the ExportControl builds the dialog box, it will add that optr as one of the children in the tree and set it "usable".
GEOS comes with many translation libraries, and more are being added all the time. Geoworks is continually adding new translation libraries for popular formats. Nevertheless, we cannot guarantee to support every format. Developers may decide to write their own translation libraries. This section describes how the libraries work in enough detail that developers will be able to do preliminary work in writing the libraries.
Most applications will find the provided translation libraries sufficient for their needs. Therefore, most developers can skip this section. You should read this if you are planning on writing translation libraries, or just if you want more understanding of the importing and exporting process.
Remember: once a translation library has been written, all a user has to do to install it is copy it to the appropriate directory. All existing applications which use Impex will then automatically be able to import and export that format. Users will be able to buy translation library collections from third-party vendors the way they buy font collections now.
How Translation Libraries Work
A translation library's task is easily stated. It has to do two things: read a native-format file and produce a Metafile translation, and read data in a Metafile and write corresponding data in a native-format file. How easy this is to do depends on the formats involved.
Every translation library specifies what format of Metafile it expects to work with. For example, the FooWrite translation library would translate FooWrite files into IDC_TEXT Metafiles and vice versa. When a user activates the "Import" trigger, he will be presented with a list of formats to use; those formats will correspond to all the libraries which can translate files into formats the application can accept. For example, if the application specified that it could accept text or graphics Metafiles, the user's choice of format would depend on which of the installed libraries could generate text or graphics Metafiles.
The translation library can also suggest a file mask. For example, the FooWrite translation library might specify that FooWrite data files meet the pattern "*.FOO". By default, the Import file selector will show only the files that match the library's mask. However, the user can override this mask, setting a different one or no mask at all.
When a user decides to import a file, the ImportControl opens the source file and creates a temporary transfer VM file. The ImportControl then starts up the appropriate translation library and passes the two file handles to it. The translation library should read the entire source file, translate it to the appropriate Metafile format, and write it to a VM chain in the transfer file. It then returns the
VMBlockHandle
of the head of the
VMChain
to the ImportControl. If it was unable to translate the file, it should return a null handle; the ImportControl then displays an appropriate error message. The ImportControl will close the source file automatically.
When a user decides to export a file, the ExportControl creates a temporary transfer file and opens an empty native-format file for the output. The ExportControl then calls the translation library. The library is passed the handles of the two files, as well as the handle of the Metafile VM chain. The library reads the Metafile and writes an appropriate data file. When it is finished, it notifies the ExportControl, which automatically closes the destination file and destroys the temporary transfer file.
Many libraries will want to make use of intermediate formats. For example, a company may have defined its own transfer format for its applications. The simplest way for it to translate files into the GEOS Metafile might be to translate the file into its own transfer format, then translate from this format into the Metafile format. GEOS supports this with its use of intermediate translation libraries.
An intermediate library is much like an ordinary translation library. Like other libraries, it must translate from its own format into the Metafile format. The only difference is that intermediate libraries are not called by the Impex objects; instead, they are called by other translation libraries.
For example, suppose FooWare, Inc., has a line of graphic FooApps which includes FooDraw, FooPaint, FooSketch, and FooScribble. FooWare has developed its own file-transfer format, FooInterchangeFormat (FIF); it has code written to translate any FooApp's files into FIF and back.
FooWare now wants to write translation libraries for GEOS. The first thing FooWare does is write an intermediate translation library which takes a DOS file containing FIF data and produces a VM chain containing a GEOS graphic Metafile, and vice versa. Once this is written, FooWare has an easy time writing the actual translation libraries. For example, the FooPaint translation library imports files by converting a FooPaint data file into the analogous FIF file. Since FooWare already has routines to do this translation, it just has to port existing code to the GEOS library. The FooPaint translation library then calls the FIF-to-Metafile intermediate translation library and gets the finished translation. Similarly, the FooPaint translation library exports data by calling the FIF-to-Metafile library to produce a FIF version of the data; it can then use ported code to produce an actual FooPaint file.
Note that any ordinary translation library can also be used as an intermediate translation library. For example, let's suppose that FooWare has code written to translate FIF files into PostScript files. This makes translating the documents even easier. The FIF-to-Metafile library can just use ported code to produce a PostScript version of the data; it can then call the PostScript-to-Metafile translation library, which is provided with GEOS. GEOS comes with translation libraries for many popular file-interchange formats; thus, many developers will be able to write translation libraries just by porting code from their pre-existing translators, then calling one of the GEOS translation libraries.