Screen Settings

Questions and comments specific to a particular plugin should go here.
User avatar
kgschlosser
Site Admin
Posts: 5200
Joined: Fri Jun 05, 2015 5:43 am
Location: Rocky Mountains, Colorado USA

Screen Settings

Post by kgschlosser » Sat Jul 14, 2018 4:03 am

I know EG has been missing this ability for some time.

I am working on a plugin that is going to give the user the ability to make adjustments to their display screen

I am not going to use the Windows API to make adjustments to the video output and I am not going to have the video card change the output stream either. So you ask.. How am I going to do this??? I am going to grab the bull by the proverbial balls and tell the screen what to do. I am doing this by leveraging the VESA MCCS control protocol to tell the screen what to change as tho you were the one pressing the button on the screen directly.

A really nice thing about this is we will now have an alternate means of powering off and on a monitor. Microsoft messed up powering on the monitor via their API in windows 8.0 and it is still not working with Windows 10. How many years later is this?? LOL

The list below is an almost complete list of things we are going to be able to do (so long as the screen supports settings the items listed below)

Code: Select all

Global Adjustments
----------------------------------------------
Factory Defaults All - write only
Factory Defaults TV - write only
Factory Defaults Image - write only
Factory Defaults Color - write only
Factory Defaults Geometry - write only


Miscellaneous Adjustments
--------------------------------------------- 
Clock- read/write
Clock Phase - read/write
Auto Setup - read/write
Auto Setup On Off - write only
Degauss - write only
Save Restore Settings - write only
Save Settings - read/write
Restore Settings - read/write


TV Adjustments
----------------------------------------------
TV Channel Up Down - write only
TV Sharpness - read/write
TV Contrast - read/write
TV Black Level/Brightness- read/write


Image Adjustments
----------------------------------------------
Brightness - read/write
Backlight White - read/write
Backlight Red - read/write
Backlight Green - read/write
Backlight Blue - read/write
Contrast - read/write
Focus - read/write
Active Control - read only
Performance Preservation - read/write
Gamma - read/write
H Moire - read/write
V Moire - read/write
Adjust Zoom - read/write
Display Scaling - read/write
Horizontal Mirror - read/write
Vertical Mirror - read/write
Screen Orientation - read only
Velocity Scan Modulation - read/write
OSD - read/write
OSD Language - read/write
Stereo Video Mode - read/write
Scan Mode - read/write
Image Mode - read/write
Display Application - read/write


Color Adjustments
----------------------------------------------
Auto Color - read/write
Temperature Preset - read/write
Temperature Increment - read only
Temperature Request - read/write
Saturation - read/write
Hue - read/write
Six Axis Hue Red - read/write
Six Axis Hue Yellow - read/write
Six Axis Hue Green - read/write
Six Axis Hue Cyan - read/write
Six Axis Hue Blue - read/write
Six Axis Hue Magenta - read/write
Six Axis Saturation Red - read/write
Six Axis Saturation Yellow - read/write
Six Axis Saturation Green - read/write
Six Axis Saturation Cyan - read/write
Six Axis Saturation Blue - read/write
Six Axis Saturation Magenta - read/write
Flesh Tone - read/write
Vision Compensation - read/write
Video Gain Red - read/write
Video Gain Green - read/write
Video Gain Blue - read/write
Black Level Red - read/write
Black Level Green - read/write
Black Level Blue - read/write
Gray Scale Expansion - read/write


Geometry Adjustments
----------------------------------------------
Horizontal Keystone - read/write
Horizontal Linearity - read/write
Horizontal Linearity Balance - read/write
Horizontal Mirror - read/write
Horizontal Parallelogram - read/write
Horizontal Pincushion - read/write
Horizontal Pincushion Balance - read/write
Horizontal Position - read/write
Horizontal Size - read/write
Horizontal Convergence R B - read/write
Horizontal Convergence M G - read/write
Vertical Keystone - read/write
Vertical Linearity - read/write
Vertical Linearity Balance - read/write
Vertical Mirror - read/write
Vertical Parallelogram - read/write
Vertical Pincushion - read/write
Vertical Pincushion Balance - read/write
Vertical Position - read/write
Vertical Size - read/write
Vertical Convergence R B - read/write
Vertical Convergence M G - read/write
Rotation - read/write


Audio Adjustments
----------------------------------------------
Speaker Volume - read/write
Speaker Pair Select - read/write
Microphone Volume - read/write
Jack Connection Status - read only
Mute - read/write
Treble - read/write
Bass - read/write


One of the features I am going to put into place is profiles. this is going to save all of the settings on the screen and store them locally on your computer. you will have the ability to restore them. so instead of having a couple of the color adjustments that the screen stores as profiles. you will have all settings stored. Now you will be able to turn off that over scanning on your video card and have the screen make the adjustment for fit. YAY!!!

And I know we have all had that pain in the ass screen that every time you turned it on you had to move/adjust the size/position. that headache goes bye bye with this profile feature.
If you like the work I have been doing then feel free to Image

