Is it possible to enable software brightness control on Dell U2412M

I have a Dell U2515H connected via HDMI to an nVidia card.

I tried softMCCS and it worked fine. I was able to adjust the backlight brightness from the software.

These are the control codes this monitors apparently supports:

New control value
Restore factory defaults
Restore luminance/contrast defaults
Restore color defaults
Luminance
Contrast
Select color preset
Red video gain
Green video gain
Blue video gain
Active control
Input source
Screen orientation
Horizontal frequency
Vertical frequency
Panel sub-pixel layout
Display technology type
Application enable key
Display controller type
Display firmware level
Power mode
Display application
VCP version
Manufacturer specific - 0xE0
Manufacturer specific - 0xE1
Manufacturer specific - 0xE2
Manufacturer specific - 0xF0
Manufacturer specific - 0xF1
Manufacturer specific - 0xF2
Manufacturer specific - 0xFD

I have also evaluated a few other tools:

  • Dimmer - Doesn't dim the backlight. Uses fake software dimming.
  • ScreenBright - Apparently uses DDC/CI to control the backlight, but has been removed from the author's website. I haven't tried downloading it from one of those dodgy mirror sites.
  • Redshift - Fakes it like Dimmer.

Edit: Turns out there is an easy to use API for setting the screen brightness in Windows. Here is some example code:

Monitor.h

#pragma once

#include <physicalmonitorenumerationapi.h>
#include <highlevelmonitorconfigurationapi.h>

#include <vector>

class Monitor
{
public:
    explicit Monitor(PHYSICAL_MONITOR pm);
    ~Monitor();

    bool brightnessSupported() const;

    int minimumBrightness() const;
    int maximumBrightness() const;
    int currentBrightness() const;

    void setCurrentBrightness(int b);
    // Set brightness from 0.0-1.0
    void setCurrentBrightnessFraction(double fraction);

private:
    bool mBrightnessSupported = false;

    int mMinimumBrightness = 0;
    int mMaximumBrightness = 0;
    int mCurrentBrightness = 0;
    PHYSICAL_MONITOR mPhysicalMonitor;
};

std::vector<Monitor> EnumerateMonitors();

Monitor.cpp

#include "stdafx.h"
#include "Monitor.h"

Monitor::Monitor(PHYSICAL_MONITOR pm) : mPhysicalMonitor(pm)
{
    DWORD dwMonitorCapabilities = 0;
    DWORD dwSupportedColorTemperatures = 0;
    BOOL bSuccess = GetMonitorCapabilities(mPhysicalMonitor.hPhysicalMonitor, &dwMonitorCapabilities, &dwSupportedColorTemperatures);

    if (bSuccess)
    {
        if (dwMonitorCapabilities & MC_CAPS_BRIGHTNESS)
        {
            // Get min and max brightness.
            DWORD dwMinimumBrightness = 0;
            DWORD dwMaximumBrightness = 0;
            DWORD dwCurrentBrightness = 0;
            bSuccess = GetMonitorBrightness(mPhysicalMonitor.hPhysicalMonitor, &dwMinimumBrightness, &dwCurrentBrightness, &dwMaximumBrightness);
            if (bSuccess)
            {
                mBrightnessSupported = true;
                mMinimumBrightness = dwMinimumBrightness;
                mMaximumBrightness = dwMaximumBrightness;
            }
        }
    }
}

Monitor::~Monitor()
{
}

bool Monitor::brightnessSupported() const
{
    return mBrightnessSupported;
}

int Monitor::minimumBrightness() const
{
    return mMinimumBrightness;
}

int Monitor::maximumBrightness() const
{
    return mMaximumBrightness;
}

int Monitor::currentBrightness() const
{
    if (!mBrightnessSupported)
        return -1;

    DWORD dwMinimumBrightness = 0;
    DWORD dwMaximumBrightness = 100;
    DWORD dwCurrentBrightness = 0;
    BOOL bSuccess = GetMonitorBrightness(mPhysicalMonitor.hPhysicalMonitor, &dwMinimumBrightness, &dwCurrentBrightness, &dwMaximumBrightness);
    if (bSuccess)
    {
        return dwCurrentBrightness;
    }
    return -1;
}

void Monitor::setCurrentBrightness(int b)
{
    if (!mBrightnessSupported)
        return;

    SetMonitorBrightness(mPhysicalMonitor.hPhysicalMonitor, b);
}

void Monitor::setCurrentBrightnessFraction(double fraction)
{
    if (!mBrightnessSupported)
        return;
    if (mMinimumBrightness >= mMaximumBrightness)
        return;
    setCurrentBrightness((mMaximumBrightness - mMinimumBrightness) * fraction + mMinimumBrightness);
}


