Meta:Samples/Software
Jump to navigation
Jump to search
Introduction.
Features
This software is made to do this, it has these unique selling points:
- Feature 1[1]
- Feature 2
- Feature 3
Requirements
- Microsoft Windows XP or later.
- Intel Core 2 Duo E8600 or higher.
- Python
Installation
Windows 7 64-bit
- Step 1
- Step 2
- Step 3
Configuration
General settings.
Usage
Templates and how-to's go here.
Template
import time
from ctypes import windll, byref, c_char, Structure, WinError, POINTER, WINFUNCTYPE
from ctypes.wintypes import BOOL, HMONITOR, HDC, RECT, LPARAM, DWORD, BYTE, WCHAR, HANDLE
_MONITORENUMPROC = WINFUNCTYPE(BOOL, HMONITOR, HDC, POINTER(RECT), LPARAM)
class _PHYSICAL_MONITOR(Structure):
_fields_ = [('handle', HANDLE), ('description', WCHAR * 128)]
def _iter_physical_monitors(close_handles=True):
"""Iterates physical monitors.
The handles are closed automatically whenever the iterator is advanced.
This means that the iterator should always be fully exhausted!
If you want to keep handles e.g. because you need to store all of them and
use them later, set `close_handles` to False and close them manually."""
def callback(hmonitor, hdc, lprect, lparam):
monitors.append(HMONITOR(hmonitor))
return True
monitors = []
if not windll.user32.EnumDisplayMonitors(None, None, _MONITORENUMPROC(callback), None):
raise WinError('EnumDisplayMonitors failed')
for monitor in monitors:
# Get physical monitor count
count = DWORD()
if not windll.dxva2.GetNumberOfPhysicalMonitorsFromHMONITOR(monitor, byref(count)):
raise WinError()
# Get physical monitor handles
physical_array = (_PHYSICAL_MONITOR * count.value)()
if not windll.dxva2.GetPhysicalMonitorsFromHMONITOR(monitor, count.value, physical_array):
raise WinError()
for physical in physical_array:
handle = physical.handle
# Get physical monitor capabilities. This may take a while...
length = DWORD()
if not windll.dxva2.GetCapabilitiesStringLength(HANDLE(handle), byref(length)):
raise WinError()
capabilities_string = (c_char * length.value)()
if not windll.dxva2.CapabilitiesRequestAndCapabilitiesReply(HANDLE(handle), capabilities_string, length):
raise WinError()
raw_capabilities = capabilities_string.value.decode('ascii')
capabilities = _parse_capabilities_string(raw_capabilities)
if capabilities:
# We only care about the model info for now.
yield [capabilities['model'], handle]
if close_handles:
if not windll.dxva2.DestroyPhysicalMonitor(handle):
raise WinError()
def _parse_capabilities_string(capabilities_string):
level = 0
capabilities = {}
open_p = {}
close_p = {0: 0}
id = {}
for i, chr in enumerate(capabilities_string):
if chr == '(':
if i == 0:
close_p[0] = 1
continue
open_p[level] = i
if level == 0:
id[0] = capabilities_string[close_p[0] + 1:i]
level += 1
elif chr == ')':
level -= 1
close_p[level] = i
if level == 0:
values = capabilities_string[open_p[0] + 1:i]
# We only care about the model info for now.
if id[0] == 'model':
capabilities[id[0]] = values
return capabilities
def set_vcp_feature(monitor, code, value):
"""Sends a DDC command to the specified monitor.
See this link for a list of commands:
ftp://ftp.cis.nctu.edu.tw/pub/csie/Software/X11/private/VeSaSpEcS/VESA_Document_Center_Monitor_Interface/mccsV3.pdf
"""
if not windll.dxva2.SetVCPFeature(HANDLE(monitor), BYTE(code), DWORD(value)):
raise WinError()
for model, handle in _iter_physical_monitors():
if model == "XL2420Z":
set_vcp_feature(handle, 0xDC, 12) # picture mode
time.sleep(2) # wait for picture mode to load
set_vcp_feature(handle, 0x10, 31) # brightness
set_vcp_feature(handle, 0x12, 50) # contrast
set_vcp_feature(handle, 0xF0, 0) # AMA (overdrive)
See Also
References
- ↑ Some reference