User avatar
kgschlosser
Site Admin
Posts: 5200
Joined: Fri Jun 05, 2015 5:43 am
Location: Rocky Mountains, Colorado USA

Re: Screen Settings

Post by kgschlosser » Sun Jul 15, 2018 12:29 am

OK cool I have some pretty neat news on this.

Anything explained below is if the screen supports these features

Set a user defined description of the screen. It gets stored in NVRAM on the screen.

If your screen has all kinds of lights on it. for things like HDD activity, LAN activity, E-mail. we are going to be able to set those lights on or off. Pretty cool when coupled with EG. we can use those lights as Notifications other then their intended use.

Button events.. for pressing and releasing specific buttons. Another neat thing. so for instance if you press the Power Button on the screen we can have it pause a movie. or tell the PC to sleep. This is nice so you won't have to bend down to hit to button on the Computer or go tell Windows to put the computer to sleep. a simple press of the power button on the screen will do it.

if the screen has an ambient light sensor you will be able to enable or disable it.

setting overscan or underscan
setting scaling

Now this is an awesome feature. getting events if the screen is out of sync or the refresh rate is not supported.. anyone with an HTPC i am sure has seen this before.

events for resolution/refresh rate changes. for TV's as well as PC screens.

For those of you that have a very large 3D PC screen, you will have the ability to change the Stereo video mode. (side by side, left eye, right eye)


But I finished mapping out all of the control codes. I would post them. but the post is 4223 characters more then the max 60000 if that gives you an idea oh how sizeable this is.
If you like the work I have been doing then feel free to Image

User avatar
kgschlosser
Site Admin
Posts: 5200
Joined: Fri Jun 05, 2015 5:43 am
Location: Rocky Mountains, Colorado USA

Re: Screen Settings

Post by kgschlosser » Sun Jul 15, 2018 1:04 am

@Terr & Snowbird

Give this a try.

Code: Select all

BRIGHTNESS = 50

import ctypes
from ctypes.wintypes import HMONITOR, BOOL, DWORD, HDC, RECT, LPARAM, WCHAR, BYTE


NULL = None
PHYSICAL_MONITOR_DESCRIPTION_SIZE = 128

dxva2 = ctypes.windll.dxva2
user32 = ctypes.windll.user32

MONITORENUMPROC = ctypes.WINFUNCTYPE(
    BOOL,
    HMONITOR,
    HDC,
    ctypes.POINTER(RECT),
    LPARAM
)


class _PHYSICAL_MONITOR(ctypes.Structure):
    _fields_ = [
        ('hPhysicalMonitor', HMONITOR),
        (
            'szPhysicalMonitorDescription',
            WCHAR * PHYSICAL_MONITOR_DESCRIPTION_SIZE
        )
    ]


PHYSICAL_MONITOR = _PHYSICAL_MONITOR

CapabilitiesRequestAndCapabilitiesReply = (
    dxva2.CapabilitiesRequestAndCapabilitiesReply
)
CapabilitiesRequestAndCapabilitiesReply.restype = BOOL

GetCapabilitiesStringLength = dxva2.GetCapabilitiesStringLength
GetCapabilitiesStringLength.restype = BOOL

GetNumberOfPhysicalMonitorsFromHMONITOR = (
    dxva2.GetNumberOfPhysicalMonitorsFromHMONITOR
)
GetNumberOfPhysicalMonitorsFromHMONITOR.restype = BOOL

SetMonitorBrightness = dxva2.SetMonitorBrightness
SetMonitorBrightness.restype = BOOL

GetPhysicalMonitorsFromHMONITOR = (
    dxva2.GetPhysicalMonitorsFromHMONITOR
)
GetPhysicalMonitorsFromHMONITOR.restype = BOOL

EnumDisplayMonitors = user32.EnumDisplayMonitors
EnumDisplayMonitors.restype = BOOL

GetVCPFeatureAndVCPFeatureReply = dxva2.GetVCPFeatureAndVCPFeatureReply
GetVCPFeatureAndVCPFeatureReply.restype = BOOL

SetVCPFeature = dxva2.SetVCPFeature
SetVCPFeature.restype = BOOL


def get_displays():
    """Get a list of the available displays"""

    def MonitorEnumProc(hMonitor, *_):
        pdwNumberOfPhysicalMonitors = DWORD()

        if not GetNumberOfPhysicalMonitorsFromHMONITOR(
            hMonitor,
            ctypes.byref(pdwNumberOfPhysicalMonitors)
        ):
            raise ctypes.WinError()

        pPhysicalMonitorArray = (
            PHYSICAL_MONITOR * pdwNumberOfPhysicalMonitors.value
        )()

        if not GetPhysicalMonitorsFromHMONITOR(
            hMonitor,
            pdwNumberOfPhysicalMonitors,
            pPhysicalMonitorArray
        ):
            raise ctypes.WinError()

        for pPhysicalMonitor in pPhysicalMonitorArray:
            pPhysicalMonitors.append(pPhysicalMonitor.hPhysicalMonitor)

        return True

    pPhysicalMonitors = []

    # get display monitors
    if not EnumDisplayMonitors(
        NULL,
        NULL,
        MONITORENUMPROC(MonitorEnumProc),
        NULL
    ):
        raise ctypes.WinError()

    return pPhysicalMonitors


