Files
redshift-rebooted/rewrite/INI_CONFIG_IMPLEMENTATION.md
2025-10-07 18:05:23 -05:00

7.5 KiB

INI Configuration File Implementation

This document describes the INI configuration file parsing implementation for Redshift.

Overview

The Rust rewrite now supports reading configuration files in the same INI format as the original C version. This provides backward compatibility and allows users to configure Redshift without command-line arguments.

Implementation Details

Files Added/Modified

  1. src/config_ini.rs - New module for INI parsing

    • RedshiftConfig struct to hold all INI settings
    • Config file search logic (XDG directories)
    • Parsing functions for special formats (brightness, gamma, time ranges)
  2. src/main.rs - Updated main program

    • Load INI config early in startup
    • Merge INI settings with CLI args (CLI takes priority)
    • Build transition scheme from merged settings
    • Support new CLI options: -b/--brightness and -g/--gamma
  3. Cargo.toml - Added dependency

    • rust-ini = "0.21" for INI file parsing
  4. Test files:

    • tests/config_ini_tests.rs - Unit tests for INI parsing
    • tests/config_merging_tests.rs - Integration tests for config merging
  5. Documentation:

    • CONFIG.md - User-facing configuration guide
    • redshift.conf.sample - Sample configuration file

Dependencies

  • rust-ini (0.21): Mature, well-maintained INI parsing library
    • Simple API for reading INI files
    • Section-based organization matching our config format
    • Handles edge cases and malformed files gracefully

Config File Search Order

The implementation searches for config files in these locations:

  1. $XDG_CONFIG_HOME/redshift/redshift.conf
  2. $XDG_CONFIG_HOME/redshift.conf
  3. $HOME/.config/redshift/redshift.conf
  4. $HOME/.config/redshift.conf
  5. /etc/redshift/redshift.conf
  6. /etc/redshift.conf

This matches the C version's behavior for maximum compatibility.

Supported Settings

[redshift] Section

Setting Format Example Description
temp-day Integer 5700 Day temperature in Kelvin
temp-night Integer 3500 Night temperature in Kelvin
fade / transition 0 or 1 1 Enable smooth transitions
brightness Float or Float:Float 0.9 or 0.7:0.4 Brightness (day:night)
brightness-day Float 0.9 Day brightness (0.1-1.0)
brightness-night Float 0.7 Night brightness (0.1-1.0)
gamma Float or R:G:B 0.8 or 0.8:0.7:0.9 Gamma for all or RGB
gamma-day Float or R:G:B 0.8:0.7:0.9 Day gamma
gamma-night Float or R:G:B 0.6 Night gamma
elevation-high Float 3.0 Solar elevation for day (degrees)
elevation-low Float -6.0 Solar elevation for night (degrees)
dawn-time HH:MM[-HH:MM] 6:00-7:45 Dawn time range
dusk-time HH:MM[-HH:MM] 18:35-20:15 Dusk time range
location-provider String manual Location provider
adjustment-method String randr Gamma method

[manual] Section

Setting Format Example Description
lat Float 40.7 Latitude (-90 to 90)
lon Float -74.0 Longitude (-180 to 180)

[randr] Section

Setting Format Example Description
screen Integer 0 X11 screen number
crtc Integer 0 Specific CRTC ID

Parsing Functions

Brightness Parsing

parse_brightness_string(s: &str) -> Result<(f32, f32), String>
  • Single value: "0.9" → (0.9, 0.9)
  • Separate values: "0.7:0.4" → (0.7, 0.4)

Gamma Parsing

parse_gamma_string(s: &str) -> Result<[f32; 3], String>
  • Single value: "0.8" → [0.8, 0.8, 0.8]
  • RGB values: "0.8:0.7:0.9" → [0.8, 0.7, 0.9]

Time Range Parsing

parse_time_range(s: &str) -> Result<TimeRange, String>
  • Single time: "6:00" → TimeRange { start: 21600, end: 21600 }
  • Range: "6:00-7:45" → TimeRange { start: 21600, end: 27900 }

Times are stored as seconds since midnight.

Merging Strategy

Settings are applied with this priority:

  1. Command-line arguments (highest)
  2. INI configuration file
  3. Built-in defaults (lowest)

Example:

# Config file has temp-day=5700
# Running with: redshift -t 6000
# Result: Uses 6000K (CLI override)

Location is also merged with priority:

  1. CLI location (-l LAT:LON)
  2. INI manual location ([manual] section)
  3. Saved TOML location (from previous runs)
  4. GeoClue2 automatic detection
  5. Interactive selection

Validation

All settings are validated against bounds:

  • Temperature: 1000-25000 K
  • Brightness: 0.1-1.0
  • Gamma: 0.1-10.0
  • Latitude: -90 to 90
  • Longitude: -180 to 180

Invalid values result in error messages and the program exits.

Testing

Unit Tests

Located in src/config_ini.rs:

  • test_parse_brightness_single
  • test_parse_brightness_separate
  • test_parse_gamma_single
  • test_parse_gamma_rgb
  • test_parse_time
  • test_parse_time_range
  • test_parse_time_range_single

Integration Tests

tests/config_ini_tests.rs:

  • Full config file parsing
  • Individual section parsing
  • Error handling for malformed configs
  • Path search logic
  • Config file not found scenarios

tests/config_merging_tests.rs:

  • Temperature loading
  • Brightness loading (separate day/night)
  • Gamma loading (separate day/night)
  • Elevation settings
  • Time-based transitions
  • All sections together

All tests pass successfully.

Manual Testing

Verified with sample config:

env HOME=/tmp/redshift-test ./target/release/redshift-rebooted -pv

Output correctly shows:

  • Location from INI config
  • Temperature from config
  • Brightness from config
  • Gamma from config
  • CLI overrides work correctly

Backward Compatibility

The implementation is fully compatible with the C version:

  1. Same file format: Standard INI with sections
  2. Same search paths: XDG directories, fallbacks, etc.
  3. Same section names: [redshift], [manual], [randr]
  4. Same setting names: All original settings supported
  5. Same aliases: Both fade and transition work

Existing redshift.conf files work without modification.

Usage Examples

Basic Configuration

[redshift]
temp-day=5700
temp-night=3500

[manual]
lat=40.7
lon=-74.0

Advanced Configuration

[redshift]
temp-day=5500
temp-night=3200
brightness-day=1.0
brightness-night=0.75
gamma-day=0.9:0.85:0.95
gamma-night=0.7
elevation-high=5
elevation-low=-8
fade=1

[manual]
lat=51.5074
lon=-0.1278

Time-Based Transitions

[redshift]
temp-day=6500
temp-night=3500
dawn-time=6:00-7:45
dusk-time=18:35-20:15

[manual]
lat=48.1
lon=11.6

Command-Line Overrides

All config settings can be overridden:

# Override temperature
redshift -t 6000 --temp-night 4000

# Override brightness
redshift -b 0.8:0.6

# Override gamma
redshift -g 0.9

# Override with RGB gamma
redshift -g 1.0:0.9:1.0

# Override location
redshift -l 40.7:-74.0

Future Enhancements

Potential improvements for future versions:

  1. Support for additional gamma methods (DRM, VidMode, etc.)
  2. Per-screen/CRTC brightness and gamma settings
  3. Hook scripts configuration
  4. Multiple location providers in config
  5. Configuration validation with detailed error messages
  6. Config file generation from CLI settings

References