SDK
Software Development Kit
What is this SDK?
An SDK is a collection of information that tells you how to go about building software that works together with another piece of software. Any piece of software has its own structures and symbols, designed or chosen by the programmer at his own discretion, with which you must be familiar to successfully link with it. For example, to build a program that runs under the Windows operating system, you need the Win32 SDK.
This particular SDK is targeted at developers who intend to build plug-ins for Chasys Photo. Some sample source-code may be included with your copy. This SDK also includes some embedded sample code, and the common plug-in header file. It is strongly adviced that you always compile your code against the latest version of the header.
General Rules for Plug-ins
Neighbourliness
A plug-in must never take any action that will affect the stability of the host. It is considered to be especially bad behaviour for a plug-in to call functions such as abort() and TerminateProcess(); the reason being that there is no error that can be encountered within a library that justifies aborting the calling process (Chasys Photo) and destroying the user’s work in the process. It is the developer’s responsibility to ensure that any third-party libraries the plug-in uses don’t call abort() and friends.
Programming Language
The preferred language for building Chasys Photo plug-ins is C/C++, although any language that can produce DLLs linkable from standard C will do. The use of C# is discouraged because of its dependency on the so-called Microsoft Common Languages Runtime (mscoree.dll), which is not a particularly common DLL. Visual BASIC is simply too basic to cut it (and also has dependencies).
Filename & Location
The plug-in file name must have a “.dll ” extension, and its name (including the extension) must not exceed 30 characters. The plug-in must be placed in the “\Plugins” directory (folder) or a sub-directory thereof. If the plug-in is in a subdirectory, it must no be more than four levels deep because Chasys Photo will not search deeper than that. The name of the plug-in’s .dll file must be unique, even if the plugin is in its own separate folder. It is highly recommended that you follow the naming convention used by the default plug-ins.
Configuration Information
Never store configuration information in the system registry or in files because you won't get a chance to clean up that info, and you may lack the permissions to do so. If you need to store configuration infomation, do so using the permanent state-stores provided by pi_StateStore. Temporary state-stores may be used for transient information.
Data Validity
Never assume the validity of data across function calls. Most of the data Chasys Photo exchanges with plug-ins is created immediately before the call and destroyed immediately afterwards.
Linkage
All linkage to Chasys Photo must use the C/C++ calling convection ( __cdecl ), and strings of type “wchar_t*” where applicable. The use of standard Win32 functions and structures is encouraged (as opposed to using extensions such as dot-NET).
Dependencies
Avoid dependency on non-universal system DLLs or third-party DLLs. First, doing so will negate the principle of universal compatibility that Chasys Photo has always stuck to. Secondly, Chasys Photo will not let you install them, and will certainly not give you a chance to even think of removing them. If you are wondering why this is so, it is because most people (myself included) hate it when software decides to start installing stuff left, right and center without asking for permission first. In other words, it’s not your computer - it’s the user’s, and he/she doesn’t want you filling it with bloat-ware.
Extensibility
Most of the structures defined in this SDK float in a 1024-byte pool, and thus have a range of reserved bytes. Do not access these, they are meant for future expansion of the API and internal communication within the host. Leaving them untouched ensures that older plug-ins can work in newer hosts and vice-versa, since an older host will initialize them to zero.
Structure Padding
All structures exposed by this interface use 1-byte padding. The included headers have #pragma pack(1) defined for this reason.
Metadata (Attachments)
Plug-ins can access (and in some cases create) layer attachments. These may be used for plug-in-specific purposes. See the Layer Attachments section for more information. Do not use restricted metadata types, and please check with the author before creating custom metadata types.
General Plug-in Interface
Chasys Photo expects all plug-ins to have the following functions, irrespective of type. The sample code for the OpenRaster plug-in shows how to use these functions. Please refer to it later on.
| // called to query plugin's name and type unsigned long plg_GetInfo(plg_INFO* info); |
| // called to display plugin dialogs unsigned long plg_ShowDialog(plg_DIALOG* data); |
plg_GetInfo() is called by the host to collect information about the plug-in. It takes a pointer to a struct of type plg_INFO:
struct plg_INFO { unsigned long api_type; // PLUGIN_APITYPE_* flags unsigned long api_version; // PLUGIN_INTERFACE_VERSION unsigned long api_flags; // do not touch unsigned long api_extra; // do not touch //16 unsigned long plg_version; // plug-in's version number unsigned long plg_options; // plug-in's options unsigned long plg_flags; // do not touch unsigned long plg_extra; // do not touch //32 wchar_t plg_name[64]; // plug-in's name wchar_t plg_author[64]; // plug-in's author //288 unsigned char reserved_x[1024-288]; //do not touch }; |
Upon entry, the api_version member contains the version number of the FastExternalsTM interface implemented by the host (PLUGIN_INTERFACE_VERSION, see plugin.h for definition). The plug-in is required to return the version it was compiled for.
The plug-in should fill the api_type member with a combination of one or more of the following constants to indicate which interfaces in implements:
| PLUGIN_APITYPE_FILE | 0x00000001: File format Plug-in |
| PLUGIN_APITYPE_DEVICE | 0x00000002: Device Plug-in |
| PLUGIN_APITYPE_EFFECT | 0x00000004: Effect Plug-in |
| PLUGIN_APITYPE_ENGINE | 0x00000100: Engine Plug-in |
The api_flags and api_extra members are reserved and should be left untouched.
The plug-in should fill the plg_name and plg_author members with strings containing the name of the plug-in and the name of the vendor. These strings should not exceed 64 wide characters, including the null characters that terminate them. The plug-in should also fill the plg_version member with its own version number (major in high word and minor in low word). The plg_flags and plg_extra members are reserved and should be left untouched.
plg_ShowDialog() is called by the host to display a plugin dialog box, such as the "about" or the "config" window. It takes a pointer to a struct of type plg_DIALOG:
struct plg_DIALOG { HWND hwnd; unsigned long dialog; unsigned long param_1; unsigned long param_2; //16 unsigned char reserved_1[256-16]; //do not touch //256 pi_STATESTORE* pi_StateStore; pi_METAMARKUP* pi_MetaMarkup; pi_BASICQUERY* pi_BasicQuery; pi_BASICIMAGE* pi_BasicImage; pi_BASICCOLOR* pi_BasicColor; pi_BASICUTILS* pi_BasicUtils; //280 unsigned char reserved_x[1024-280];//do not touch }; |
The dialog member indicates which dialog box to display. It can be any of the following:
| PLG_DIALOG_ABOUT | 0x0000: Show the About box for the plug-in |
| PLG_DIALOG_CONFIG | 0x0001: Show the Config box for the plug-in |
| PLG_DIALOG_HELP | 0x0002: Show the Help box for the plug-in |
The hwnd member contains the window handle that should be used as the parent for the dialog box. The param_1 and param_2 members are dialog-specific, but are currently not used. Config dialog boxes must use the pi_StateStore member to persist the plug-ins settings; plug-ins are not allowed to directly write their settings to configuration files.
If the plug-in manages to display the dialog box, it should return PLUGIN_OKAY to indicate success. If the specified dialog is unnecessary (e.g. config box for a plug-in with no user-selectable options), it should return PLUGIN_ERR_NO_SUPPORT instead. The plug-in should return one of the other PLUGIN_ERR_* codes if an error occurs.
Type-specific Plug-in Interfaces
Chasys Photo supports various interfaces for the various types of plug-ins. Every plug-in must implement at least one of these interfaces; you may implement more than one if you wish.
| File Format Plug-in Interface | Used to open files that are not supported natively by Chasys Photo |
| Effects Plug-in Interface | Used to add external visual effects and transforms to Chasys Photo |
| Device Plug-in Interface | Used to allow Chasys Photo to exchange images with external devices |
Each interface has rules governing its plug-ins' construction.
Your plug-in is up and running, so what’s next?
Chasys Photo is a high-speed graphics environment, and if your plug-in can't keep up, things might get a little rough for it. Here are some tips that will help you keep the code flying like bullets:
- Always use the latest FastExternals™ interface.
- Where possible, use the utilities and callback suites exposed by the interface.
- Stick to the rules: Chasys Photo spends less time authenticating well-behaved plug-ins.
- Keep your plug-in filenames short and unambiguous. Chasys Photo implements a speculative loading mechanism that maintains a short cache of plug-in filenames. If the filename is too long (more than about 28 characters) or is ambiguous (causing the user to install two plug-ins that serve the same purpose) the loading mechanism will award it a low priority when deciding what to try first.