for hMonitor in get_displays():
    pdwCurrentValue = DWORD()
    pdwMaximumValue = DWORD()
    bVCPCode = BYTE(0x10)
    if not GetVCPFeatureAndVCPFeatureReply(
        hMonitor,
        bVCPCode,
        None,
        ctypes.byref(pdwCurrentValue),
        ctypes.byref(pdwMaximumValue)
    ):
        raise ctypes.WinError()
    
    print 'pdwCurrentValue:', pdwCurrentValue.value
    print 'pdwMaximumValue:', pdwMaximumValue.value

    dwNewValue = BRIGHTNESS 
    if dwNewValue == pdwCurrentValue.value:
        continue
    if dwNewValue > pdwMaximumValue.value:
        dwNewValue = pdwMaximumValue.value
    elif dwNewValue < 0:
        dwNewValue = 0
        
    print 'dwNewValue:', dwNewValue
    
    if not SetVCPFeature(
        hMonitor,
        bVCPCode,
        DWORD(dwNewValue)
    ):
        raise ctypes.WinError()
        
This works on my screens. it also reports the maximum allowed value, the current value and the new value

I have an HP monitor from 2007 another HP from 2009 and 3 Samsungs that are identical and only a few years old they are all hooked to the same video card and each one the code above works.

It takes 200ms for it to run. on a single screen.
if i remove the checking of the max value as well as the current value it takes 1/2 that time.
If you like the work I have been doing then feel free to Image

User avatar
kgschlosser
Site Admin
Posts: 5200
Joined: Fri Jun 05, 2015 5:43 am
Location: Rocky Mountains, Colorado USA

Re: Screen Settings

Post by kgschlosser » Sun Jul 15, 2018 1:12 am

here is a better version. tells you the monitor number as well as gives a description of it.

Code: Select all

BRIGHTNESS = 100

import ctypes
from ctypes.wintypes import HMONITOR, BOOL, DWORD, HDC, RECT, LPARAM, WCHAR, \
    BYTE


NULL = None
PHYSICAL_MONITOR_DESCRIPTION_SIZE = 128

dxva2 = ctypes.windll.dxva2
user32 = ctypes.windll.user32

MONITORENUMPROC = ctypes.WINFUNCTYPE(
    BOOL,
    HMONITOR,
    HDC,
    ctypes.POINTER(RECT),
    LPARAM
)


class _PHYSICAL_MONITOR(ctypes.Structure):
    _fields_ = [
        ('hPhysicalMonitor', HMONITOR),
        (
            'szPhysicalMonitorDescription',
            WCHAR * PHYSICAL_MONITOR_DESCRIPTION_SIZE
        )
    ]


PHYSICAL_MONITOR = _PHYSICAL_MONITOR

CapabilitiesRequestAndCapabilitiesReply = (
    dxva2.CapabilitiesRequestAndCapabilitiesReply
)
CapabilitiesRequestAndCapabilitiesReply.restype = BOOL

GetCapabilitiesStringLength = dxva2.GetCapabilitiesStringLength
GetCapabilitiesStringLength.restype = BOOL

GetNumberOfPhysicalMonitorsFromHMONITOR = (
    dxva2.GetNumberOfPhysicalMonitorsFromHMONITOR
)
GetNumberOfPhysicalMonitorsFromHMONITOR.restype = BOOL

SetMonitorBrightness = dxva2.SetMonitorBrightness
SetMonitorBrightness.restype = BOOL

GetPhysicalMonitorsFromHMONITOR = (
    dxva2.GetPhysicalMonitorsFromHMONITOR
)
GetPhysicalMonitorsFromHMONITOR.restype = BOOL

EnumDisplayMonitors = user32.EnumDisplayMonitors
EnumDisplayMonitors.restype = BOOL

GetVCPFeatureAndVCPFeatureReply = dxva2.GetVCPFeatureAndVCPFeatureReply
GetVCPFeatureAndVCPFeatureReply.restype = BOOL

SetVCPFeature = dxva2.SetVCPFeature
SetVCPFeature.restype = BOOL

def get_displays():
    """Get a list of the available displays"""

    def MonitorEnumProc(hMonitor, *_):
        pdwNumberOfPhysicalMonitors = DWORD()

        if not GetNumberOfPhysicalMonitorsFromHMONITOR(
            hMonitor,
            ctypes.byref(pdwNumberOfPhysicalMonitors)
        ):
            raise ctypes.WinError()

        pPhysicalMonitorArray = (
            PHYSICAL_MONITOR * pdwNumberOfPhysicalMonitors.value
        )()

        if not GetPhysicalMonitorsFromHMONITOR(
            hMonitor,
            pdwNumberOfPhysicalMonitors,
            pPhysicalMonitorArray
        ):
            raise ctypes.WinError()


        for pPhysicalMonitor in pPhysicalMonitorArray:
            pPhysicalMonitors.append((pPhysicalMonitor.hPhysicalMonitor, pPhysicalMonitor.szPhysicalMonitorDescription))

        return True

    pPhysicalMonitors = []

    # get display monitors
    if not EnumDisplayMonitors(
        NULL,
        NULL,
        MONITORENUMPROC(MonitorEnumProc),
        NULL
    ):
        raise ctypes.WinError()

    return pPhysicalMonitors

