Rezilla logo


This is a tutorial about the plugin architecture defined by Rezilla, a resource forks editor for Mac OS X. It explains and demonstrates how to write third party editors for Rezilla. This document corresponds to version 1.1 of Rezilla.


Writing a Plugin for Rezilla

This section is for developers who wish to write a plugin for Rezilla.

A complete plugins support has been introduced in Rezilla starting from version 1.1. It uses the CFPlugin API defined in the CoreFoundation framework. This programming interface is based on the COM model (MicrosoftÕs Component Object Model architecture). To learn more about the CFPlugin model and the COM architecture, refer to the Apple's developer documentation, in particular: http://developer.apple.com/documentation/CoreFoundation/Conceptual/CFPlugIns/index.html

The present document explains how to write a plugin for Rezilla, complying with this model. It is written for developers who want to bring new editing capacities to Rezilla and contains the main guidelines and technical information for this purpose.

The plugin model

A plugin implements an interface which can be viewed as a particular incarnation of a service. In the official terminology, one speaks of type to designate a kind of service: the type of an editor plugin, in the case of Rezilla, is the fact of editing a particular resource (the word type here should not be confused with the type of a resource!). As of version 1.1, Rezilla knows of only this plugin type: the editing service. In the future, Rezilla could also support external plugins defining new resource pickers, for instance, and this would be another type since it is a different kind of service.

There is not necessarily one interface for a given type: there can be several interfaces. For instance, future versions of Rezilla, might modify the current interface: this would be done via the definition of a new, additional, interface. In that case, a Rezilla plugin would have to provide implementations for both the old and the new interface and the main Rezilla application would decide which one to use depending on the circumstances and the context. As of version 1.1 of Rezilla, there is only one interface for the editing service. An interface can be understood as a list of functions corresponding to different tasks and which are expected by Rezilla to be defined in the plugin.

The plugin's bundle

Technically a plugin is just a dynamic library which is loaded by the main application when necessary. On OS X, this library is packaged in a bundle, that is to say a directory-like structure containing the library itself and a few other resources.

To learn more about bundles on OS X, see: http://developer.apple.com/documentation/CoreFoundation/Conceptual/CFBundles/Concepts/about.html

Using this architecture makes it very easy, from the user's point of view, to perform the maintenance tasks related to plugins, for instance adding a new plugin, removing a plugin, enabling or disabling a plugin. All these actions can be performed in the Finder in a transparent manner (see the External Editors section in Rezilla's help). The user does not have to know where exactly the plugin resides inside the application's bundle.

Here is, for instance, the internal structure of the RezImagePlugin, a plugin provided with version 1.1 of Rezilla:

Plugin anatomy

The plugin's bundle is named RezImagePlugin.plugin. It must have a .plugin extension to make sure that Rezilla will find it. Some elements of the Contents subfloder are required, some are optional. Required elements are:

The Resources subfolder may contain additional data. In the previous example, it contains:

The plugin's UUIDs

Various elements of the Core Foundation plugin model are identified using an UUID (Universally Unique Identifier). Some UUIDs are defined on the main application's side, others on the plugin's side.

