Preferences File Formats (FORM PREF)¶
Every system preferences editor in AmigaOS 3.x saves its settings as an IFF file of type PREF. The file opens with a PRHD header chunk, followed by one or more data chunks whose layout is defined in the <prefs/*.h> headers. IPrefs reads these files and pushes the settings into Intuition, Workbench, diskfont, the printer device and the rest of the system. You read or write them with iffparse.library like any other IFF file.
This article lists every chunk ID and structure in the NDK 3.2 R4 prefs/ headers, covering both the V47 additions (IControl V2 fields, Workbench title format, WBTF, IEXC, wallpaper placement flags) and the older chunks. It ends with a minimal reader in C.
File layout¶
FORM <size> PREF
PRHD <6> struct PrefHeader
<ID> <size> struct ...Prefs (one or more data chunks)
<ID> <size> ...
<prefs/prefhdr.h> ($VER: prefhdr.h 47.1) defines the container and header:
#define ID_PREF MAKE_ID('P','R','E','F')
#define ID_PRHD MAKE_ID('P','R','H','D')
struct PrefHeader
{
UBYTE ph_Version; /* version of following data */
UBYTE ph_Type; /* type of following data */
ULONG ph_Flags; /* always set to 0 for now */
};
| Field | Type | Meaning |
|---|---|---|
ph_Version |
UBYTE |
Version of the data that follows |
ph_Type |
UBYTE |
Type of the data that follows |
ph_Flags |
ULONG |
Always 0 for now |
The structure is 6 bytes long in 68k alignment: two UBYTEs, then a ULONG at offset 2.
Where the files live¶
The release notes name these files and locations:
env:sys/font.prefs. diskfont 46.9: "SetDiskFontCtrl(DFCTRL_CHARSET,...)now touches env:sys/font.prefs to force IPrefs to force a reload of the system fonts."ENV:Sys/deficons.prefs(DefIcons release notes).workbench.prefsinENV:(Workbench prefs 47.x: "Title Format string will be set to system default, if no workbench.prefs exists in ENV:").icontrol.prefs,palette.prefs,wbpattern.prefs,reaction.prefs,printer.prefsandprintergfx.prefsare all named in the IPrefs and IControl release notes. IPrefs 45.14 also refers toENVARC:sys/PrinterGfx.
The editors' "Use" action writes the file to ENV:. The Pointer release notes, for example, mention "writing a damaged prefs file to ENV: when calling Pointer Prefs with the FROM ... USE arguments". IPrefs watches these files: touching one, as diskfont does with font.prefs, is enough to make IPrefs reload it.
Chunk ID summary¶
| Chunk | Header | Structure |
|---|---|---|
ASL |
prefs/asl.h |
struct AslPrefs |
FONT |
prefs/font.h |
struct FontPrefs |
ICTL |
prefs/icontrol.h |
struct IControlPrefs |
IEXC |
prefs/icontrol.h |
struct IExceptionPrefs (tag list) |
INPT |
prefs/input.h |
struct InputPrefs |
LCLE |
prefs/locale.h |
struct LocalePrefs |
CTRY |
prefs/locale.h |
struct CountryPrefs |
OSCN |
prefs/overscan.h |
struct OverscanPrefs |
PALT |
prefs/palette.h |
struct PalettePrefs |
PNTR |
prefs/pointer.h |
struct PointerPrefs + data |
PGFX |
prefs/printergfx.h |
struct PrinterGfxPrefs |
PSPD |
prefs/printerps.h |
struct PrinterPSPrefs |
PTXT |
prefs/printertxt.h |
struct PrinterTxtPrefs |
PUNT |
prefs/printertxt.h |
struct PrinterUnitPrefs |
PDEV |
prefs/printertxt.h |
struct PrinterDeviceUnitPrefs |
RACT |
prefs/reaction.h |
struct ReactionPrefs |
SCRM |
prefs/screenmode.h |
struct ScreenModePrefs |
SERL |
prefs/serial.h |
struct SerialPrefs |
SOND |
prefs/sound.h |
struct SoundPrefs |
PTRN |
prefs/wbpattern.h |
struct WBPatternPrefs + data |
WBNC |
prefs/workbench.h |
struct WorkbenchPrefs / WorkbenchExtendedPrefs |
WBHD |
prefs/workbench.h |
struct WorkbenchHiddenDevicePrefs |
WBTF |
prefs/workbench.h |
struct WorkbenchTitleFormatPrefs (V47) |
The IControl 47.17 notes confirm that IEXC chunks are stored in IControl.prefs.
Display and GUI chunks¶
FONT — struct FontPrefs (font.h 47.2)¶
| Field | Type | Notes |
|---|---|---|
fp_Reserved[3] |
LONG |
|
fp_Reserved2 |
UWORD |
|
fp_Type |
UWORD |
FP_WBFONT 0, FP_SYSFONT 1, FP_SCREENFONT 2 |
fp_FrontPen, fp_BackPen |
UBYTE |
|
fp_DrawMode |
UBYTE |
|
fp_SpecialDrawMode |
UBYTE |
|
fp_TextAttr |
struct TextAttr |
Size and style |
fp_Name[FONTNAMESIZE] |
BYTE |
FONTNAMESIZE = 128 |
fp_Type tells you which of the three fonts a chunk describes, so a reader should handle every FONT chunk it finds. The font name is stored in fp_Name. IPrefs 47.6 "Added support of wb outline and shadow icon text", and the Font editor notes mention outline and shadow support in the same release cycle.
ICTL — struct IControlPrefs (icontrol.h 47.3)¶
| Field | Type | Notes |
|---|---|---|
ic_Reserved[4] |
LONG |
|
ic_TimeOut |
UWORD |
Verify timeout |
ic_MetaDrag |
WORD |
Meta-drag qualifier |
ic_Flags |
ULONG |
ICF_*, see below |
ic_WBtoFront, ic_FrontToBack, ic_ReqTrue, ic_ReqFalse |
UBYTE |
Command-key shortcuts |
ic_Version |
UWORD |
Valid only if ICF_VERSIONED; IC_CURRENTVERSION = 2 |
ic_VersionMagic |
UWORD |
Must be 0 |
ic_HoverSlugishness : 3 |
bitfield | V2+: intuiticks to wait when the mouse moves fast |
ic_HoverFlags : 5 |
bitfield | V2+: ICF_HF_HOVERGADGETS (1<<0), ICF_HF_REFLECTHOVER (1<<1) |
ic_Pad |
UBYTE |
|
ic_GUIGeometry[4] |
UBYTE |
Title bar and border geometry |
ic_Flags bits:
| Bit | Name | Mask |
|---|---|---|
| 0 | ICB_COERCE_COLORS |
ICF_COERCE_COLORS |
| 1 | ICB_COERCE_LACE |
ICF_COERCE_LACE |
| 2 | ICB_STRGAD_FILTER |
ICF_STRGAD_FILTER |
| 3 | ICB_MENUSNAP |
ICF_MENUSNAP |
| 4 | ICB_MODEPROMOTE |
ICF_MODEPROMOTE |
| 5 | ICB_CORRECT_RATIO |
ICF_CORRECT_RATIO |
| 6–14 | reserved | — |
| 15 | ICB_OFFSCRNWIN |
ICF_OFFSCRNWIN |
| 16 | ICB_MORESIZEGADGETS |
ICF_MORESIZEGADGETS |
| 17–18 | ICB_RATIO_LSB..ICB_RATIO_MSB |
ICF_RATIO_MASK = 3<<17: ICF_RATIO_9_7 (0), ICF_RATIO_9_8 (1), ICF_RATIO_1_1 (2), ICF_RATIO_8_9 (3) |
| 31 | ICB_VERSIONED |
ICF_VERSIONED: fields after ic_ReqFalse are present |
Gotcha: the structure has grown over time. Only look at ic_Version and the fields after it when ICF_VERSIONED is set, and only use the hover fields when ic_Version >= 2. IPrefs 47.23 fixed a bug where loading an old (shorter) icontrol.prefs wrote into unallocated memory. Size your read from the chunk's cn_Size, never from sizeof.
IEXC — GUI exception list (V47)¶
#define ID_IEXC MAKE_ID('I','E','X','C')
struct IExceptionPrefs
{
struct TagItem ie_Tags[0]; /* Relocatable tag list including TAG_END, 0 */
};
From the IControl 47.17 release notes: "The preferences file (IControl.prefs) written by the editor now contains an IEXC chunk for every item in the exception list (if any exists). These chunks will be read and parsed by the latest version of IPrefs in order to update its internal GUI exception database. Older versions of IPrefs (and Intuition) will simply ignore this extra information." Each entry names a program or screen (wildcards allowed) together with per-application compatibility options.
OSCN — struct OverscanPrefs¶
| Field | Type | Notes |
|---|---|---|
os_Reserved |
ULONG |
|
os_Magic |
ULONG |
OSCAN_MAGIC = 0xFEDCBA89 |
os_HStart, os_HStop, os_VStart, os_VStop |
UWORD |
Valid only if os_Magic == OSCAN_MAGIC, otherwise undefined |
os_DisplayID |
ULONG |
Mode the chunk applies to |
os_ViewPos |
Point |
|
os_Text |
Point |
|
os_Standard |
struct Rectangle |
PALT — struct PalettePrefs¶
| Field | Type | Notes |
|---|---|---|
pap_Reserved[4] |
LONG |
|
pap_4ColorPens[32] |
UWORD |
Pen array for 4-colour screens |
pap_8ColorPens[32] |
UWORD |
Pen array for 8+ colour screens |
pap_Colors[32] |
struct ColorSpec |
"Used as full 16-bit RGB values" |
IPrefs 47.20–47.22 limit the number of pens to 11 when running on Intuition V40 or older, "to avoid trashing portions of IntuitionBase".
PNTR — struct PointerPrefs¶
| Field | Type | Notes |
|---|---|---|
pp_Reserved[4] |
ULONG |
|
pp_Which |
UWORD |
WBP_NORMAL 0, WBP_BUSY 1 |
pp_Size |
UWORD |
See <intuition/pointerclass.h> |
pp_Width, pp_Height |
UWORD |
Pixels |
pp_Depth |
UWORD |
|
pp_YSize |
UWORD |
|
pp_X, pp_Y |
WORD |
Hot spot |
The colour table follows the structure inside the chunk as struct RGBTable { UBYTE t_Red, t_Green, t_Blue; } entries ("numEntries = (1 << pp_Depth) - 1"), and the image data comes after that. Pointer prefs 47.7 "Added support for 40 different standard pointertypes", and IPrefs 47.22 skips the extra pointer data on Intuition V40.
SCRM — struct ScreenModePrefs¶
| Field | Type | Notes |
|---|---|---|
smp_Reserved[4] |
ULONG |
|
smp_DisplayID |
ULONG |
Workbench display mode |
smp_Width, smp_Height, smp_Depth |
UWORD |
|
smp_Control |
UWORD |
SMF_AUTOSCROLL (bit 0) |
smp_Control is the one documented flag field, so SMB_AUTOSCROLL is defined as 1 even though the mask is 1<<0. Test with SMF_AUTOSCROLL.
PTRN — struct WBPatternPrefs (wbpattern.h 47.1)¶
| Field | Type | Notes |
|---|---|---|
wbp_Reserved[4] |
ULONG |
|
wbp_Which |
UWORD |
WBP_ROOT 0, WBP_DRAWER 1, WBP_SCREEN 2 |
wbp_Flags |
UWORD |
See below |
wbp_Revision |
BYTE |
Must be 0 |
wbp_Depth |
BYTE |
Pattern depth |
wbp_DataLength |
UWORD |
Length of the data that follows the structure |
wbp_Flags:
| Mask | Values |
|---|---|
WBPF_PATTERN 0x0001 |
Data contains a pattern |
WBPF_NOREMAP 0x0010 |
Don't remap the pattern |
WBPF_DITHER_MASK 0x0300 |
WBPF_DITHER_DEF 0x0000, _BAD 0x0100 (DitherQuality 0), _GOOD 0x0200 (2), _BEST 0x0300 (4) |
WBPF_PRECISION_MASK 0x0C00 |
WBPF_PRECISION_DEF 0x0000, _ICON 0x0400, _IMAGE 0x0800, _EXACT 0x0C00 |
WBPF_PLACEMENT_MASK 0x3000 (V47) |
WBPF_PLACEMENT_TILE 0x0000, _CENTER 0x1000, _SCALE 0x2000, _SCALEGOOD 0x3000 |
WBPF_ALIGNMENT_MASK 0xC000 (V47) |
WBPF_ALIGNMENT_MIDDLE 0x0000, _LEFTTOP 0x4000, _RIGHTBOTTOM 0x8000. The header says "Currently ignored" |
Related constants: MAXDEPTH 3 ("Max depth supported (8 colors)"), DEFPATDEPTH 2, and PAT_WIDTH × PAT_HEIGHT = 16 × 16. The dither values map onto PDTA_DitherQuality and the precision values onto OBP_Precision of picture.datatype (see AmigaOS 3.2 DataTypes).
From the release notes: WBPattern 47.4 added the V47 placement item. WBPattern 47.8 made precision and dither selectable per backdrop type. IPrefs 44.16/44.18 added "limited FastIPrefs compatibility" for pattern chunks written by FastIPrefs. When FastIPrefs and WBPattern settings disagree on colour precision, IPrefs 47.11 picks the highest level.
RACT — struct ReactionPrefs¶
| Field | Type |
|---|---|
rp_BevelType, rp_GlyphType |
UWORD (see <reaction/reaction_prefs.h>) |
rp_LayoutSpacing |
UWORD |
rp_3DProp |
BOOL |
rp_LabelPen, rp_LabelPlace |
UWORD |
rp_3DLabel, rp_SimpleRefresh, rp_3DLook |
BOOL |
rp_FallbackAttr, rp_LabelAttr |
struct TextAttr |
rp_FallbackName[128], rp_LabelName[128] |
UBYTE |
rp_Pattern[256] |
UBYTE |
IPrefs 44.9 publishes the applied ReAction settings under the global semaphore name "REACTION-PREFS".
Workbench chunks¶
WBNC — struct WorkbenchPrefs / struct WorkbenchExtendedPrefs (workbench.h 47.3)¶
struct WorkbenchPrefs
{
ULONG wbp_DefaultStackSize; /* in bytes */
ULONG wbp_TypeRestartTime; /* in seconds */
ULONG wbp_IconPrecision; /* PRECISION_#? values */
struct Rectangle wbp_EmbossRect;
BOOL wbp_Borderless;
LONG wbp_MaxNameLength;
BOOL wbp_NewIconsSupport;
BOOL wbp_ColorIconSupport;
};
struct WorkbenchExtendedPrefs /* V45 (OS 3.9) extensions */
{
struct WorkbenchPrefs wbe_BasicPrefs;
ULONG wbe_IconMemoryType; /* exec MEMF_xxxx, obsolete */
BOOL wbe_LockPens; /* lock pens 4..7 with predefined colours */
BOOL wbe_DisableTitleBar;
BOOL wbe_DisableVolumeGauge;
/* new for V47 */
UWORD wbe_TitleUpdateDelay; /* in milliseconds */
ULONG wbe_CopyBufferSize; /* in bytes */
ULONG wbe_Flags; /* assorted options */
};
A WBNC chunk can be the basic structure, the V45 extended structure, or the V47 extended structure. Tell them apart by the chunk size. The Workbench prefs 47.x notes state that "Loading V44/V45 prefs will no longer cause an error requester", and that the default title update interval is "the classic 5 seconds". wbe_LockPens is the MagicWB-style pen lock that IPrefs 45.6 took over from the OS 3.9 preferences. IPrefs 47.19 "Corrected the extended MagicWB colours 4-7".
WBHD — hidden devices¶
struct WorkbenchHiddenDevicePrefs
{
TEXT whdp_Name[0]; /* C String including NUL char */
};
There is one WBHD chunk per hidden device, and the chunk body is the NUL-terminated name. IPrefs 44.10 "properly supports empty hidden device lists".
WBTF — title format (V47)¶
#define ID_WBTF MAKE_ID('W','B','T','F')
struct WorkbenchTitleFormatPrefs
{
TEXT wtfp_Format[0];
};
IPrefs 47.3 "Added support for custom Workbench title format and title update delay." The Workbench editor (47.25) saves the title string only when it differs from the default, "This way default strings can be kept localized."
Input, locale and device chunks¶
INPT — struct InputPrefs¶
| Field | Type |
|---|---|
ip_Keymap[16] |
char |
ip_PointerTicks |
UWORD |
ip_DoubleClick |
TimeVal_Type |
ip_KeyRptDelay |
TimeVal_Type |
ip_KeyRptSpeed |
TimeVal_Type |
ip_MouseAccel |
WORD |
TimeVal_Type comes from <devices/timer.h> and is two ULONGs.
LCLE / CTRY — struct LocalePrefs, struct CountryPrefs¶
struct LocalePrefs holds lp_Reserved[4], lp_CountryName[32], lp_PreferredLanguages[10][30], lp_GMTOffset (LONG), lp_Flags (ULONG), and an embedded struct CountryPrefs lp_CountryData. struct CountryPrefs (stored on its own in a CTRY chunk) has these fields:
| Group | Fields |
|---|---|
| Identity | cp_Reserved[4], cp_CountryCode, cp_TelephoneCode (ULONG), cp_MeasuringSystem (UBYTE) |
| Date/time formats | cp_DateTimeFormat[80], cp_DateFormat[40], cp_TimeFormat[40], cp_ShortDateTimeFormat[80], cp_ShortDateFormat[40], cp_ShortTimeFormat[40] |
| Numbers | cp_DecimalPoint[10], cp_GroupSeparator[10], cp_FracGroupSeparator[10], cp_Grouping[10], cp_FracGrouping[10] |
| Money | cp_MonDecimalPoint[10], cp_MonGroupSeparator[10], cp_MonFracGroupSeparator[10], cp_MonGrouping[10], cp_MonFracGrouping[10], cp_MonFracDigits, cp_MonIntFracDigits |
| Currency | cp_MonCS[10], cp_MonSmallCS[10], cp_MonIntCS[10] |
| Positive values | cp_MonPositiveSign[10], cp_MonPositiveSpaceSep, cp_MonPositiveSignPos, cp_MonPositiveCSPos |
| Negative values | cp_MonNegativeSign[10], cp_MonNegativeSpaceSep, cp_MonNegativeSignPos, cp_MonNegativeCSPos |
| Calendar | cp_CalendarType |
SERL — struct SerialPrefs¶
| Field | Type | Notes |
|---|---|---|
sp_Reserved[3] |
LONG |
|
sp_Unit0Map |
ULONG |
What unit 0 really refers to |
sp_BaudRate |
ULONG |
|
sp_InputBuffer |
ULONG |
0–65536 |
sp_OutputBuffer |
ULONG |
"Future" |
sp_InputHandshake |
UBYTE |
HSHAKE_XON 0, HSHAKE_RTS 1, HSHAKE_NONE 2 |
sp_OutputHandshake |
UBYTE |
"Future" |
sp_Parity |
UBYTE |
PARITY_NONE 0, _EVEN 1, _ODD 2, _MARK 3 and _SPACE 4 ("Future enhancement") |
sp_BitsPerChar |
UBYTE |
|
sp_StopBits |
UBYTE |
IPrefs 45.10 passes on the new 38400 and 57600 baud rates from Serial prefs "(or not, as intuition prefs does not allow them)".
SOND — struct SoundPrefs (sound.h 47.2)¶
| Field | Type | Notes |
|---|---|---|
sop_Reserved[4] |
LONG |
|
sop_DisplayQueue |
BOOL |
Flash the display |
sop_AudioQueue |
BOOL |
Make a sound |
sop_AudioType |
UWORD |
SPTYPE_BEEP 0, SPTYPE_SAMPLE 1 |
sop_AudioVolume |
UWORD |
0..64 |
sop_AudioPeriod |
UWORD |
127..2500 |
sop_AudioDuration |
UWORD |
Length of a simple beep |
sop_AudioFileName[256] |
TEXT |
Sample file |
The header comment still says "Filename of 8SVX file". Sound prefs 47.8 removed the IFF filter from its file requester because "it supports all sound types that the system supports via datatypes".
ASL — struct AslPrefs¶
ap_Reserved[4] (LONG), followed by ap_SortBy, ap_SortDrawers, ap_SortOrder and ap_SizePosition (UBYTE), ap_RelativeLeft and ap_RelativeTop (WORD), and ap_RelativeWidth and ap_RelativeHeight (UBYTE). These "correspond directly to the associated members of the 'AslSemaphore' data structure" in <libraries/asl.h>. IPrefs 45.1 added ASL preferences support.
Printer chunks¶
PTXT / PUNT / PDEV (printertxt.h 47.2)¶
struct PrinterTxtPrefs field |
Type | Values |
|---|---|---|
pt_Reserved[4] |
LONG |
|
pt_Driver[DRIVERNAMESIZE] |
TEXT |
30 bytes, driver file name |
pt_Port |
UBYTE |
PP_PARALLEL 0, PP_SERIAL 1 |
pt_PaperType |
UWORD |
PT_FANFOLD 0, PT_SINGLE 1 |
pt_PaperSize |
UWORD |
PS_US_LETTER 0, PS_US_LEGAL 1, PS_N_TRACTOR 2, PS_W_TRACTOR 3, PS_CUSTOM 4, PS_EURO_A0..PS_EURO_A8 5..13 |
pt_PaperLength |
UWORD |
Lines |
pt_Pitch |
UWORD |
PP_PICA 0, PP_ELITE 1, PP_FINE 2 |
pt_Spacing |
UWORD |
PS_SIX_LPI 0, PS_EIGHT_LPI 1 |
pt_LeftMargin, pt_RightMargin |
UWORD |
|
pt_Quality |
UWORD |
PQ_DRAFT 0, PQ_LETTER 1 |
struct PrinterUnitPrefs (PUNT) "is used from printer.device to open the connection device". Its fields are pu_Reserved[4], pu_UnitNum (LONG), pu_OpenDeviceFlags (ULONG) and pu_DeviceName[DEVICENAMESIZE] (32). struct PrinterDeviceUnitPrefs (PDEV) is the "descriptor for printer device units", with pd_Reserved[4], pd_UnitNum and pd_UnitName[UNITNAMESIZE] (32).
PGFX — struct PrinterGfxPrefs¶
| Field | Type | Values |
|---|---|---|
pg_Reserved[4] |
LONG |
|
pg_Aspect |
UWORD |
PA_HORIZONTAL 0, PA_VERTICAL 1 |
pg_Shade |
UWORD |
PS_BW 0, PS_GREYSCALE 1, PS_COLOR 2, PS_GREY_SCALE2 3 |
pg_Image |
UWORD |
PI_POSITIVE 0, PI_NEGATIVE 1 |
pg_Threshold |
WORD |
|
pg_ColorCorrect |
UBYTE |
PCCF_RED 1<<0, PCCF_GREEN 1<<1, PCCF_BLUE 1<<2 |
pg_Dimensions |
UBYTE |
PD_IGNORE 0, PD_BOUNDED 1, PD_ABSOLUTE 2, PD_PIXEL 3, PD_MULTIPLY 4 |
pg_Dithering |
UBYTE |
PD_ORDERED 0, PD_HALFTONE 1, PD_FLOYD 2 |
pg_GraphicFlags |
UWORD |
PGFF_CENTER_IMAGE, PGFF_INTEGER_SCALING, PGFF_ANTI_ALIAS (bits 0–2) |
pg_PrintDensity |
UBYTE |
1–7 |
pg_PrintMaxWidth, pg_PrintMaxHeight |
UWORD |
|
pg_PrintXOffset, pg_PrintYOffset |
UBYTE |
Gotcha: the PCCB_* bit numbers are defined as 1, 2 and 3, but the PCCF_* masks are 1<<0, 1<<1 and 1<<2. Use the masks.
IPrefs 45.14: when both printer.prefs and printergfx.prefs carry graphics settings, the PrinterGfx file wins. "If this is not desirable, delete ENVARC:sys/PrinterGfx".
PSPD — struct PrinterPSPrefs¶
All measurements are in millipoints (1/72000 inch). The groups are: global (ps_DriverMode: DM_POSTSCRIPT 0 / DM_PASSTHROUGH 1; ps_PaperFormat: PF_USLETTER, PF_USLEGAL, PF_A4, PF_CUSTOM; ps_Copies, ps_PaperWidth/Height, ps_HorizontalDPI/VerticalDPI), text options (ps_Font: FONT_COURIER..FONT_ZAPFCHANCERY 0..8; ps_Pitch PITCH_*; ps_Orientation ORIENT_PORTRAIT/LANDSCAPE; ps_Tab TAB_4, TAB_8, TAB_QUART, TAB_HALF, TAB_INCH), text dimensions (margins, ps_FontPointSize, ps_Leading), graphics options (ps_LeftEdge, ps_TopEdge, ps_Width, ps_Height, ps_Image IM_*, ps_Shading SHAD_*, ps_Dithering DITH_DEFAULT..DITH_DIAG) and scaling (ps_Aspect ASP_*, ps_ScalingType ST_ASPECT_ASIS..ST_FITS_BOTH 0..6, ps_Centering CENT_NONE..CENT_BOTH). Several ps_ReservedN[] byte arrays pad each group. Keep them zero.
Reading a prefs file with iffparse¶
This reader prints the font entries from ENV:Sys/font.prefs. It stops on PRHD and FONT, and copies at most sizeof(struct FontPrefs) bytes from each chunk so that a longer or shorter chunk from another version stays safe.
#include <string.h>
#include <exec/types.h>
#include <dos/dos.h>
#include <libraries/iffparse.h>
#include <prefs/prefhdr.h>
#include <prefs/font.h>
#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/iffparse.h>
struct Library *IFFParseBase;
int main(void)
{
struct IFFHandle *iff;
struct ContextNode *cn;
struct PrefHeader ph;
struct FontPrefs fp;
LONG err;
BPTR fh;
if (!(IFFParseBase = OpenLibrary("iffparse.library", 39)))
return RETURN_FAIL;
if ((fh = Open("ENV:Sys/font.prefs", MODE_OLDFILE)) != 0)
{
if ((iff = AllocIFF()) != NULL)
{
iff->iff_Stream = (ULONG)fh;
InitIFFasDOS(iff);
if (OpenIFF(iff, IFFF_READ) == 0)
{
StopChunk(iff, ID_PREF, ID_PRHD);
StopChunk(iff, ID_PREF, ID_FONT);
while ((err = ParseIFF(iff, IFFPARSE_SCAN)) == 0)
{
cn = CurrentChunk(iff);
if (cn->cn_ID == ID_PRHD)
{
ReadChunkBytes(iff, &ph, sizeof(ph));
Printf("PRHD version %ld\n", (LONG)ph.ph_Version);
}
else if (cn->cn_ID == ID_FONT)
{
LONG len = cn->cn_Size;
if (len > sizeof(fp)) len = sizeof(fp);
memset(&fp, 0, sizeof(fp));
if (ReadChunkBytes(iff, &fp, len) == len)
{
fp.fp_Name[FONTNAMESIZE - 1] = 0;
Printf("type %ld: %s/%ld\n",
(LONG)fp.fp_Type, fp.fp_Name,
(LONG)fp.fp_TextAttr.ta_YSize);
}
}
}
/* IFFERR_EOF is the normal end of the scan */
CloseIFF(iff);
}
FreeIFF(iff);
}
Close(fh);
}
CloseLibrary(IFFParseBase);
return RETURN_OK;
}
To write a file, open it with IFFF_WRITE and PushChunk(iff, ID_PREF, ID_FORM, IFFSIZE_UNKNOWN). Then push the PRHD chunk, write a zeroed PrefHeader (with ph_Flags = 0), call PopChunk, write each data chunk the same way, and pop the FORM. IPrefs then picks up the change in ENV:, as described above.
Gotchas¶
- Size chunks from
cn_Size.IControlPrefs,WorkbenchExtendedPrefsandFontPrefshave all grown, and older or newer files will differ in length. - Reserved fields must be zero when you write a file.
ic_VersionMagic"must be NULL" andwbp_Revision"Must be set to zero". - IPrefs batches changes. IPrefs 45.17 "accumulates now multiple prefs changes and then handles them in one go". Some changes reset Workbench, such as the aspect-ratio setting (45.8/45.9) and off-screen dragging (47.1). In those cases IPrefs closes and reopens the Workbench screen, and 47.4 lists the windows that block it.
- Conflicting sources. Some settings can come from more than one file (FastIPrefs vs. Workbench). IPrefs 45.18 handles that "more consistently".
See Also¶
- iffparse.library Reference
- IFF Format and MountList
- DOS Notification Requests
- AmigaOS 3.2 DataTypes
- ReAction GUI Toolkit
- AmigaOS 3.2 — What Changed for Developers
Sources: NDK 3.2 R4 Include_H/prefs/{prefhdr,asl,font,icontrol,input,locale,overscan,palette,pointer,printergfx,printerps,printertxt,reaction,screenmode,serial,sound,wbpattern,workbench}.h, Include_H/libraries/iffparse.h, SFD/iffparse_lib.sfd, ReleaseNotes/{IPrefs,IControl,WBPattern,Pointer,Workbench,Sound,diskfont,DefIcons}-RelNotes Updated: 2026-11-13