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.prefs in ENV: (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.prefs and printergfx.prefs are all named in the IPrefs and IControl release notes. IPrefs 45.14 also refers to ENVARC: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, WorkbenchExtendedPrefs and FontPrefs have 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" and wbp_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


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