An UUID is a 128-bits value guaranteed to be unique. It can be represented in two forms: a byte form and a string form. The byte form is a C structure defined in the Core Foundations (see the CFUUIDBytes struct in the CFUUID.h header file). The string form is a convenience form: it is a hyphen-punctuated ASCII string which is used, for instance, in the property list of the plugin (see the section The plugin's property list below).

Rezilla UUIDs

Rezilla defines two UUIDs to refer to the type of the plugin and to the factory implementing the interface respectively. The values are defined in the RezillaPluginInterface.h header file using symbolic values: These UUIDs are defined like this:
    #define kRezillaPluginEditorTypeID (CFUUIDGetConstantUUIDWithBytes(NULL,0x30,0x6A,0x0E,0xF3,0x20,0x6E,0x11,0xDA,0x83,0x20,0x00,0x0A,0x95,0xB1,0xFF,0x7C))
    #define kRezillaPluginEditorInterfaceVs1 (CFUUIDGetConstantUUIDWithBytes(NULL,0x30,0x6A,0xE1,0x67,0x20,0x6E,0x11,0xDA,0x83,0x20,0x00,0x0A,0x95,0xB1,0xFF,0x7C))
which can be written in string form as:
    306A0EF3-206E-11DA-8320-000A95B1FF7C
    306AE167-206E-11DA-8320-000A95B1FF7C

Factory UUIDs

The plugin will have to provide UUIDs for all the implementations of interfaces it contains. The implementation is done by a factory function. These factory functions are declared in the property list of the plugin and defined in the plugin itself. The RezillaImage plugin for instance supports Rezilla's editing type and its associated interface, so it has to define one factory UUID. So its C code contains the following instruction:
    #define kRezillaImageFactoryID (CFUUIDGetConstantUUIDWithBytes(NULL,0x09,0x05,0xF8,0x36,0xA2,0x0C,0x11,0xDA,0xBC,0x6C,0x00,0x0A,0x95,0xB1,0xFF,0x7C))
and its property list declares this same value in string form as
    0905F836-A20C-11DA-BC6C-000A95B1FF7C
In case there are several interfaces, each interface must have an UUID.

Generating an UUID

There is a simple command line tool called uuidgen, provided with the Apple's Developers Tools, which generates UUIDs. Here is an example of the uuidgen usage (to execute in a Terminal window):
    shell> uuidgen
    9A347042-427C-11DB-9237-000A95B1FF7C

The Rezilla SDK also provides a slightly more elaborate tool called mkuuid. With mkuuid you can specify the number of UUIDs you want to generate and its output returns the UUIDs both in bytes form (to use in the C code) and in string form (to use in the property list). Here is an example of its usage:

    shell> mkuuid 2
    UUID as bytes: (NULL,0xC1,0x37,0x86,0xB4,0x42,0x7C,0x11,0xDB,0xA0,0xC4,0x00,0x0A,0x95,0xB1,0xFF,0x7C)
    UUID as string: "C13786B4-427C-11DB-A0C4-000A95B1FF7C"
    
    UUID as bytes: (NULL,0xC1,0x38,0x2C,0x85,0x42,0x7C,0x11,0xDB,0xA0,0xC4,0x00,0x0A,0x95,0xB1,0xFF,0x7C)
    UUID as string: "C1382C85-427C-11DB-A0C4-000A95B1FF7C"

The plugin's property list

The Info.plist file stores useful data and information related to the plugin. It uses an XML format: some of its keys are used by the Finder and the System, some are used by Rezilla itself.

System keys

The keys defined for the System are the usual ones found in application bundles. In the case of the RezImage plugin, for instance, we have the following key/value pairs:

KeyValue
CFBundleIdentifiernet.sourceforge.rezilla.RezImagePlugin
CFBundleNameRezImagePlugin
CFBundleShortVersionStringRezImagePlugin 0.1
CFBundlePackageTypeBNDL
CFBundleSignatureRzil
CFBundleExecutableRezImagePlugin
CFBundleVersion0.1
CFBundleIconFileRezillaPlugin.icns
CFBundleDevelopmentRegionEnglish
CFBundleInfoDictionaryVersion6.0
LSRequiresCarbonyes

The Resources subfolder, inside the plugin bundle, can store an icon file (with .icns extension). If this icon file is declared in Info.plist under the CFBundleIconFile key, the image will be displayed by Rezilla in the Plugin Info panel invoked with the Plugins... command located in the File menu.

CFPlugin keys

Some keys are required by the CFPlugin programming interface:

Rezilla keys

Rezilla expects to find two additional custom keys in the Info.plist file:

The plugin's interface

The members of the plugin interface are defined in the RezillaPluginInterface.h header file provided by the Rezilla SDK. This file must be included in the source code of the plugin. It defines the interface itself and a few other structures and enumerations which organize the communication between the main application and the plugins.

The interface structure

The interface is defined as a structure made of function pointers. This is the list of all the functions that the plugin must define. These are the functions which Rezilla will invoke to execute various editing tasks.

typedef struct SPluginEditorInterface {
    IUNKNOWN_C_GUTS;
    Boolean  (*AcceptResource)(void *myInstance, ResType inType, short inID, Handle inDataH, RezPlugInfo * outInfo);
    OSErr    (*EditResource)(RezPlugRef inPlugref, RezHostInfo inInfo);
    Handle   (*ReturnResource)(RezPlugRef inPlugref, Boolean * outRelease, OSErr * outError);
    OSErr    (*RevertResource)(RezPlugRef inPlugref, Handle inDataH);
    Boolean  (*IsModified)(RezPlugRef inPlugref);
    void     (*CleanUp)(RezPlugRef inPlugref);
    void     (*Refresh)(RezPlugRef inPlugref);
    OSErr    (*ResizeBy)(RezPlugRef inPlugref, SInt16 inWidthDelta, SInt16 inHeightDelta);
    void     (*HandleMenu)(RezPlugRef inPlugref, MenuRef menu, SInt16 inMenuItem);
    void     (*HandleClick)(RezPlugRef inPlugref, const EventRecord * inMacEvent, Point inPortCoords);
    void     (*HandleKeyDown)(RezPlugRef inPlugref, const EventRecord * inKeyEvent);
    Boolean  (*HandleCommand)(RezPlugRef inPlugref, SInt16 inCommand);
}

This structure gives the protopypes of the functions. The IUNKNOWN_C_GUTS symbol is a macro defined in the CFPlugInCOM.h header file which expands to three mandatory functions: QueryInterface, AddRef, and Release. They form the basis of the COM architecture: any plugin based on this model must define them. This is where the basic verifications take place: for instance, the application must verify that the UUIDs are the expected ones. Here are the prototypes of the three COM functions:

    HRESULT (*QueryInterface)(void *thisPointer, REFIID iid, LPVOID *ppv); \
    ULONG (*AddRef)(void *thisPointer); \
    ULONG (*Release)(void *thisPointer)

All the remaining functions are required by Rezilla: Rezilla expects them to be defined by the plugin. All of them (except for the AcceptResource function) have a RezPlugRef as their first argument: this is a reference attributed by the plugin to every editing transaction. More specifically a RezPlugRef is a pointer to plugin defined client data corresponding to a particular resource being edited: it identifies which resource is concerned and which data are attached to it, since several resources of the same type could be edited simultaneously by the plugin. Rezilla does not interfere with the data pointed to by this RezPlugRef: it just guarantees to pass it back in all the calls of the interface. The RezPlugRef type is declared in the RezillaPluginInterface.h header file like this:

    typedef void *	RezPlugRef;

When the plugin is first invoked, Rezilla loads it using the CFPlugin API functions. This is where the factory function is called: this function is declared in the Info.plist property list file, as explained in the section The plugin's property list above.

Interaction with the plugin

When Rezilla needs to edit a resource via a plugin, there is an initial transaction between them. This transaction is executed in two steps involving the AcceptResource and the EditResource functions successively:
  1. Rezilla first invokes the AcceptResource function to ask the plugin whether it accepts to edit this resource: it passes the type, the ID and a handle to the data of the resource so that the plugin can determine its answer. If it accepts the resource, it fills a RezPlugInfo structure also provided by Rezilla in the same function to make some requests: the plugin could ask Rezilla to provide one or several menus for instance. The plugin can also attribute a RezPlugRef, a pointer to private data which Rezilla will pass back in all its calls to interface functions.

  2. after Rezilla receives acceptance and requests from the plugin, it invokes the EditResource function. Through this function the plugin receives a RezHostInfo structure filled by Rezilla and containing basic information such as a WindowRef for the editing window, the MenuRef pointers in case the plugin needs some menus, etc.

At this point the plugin can do its job to edit the resource. It can populate the window with controls and graphic elements, install CarbonEvents on these controls if necessary, etc. The window provided by Rezilla is constructed in compositing mode: this makes the HIView drawing model fully available.

Note though that the plugin is not obliged to use CarbonEvents; the basic user actions are passed to it by Rezilla with an EventRecord via the following functions declared in the interface: HandleMenu, HandleClick, HandleKeyDown and HandleCommand.

When it is time to save the modifications made in a resource (for instance when the user clicks on the Save button or attempts to close the window), Rezilla invokes the ReturnResource function so that the plugin returns the new data and then the CleanUp function so that it terminates its editing session.

If the user clicks on the Revert button (if there is one!), Rezilla invokes the RevertResource function: the data to revert to are provided in the inDataH argument, so the plugin does not have to worry about keeping a copy of the original data.

Plugin requests

This section gives more details about the requests made by the plugin in the AcceptResource function. The RezPlugInfo structure is defined like this:

typedef struct RezPlugInfo {
    RezPlugRef    plugref;
    UInt32        attributes;
    Rect          winbounds;
    UInt8         menucount;
    MenuID *      menuIDs;
    OSErr         error;
}

Most important is the attributes member of the structure. This is an UInt32 additive value, sum of different flags which determine various aspects of the editing window provided by Rezilla and the basic Rezilla commands supported by the plugin. The values of the flags are defined in the RezillaPluginFlags enumeration declared in the RezillaPluginInterface.h header file:

enum RezillaPluginFlags {
    kPluginNoAttributes             = 0L,
    
    kPluginEditorHasSaveButton      = (1L << 0),
    kPluginEditorHasCancelButton    = (1L << 1),
    kPluginEditorHasRevertButton    = (1L << 2),
    kPluginEditorHasLockIcon        = (1L << 3),
    kPluginEditorHasNameField       = (1L << 4),
    kPluginEditorStandardControls   = (kPluginEditorHasSaveButton 
                                   | kPluginEditorHasCancelButton 
                                   | kPluginEditorHasRevertButton 
                                   | kPluginEditorHasLockIcon),
    
    kPluginWinHasCollapseBox        = (1L << 5),
    kPluginWinIsResizable           = (1L << 6),
    
    kPluginSupportCut               = (1L << 10),
    kPluginSupportCopy              = (1L << 11),
    kPluginSupportPaste             = (1L << 12),
    kPluginSupportClear             = (1L << 13),
    kPluginSupportSelectAll         = (1L << 14),
    kPluginSupportFind              = (1L << 15),
    kPluginSupportFindNext          = (1L << 16),
    kPluginSupportImport            = (1L << 17),
    kPluginSupportExport            = (1L << 18),
    kPluginSupportEditCommands      = (kPluginSupportCut 
                                   | kPluginSupportCopy 
                                   | kPluginSupportPaste 
                                   | kPluginSupportClear)
}

The winbounds member is a Rect structure indicating the position and dimension of the editing window: it is in global coordinates and corresponds to the entire structure of the window, that is to say the dimensions that will be passed to the CreateWindow toolbox function. Rezilla always provides an editing window which can be equiped with some basic controls such as a Save button, a Cancel button etc. The plugin does not have to track these controls: they are managed by the main application. The plugin just decides, using the appropriate flags, which controls should be present in the editing window. For instance, add the kPluginEditorHasRevertButton flag to the attributes to get a Revert button.

The menucount member indicates how many menus are needed by the plugin (possibly 0). If the plugin defines some menus, it must pass an array of the corresponding MenuIDs in the menuIDs member of the structure. These MenuIDs are the IDs of resources of type 'MENU' which must be defined in the resource file of the plugin: this resource file is located in the Resources subfolder inside the plugin's bundle as explained in the section The plugin's bundle above.

In case the plugin does not accept to edit the resource, it must return false in the AcceptResource function and there is of course no need to make any request. If an error occured, the plugin can return an error code in the error member of the RezPlugInfo structure.

Supported commands

The basic Rezilla menus (File, Edit, Resources) have commands which are not always enabled: it depends on the context. For instance, the Export command makes sense only in particular circumstances or with some types of resources: similarly a plugin can support this command or not. Which commands are supported by the plugin is declared in the initial attributes as explained in the previous section: if the Export command is supported by the plugin, the kPluginSupportExport flag should be added to the attributes. If the flag is not set, the corresponding menu item is disabled.

Later, when the Export command in the File menu is invoked by the user, Rezilla calls the HandleCommand function with a command number so that the plugin can react appropriately. The command numbers are defined in the RezillaPluginCmdIDs enumeration declared in the RezillaPluginInterface.h header file:

enum RezillaPluginCmdIDs {
    kPluginCommandCut        = 1,
    kPluginCommandCopy,
    kPluginCommandPaste,
    kPluginCommandClear,
    kPluginCommandSelectAll,
    kPluginCommandFind,
    kPluginCommandFindNext,
    kPluginCommandImport,
    kPluginCommandExport
}

Host info

The RezHostInfo structure is defined like this:

typedef struct RezHostInfo {
    CFBundleRef  bundleref;
    short        refnum;
    WindowRef    winref;
    UInt8        menucount;
    MenuRef *    menurefs;
    Rect         editrect;
    Boolean      readonly;
}

This is where Rezilla passes useful informations back to the plugin. The bundleref member of the structure is a convenience: it is a reference of type CFBundleRef to the plugin's bundle in case the plugin needs to find something in its own structure (localized strings for instance).

The refnum member is the reference number of the resource map the currently edited resource belongs to. This gives access to various Resource Manager functions: the plugin might want to get other resources related to the one it is currently editing.

The winref member is the toolbox WindowRef of the editing window provided by Rezilla.

The menucount member indicates how many menus have been created by Rezilla. Hopefully this is the same number as requested by the plugin in the RezillaPluginFlags structure. The menurefs member is an array of toolbox MenuRefs corresponding to the different menus.

The editrect member is a Rect structure indicating the coordinates of the contents area of the window which is available to the plugin, so that the plugin knows where to place its controls and does not draw over parts installed by Rezilla (the top placard or the bottom area containing the Save and Cancel buttons). This Rect is passed in window coordinates.

The readonly member tells whether the map the resource belongs to is read-only. If it is read-only there is no point making modifications to the resource. In that case, the plugin would act simply as a viewer.

Error codes

Rezilla defines error codes for the main errors likely to be encountered during an editing session. They start at value 5000:

enum RezillaPluginErrors {
    plugErr_Generic                = 5000,    
    plugErr_InitializationFailed,
    plugErr_UnsupportedType,
    plugErr_UnsupportedID,
    plugErr_InvalidData,
    plugErr_UnsupportedResourceFormat,
    plugErr_UnsupportedResourceVersion,
    plugErr_EditResourceFailed,
    plugErr_ReturnResourceFailed,
    plugErr_RevertResourceFailed,
    plugErr_CantResizeWindow,
    plugErr_CantHandleMenuCommand,
	plugErr_CantEditEmptyResource,
    plugErr_LastError
}

The Sample plugin

This section comments the code of the Sample plugin provided by the Rezilla SDK as an example and possibly a template for creating a Rezilla plugin. An XCode project file is also provided. The Sample plugin demonstrates the various aspects of the programming tasks necessary to build a Rezilla plugin. The source code itself also contains useful comments.

To learn more about Rezilla plugins, one can also have a look at the code of the RezImage plugin which is a real-life example. It is included in version 1.1 of Rezilla and is able to edit image resources ('jpeg', 'tiff', 'gif ', etc.)

The Sample plugin edits resources of type 'PStr' or 'STR '. These are very simple resources which just contain a Pascal string. The plugin will display an edit field to let the user modify the string and will insert a menu in the menu bar with two commands (nothing really useful, it is just for the sake of demonstration).

The Sample source files

The SamplePlugin folder in the Rezilla SDK contains the following files:

The Sample UUID

The plugin needs to define a single UUID corresponding to the unique factory function. This UUID has been created with the genuuid utility provided by the Apple's Developer Tools or the mkuuid utility provided with the Rezilla SDK.

The definition is found at the top of the RezSamplePlugin.c source file.

    #define kRezillaSampleFactoryID (CFUUIDGetConstantUUIDWithBytes(NULL,0x30,0x6B,0x89,0xA8,0x20,0x6E,0x11,0xDA,0x83,0x20,0x00,0x0A,0x95,0xB1,0xFF,0x7C))

The Sample property list

The string form of the UUID mentioned in the previous section is:

    306B89A8-206E-11DA-8320-000A95B1FF7C 
It is used in the Info.plist file in two places: as a key in the CFPlugInFactories dictionary and as a value in the CFPlugInTypes dictionary:
    <key>CFPlugInFactories</key>
    <dict>
    	<key>306B89A8-206E-11DA-8320-000A95B1FF7C</key>
    	<string>RezSampleFactory</string>
    </dict>
    <key>CFPlugInTypes</key>
    <dict>
    	<key>306A0EF3-206E-11DA-8320-000A95B1FF7C</key>
    	<array>
    		<string>306B89A8-206E-11DA-8320-000A95B1FF7C</string>
    	</array>
    </dict>
Note that the key (not the value) of the CFPlugInTypes dictionary is the UUID identifying the type of service of the plugin (the constant kRezillaPluginEditorTypeID defined by Rezilla). The value of the CFPlugInFactories dictionary is the name of the function which will be invoked to instanciate the plugin interface: this function (RezSampleFactory) is defined in the source file (RezSamplePlugin.c).

The Info.plist file also declares the resource types supported by this plugin ('PStr' and 'STR '):

    <key>RezillaPluginEditTypes</key>
    <array>
    	<string>PStr</string>
    	<string>STR </string>
    </array>
and the role of the plugin:
    <key>RezillaPluginRole</key>
    <string>Editor</string>

The other key/value pairs are standard and self explanatory.

The Sample project file

The Sample plugin project file RezSamplePlugin.xcode has been created with XCode 1.5 to ensure compatibility with older versions of the OS X System (Jaguar and Panther). It will work with more recent versions of XCode: on the 10.4 System (Tiger), versions 2.0 or greater of XCode will convert it to a file named RezSamplePlugin.xcodeproj.

The Sample code

The C code defining the plugin is found in the RezSamplePlugin.c source file.

The Sample structures

The Sample plugin defines two structures to manage its editing sessions:

A function table is also created: it is a static instanciation of a SPluginEditorInterface struct (i-e the struct defined by Rezilla to describe the interface) and contains the name of the interface functions defined by the plugin.

    static SPluginEditorInterface sSamplePlugFuncTable = {
            NULL,
            sample_QueryInterface,
            sample_AddRef,
            sample_Release,
            sample_AcceptResource,
            sample_EditResource,
            sample_ReturnResource,
            sample_RevertResource,
            sample_IsModified,
            sample_CleanUp,
            sample_Refresh,
            sample_ResizeBy,
            sample_HandleMenu,
            sample_HandleClick,
            sample_HandleKeyDown,
            sample_HandleCommand
    };

Two static variables hold the ID and the ref of the menu associated with the plugin:

    static MenuID    sampleMenuID;
    static MenuRef   sampleMenuRef;

The Sample factory

The RezSampleFactory() function is invoked by Rezilla (via the CFPlugin API) when the plugin is first loaded. This function is known thanks to the Info.plist property list file. After verifying that the type of the plugin is the expected one (kRezillaPluginEditorTypeID), it then allocates memory for a SampleRec structure and fills it appropriately. Finally it declares the factory with CFPlugInAddInstanceForFactory().

The COM functions
The COM model requires the definition of three functions: QueryInterface, AddRef and Release. They are instanciated in the Sample plugin as functions sample_QueryInterface(), sample_AddRef(), and sample_Release().

The initial transaction

The initial transaction between the main application and the plugin is accomplished by the sample_AcceptResource() and the sample_EditResource() functions.

In the sample_AcceptResource() function, the plugin first verifies that the type of the resource is one of the expected ones and then allocates memory for a SampleEditInfo struct associated with this resource. The pointer to this struct will be used as a RezPlugRef passed as an argument of all the other functions of the Rezilla interface. So the info stored in this structure can be retrieved by any of these functions.

The function sample_AcceptResource() also fills the RezPlugInfo struct passed by Rezilla as last argument in order to make some requests to the main application. In particular, it sets the attribute field like this:

    outInfo->attributes = kPluginEditorStandardControls | kPluginSupportEditCommands;

The kPluginEditorStandardControls symbol is a constant defined by Rezilla (in RezillaPluginInterface.h) asking for the standard controls to be present in the editing window (Save button, Cancel button, etc.). The kPluginSupportEditCommands constant is also a convenience value designed to enable the commands of the Edit menu in Rezilla (Cut, Copy, Paste, etc.). The function makes also a request for one menu:

    outInfo->menucount = 1;
    outInfo->menuIDs   = &sampleMenuID;
The menu is defined as a 'MENU' resource in the resource file RezSamplePlugin.rsrc. It defines two (totally useless, but, hey, this is a sample plugin) commands, Reverse string and Rotate string, which modify the string.

The interface functions

The remaining functions, expected by the interface, are:

sample_ReturnResource
sample_RevertResource
sample_IsModified
sample_CleanUp
sample_Refresh
sample_ResizeBy
sample_HandleMenu
sample_HandleClick
sample_HandleKeyDown
sample_HandleCommand

They are defined in straightforward manner.

Rezilla plugins reference

Here is, as a reference, a summary of Rezilla's client plugins public data.

A RezPlugRef is a pointer to plugin defined client data:

	typedef void *	RezPlugRef;

Structures

SPluginEditorInterface
typedef struct SPluginEditorInterface {
    IUNKNOWN_C_GUTS;
    Boolean  (*AcceptResource)(void *myInstance, ResType inType, short inID, Handle inDataH, RezPlugInfo * outInfo);
    OSErr    (*EditResource)(RezPlugRef inPlugref, RezHostInfo inInfo);
    Handle   (*ReturnResource)(RezPlugRef inPlugref, Boolean * outRelease, OSErr * outError);
    OSErr    (*RevertResource)(RezPlugRef inPlugref, Handle inDataH);
    Boolean  (*IsModified)(RezPlugRef inPlugref);
    void     (*CleanUp)(RezPlugRef inPlugref);
    void     (*Refresh)(RezPlugRef inPlugref);
    OSErr    (*ResizeBy)(RezPlugRef inPlugref, SInt16 inWidthDelta, SInt16 inHeightDelta);
    void     (*HandleMenu)(RezPlugRef inPlugref, MenuRef menu, SInt16 inMenuItem);
    void     (*HandleClick)(RezPlugRef inPlugref, const EventRecord * inMacEvent, Point inPortCoords);
    void     (*HandleKeyDown)(RezPlugRef inPlugref, const EventRecord * inKeyEvent);
    Boolean  (*HandleCommand)(RezPlugRef inPlugref, SInt16 inCommand);
}

RezPlugInfo
typedef struct RezPlugInfo {
    RezPlugRef    plugref;
    UInt32        attributes;
    Rect          winbounds;
    UInt8         menucount;
    MenuID *      menuIDs;
    OSErr         error;
}

RezHostInfo
typedef struct RezHostInfo {
    CFBundleRef  bundleref;
    short        refnum;
    WindowRef    winref;
    UInt8        menucount;
    MenuRef *    menurefs;
    Rect         editrect;
    Boolean      readonly;
}

Enumerations

RezillaPluginFlags
enum RezillaPluginFlags {
    kPluginNoAttributes             = 0L,
    
    kPluginEditorHasSaveButton      = (1L << 0),
    kPluginEditorHasCancelButton    = (1L << 1),
    kPluginEditorHasRevertButton    = (1L << 2),
    kPluginEditorHasLockIcon        = (1L << 3),
    kPluginEditorHasNameField       = (1L << 4),
    kPluginEditorStandardControls   = (kPluginEditorHasSaveButton 
                                   | kPluginEditorHasCancelButton 
                                   | kPluginEditorHasRevertButton 
                                   | kPluginEditorHasLockIcon),
    
    kPluginWinHasCollapseBox        = (1L << 5),
    kPluginWinIsResizable           = (1L << 6),
    
    kPluginSupportCut               = (1L << 10),
    kPluginSupportCopy              = (1L << 11),
    kPluginSupportPaste             = (1L << 12),
    kPluginSupportClear             = (1L << 13),
    kPluginSupportSelectAll         = (1L << 14),
    kPluginSupportFind              = (1L << 15),
    kPluginSupportFindNext          = (1L << 16),
    kPluginSupportImport            = (1L << 17),
    kPluginSupportExport            = (1L << 18),
    kPluginSupportEditCommands      = (kPluginSupportCut 
                                   | kPluginSupportCopy 
                                   | kPluginSupportPaste 
                                   | kPluginSupportClear)
}

RezillaPluginCmdIDs
enum RezillaPluginCmdIDs {
    kPluginCommandCut        = 1,
    kPluginCommandCopy,
    kPluginCommandPaste,
    kPluginCommandClear,
    kPluginCommandSelectAll,
    kPluginCommandFind,
    kPluginCommandFindNext,
    kPluginCommandImport,
    kPluginCommandExport
}

RezillaPluginErrors
enum RezillaPluginErrors {
    plugErr_Generic                = 5000,    
    plugErr_InitializationFailed,
    plugErr_UnsupportedType,
    plugErr_UnsupportedID,
    plugErr_InvalidData,
    plugErr_UnsupportedResourceFormat,
    plugErr_UnsupportedResourceVersion,
    plugErr_EditResourceFailed,
    plugErr_ReturnResourceFailed,
    plugErr_RevertResourceFailed,
    plugErr_CantResizeWindow,
    plugErr_CantHandleMenuCommand,
	plugErr_CantEditEmptyResource,
    plugErr_LastError
}


Last updated 2006-11-25 12:19:20


Rezilla is hosted by

SourceForge.net Logo