dev-doc/introspection.md
The introspection system in darktable is a powerful mechanism that allows the application to understand and manipulate the internal structure of C structs at runtime. It is primarily used for Image Operation (IOP) modules to define their parameters.
Introspection serves three main purposes:
legacy_params).DT_BAUHAUS_WIDGET macros and functions) uses introspection data to automatically create sliders, comboboxes, and toggle buttons with the correct ranges, defaults, and labels.Introspection is defined directly in the C code using the DT_MODULE_INTROSPECTION macro. This macro associates a struct type with a version number.
Example from src/iop/exposure.c (simplified):
typedef struct dt_iop_exposure_params_t
{
// $MIN: -3.0 $MAX: 3.0 $DEFAULT: 0.0 $DESCRIPTION: "EV shift"
float exposure;
// $MIN: 0.0 $MAX: 100.0 $DEFAULT: 0.0
float black;
// $DEFAULT: 0
int mode;
} dt_iop_exposure_params_t;
DT_MODULE_INTROSPECTION(1, dt_iop_exposure_params_t)
The comments above each field are parsed during the build process to generate metadata. The supported tags are:
$MIN: The minimum allowed value.$MAX: The maximum allowed value.$DEFAULT: The default value.$DESCRIPTION: A human-readable description (often used as a widget tooltip or label).$VALUES: For enums, a list of valid values.The introspection data is compiled into a tree of dt_introspection_field_t structures.
dt_introspection_tThe top-level descriptor for a type.
version: The version number passed to DT_MODULE_INTROSPECTION.size: The size of the struct in bytes.fields: A list of dt_introspection_field_t.dt_introspection_field_tDescribes a single field in the struct. It is a union of various types (Float, Int, Bool, Enum, Struct, etc.), all sharing a common header.
dt_introspection_type_header_ttype: The type enum (DT_INTROSPECTION_TYPE_FLOAT, etc.).name: The name of the field.offset: The byte offset of the field within the parent struct.size: The size of the field.The dt_bauhaus_* family of functions (e.g., dt_bauhaus_slider_from_params) uses introspection to bind a widget to a struct field.
When you call:
g->exposure = dt_bauhaus_slider_from_params(self, "exposure");
$MIN, $MAX, and $DEFAULT values.(char *)self->params + field->offset.When you change the layout of a params struct, you must increment the introspection version number.
DT_MODULE_INTROSPECTION(2, dt_iop_exposure_params_t)
You must then implement the legacy_params function in your module to migrate data from the old version (1) to the new version (2). This ensures that edits made with older versions of darktable are preserved.