Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
120 changes: 120 additions & 0 deletions docs/brightness_check_api.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
# Brightness Support Test API

## Overview

The `ddca_check_brightness_support()` function provides the most reliable method to determine if a display actually supports brightness control. Unlike other methods that only check capabilities or metadata, this function performs a real set operation to verify that brightness control actually works.

## Function Signature

```c
DDCA_Status
ddca_check_brightness_support(
DDCA_Display_Handle ddca_dh,
bool* is_supported,
uint16_t* current_value,
uint16_t* max_value);
```

## Parameters

- `ddca_dh`: Display handle for the display to test
- `is_supported`: Pointer to return whether brightness control is supported
- `current_value`: Pointer to return current brightness value (0-100)
- `max_value`: Pointer to return maximum brightness value (0-100)

## Return Value

- `0`: Test completed successfully
- Non-zero: Test failed (check error details)

## How It Works

The function performs the following steps:

1. **Reads current brightness value** and maximum value from the display
2. **Checks if maximum value is 0** - if so, brightness control is not supported
3. **Calculates a test value** (current value ± 1, depending on available range)
4. **Saves original verification setting** to restore later
5. **Disables verification** to avoid verification failures affecting the test
6. **Attempts to set the test value** using DDC/CI
7. **Verifies the test value was actually set** by reading it back immediately
8. **Restores the original value** to minimize visual impact
9. **Re-enables verification** setting

## Key Verification Logic

The most important improvement in this function is the verification step (step 7). After setting the test value, the function immediately reads back the current brightness value to verify that the set operation actually took effect. This distinguishes between:

- **True support**: Set command succeeds AND the value actually changes
- **False support**: Set command succeeds but the value doesn't change (display ignores the command)

## Important Notes

- **Visual Impact**: This function will briefly change the display brightness during testing
- **Immediate Restoration**: The original brightness value is restored immediately after the test
- **Minimal Change**: The test uses the smallest possible change (±1) to minimize visual impact
- **Most Reliable**: This is the most accurate method because it tests actual functionality
- **Verification Logic**: The function verifies that the test value was actually set before determining support

## Usage Example

```c
#include "ddcutil_c_api.h"

DDCA_Display_Handle dh;
// ... open display ...

bool is_supported;
uint16_t current_value, max_value;

DDCA_Status rc = ddca_check_brightness_support(dh, &is_supported, &current_value, &max_value);
if (rc == 0) {
if (is_supported) {
printf("Display supports brightness control\n");
printf("Current brightness: %d\n", current_value);
printf("Maximum brightness: %d\n", max_value);
} else {
printf("Display does not support brightness control\n");
}
} else {
printf("Test failed: %s\n", ddca_rc_name(rc));
}
```

## When to Use

Use this function when you need to:

- **Verify brightness control works** before providing brightness adjustment features
- **Handle displays that report support but don't actually work**
- **Provide accurate feedback to users** about brightness control capability
- **Avoid runtime failures** in brightness control applications

## Alternative Methods

Other methods for checking brightness support are less reliable:

- **Capabilities string**: May report support even when set operations fail
- **Feature metadata**: Only checks if the feature is defined as writable
- **Simple read**: Only verifies the feature can be read, not written

## Demo Program

A demo program is available at `src/sample_clients/demo_check_brightness_support.c` that shows how to use this API to test all connected displays.

## Compilation

To compile the demo program:

```bash
cd src/sample_clients
make demo_test_brightness
```

## Running the Demo

```bash
sudo ./demo_test_brightness
```

The demo will test all connected displays and report whether each one supports brightness control.
253 changes: 253 additions & 0 deletions docs/brightness_check_verification_logic.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,253 @@
# ddca_check_brightness_support Verification Logic Analysis

## Overview

This document provides a detailed analysis of the verification logic in the `ddca_check_brightness_support()` function, which is the most reliable method to determine if a display actually supports brightness control.

## Complete Verification Process

### Function Execution Steps

The `ddca_check_brightness_support()` function performs the following steps:

```c
DDCA_Status
ddca_check_brightness_support(
DDCA_Display_Handle ddca_dh,
bool* is_supported,
uint16_t* current_value,
uint16_t* max_value)
{
// Step 1: Read current brightness value
Parsed_Nontable_Vcp_Response * parsed_response;
Error_Info * ddc_excp = ddc_get_nontable_vcp_value(dh, 0x10, &parsed_response);

*current_value = RESPONSE_CUR_VALUE(parsed_response);
*max_value = RESPONSE_MAX_VALUE(parsed_response);

// Check if maximum value is 0
if (*max_value == 0) {
*is_supported = false;
goto bye;
}

// Step 2: Calculate test value (minimum change)
uint16_t test_value;
if (*current_value < *max_value) {
test_value = *current_value + 1;
} else {
test_value = *current_value - 1;
}

// Step 3: Save original verification setting
bool original_verify = ddc_get_verify_setvcp();

// Step 4: Disable verification to avoid verification failures affecting the test
ddc_set_verify_setvcp(false);

// Step 5: Attempt to set test value
ddc_excp = ddc_set_nontable_vcp_value(dh, 0x10, test_value);
if (ddc_excp) {
// Set failed, brightness control not supported
*is_supported = false;
ddc_set_verify_setvcp(original_verify);
goto bye;
}

// Step 6: Verify if the set operation actually took effect (key improvement!)
usleep(50000); // 50ms wait

Parsed_Nontable_Vcp_Response * verify_parsed_response;
ddc_excp = ddc_get_nontable_vcp_value(dh, 0x10, &verify_parsed_response);

if (!ddc_excp) {
uint16_t verify_value = RESPONSE_CUR_VALUE(verify_parsed_response);
// Verify if the set value actually took effect
if (verify_value == test_value) {
// Set successful, brightness control supported
*is_supported = true;
} else {
// Set command succeeded but value didn't change, brightness control not supported
*is_supported = false;
}
free(verify_parsed_response);
} else {
// Read verification failed, but set command succeeded, assume brightness control supported
*is_supported = true;
ERRINFO_FREE_WITH_REPORT(ddc_excp, IS_DBGTRC(debug, DDCA_TRC_API));
}

// Step 7: Restore original value
ddc_excp = ddc_set_nontable_vcp_value(dh, 0x10, *current_value);

// Step 8: Restore verification setting
ddc_set_verify_setvcp(original_verify);

if (ddc_excp) {
// Restore failed, but set succeeded, so brightness control is supported
*is_supported = true;
goto bye;
}

// Free memory
free(parsed_response);
}
```