count = 1

for hMonitor, szPhysicalMonitorDescription in get_displays():

    print 'Monitor:', count
    print 'Description:', szPhysicalMonitorDescription
    count += 1
    pdwCurrentValue = DWORD()
    pdwMaximumValue = DWORD()
    bVCPCode = BYTE(0x10)
    if not GetVCPFeatureAndVCPFeatureReply(
        hMonitor,
        bVCPCode,
        None,
        ctypes.byref(pdwCurrentValue),
        ctypes.byref(pdwMaximumValue)
    ):
        raise ctypes.WinError()

    print 'Current Value:', pdwCurrentValue.value
    print 'Maximum Value:', pdwMaximumValue.value

    dwNewValue = BRIGHTNESS
    if dwNewValue == pdwCurrentValue.value:
        continue
    if dwNewValue > pdwMaximumValue.value:
        dwNewValue = pdwMaximumValue.value
    elif dwNewValue < 0:
        dwNewValue = 0

    print 'New Value:', dwNewValue

    if not SetVCPFeature(
        hMonitor,
        bVCPCode,
        DWORD(dwNewValue)
    ):
        raise ctypes.WinError()

If you like the work I have been doing then feel free to Image

User avatar
kgschlosser
Site Admin
Posts: 5200
Joined: Fri Jun 05, 2015 5:43 am
Location: Rocky Mountains, Colorado USA

Re: Screen Settings

Post by kgschlosser » Sun Jul 15, 2018 2:00 am

ok an even more updated version

This one allows you to set all 3 things that effect how bright the screen is
Contrast
Brightness
Backlight

It also takes into consideration TV's which uses a completely different control code

It also takes into consideration LED backlit screens which make use of an RGB color value for setting the backlight. (yes you can make the backlight of an LED screen completely Red if you wanted to)

Now this may or may not require you to have specific monitor drivers installed. I have mine installed and everything works. Most people overlook this when updating/installing drivers. personally i did it because I wanted the nice purdy icon that matched my screen in the Devices and Printers dialog. But this is something that could effect the functionality.

Code: Select all

# Set any of the below to None to not have that item set. 

# Set MONITOR to None to have it apply changes to all monitors. 
# Or enter the monitor number as found in the Screen Resolution dialog
# (right click on the desktop and click on screen resolution in the menu that appears)

BRIGHTNESS = 100 # Typical max is 100
BACKLIGHT = 255 # Typical max is 255
CONTRAST = 75 # Typical max is 100
MONITOR = None

import ctypes
from ctypes.wintypes import (
    HMONITOR,
    BOOL,
    DWORD,
    HDC,
    RECT,
    LPARAM,
    WCHAR,
    BYTE
)


NULL = None
PHYSICAL_MONITOR_DESCRIPTION_SIZE = 128

dxva2 = ctypes.windll.dxva2
user32 = ctypes.windll.user32

MONITORENUMPROC = ctypes.WINFUNCTYPE(
    BOOL,
    HMONITOR,
    HDC,
    ctypes.POINTER(RECT),
    LPARAM
)


class _PHYSICAL_MONITOR(ctypes.Structure):
    _fields_ = [
        ('hPhysicalMonitor', HMONITOR),
        (
            'szPhysicalMonitorDescription',
            WCHAR * PHYSICAL_MONITOR_DESCRIPTION_SIZE
        )
    ]


PHYSICAL_MONITOR = _PHYSICAL_MONITOR

CapabilitiesRequestAndCapabilitiesReply = (
    dxva2.CapabilitiesRequestAndCapabilitiesReply
)
CapabilitiesRequestAndCapabilitiesReply.restype = BOOL

GetCapabilitiesStringLength = dxva2.GetCapabilitiesStringLength
GetCapabilitiesStringLength.restype = BOOL

GetNumberOfPhysicalMonitorsFromHMONITOR = (
    dxva2.GetNumberOfPhysicalMonitorsFromHMONITOR
)
GetNumberOfPhysicalMonitorsFromHMONITOR.restype = BOOL

SetMonitorBrightness = dxva2.SetMonitorBrightness
SetMonitorBrightness.restype = BOOL

GetPhysicalMonitorsFromHMONITOR = (
    dxva2.GetPhysicalMonitorsFromHMONITOR
)
GetPhysicalMonitorsFromHMONITOR.restype = BOOL

EnumDisplayMonitors = user32.EnumDisplayMonitors
EnumDisplayMonitors.restype = BOOL

