Difference between revisions of "Meta:Samples/Software"

From TSG Doc
Jump to navigation Jump to search
(Created page with "<!-- Introduction. What does this software do? Whom is it for? --> Introduction. <!-- Table of Contents will be generated here --> ==Features== This software is made to do t...")
 
Line 33: Line 33:
  
 
===Template===
 
===Template===
<pre>
 
Some code
 
</pre>
 
  
 +
<syntaxhighlight lang="python">
 +
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)
 +
 +
</syntaxhighlight>
  
 
==See Also== <!-- Optional -->
 
==See Also== <!-- Optional -->

Revision as of 11:54, 28 April 2015

Introduction.


Features

This software is made to do this, it has these unique selling points:

  • Feature 1
  • Feature 2
  • Feature 3

Requirements

  • Microsoft Windows XP or later.
  • Intel Core 2 Duo E8600 or higher.
  • Python


Installation

Windows 7 64-bit

  1. Step 1
  2. Step 2
  3. 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