BOOL CALLBACK MonitorEnumCallback(_In_ HMONITOR hMonitor, _In_ HDC hdcMonitor, _In_ LPRECT lprcMonitor, _In_ LPARAM dwData)
{
    std::vector<Monitor>* monitors = reinterpret_cast<std::vector<Monitor>*>(dwData);

    // Get the number of physical monitors.
    DWORD cPhysicalMonitors;
    BOOL bSuccess = GetNumberOfPhysicalMonitorsFromHMONITOR(hMonitor, &cPhysicalMonitors);

    LPPHYSICAL_MONITOR pPhysicalMonitors = NULL;
    if (bSuccess)
    {
        // Allocate the array of PHYSICAL_MONITOR structures.
        LPPHYSICAL_MONITOR pPhysicalMonitors = new PHYSICAL_MONITOR[cPhysicalMonitors];

        if (pPhysicalMonitors != NULL)
        {
            // Get the array.
            bSuccess = GetPhysicalMonitorsFromHMONITOR(hMonitor, cPhysicalMonitors, pPhysicalMonitors);

            // Use the monitor handles.
            for (unsigned int i = 0; i < cPhysicalMonitors; ++i)
            {
                monitors->push_back(Monitor(pPhysicalMonitors[i]));
            }
        }
    }
    // Return true to continue enumeration.
    return TRUE;
}

std::vector<Monitor> EnumerateMonitors()
{
    std::vector<Monitor> monitors;
    EnumDisplayMonitors(NULL, NULL, MonitorEnumCallback, reinterpret_cast<LPARAM>(&monitors));
    return monitors;
}

Use in the obvious way.


See the DDC page on Wikipedia :

It links to software that provide GUI and command line control of most modern displays.


It is possible to control firmware settings and configuration of monitors that support DDC/CI.

Dell provides a custom-branded software by the name of Dell Display Manager, designed by EnTech Taiwan, for use with their monitors. It is primarily a GUI-based utility but offers a fairly comprehensive command-line capability. The current version is compatible with Windows Vista - Windows 10. It may work with displays from other vendors, but that has not been confirmed.

The latest version of the software can be downloaded directly from the official website.


Dell Display Manager

The below information is excerpted from the program's About info and part of the Readme.txt file highlighting command-line syntax.

About

Dell Display Manager
Version 1.27.0.1792
Copyright (c) 2007-2016, EnTech Taiwan.

Licensed to Dell Inc.

Website: http://www.entechtaiwan.com
E-mail: [email protected]

Command Language

A rich and flexible command language is supported via the command-line, and command-line arguments can be combined. Where appropriate, a specific display can be targeted by prefacing the command with the display number, e.g.,2:AutoSetup; if a display number is not specified, the command will be applied to the current selected display or to all displays, as appropriate. Commands include:

SetActiveInput [DVI2/HDMI/DP2,etc] - switches active input
RestoreFactoryDefaults - restores factory defaults*
AutoSetup - executes an autosetup (analog only)*
RestoreLevelDefaults - restores level defaults*
RestoreColorDefaults - restores color defaults*
SetBrightnessLevel X - sets brightness to X% (0-100)*
SetContrastLevel X - sets contrast to X% (0-100)*
SetNamedPreset [Movie/CAL1,etc] - changes the Preset mode*
SetPowerMode [on/off] - sets the display power mode*
SetOptimalResolution - switches to optimal resolution
SaveProfile [Name] - save settings to named profile*
RestoreProfile [Name] - restore settings from named profile*
DeleteProfile [Name] - delete named profile
SetGridType [X] - changes Easy Arrange grid type to X
Rescan - rescans display hardware
ForceReset - reconnects and rescans display hardware
SetControl X Y - sets hex control X to hex value Y
IncControl X Y - increases the value of control X by Y
DecControl X Y - decreases the value of control X by Y
Wait X - pause X milliseconds
Exit - terminates the program

Some of these commands require familiarity with the MCCS standard. For example, on monitors that support it, the command to switch the OSD language to Spanish would be SetControl CC 0A; to unlock an OSD that has been inadvertently locked SetControl CA 02.

Instructions can be combined on the command-line and assigned to standard Windows shortcuts with optional hotkeys. For example:

ddm.exe /RestoreLevelDefaults /2:SetContrastLevel 70

would first restore level defaults on all monitors, and then set the contrast level on monitor #2 to 70%.

Note: If not targeted to a specific monitor, commands listed above that are tagged with an asterisk (*) apply to all monitors to facilitate simple and uniform control over all members of a multi-monitor matrix. For instance, if executed on a matrix of 16 identical monitors, the command-line:

ddm.exe /SetNamedPreset Warm /SetBrightnessLevel 75

would set all 16 monitors to Warm preset mode, with a brightness level of 75%.