GetVCPFeatureAndVCPFeatureReply = dxva2.GetVCPFeatureAndVCPFeatureReply
GetVCPFeatureAndVCPFeatureReply.restype = BOOL

SetVCPFeature = dxva2.SetVCPFeature
SetVCPFeature.restype = BOOL

def get_displays():
    """Get a list of the available displays"""

    def MonitorEnumProc(hMonitor, *_):
        pdwNumberOfPhysicalMonitors = DWORD()

        if not GetNumberOfPhysicalMonitorsFromHMONITOR(
            hMonitor,
            ctypes.byref(pdwNumberOfPhysicalMonitors)
        ):
            raise ctypes.WinError()

        pPhysicalMonitorArray = (
            PHYSICAL_MONITOR * pdwNumberOfPhysicalMonitors.value
        )()

        if not GetPhysicalMonitorsFromHMONITOR(
            hMonitor,
            pdwNumberOfPhysicalMonitors,
            pPhysicalMonitorArray
        ):
            raise ctypes.WinError()


        for pPhysicalMonitor in pPhysicalMonitorArray:
            pPhysicalMonitors.append((pPhysicalMonitor.hPhysicalMonitor, pPhysicalMonitor.szPhysicalMonitorDescription))

        return True

    pPhysicalMonitors = []

    # get display monitors
    if not EnumDisplayMonitors(
        NULL,
        NULL,
        MONITORENUMPROC(MonitorEnumProc),
        NULL
    ):
        raise ctypes.WinError()

    return pPhysicalMonitors

MCCS_IMAGE_LUMINANCE = 0x10
MCCS_IMAGE_TV_BLACK_LEVEL_LUMINANCE = 0x92 # read/write

MCCS_IMAGE_CONTRAST = 0x12 # read/write
MCCS_IMAGE_TV_CONTRAST = 0x8E # read/write

MCCS_IMAGE_BACKLIGHT_WHITE = 0x6B # read/write
MCCS_IMAGE_BACKLIGHT_RED = 0x6D # read/write
MCCS_IMAGE_BACKLIGHT_GREEN = 0x6F # read/write
MCCS_IMAGE_BACKLIGHT_BLUE = 0x71 # read/write


count = 1
displays = get_displays()
if MONITOR is not None:
    count = MONITOR
    displays = [displays[MONITOR - 1]]

for hMonitor, szPhysicalMonitorDescription in displays:
    print 'Monitor:', count
    print 'Description:', szPhysicalMonitorDescription

    def get_feature():
        pdwCurrentValue = DWORD()
        pdwMaximumValue = DWORD()
        if not GetVCPFeatureAndVCPFeatureReply(
            hMonitor,
            bVCPCode,
            None,
            ctypes.byref(pdwCurrentValue),
            ctypes.byref(pdwMaximumValue)
        ):
            return None, None
        return pdwMaximumValue.value, pdwCurrentValue.value

    def set_feature():
        return SetVCPFeature(hMonitor, bVCPCode, DWORD(value))

    count += 1

    if BRIGHTNESS is not None:
        bVCPCode = BYTE(MCCS_IMAGE_LUMINANCE)
        max_val, current_val = get_feature()

        if max_val is None:
            bVCPCode = BYTE(MCCS_IMAGE_TV_BLACK_LEVEL_LUMINANCE)
            max_val, current_val = get_feature()

        if max_val is None:
            print 'Brightness is not supported'

        else:
            value = BRIGHTNESS
            print 'Brightness Current Value:', current_val
            print 'Brightness Maximum Value:', max_val
            if value != current_val:
                if value > max_val:
                    value = max_val
                if value < 0:
                    value = 0
                set_feature()

    if CONTRAST is not None:
        bVCPCode = BYTE(MCCS_IMAGE_CONTRAST)
        max_val, current_val = get_feature()

        if max_val is None:
            bVCPCode = BYTE(MCCS_IMAGE_TV_CONTRAST)
            max_val, current_val = get_feature()

        if max_val is None:
            print 'Contrast is not supported'

        else:
            value = BRIGHTNESS
            print 'Contrast Current Value:', current_val
            print 'Contrast Maximum Value:', max_val
            if value != current_val:
                if value > max_val:
                    value = max_val
                if value < 0:
                    value = 0
                set_feature()

    if BACKLIGHT is not None:
        bVCPCode = BYTE(MCCS_IMAGE_BACKLIGHT_WHITE)
        max_val, current_val = get_feature()

        if max_val is None:
            for color, code in (
                ('Red', MCCS_IMAGE_BACKLIGHT_RED),
                ('Green', MCCS_IMAGE_BACKLIGHT_GREEN),
                ('Blue', MCCS_IMAGE_BACKLIGHT_BLUE)
            ):
                bVCPCode = BYTE(code)
                max_val, current_val = get_feature()

                if max_val is None:
                    print 'Backlight is not supported'
                    break

                print 'Backlight {0} Current Value: {1}'.format(color, current_val)
                print 'Backlight {0} Maximum Value: {1}'.format(color, max_val)

                value = BACKLIGHT
                if value != current_val:
                    if value > max_val:
                        value = max_val
                    if value < 0:
                        value = 0
                    set_feature()
        else:
            print 'Backlight White Current Value: {1}'.format(color, current_val)
            print 'Backlight White Maximum Value: {1}'.format(color, max_val)

            value = BACKLIGHT
            if value != current_val:
                if value > max_val:
                    value = max_val
                if value < 0:
                    value = 0
                set_feature()
    print
    print
