Creating Custom Resource Editors
![]() |
![]() |
![]() |
![]() |
Creating Custom Resource Editors
This chapter describes the resource plugin API for creating your own resource editors for PhAB.
In PhAB, widgets have resources that are displayed in the Resources control panel. You modify these resources using either a small, specialized "frugal"editor directly in the control panel, or by opening a more complex "full"editor.
Previously the code for these resource editors was statically built into PhAB. Now the editors are resource editor plugins -- they are small pieces of code and data put together into a DLL that PhAB loads at runtime. The purpose of this chapter is to describe how you can write your own resource editors.
Any resource has a type and a person that writes a resource editor plugin will write a plugin for one of these defined types:
- RES_DATATYPE_STRING
- RES_DATATYPE_MULTI
- RES_DATATYPE_CODE
- RES_DATATYPE_FONT
- RES_DATATYPE_COLOR
- RES_DATATYPE_DOUBLE
- RES_DATATYPE_NUMERIC
- RES_DATATYPE_CHOICE
- RES_DATATYPE_FLAG
- RES_DATATYPE_PATTERN
- RES_DATATYPE_LIST
- RES_DATATYPE_PIXMAP
- RES_DATATYPE_ALLOC
Each of these types is described in the section Resource datatypes. If you write a custom widget and devise a new resource that doesn't seem to fit in any of the above types, then you should use RES_DATATYPE_ALLOC since it describes a general resource datatype. This resource type consists of a buffer of bytes, with a given length. A protocol for ensuring the endian safety when saving/loading the alloc resource is documented in the section Endian issues.
Once you've chosen one of these types for a newly devised resource, the resource type is recorded in the widget's palette file as a string. See the sections Editing palette.def and Creating a widget description table in the Binding Widgets into PhAB chapter.
You can put one, two or more editors into the same DLL, or you can put a frugal editor into one DLL and a full editor into a different DLL. You can choose to only write the full editor and let the frugal editor be the predefined one, or use the frugal editor written by another user, and so on.
To decide which resource editor should be used for a resource type, PhAB looks at the res_editors.def to match entries with the abstract_name_of_editor specified in the palette.def file. There is a res_editors.def file for each user on a system, and a global res_editors.def file for all users. See The res_editors.def file section for more information about the structure of this file.
With the resource editor plugin API, you can:
- override the predefined resource editors. For instance, you might want to override the RES_DATATYPE_PIXMAP resource editor with your own. You specify the new editor in the palette.def file.
- write a specialized resource editor for a datatype that already exists.
For instance, if you have a new widget class that has a new resource representing a date (time_t), the default numeric resource editor might be inappropriate. Instead, you can specify that for this date resource, an alternate custom resource editor is used.
- devise a brand new resource type using the RES_DATATYPE_ALLOC type and write a resource editor for it. PhAB and the aplib will know how to save it and load it at runtime, and the resource editor plugin gives you a way to change it in PhAB.
This chapter contains:
- Resource datatypes -- describes the resource datatypes supported by the plugin API.
- The life cycle of a plugin instance -- describes the life cycle of of resource editor plugins.
- The res_editors.def file -- describes the configuration file you need to edit when you create a new resource and resource editor.
- Endian issues -- describes how endian issues are handled with the RES_DATATYPE_ALLOC type.
See these chapters for more information about building a resource editor using the plugin API:
Resource datatypes
When you create a new resource, for example for a new widget, you need to tell PhAB about the resource and how it should be handled. You need to enroll the resource in one of the types listed below by entering the resource in the widget's palette file. For more information on this, see Creating a widget description table in the Binding Widgets into PhAB chapter.
A widget resource can be one of the following datatypes:
- RES_DATATYPE_CHOICE -- an exclusive choice resource type, for example Pt_ARG_LABEL_TYPE.
- RES_DATATYPE_CODE -- a function resource type, for example Pt_ARG_RAW_DRAW_F
- RES_DATATYPE_COLOR -- a color resource type, for example Pt_ARG_FILL_COLOR.
- RES_DATATYPE_DOUBLE -- a numeric double resource type, for example Pt_ARG_NUMERIC_VALUE for a PtNumericFloat.
- RES_DATATYPE_FLAG -- a flag resource type, for example Pt_ARG_FLAGS.
- RES_DATATYPE_FONT -- a font resource type, for example Pt_ARG_TEXT_FONT.
- RES_DATATYPE_LIST -- a list resource type, for example Pt_ARG_ITEMS.
- RES_DATATYPE_MULTI -- a multi line string resource type, for example Pt_ARG_TEXT_STRING.
- RES_DATATYPE_NUMERIC -- a numeric resource type, for example Pt_ARG_NUMERIC_VALUE for a PtNumericInteger.
- RES_DATATYPE_PATTERN -- a pattern resource type, Pt_ARG_FILL_PATTERN.
- RES_DATATYPE_PIXMAP -- an image resource type, for example Pt_ARG_LABEL_IMAGE.
- RES_DATATYPE_STRING -- a string resource type, for example Pt_ARG_WINDOW_TITLE.
- RES_DATATYPE_ALLOC -- a generic resource type, not covered by the other types. For example, Pt_ARG_RAW_LAYOUT_DATA.
Resource datatypes general notes
Resource data is passed from PhAB to the plugin instance via a call to ResPluginSetDataF_t, and passed from the plugin instance to PhAB with apply(), ResPluginAnyChangesF_t, or answer_changes(). Each of these functions has a value and an n parameter for the data, though for each resource type these parameters are used differently.
For some resource datatypes, additional format information is required. Format data is passed as a pointer to this structure:
typedef struct ResPluginFormatData_ {
int n;
const void *value;
} ResPluginFormatData_t ;
Each resource data type uses the members of this structure differently. The resource editor should not assume that the pointer to ResPluginFormatData_t remains valid byond the call that passed the pointer.
For some datatypes, the "master copy rule" applies, which means PhAB maintains a master copy of the data and these conditions apply:
- When this data is being passed from PhAB to the plugin, PhAB holds the "master copy" and the value is guaranteed to remain a valid pointer until PhAB informs the plugin about a new value by calling the ResPluginSetDataF_t method. When the ResPluginSetDataF_t method is called, the old master copy is still valid.
- When this data is passed from the plugin to PhAB, PhaB frees its master copy and the data passed by the plugin becomes the master copy.
For other datatypes, the master copy rule doesn't apply. In these cases, when the data is passed, the recipient (either the plugin or PhAB) must make its own copy of the passed data.
RES_DATATYPE_ALLOC
This is the generic datatype that you can use for newly devised resources that do not fit any of the other predefined types. There is no predefined resource editor for this data type. An example of this resource type is Pt_ARG_ROW_LAYOUT_DATA.
When this datatype is passed between the plugin and PhAB, in the passing function the parameter value is an array of bytes and n is the number of bytes being passed.
To allocate memory for this data type in your resource editor, you should use the alloc_mem() function exported by PhAB to allocate memory, and free_mem() to free it.
The palette file type string for this resource type is alloc.
This resource datatype does not require additional format information from ResPluginFormatData_t.
RES_DATATYPE_CHOICE
This data type represents a list of choices, which are string and numeric value pairs that a user can choose from. An example of this resource type is Pt_ARG_LABEL_TYPE.
When this datatype is passed between the plugin and PhAB, in the passing function the parameter value is not used. The n parameter contains the numeric value.
The master copy rule doesn't apply, so the plugin should make its own copy of the data when it is passed.
The ResPluginFormatData_t structure is used to indicate the list of choices and the associated numeric values. In the structure, value is an array of ResPluginChoiceFormat_t*, and n indicates the number of the items in the array.
The resource editor can safely assume that the array will remain valid beyond the call that passed this structure (that is, it will stay valid during the existence of the plugin ).
The ResPluginChoiceFormat_t is defined as:
typedef struct {
char *name;
long value;
} ResPluginChoiceFormat_t;
The members are:
- name
- the choice name
- value
- the choice value
The value being passed to the plugin or from the plugin has to be one of the values indicated in the format structure.
The palette file type string for this resource type is choice.
RES_DATATYPE_CODE
This data type represents a function, for example Pt_ARG_RAW_DRAW_F. It is similar to the RES_DATATYPE_STRING resource type, except that the master copy rule doesn't apply. This means that you have to make a copy of the value in the resource editor plugin, because it might point to memory on the stack, which is invalid beyond the call that passed the value.
An editor for this resource should allow the user to edit one line of characters.
The resulting line of characters should be a valid string for specifying a function name in PhAB. For more information on properly formatting this string, see Function names and filenames in the Working with Code chapter of the Photon Programmer's Guide.
The ResPluginFormatData_t structure is used to indicate the prototype of the function. The n member is not used and the value member is a pointer to the following structure:
/* format for code datatype */
typedef struct {
char *prototype;
} ResPluginCodeFormat_t;
The prototype member should point to a function prototype string. For example:
PtWidget_t* @( PtWidget_t *window, PtWidget_t *widget, int position,
char *text, char *font, PgColor_t fill_color,
PgColor_t text_color )
The @ is used to indicate the function name place holder. The plugin could use the provided prototype to display a list of already defined functions that match the prototype.
The resource editor can safely assume that the value pointer in the format structure will remain valid beyond the call that passed this structure. In fact, it will stay valid during the existence of the plugin.
The palette file type string for this resource type is code.
RES_DATATYPE_COLOR
This data type represents a color resource, for example Pt_ARG_FILL_COLOR.
When this datatype is passed between the plugin and PhAB, in the passing function the value parameter is not used. The n parameter contains the color, which is a PgColor_t type.
The master copy rule doesn't apply, so your plugin should make a copy of this data when it receives it.
No format data is required.
The palette file type string for this resource type is crgb.
RES_DATATYPE_DOUBLE
This data type represents a double-precision floating point value, such as Pt_ARG_NUMERIC_VALUE for PtNumericFloat.
When this datatype is passed between the plugin and PhAB, in the passing function the value parameter is a pointer to a double representing the value, and the n parameter is not used.
The master copy rule applies.
The ResPluginFormatData_t structure indicates the range of values the resource editor should allow this resource to have. In ResPluginFormatData_t, the n member is not used and the value member is a pointer to this structure:
typedef struct {
double min;
double max;
} ResPluginDoubleFormat_t;
The min and max members indicate the minimum and maximum values allowed for the data type. The resource editor can safely assume that the value pointer in the format structure will remain valid beyond the call that passed this information. In fact, it will remain valid during the existance of the plugin.
The palette file entry for this data type is double. The palette file string for this resource type indicates the range this way :
r=manifest_name,desc_name,resource_no,reserved, select_ind,type, default_value[,additional_info]
where:
- type is double
- additional_info (if required) can be either:
- f -- specifies single-precision 32 bit floating point resources
- min/max -- specifies the explicit minimum and maximum values
For example:
r=Pt_ARG_NUMERIC_INCREMENT,Numeric increment,53003, 0,0,double,1,0/100
Also see the chapter Binding Widgets into PhAB in the Photon Programmer's Guide.
RES_DATATYPE_FLAG
This data type represents a flag resource, for example Pt_ARG_FLAGS.
When this datatype is passed between the plugin and PhAB, in the passing function the value parameter is an unsigned long integer representing the value, and the n parameter is not used.
The master copy rule doesn't apply.
The ResPluginFormatData_t structure is used to indicate the list of values, names and masks. In the ResPluginFormatData_t structure, the value member is an array of ResPluginFlagFormat_t* , and the n member is the number of items in the array.
The resource editor can safely assume that the array of ResPluginFlagFormat_t* will remain valid beyond the call that passed this structure. In fact, it will stay valid during the existence of the plugin.
The ResPluginFlagFormat_t is defined as:
typedef struct {
char *name;
unsigned long value;
unsigned long mask;
} ResPluginFlagFormat_t;
where name is the flag's name, value is the flag's value and mask is the associated mask.
The flags should be presented as names in the resource editor, so that a user can choose one or more values. When the user chooses more than one value, the resulting value is all selected values ORed together.
The mask controls how the different values interact with each other. All the values that match a bit in a mask are exclusive values, that is, they exclude each other.For instance if the current value of the resource is current_value and the user selects another flag of the value that has a mask associated, the resulting value will be:
(current_value & ( ~ mask ) ) | value
That means that first the mask is used to clear all the corresponding bits from the current_value and then the value is OR-ed in.
The mask can be 0, which means that the respective flag value doesn't interact with any other flag values.
The palette file type string for this resource type is flag.
RES_DATATYPE_FONT
This data type represents a font resource, such as Pt_ARG_TEXT_FONT.
This type is the same as the RES_DATATYPE_STRING resource type, but the resulting string has to be a valid font name. For more information on generating a valid font name, see PgGenerateFontName().
The ResPluginFormatData_t structure is used to pass extra information about the fonts allowed for selection. The value member is not used, and the n member can be:
- RES_DATATYPE_FONT_FIXED
- This resource requires a fixed font.
To define a font resource in a palette file, use this string format:
r=manifest_name,desc_name,resource_no,reserved, select_ind, type,default_value[,additional_info]
where type is font and if the font is fixed-width, additional_info is fixed.
RES_DATATYPE_LIST
This resource type represents a list, such as Pg_ARG_ITEMS.
When this datatype is passed between the plugin and PhAB, in the passing function the value parameter is an array of strings, the last item of the array being NULL, and the n parameter is the number of strings in the array, not including the last item.
The master copy rule applies.
No format data is required.
You should should use alloc_mem() exported from PhAB in your resource editor to allocate memory for this resource, and free_mem() to free it.
The palette file type string for this resource type is list.
RES_DATATYPE_MULTI
This resource type represents a multi-line text string, such as Pt_ARG_TEXT_STRING.
This resource type is the same as the RES_DATATTYPE_STRING, with the difference that the RES_DATATYPE_MULTI type can contain newline \n characters. The resource editor should allow you to expand on multiple lines.
No format data is required.
The palette file type string for this resource type is multi.
RES_DATATYPE_NUMERIC
This resource type represents a numeric value, including short, integer, long signed and unsigned values. An example is Pt_ARG_NUMERIC_VALUE.
When this datatype is passed between the plugin and PhAB, in the passing function the value parameter is not used. The parameter n contains the numeric value.
The master copy rule doesn't apply.
The ResPluginFormatData_t structure is used to indicate the range of values the editor should allow. In the structure, the n parameter is not used and the value parameter is a pointer to this structure:
typedef struct {
int64_t min;
int64_t max;
} ResPluginNumericFormat_t;
The min and max fields indicate the minimum and maximum values allowed in the editor. The resource editor can safely assume that the value pointer in the format structure will remain valid beyond the call that passed this structure. In fact, it will remain valid during the existence of the plugin.
The palette file type string for this resource type is numeric. The previous string short is deprecated, but it is still recognized for backward compatibility. The palette file string for this resource type indicates the range this way:
r=manifest_name,desc_name,resource_no,reserved, select_ind,type, default_value[,additional_info]
where type is numeric and additional_info can be:
- s8 -- signed byte
- s16 -- signed short
- s32 -- signed int
- u8, u16, u32 -- the unsigned counterparts
- s -- a shortcut for signed int
- u -- a short cut for unsigned int
- min/max the explicit minimum and maximum values
Also see the chapter Binding Widgets into PhAB.
If the additional_info section is missing, the resources is assumed to be s32, a signed int.
RES_DATATYPE_PATTERN
This data type represents a pattern.
When this datatype is passed between the plugin and PhAB, in the passing function the value parameter is a pointer to a PgPattern_t, and the n parameter is not used.
The master copy rule doesn't apply, so the value pointer might be allocated on the stack and your plugin should make a copy of the data as soon as it receives the data.
No format data is required.
The palette file type string for this resource type is pattern.
RES_DATATYPE_PIXMAP
This data type represents an image map, for example Pt_ARG_LABEL_IMAGE.
When this datatype is passed between the plugin and PhAB, in the passing function the value parameter is a PhImage_t pointer and the n parameter is not used.
The master copy rule applies over the whole image. When this value is passed, the PhImage_t* is passed together with all associated data such as the image data and image palette.
No format data is required.
You should use alloc_image() exported from PhAB to allocate the image pointer, and free_image() to free it.
The palette file type string for this resource type is pixmap.
RES_DATATYPE_STRING
This data type represents a string.
When this datatype is passed between the plugin and PhAB, in the passing function the value parameter is an array of characters, NULL terminated, and the n parameter is set to the length of the string.
The master copy rule applies.
You should use the exported PhABExportAllocMemF_t to allocate memory, and PhABExportFreeMemF_t to free the memory.
This is the same as the RES_DATATYPE_MULTI type , with the difference that the data cannot contain '\n' characters, and the resource editor should allow only one line of characters to be edited.
No format data is required.
The palette file type string for this resource type is string.
The life cycle of a plugin instance
The life cycle of a plugin depends on how it is written. A resource editor plugin can be a frugal editor, or a full editor, and the full editor can be implemented to use an external application. Each scenario is described here.
The frugal resource editor
The following scenario applies to a frugal resource editor:
- PhAB creates an instance of the plugin using the ResPluginFrugalCreateF_t method.
- The user interacts with the plugin
- The plugin can call into PhAB with the apply() method, requesting PhAB apply the current value.
- The plugin can call into PhAB with the open() method, requesting PhAB open a full editor to edit this resource.
- PhAB gives the plugin new data it just got from the full editor; the plugin must take the new data and throw away any modified version of the old data it might have.
- ...
- PhAB calls the ResPluginDestroyF_t method to destroy the plugin instance.
The full resource editor
The following scenario applies for a full resource editor that doesn't use an external application:
PhAB creates an instance of the plugin using its ResPluginFullCreateF_t method.
In this method:
- We recommend that in order to ensure a consistent look and feel for all resource editors, that you use the convenience function create_window(), exported from PhAB.
- The create_window() function creates the resource editor window and fills in a PtWidget_t ** with a pointer to the container widget that the plugin has to populate.
- The plugin populates the container widget.
- The plugin returns from its "create" method.
- Instead of using the create_window() convenience function, you can choose construct the resource window in the plugin yourself.
- The user edits the data inside the editor window.
- The plugin should show its state graphically. If the window was created using create_window() it can use the convenience function set_state() to render the state.
- The plugin can call into PhAB with the apply() method, requesting PhAB to apply the current resource editor value.
- PhAB can call the ResPluginAnyChangesF_t method and the plugin should answer if there are changes to its data. The call to this function is made because PhAB wants to close or disable the editor's window, or put a new value into the editor, and it wants to know what to do with the old value (for instance, when the selection changes). If there are changes, they are passed in this function call.
- PhAB can call the ResPluginDisableF_t method, and the plugin has to throw away it's value, and disable the content of the window, except for the Cancel button. If you used the create_window() function to create the resource editor window, use the set_state() function exported by PhAB to disable that part of the interface that was not created directly by you.
- PhAB can later call ResPluginSetDataF_t and the plugin should re-enable itself and display the new data.
- If the frugal editor asks PhAB to change the value while the
full editor has some modification in it, then the full editor plugin
will get a call to
ResPluginSetDataF_t and the plugin is already enabled. The full editor can have
one of the following behaviors:
- Throw away its own modifications and use the new data passed from PhAB.
- Keep the modifications it already has.
- The user may press Cancel or close the editor's window. In this case if the window was not created with create_window(), the plugin has to call into PhAB with the closing() method. If create_window() was used, then PhAB drives the plugin and the closing method shouldn't be called.
- PhAB calls ResPluginDestroyF_t to destroy the plugin instance.
An external application resource editor
When your full resource editor uses an external application, PhAB assumes that the plugin does not have access to the external application code -- the external application is considered to be a black box. The only assumptions made are:
- The plugin can spawn the external application.
- The plugin has a way of passing data to the external application, for example, by putting the data into a file and giving the file to the external application.
- The plugin has a way of detecting when the external application was closed, for example by polling the PID or by attaching a SIGCHLD handler.
- The plugin has a way of detecting when the user has saved the changes, for example by using stat() to examine the modification time of a data file.
- The plugin can send a Ph_WM_CLOSE event, and the external application displays a standard "save, discard, or cancel" dialog, before closing.
For an example of a resource editor that uses an external application, see the external application example in the Plugin Examples chapter. That example shows how you can use ped as an editor for a PtButton's Pt_ARG_TEXT_STRING resource.
The following scenario applies for a full resource editor that uses an external application:
- PhAB creates an instance of the plugin using its ResPluginFullCreateF_t method.
- Inside this method, the plugin packages the resource data passed as an argument and gives it to the external application. For example, it might package the data into a file and spawn an external application, passing the file as an argument.
- The user starts editing the data inside the editor's window.
- The plugin has a way to monitor the external application for
the following events:
- The user chooses Save in the external application. At this point, the plugin calls into PhAB with the apply() method.
- The user closes the external application. At this point the plugin checks if there are changes and possibly calls apply, and then calls the exported closing() method. Because the user has already made the decision about saving or not saving the data, when PhAB calls the ResPluginAnyChangesF_t method, the plugin should return RESPLUGIN_NO_CHANGES inside the closing() method.
- PhAB can decide to call the ResPluginAnyChangesF_t method and the plugin should answer if there are changes or not. The call to this function is made because PhAB wants to close the editor's window or disable the editor's window, or PhAB wants to put a new value in the resource editor's window and wants to know what to do with the old value (for instance, when the selection changes).
- If the plugin is able, it can answer right away whether there are changes or not. But most likely the plugin will not know and will want to let the external application decide if there are changes or not. Therefore, the plugin should send a Ph_WM_CLOSE event to the external application's window and bring it to front, and then return RESPLUGIN_WAIT to the call to ResPluginAnyChangesF_t.
- At this point PhAB goes into a waiting state, in which the user cannot change the current selection and PhAB displays a message telling the user what's happening.
- The external application will display a typical "save, discard, or cancel" dialog.
- Any choice other than Cancel will terminate the external application, the plugin will detect this and will call into PhAB with the answer_changes() method, giving PhAB the new data, if necessary. Note that at this point PhAB doesn't mind if the plugin always replies that there are changes -- it might be easier for the plugin to always grab the file and pass the data to PhAB).
- If the user chooses Cancel, then PhAB will remain in the waiting state until the user closes the external application and the plugin calls with the answer_changes() method. PhAB always assumes that a call to answer_changes() means the user has closed the editor's window. The plugin doesn't have to call the exported closing() method explicitly.
- PhAB calls ResPluginDestroyF_t to destroy the plugin instance.
The res_editors.def file
The mapping between the abstract_name_of_editor in the palette files and the actual frugal and full editors is done in the res_editors.def file (see Creating a widget description table in the Binding Widgets into PhAB chapter).
There are two res_editors.def files, one at the user level file located under the user's home directory along with the other PhAB configuration files (~/.ph/phab), and a global file, located in the same directory as the PhAB executable. The user's res_editors.def file overrides the settings in the global file.
The format of both files is:
e=abstract_name_of_editor [p=path] [F=full_editor] [p=path] [f=frugal_editor]
Each resource definition in the palette files should have a corresponding abstract_name_of_editor definition (the r= line).
The lines that define resources in the palette file are supposed to have an abstract_name_of_editor for each resource definition line ( the lines that begin with r= ). See Creating a widget description table in the Binding Widgets into PhAB chapter. When the abstract_name_of_editor for a resource is missing, it is assumed that the abstract_name_of_editor is the datatype string.
For instance, for the Pt_ARG_CONTAINER_FLAGS definition, the abstract_name_of_editor and the datatype string are both flag:
r=Pt_ARG_CONTAINER_FLAGS,Container Flags,10005,10005, 1,flag,0x30,9
Each one of the abstract_name_of_editors specified in all the palette files must have a section in at least one of the res_editors.def files (either the user specific or the global file). This section indicates the path and the name of the DLL that contains the code for the plugin. Please note that the predefined editors are statically built into PhAB and are not specified in the res_editors.def files. You can override these predefined editors by adding sections to the res_editors.def file.
For instance you can define a section e=string to override the default resource editor for the RES_DATATYPE_STRING resource datatype.
The res_editors.def file defines these settings:
- e=abstract_name_of_editor
- The settings for a particular resource editor. This line must match the abstract name of editor in a palette file.
- p=path
An optional setting, which can be used to specify the path to the next shared objects. It applies to only the shared objects specified inside the current e=abstract_name_of_editor section.
An empty line p= means the path is PhAB's standard location for the plugin editors, which is plugins/resource in PhAB's directory.
If the part following p= doesn't start with a slash /, the path is considered to be relative to the user's home directory.
If no path information is available when the F= or f= settings are parsed, then the path is considered to be PhAB's standard location for the plugin editors, which is plugins/resource in PhAB's directory.
If the setting is p=$, then the $LD_LIBRARY_PATH environment variable is used.
- F=full_editor, f=frugal_editor
Specifies the full and frugal editors. These lines have the form editor@dll_name.
The dll_name includes the shared library extension. On QNX the extension for shared objects is .so, while on Windows it is .so or .dll.
For example, the frugal_editor can be specified as: date@editors.so). If the @dll_name part is missing, the dll name is considered to be the same as the editor's name plus the extension.
For instance, assume you want to write a resource editor to edit a date. The datatype used is numeric, but the default editors for the numeric dataype are not suitable for editing a date format:
a)
e=date p=/tmp/plugins F=date1@exp_date p= f=date2@date
In this example, the date type uses the full editor date1 located in the /tmp/plugins/exp_date.so, and the frugal editor date2, located in date.so, in PhAB's standard plugin directory plugins/resource under the PhAB's executable directory.
b)
e=date f=date2
This example uses the date2 editor for the frugal editor, located in plugins/resource/date2.so.
c)
e=date p=my_plugins F=date
This example uses the full editor date located in my_plugins/date.so, under the user's home directory.
If a palette file specifies an abstract name of an editor and there is no information about it in any of the res_editors.def files, and PhAB detects this at startup, it will exit with an error, except for the cases where it is safe to use the default datatype editor instead.
The def_res.def file in PhAB's executable directory lists the abstract editors (one editor per line) for which it is safe to use the default datatype editor, anytime something prevents a different editor from being used.
For instance, in the example c) above, the frugal editor for date is not specified (there is no "f=" entry). If the predefined frugal editor for the datatype numeric is to be used, def_res.def has to specify date inside.
![]() |
The RES_DATATYPE_ALLOC datatype can't be listed in def_res.def since there is no default editor for it. |
Endian issues
Because you can run PhAB on one platform and target another platform with a different endianness, PhAB needs to know how to load and save the widget files and the aplib needs to know how to load the content of the resource file at run time.
For the predefined datatypes, this is already taken care of, because the widget files are saved in a endian-insensitive form, and at runtime they are converted to the right endian form.
For the RES_DATATYPE_ALLOC datatype, you can specify an endian signature. This is a string that you put in the palette files. Each time a resource is saved, the string tells PhAB how to save the resource data in a endian-insensitive form. The string is saved along the resource data in the widget files. When the widget files are loaded either at runtime by aplib, or by PhAB, the endian string is read before reading the actual data. The string tells aplib and PhAB how to convert the loaded data to the right endian form.
Here's an example of endian string:
24css+il4c
This string describes an endian structure with:
- 24 characters (24 bytes endian insensitive )
- 2 shorts followed by an array of structures containing:
- one integer ( 4 bytes )
- one long ( 8 bytes )
- 4 characters
Use:
- c for a character (1 byte endian insensitive)
- s for a "short" (2 bytes)
- i for an integer (4 bytes)
- l for a long (8 bytes)
Each of these can be preceded by a number to indicate a sequence of the same type data.
Use a + to indicate the start of an array of structures. The number of items in the array is determined by looking at the length of the resource data that's left to be loaded for that particular resource.
You can only specify an endian string for RES_DATATYPE_ALLOC resource types, and it's optional. A RES_DATATYPE_ALLOC resource type that has no endian string will be considered to be endian insensitive and in this case it will be the widget's and the plugin's responsibilities to correctly interpret the array of bytes.
In other words, when the endian string is missing, it's the same as setting the endian string to +c.
![]() |
![]() |
![]() |
![]() |
![[Previous]](prev.gif)
![[Contents]](contents.gif)
![[Index]](keyword_index.gif)
![[Next]](next.gif)