## Key Verification Logic Analysis

### Critical Improvement: Verification After Setting

The most important improvement in this function is **Step 6**, where the function verifies that the test value was actually set by reading it back immediately after setting it. This distinguishes between:

1. **True support**: Set command succeeds AND the value actually changes
2. **False support**: Set command succeeds but the value doesn't change (display ignores the command)

### Verification Logic Flow

```c
// Step 5: Set test value
ddc_set_nontable_vcp_value(dh, 0x10, test_value);

// Step 6: Verify the set operation (key improvement!)
usleep(50000); // Wait for display to process
ddc_get_nontable_vcp_value(dh, 0x10, &verify_parsed_response);
uint16_t verify_value = RESPONSE_CUR_VALUE(verify_parsed_response);

if (verify_value == test_value) {
// Set operation actually took effect
*is_supported = true;
} else {
// Set command succeeded but value didn't change
*is_supported = false;
}
```

## Three Verification Scenarios

### Scenario 1: Full Support
```
Set test value → Success
Read back value → Success, value matches test value
Result: *is_supported = true
```

### Scenario 2: Set Succeeds but Read Fails
```
Set test value → Success
Read back value → Fails
Result: *is_supported = true (because set succeeded)
```

### Scenario 3: No Support
```
Set test value → Fails
Result: *is_supported = false
```

## Comparison with ddcutil setvcp

### ddca_check_brightness_support Verification Logic
```c
// 1. Disable verification setting
ddc_set_verify_setvcp(false);

// 2. Set test value
ddc_set_nontable_vcp_value(dh, 0x10, test_value);

// 3. Manually verify by reading back
usleep(50000);
ddc_get_nontable_vcp_value(dh, 0x10, &verify_parsed_response);
*is_supported = (verify_value == test_value);

// 4. Restore original value
ddc_set_nontable_vcp_value(dh, 0x10, *current_value);
```

### ddcutil setvcp Verification Logic
```c
// 1. Enable verification setting (default)
ddc_set_verify_setvcp(true);

// 2. Set value with automatic verification
ddc_set_verified_vcp_value_with_retry(dh, &vrec, NULL);
// Internally performs:
// - Set value
// - Immediately read back for verification
// - Compare set value with read value
// - Return DDCRC_VERIFY if mismatch
```

## Key Differences

### 1. Verification Timing
- **ddca_check_brightness_support**: Set → Wait 50ms → Read verification
- **ddcutil setvcp**: Set → Immediately read verification

### 2. Verification Purpose
- **ddca_check_brightness_support**: Verifies if the set operation actually took effect
- **ddcutil setvcp**: Verifies if the set operation was successful

### 3. Fault Tolerance
- **ddca_check_brightness_support**: If read fails, still considers supported (because set succeeded)
- **ddcutil setvcp**: If verification fails, reports failure

### 4. Visual Impact
- **ddca_check_brightness_support**: Minimizes impact by restoring original value immediately
- **ddcutil setvcp**: Leaves the display at the set value

## Practical Application Recommendations

### 1. For Applications
```c
// Use ddca_check_brightness_support to detect support
bool is_supported;
uint16_t current_value, max_value;
ddca_check_brightness_support(dh, &is_supported, &current_value, &max_value);

if (is_supported) {
// When setting brightness, disable verification for better compatibility
bool original_verify = ddca_enable_verify(false);
ddca_set_non_table_vcp_value(dh, 0x10, new_brightness >> 8, new_brightness & 0xFF);
ddca_enable_verify(original_verify);
}
```

### 2. For Command Line Tools
```bash
# Use --noverify option for better compatibility
ddcutil setvcp 10 80 --noverify
```

## Why This Verification Logic is Important

### 1. Real-World Display Behavior
Some displays may:
- Accept set commands without error
- Report success but ignore the command
- Have timing issues that require delays
- Support reading but not writing

### 2. Accurate Detection
The verification step ensures that:
- We detect displays that accept commands but don't change
- We handle timing-sensitive displays properly
- We provide accurate feedback to applications

### 3. User Experience
By verifying actual functionality:
- Applications can provide accurate brightness control features
- Users get reliable feedback about brightness support
- System integration is more robust

## Summary

The `ddca_check_brightness_support()` function provides the most reliable method for detecting brightness control support because:

1. **It performs real set operations** rather than just checking metadata
2. **It verifies the set operation actually took effect** by reading back the value
3. **It handles edge cases** where displays accept commands but don't change
4. **It minimizes visual impact** by restoring the original value immediately
5. **It provides accurate feedback** for application development

This verification logic is crucial for applications that need to provide reliable brightness control features to users.
Loading