If you like the work I have been doing then feel free to Image

Snowbird
Experienced User
Posts: 364
Joined: Fri Jul 03, 2009 10:04 am

Re: Screen Settings

Post by Snowbird » Sun Jul 15, 2018 5:44 am

no luck for me I guess :)

Code: Select all

15/07  07:43:23   Python Script
15/07  07:43:23      Monitor: 1
15/07  07:43:23      Description: LCD 1280x800
15/07  07:43:23      Brightness is not supported
15/07  07:43:23      Contrast is not supported
15/07  07:43:23      Backlight is not supported
15/07  07:43:23      

Snowbird
Experienced User
Posts: 364
Joined: Fri Jul 03, 2009 10:04 am

Re: Screen Settings

Post by Snowbird » Sun Jul 15, 2018 5:47 am

kgschlosser wrote:
Sun Jul 15, 2018 12:29 am
If your screen has all kinds of lights on it. for things like HDD activity, LAN activity, E-mail. we are going to be able to set those lights on or off. Pretty cool when coupled with EG. we can use those lights as Notifications other then their intended use.
I'm really interested by this feature !!

User avatar
kgschlosser
Site Admin
Posts: 5200
Joined: Fri Jun 05, 2015 5:43 am
Location: Rocky Mountains, Colorado USA

Re: Screen Settings

Post by kgschlosser » Sun Jul 15, 2018 8:18 am

Not no luck. we simply need to find the proper driver for ya.

Most screens in laptops are made by LG. but that depends on the brand of laptop as well.

if you go and look in device manager load up the hardware id. this is not going to be liek the usual hardware ids. do a google search for it and see if you can locate a driver/manufacturer. only download the driver form the manufacturers website or the manufacturer of a reputable laptop companies website.

attached is a little program that you can run to see what you can do with your screen. This does a query from the device and the device sends back the raw codes for what it supports . Now without the drivers in place we might not be able to set or get anything that is supported but at the very least we can see what is available.

unzip this and open the file with a text editor (something other then notepad/wordpad) copy the contents and paste it into a python script in EG. and run it.

paste the output here
Attachments
DDC_CI.zip
(14.56 KiB) Downloaded 41 times
If you like the work I have been doing then feel free to Image

Terr
Posts: 14
Joined: Wed Jul 11, 2018 8:42 am

Re: Screen Settings

Post by Terr » Sun Jul 15, 2018 8:50 am

my eyes yesterday were already stick together - i did not notice that there is a coding
I should note that in English the problem is really easier to identify ^^

Code: Select all

WindowsError: [Error 31] A device attached to the system is not functioning.
result with last code

Code: Select all

Monitor: 1
   Description: Generic PnP Monitor
   Brightness is not supported
   Contrast is not supported
   Backlight is not supported
result with DDC_CI.zip

Code: Select all

   Traceback (most recent call last):
     Python script "10", line 1893, in <module>
       for key, value in get_capabilities(hMonitor).items():
     Python script "10", line 1799, in get_capabilities
       raise ctypes.WinError()
   WindowsError: [Error 31] A device attached to the system is not functioning.
btw
i connect to tv throw av receiver
it does not show model of tv in system only Generic PnP Monitor in device manager, and model of av receiver in ati drivers
and i dont see any standart function in windows 10 to change brightness

User avatar
kgschlosser
Site Admin
Posts: 5200
Joined: Fri Jun 05, 2015 5:43 am
Location: Rocky Mountains, Colorado USA

Re: Screen Settings

Post by kgschlosser » Sun Jul 15, 2018 5:49 pm

we will work through it..


what is brand and model number of the TV?

and how is the TV connected to the PC? (HDMI, DVI)
If you like the work I have been doing then feel free to Image

Terr
Posts: 14
Joined: Wed Jul 11, 2018 8:42 am

Re: Screen Settings

Post by Terr » Sun Jul 15, 2018 10:06 pm

kgschlosser wrote:
Sun Jul 15, 2018 5:49 pm
what is brand and model number of the TV?
and how is the TV connected to the PC? (HDMI, DVI)
ati rx 480 -> hdmi -> pioneer vsx-423 -> hdmi -> lg lf652v

User avatar
kgschlosser
Site Admin
Posts: 5200
Joined: Fri Jun 05, 2015 5:43 am
Location: Rocky Mountains, Colorado USA

Re: Screen Settings

Post by kgschlosser » Mon Jul 16, 2018 3:23 am

OK so the problem appears to be the pioneer AVR. only Pioneers Pro line has the ability to use DDC/CI I bet if you plugged the TV directly into the video card it would probably work.

This is one of the many reasons why i do not use the HDMI on the AVR without the use of an HDMI splitter. when using a good splitter it will split all of the signals so you can still get the true multi channel audio while keeping all of the nifty video features.
Plus a lot of AVRs add more processing to the picture. what you can try to do is place the AVR into HDMI bypass. or HDMI pass through
If you like the work I have been doing then feel free to Image

Terr
Posts: 14
Joined: Wed Jul 11, 2018 8:42 am

Re: Screen Settings

Post by Terr » Mon Jul 16, 2018 6:42 am

sadness
then I will use a reserve plan
I will send mqtt messages to call a hotkey combination, that will control brightness with the help of the program volume2

User avatar
kgschlosser
Site Admin
Posts: 5200
Joined: Fri Jun 05, 2015 5:43 am
Location: Rocky Mountains, Colorado USA

Re: Screen Settings

Post by kgschlosser » Mon Jul 16, 2018 1:25 pm

@SnowBird, Terr

give this a shot. It may be able to address both issues.

Code: Select all


BRIGHTNESS = 85

import ctypes
from ctypes.wintypes import HANDLE, HMONITOR, BOOL, DWORD, HDC, RECT, LPARAM, WCHAR

UCHAR = ctypes.c_ubyte
CHAR = ctypes.c_byte

NULL = None
kernel32 = ctypes.windll.kernel32
user32 = ctypes.windll.user32
dxva2 = ctypes.windll.dxva2

DeviceIoControl = kernel32.DeviceIoControl
DeviceIoControl.restype = BOOL

EnumDisplayDevicesA = user32.EnumDisplayDevicesA
EnumDisplayDevicesA.restype = BOOL

CreateFile = kernel32.CreateFileA
CreateFile.restype = HANDLE


CapabilitiesRequestAndCapabilitiesReply = (
    dxva2.CapabilitiesRequestAndCapabilitiesReply
)
CapabilitiesRequestAndCapabilitiesReply.restype = BOOL

GetCapabilitiesStringLength = dxva2.GetCapabilitiesStringLength
GetCapabilitiesStringLength.restype = BOOL

GetNumberOfPhysicalMonitorsFromHMONITOR = (
    dxva2.GetNumberOfPhysicalMonitorsFromHMONITOR
)
GetNumberOfPhysicalMonitorsFromHMONITOR.restype = BOOL

SetMonitorBrightness = dxva2.SetMonitorBrightness
SetMonitorBrightness.restype = BOOL

GetPhysicalMonitorsFromHMONITOR = (
    dxva2.GetPhysicalMonitorsFromHMONITOR
)
GetPhysicalMonitorsFromHMONITOR.restype = BOOL

EnumDisplayMonitors = user32.EnumDisplayMonitors
EnumDisplayMonitors.restype = BOOL


PHYSICAL_MONITOR_DESCRIPTION_SIZE = 128

FILE_DEVICE_VIDEO = 0x00000023
FILE_ANY_ACCESS = 0x00000000
METHOD_BUFFERED = 0x00000000

DISPLAYPOLICY_AC = 0x00000001
DISPLAYPOLICY_DC = 0x00000002
DISPLAYPOLICY_BOTH = 0x00000003

GENERIC_READ = 0x80000000
GENERIC_WRITE = 0x40000000
FILE_SHARE_READ = 0x00000001
FILE_SHARE_WRITE = 0x00000002
OPEN_EXISTING = 0x00000003

EDD_GET_DEVICE_INTERFACE_NAME = 0x00000001

def CTL_CODE(t,f,m,a):
    return (t << 16) | (a << 14) | (f << 2) | m

IOCTL_VIDEO_QUERY_SUPPORTED_BRIGHTNESS = CTL_CODE(
    FILE_DEVICE_VIDEO,
    0x125,
    METHOD_BUFFERED,
    FILE_ANY_ACCESS
)
IOCTL_VIDEO_QUERY_DISPLAY_BRIGHTNESS = CTL_CODE(
    FILE_DEVICE_VIDEO,
    0x126,
    METHOD_BUFFERED,
    FILE_ANY_ACCESS
)
IOCTL_VIDEO_SET_DISPLAY_BRIGHTNESS = CTL_CODE(
    FILE_DEVICE_VIDEO,
    0x127,
    METHOD_BUFFERED,
    FILE_ANY_ACCESS
)


class _DISPLAY_DEVICEA(ctypes.Structure):
    _fields_ = [
        ('cb', DWORD),
        ('DeviceName', CHAR * 32),
        ('DeviceString', CHAR * 128),
        ('StateFlags', DWORD),
        ('DeviceID', CHAR * 128),
        ('DeviceKey', CHAR *128)
    ]


DISPLAY_DEVICEA = _DISPLAY_DEVICEA
PDISPLAY_DEVICEA = _DISPLAY_DEVICEA
LPDISPLAY_DEVICEA = ctypes.POINTER(_DISPLAY_DEVICEA)


class _DISPLAY_BRIGHTNESS(ctypes.Structure):
    _flags_ = [
        ('ucDisplayPolicy', UCHAR),
        ('ucACBrightness', UCHAR),
        ('ucDCBrightness', UCHAR)
    ]


DISPLAY_BRIGHTNESS = _DISPLAY_BRIGHTNESS
PDISPLAY_BRIGHTNESS = ctypes.POINTER(_DISPLAY_BRIGHTNESS)

class _PHYSICAL_MONITOR(ctypes.Structure):
    _fields_ = [
        ('hPhysicalMonitor', HMONITOR),
        (
            'szPhysicalMonitorDescription',
            WCHAR * PHYSICAL_MONITOR_DESCRIPTION_SIZE
        )
    ]


PHYSICAL_MONITOR = _PHYSICAL_MONITOR

MONITORENUMPROC = ctypes.WINFUNCTYPE(
    BOOL,
    HMONITOR,
    HDC,
    ctypes.POINTER(RECT),
    LPARAM
)

def get_displays():
    """Get a list of the available displays"""

    def MonitorEnumProc(hMonitor, *_):
        pdwNumberOfPhysicalMonitors = DWORD()

        if not GetNumberOfPhysicalMonitorsFromHMONITOR(
            hMonitor,
            ctypes.byref(pdwNumberOfPhysicalMonitors)
        ):
            raise ctypes.WinError()

        pPhysicalMonitorArray = (
            PHYSICAL_MONITOR * pdwNumberOfPhysicalMonitors.value
        )()

        if not GetPhysicalMonitorsFromHMONITOR(
            hMonitor,
            pdwNumberOfPhysicalMonitors,
            pPhysicalMonitorArray
        ):
            raise ctypes.WinError()

        for pPhysicalMonitor in pPhysicalMonitorArray:
            pPhysicalMonitors.append(pPhysicalMonitor.hPhysicalMonitor)

        return True

    pPhysicalMonitors = []

    # get display monitors
    if not EnumDisplayMonitors(
        NULL,
        NULL,
        MONITORENUMPROC(MonitorEnumProc),
        NULL
    ):
        raise ctypes.WinError()

    return pPhysicalMonitors


if not SetMonitorBrightness(get_displays()[0], DWORD(BRIGHTNESS)):
    hDevice = CreateFile(
        ctypes.create_string_buffer("\\\\.\\LCD"),
        GENERIC_READ | GENERIC_WRITE,
        FILE_SHARE_READ | FILE_SHARE_WRITE,
        NULL,
        OPEN_EXISTING,
        0,
        NULL
    )
    #
    # dwIoControlCode = IOCTL_VIDEO_QUERY_SUPPORTED_BRIGHTNESS
    # lpInBuffer = NULL
    # nInBufferSize = DWORD(ctypes.sizeof(DISPLAY_BRIGHTNESS))
    # lpOutBuffer = (LPVOID * 256)()
    # nOutBufferSize = DWORD(256)
    # lpBytesReturned = DWORD()
    # lpOverlapped = NULL
    #
    # DeviceIoControl(
    #     hDevice,
    #     dwIoControlCode,
    #     lpInBuffer,
    #     nInBufferSize,
    #     lpOutBuffer,
    #     nOutBufferSize,
    #     ctypes.byref(lpBytesReturned),
    #     lpOverlapped
    # )
    #
    # print lpBytesReturned.value

    dwIoControlCode = IOCTL_VIDEO_SET_DISPLAY_BRIGHTNESS
    lpInBuffer = DISPLAY_BRIGHTNESS()
    lpInBuffer.ucDisplayPolicy = DISPLAYPOLICY_BOTH
    lpInBuffer.ucACBrightness = BRIGHTNESS
    lpInBuffer.ucDCBrightness = BRIGHTNESS
    nInBufferSize = DWORD(ctypes.sizeof(DISPLAY_BRIGHTNESS))
    lpOutBuffer = NULL
    nOutBufferSize = DWORD(0)
    lpBytesReturned = DWORD()
    lpOverlapped = NULL
    if not DeviceIoControl(
        hDevice,
        dwIoControlCode,
        ctypes.byref(lpInBuffer),
        nInBufferSize,
        lpOutBuffer,
        nOutBufferSize,
        ctypes.byref(lpBytesReturned),
        lpOverlapped
    ):
        raise ctypes.WinError()
If you like the work I have been doing then feel free to Image

Snowbird
Experienced User
Posts: 364
Joined: Fri Jul 03, 2009 10:04 am

Re: Screen Settings

Post by Snowbird » Mon Jul 16, 2018 2:10 pm

Code: Select all

16/07  16:09:53      Traceback (most recent call last):
16/07  16:09:53        Python script "114", line 231, in <module>
16/07  16:09:53          raise ctypes.WinError()
16/07  16:09:53      WindowsError: [Error 122] The data area passed to a system call is too small.

Post Reply