Blackout Display

Do you have questions about writing plugins or scripts in Python? Meet the coders here.
User avatar
kgschlosser
Site Admin
Posts: 4203
Joined: Fri Jun 05, 2015 5:43 am
Location: Rocky Mountains, Colorado USA

Blackout Display

Post by kgschlosser » Fri Aug 04, 2017 4:53 am

I created a little addition for EG it is not a plugin and you will have to download the attached file into you eg\Classes folder in your EG installation.

you can use this in a python script and access it by using eg.DesktopDisplay

eg.DesktopDisplay has the following methods (things you can call to get data)

eg.DesktopDisplay.Refresh() - refreshes the display list. this automatically gets called when EnumDisplays() or GetDisplay() is called.
eg.DesktopDisplay.EnumDisplays() - enumerates the displays, creates a list of eg.DesktopDisplay.Display instances each instance represents a currently attached display

eg.DesktopDisplay.GetDisplay() - you can either pass this the monitor number or monitor name and this will retrun a DesktopDisplay.Display instance, The display number and display name can be found in the windows Screen Resolution dialog. NOTE if using the display number you will need to make it one digit lower then what is displayed in the Screen Resolution dialog so display 1 you would pass a 0 to this method

attributes
eg.DesktopDisplay.displays - this is a list of all of the available displays that are attached
eg.DesktopDisplay.size - this is the virtual size of the desktop display, so if you have 4 displays 3 horizontal and the 4th is above the center display. this would return the total width and total height. even tho you do not have a display for 2 spots it will report a resolution of them being there.
eg.DesktopDisplay.displayCount - number of connected displays
eg.DesktopDisplay.isTouchScreen - take a guess (True/False)
eg.DesktopDisplay.isMultiTouch - take a guess (True/False)
eg.DesktopDisplay.maxTouchCount - maximum number of simultaneous touches if the display is touch capable otherwise 0



eg.DesktopDisplay.Display:
this class will be returned as a representation of a specific display that is attached.

attributes:
Display.blackout - set True/False to blackout the display or to check if it has been set (example code below)
Display.x - upper left corner of the display pixel position relative to the top left corner of the primary display
Display.y - upper left corner of the display pixel position relative to the top left corner of the primary display
Display.w - display pixel resolution width
Display.h - display pixel resolution height
Display.primary - True/False if the display is the primary display
Display.number - display number, this the the number seen in the windows screen resolution dialog
Display.name - name of the display. this is the name seen in the screen resolution dialog
Display.size - this is the size of the display returned as (w, h)
Display.pos - this is the upper left corner pixel position of the display returned as (x, y)

If for example you have 3 displays attached and you disconnect display #2 this will automatically cause Windows to reorder the displays this will also reorder as required.

OK so here is a rundown of the blackout.
Since there is no mechanism in Windows to be able to turn off a single display in a multi display setup I decided to make something that will help a little. this will black out a display. you will still get a glow form the screen. but it is better then nothing.

to blackout a display you would replace the 0 with the display number you wanted to black out.

Code: Select all

display = eg.DesktopDisplay.GetDisplay(0)
if not display.blackout:
    display.blackout = True
in this next example it will grab the display by name. this is nice because if you have a TV and a monitor attached. but the display numbers mix about sometimes. this will return the proper display based on the name not caring what position it is in. if you have more then one display with the same name then it will always return the first one it happens across.

Code: Select all

display = eg.DesktopDisplay.GetDisplay('HP w2007 Wide LCD Monitor')
if not display.blackout:
    display.blackout = True
and if you simply wanted to know the specifics about a specific display this will print out something similar to this
Name: HP w2007 Wide LCD Monitor, 'Number: 0, Width: 1920, Height: 1080, X: 0, Y: 0, Primary: True

Code: Select all

display = eg.DesktopDisplay.GetDisplay(0)
print display
and if you wanted to make it multi line for an osd

Code: Select all

display = eg.DesktopDisplay.GetDisplay(0)
print str(display).replace(', ', '\n')
I do not know if the next couple of things actually work as I have not fully tested this portion of it.
if you power off or unplug a display while the screen is blacked out it should disable the blackout.
If you change the display position when the screen is blacked out, the blackout should remain and follow the screen to it's new location.
If you like the work I have been doing then feel free to Image

User avatar
topix
Experienced User
Posts: 415
Joined: Sat May 05, 2007 3:43 pm
Location: Germany
Contact:

Re: Blackout Display

Post by topix » Sat Aug 05, 2017 10:29 am

I get an exception when trying to use it. Seems like to be problem with my system. I have two monitors: neovo L-W27 and neovo L-W22. Both are connected through HDMI to an Intel HD Graphics 4000 adapter on a Gigabyte GA-Z77N-Wifi mainboard. When the script tries to get the monitors information it raises this exception:

Code: Select all

Traceback (most recent call last) (WIP):
  File "<string>", line 1, in <module>
  File "D:/devel/EventGhost.org/EventGhost\eg\__init__.py", line 49, in __getattr__
    mod = __import__("eg.Classes." + name, None, None, [name], 0)
  File "D:/devel/EventGhost.org/EventGhost\eg\Classes\DesktopDisplay.py", line 280, in <module>
    DesktopDisplay = DesktopDisplay()
  File "D:/devel/EventGhost.org/EventGhost\eg\Classes\DesktopDisplay.py", line 193, in __init__
    self.Refresh()
  File "D:/devel/EventGhost.org/EventGhost\eg\Classes\DesktopDisplay.py", line 200, in Refresh
    display = win32api.EnumDisplayDevices(metrics['Device'])
error: (0, 'EnumDisplayDevices', 'No error message is available')
In the Refresh() function the variables have these values:
i = 0
display_handles = (<PyHANDLE:65539>, <PyHANDLE:0>, (1920, 0, 3840, 1080))

Looks like the monitors are not correctly recognized.

jonib
Plugin Developer
Posts: 1280
Joined: Thu Mar 26, 2009 9:33 pm
Location: Sweden

Re: Blackout Display

Post by jonib » Sun Aug 06, 2017 3:47 pm

kgschlosser wrote:I created a little addition for EG it is not a plugin and you will have to download the attached file into you eg\Classes folder in your EG installation.
Cool. Haven't had a chance to look at the code yet.
eg.DesktopDisplay.GetDisplay() - you can either pass this the monitor number or monitor name and this will retrun a DesktopDisplay.Display instance, The display number and display name can be found in the windows Screen Resolution dialog.
Did you solve the "Generic PnP Monitor" problem? Some monitors/TVs are named "Generic PnP Monitor" via Windows API but Windows own display dialog is able to give them at least their manufacturer, and I seem to remember there is other unique info like a serial number.

I was working on a similar Python library as my AudioEndpointControl but for monitors, specifically to not be dependent on the ordering as I have had problems before that EventGhost would display stuff on the wrong screen when Windows decided to suddenly change the order.

Edit: I missed this part before
OK so here is a rundown of the blackout.
Since there is no mechanism in Windows to be able to turn off a single display in a multi display setup I decided to make something that will help a little. this will black out a display. you will still get a glow form the screen. but it is better then nothing.
Cool, this could be useful to me as I need to blackout the screen when running 4:3 games not in fullscreen mode, my hackish way I do it now is I changed the desktop wallpaper to black.

jonib
XBMC2 plugin to control XBMC. If you want to flatter me Image

jonib
Plugin Developer
Posts: 1280
Joined: Thu Mar 26, 2009 9:33 pm
Location: Sweden

Re: Blackout Display

Post by jonib » Sun Aug 06, 2017 4:56 pm

So I did a quick test:

This is the result for my Samsung HDTV, there is no specific driver that I have found so it uses Windows default driver.

Code: Select all

Name: Generic PnP Monitor, Number: 2, Width: 1920, Height: 1080, X: 2560, Y: 0, Primary: False
If there are more then one unidentified monitor on a system this will be problematic.

jonib

ps
I have attached my test code that I worked on last year, it has all the info I could find about displays: Just run with Python and this is not elegant code just what I used to test Windows APIs.

Looks like there is a 3 character vendor name (example "SAM" for samsung) and 16bit integer for a product id, and I believe there is a serial number to separate identical displays but that part I wasn't finished with.

Code: Select all

{u'EDID': {u'name': 'SAMSUNG',
           u'product_id': '0x470',
           u'resolution': (1920, 1080),
           u'vendor_name': u'SAM',
           u'version': u'1.3'},
This is EDID info for the same Samsung HDTV.
Attachments
displaycontrol.py
Test code to wrangle display/monitor information from Windows
(8.84 KiB) Downloaded 76 times
XBMC2 plugin to control XBMC. If you want to flatter me Image

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

Re: Blackout Display

Post by kgschlosser » Mon Aug 07, 2017 11:44 pm

well if you have more then one monitor that is attached that has the same name that is why i coded the thing up to also use monitor numbers. so simply pass the monitor number instead of the name.
If you like the work I have been doing then feel free to Image

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

Re: Blackout Display

Post by kgschlosser » Tue Aug 08, 2017 12:02 am

i tested your code and it tracebacks. this is because not every driver registers it's self in Win32_DesktopMonitor I have a monitor and the drivers re installed for the monitor but it only shows up in Win32_PNPEntity. I have tried this approach as well. and for the life of me i cannot remember what i did to get around it.
If you like the work I have been doing then feel free to Image

jonib
Plugin Developer
Posts: 1280
Joined: Thu Mar 26, 2009 9:33 pm
Location: Sweden

Re: Blackout Display

Post by jonib » Tue Aug 08, 2017 1:36 am

kgschlosser wrote:i tested your code and it tracebacks. this is because not every driver registers it's self in Win32_DesktopMonitor I have a monitor and the drivers re installed for the monitor but it only shows up in Win32_PNPEntity. I have tried this approach as well. and for the life of me i cannot remember what i did to get around it.
yeah there is no error checking or exception handling, as it was just the code I was trying to find APIs that gave me monitor info.
Unfortunately I didn't finish the code as I probably got fed up, or just needed to work on something else.

jonib
XBMC2 plugin to control XBMC. If you want to flatter me Image

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

Re: Blackout Display

Post by kgschlosser » Tue Aug 08, 2017 4:48 am

Would you mind if I used some bits of it an added it to the DesktopDisplay. I am thinking of adding more things to it. like refresh rate. and things of that nature. But also give the ability to change the position and resolution. I like the EDID part as this can be used as a means for specifying the display you want to grab. I am thinking that adding the ability to locate the display by model, manufacturer, display number, display name, caption, description. it will search all of these things to locate a match


check out my monitor information... look at the EDID resolutions and then look at the resolutions in GetMonitorInfo.

Code: Select all

3
['HP w2007 Wide LCD Monitor', 'HP 2009 Series Wide LCD Monitor', 'HP w1907 Wide LCD Monitor']
{u'EDID': {u'name': 'HP w2007',
           u'product_id': '0x26a7',
           u'resolution': (1680, 1050),
           u'serial': 'CNN7232CRF\n  ',
           u'vendor_name': u'HWP',
           u'version': u'1.3'},
 u'EnumDisplayDevices': {u'DeviceID': '\\\\?\\DISPLAY#HWP26A7#5&2b6865e4&0&UID1025#{e6f07b5f-ee97-4a90-b076-33f57bf4eaa7}',
                         u'DeviceKey': '\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Class\\{4d36e96e-e325-11ce-bfc1-08002be10318}\\0003',
                         u'DeviceName': '\\\\.\\DISPLAY1\\Monitor0',
                         u'DeviceString': 'HP w2007 Wide LCD Monitor',
                         u'StateFlags': 3L},
 u'EnumDisplayMonitors': (<PyHANDLE:65537>, <PyHANDLE:0>, (0, 0, 1920, 1080)),
 u'GetMonitorInfo': {'Device': '\\\\.\\DISPLAY1',
                     'Flags': 1,
                     'Monitor': (0, 0, 1920, 1080),
                     'Work': (0, 0, 1920, 1080)},
 u'Win32_DesktopMonitor': {u'Availability': 3,
                           u'Caption': u'HP w2007 Wide LCD Monitor',
                           u'Description': u'HP w2007 Wide LCD Monitor',
                           u'DeviceID': u'DesktopMonitor1',
                           u'MonitorManufacturer': u'HP',
                           u'MonitorType': u'HP w2007 Wide LCD Monitor',
                           u'Name': u'HP w2007 Wide LCD Monitor',
                           u'PNPDeviceID': u'DISPLAY\\HWP26A7\\5&2B6865E4&0&UID1025',
                           u'PixelsPerXLogicalInch': 96,
                           u'PixelsPerYLogicalInch': 96,
                           u'ScreenHeight': 1080,
                           u'ScreenWidth': 1920,
                           u'Status': u'OK'},
 u'Win32_PnPEntity': {u'Caption': u'HP w2007 Wide LCD Monitor',
                      u'Description': u'HP w2007 Wide LCD Monitor',
                      u'DeviceID': u'DISPLAY\\HWP26A7\\5&2B6865E4&0&UID1025',
                      u'HardwareID': (u'MONITOR\\HWP26A7',),
                      u'Manufacturer': u'HP',
                      u'Name': u'HP w2007 Wide LCD Monitor'}}
{u'EDID': {u'name': 'HP 2009',
           u'product_id': '0x2828',
           u'resolution': (1600, 900),
           u'serial': '3CQ94507FB\n  ',
           u'vendor_name': u'HWP',
           u'version': u'1.3'},
 u'EnumDisplayDevices': {u'DeviceID': '\\\\?\\DISPLAY#HWP2828#5&2b6865e4&0&UID1030#{e6f07b5f-ee97-4a90-b076-33f57bf4eaa7}',
                         u'DeviceKey': '\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Class\\{4d36e96e-e325-11ce-bfc1-08002be10318}\\0004',
                         u'DeviceName': '\\\\.\\DISPLAY2\\Monitor0',
                         u'DeviceString': 'HP 2009 Series Wide LCD Monitor',
                         u'StateFlags': 3L},
 u'EnumDisplayMonitors': (<PyHANDLE:65539>,
                          <PyHANDLE:0>,
                          (1920, 0, 3840, 1080)),
 u'GetMonitorInfo': {'Device': '\\\\.\\DISPLAY2',
                     'Flags': 0,
                     'Monitor': (1920, 0, 3840, 1080),
                     'Work': (1920, 0, 3840, 1080)},
 u'Win32_PnPEntity': {u'Caption': u'HP 2009 Series Wide LCD Monitor',
                      u'Description': u'HP 2009 Series Wide LCD Monitor',
                      u'DeviceID': u'DISPLAY\\HWP2828\\5&2B6865E4&0&UID1030',
                      u'HardwareID': (u'MONITOR\\HWP2828',),
                      u'Manufacturer': u'HP',
                      u'Name': u'HP 2009 Series Wide LCD Monitor'}}
{u'EDID': {u'name': 'HP w1907',
           u'product_id': '0x26a3',
           u'resolution': (1440, 900),
           u'serial': 'CND7061KGJ\n  ',
           u'vendor_name': u'HWP',
           u'version': u'1.3'},
 u'EnumDisplayDevices': {u'DeviceID': '\\\\?\\DISPLAY#HWP26A3#5&2b6865e4&0&UID1031#{e6f07b5f-ee97-4a90-b076-33f57bf4eaa7}',
                         u'DeviceKey': '\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Class\\{4d36e96e-e325-11ce-bfc1-08002be10318}\\0005',
                         u'DeviceName': '\\\\.\\DISPLAY3\\Monitor0',
                         u'DeviceString': 'HP w1907 Wide LCD Monitor',
                         u'StateFlags': 3L},
 u'EnumDisplayMonitors': (<PyHANDLE:65541>, <PyHANDLE:0>, (-1920, 0, 0, 1080)),
 u'GetMonitorInfo': {'Device': '\\\\.\\DISPLAY3',
                     'Flags': 0,
                     'Monitor': (-1920, 0, 0, 1080),
                     'Work': (-1920, 0, 0, 1040)},
 u'Win32_PnPEntity': {u'Caption': u'HP w1907 Wide LCD Monitor',
                      u'Description': u'HP w1907 Wide LCD Monitor',
                      u'DeviceID': u'DISPLAY\\HWP26A3\\5&2B6865E4&0&UID1031',
                      u'HardwareID': (u'MONITOR\\HWP26A3',),
                      u'Manufacturer': u'HP',
                      u'Name': u'HP w1907 Wide LCD Monitor'}}
If you like the work I have been doing then feel free to Image

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

Re: Blackout Display

Post by kgschlosser » Tue Aug 08, 2017 4:57 am

I am trying to sort the issue with the multiple displays. and windows changing the monitor numbers..

I need to create the Display instance so if a name was provided then the Display instance will follow the name so if the display number order changes it will still control the proper display. and if you use the monitor number then it will switch over all of the data to the new display if the monitor numbers change.

the serial number is also a good one to use if we can locate the place where this is stored. I am going to make a nice GUI for this so that the monitors can be selected. this way all of the tidbits that are needed to locate the exact monitor you want will be available. I am going to add to the searchable parameters. and the more information passed to it the more exact choice it will give.
If you like the work I have been doing then feel free to Image

jonib
Plugin Developer
Posts: 1280
Joined: Thu Mar 26, 2009 9:33 pm
Location: Sweden

Re: Blackout Display

Post by jonib » Tue Aug 08, 2017 5:05 am

kgschlosser wrote:Would you mind if I used some bits of it an added it to the DesktopDisplay.
Sure
check out my monitor information... look at the EDID resolutions and then look at the resolutions in GetMonitorInfo.
Weird, mine seems to match.

jonib
XBMC2 plugin to control XBMC. If you want to flatter me Image

jonib
Plugin Developer
Posts: 1280
Joined: Thu Mar 26, 2009 9:33 pm
Location: Sweden

Re: Blackout Display

Post by jonib » Tue Aug 08, 2017 5:15 am

The EDID vendor name codes are listed here if needed.

Code: Select all

HWP = Hewlett Packard 	
SAM = Samsung Electric Company
jonib
XBMC2 plugin to control XBMC. If you want to flatter me Image

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

Re: Blackout Display

Post by kgschlosser » Tue Aug 08, 2017 5:43 pm

jonib wrote:Weird, mine seems to match.
This is because of some fancy voodoo magic i am going to my displays. LOL its how you make 3 displays that have different max resolutions actually look right in a multi monitor setup


But here is a test version if you want to have a poke at it. It will either run from an interpreter (tho the touchscreen bits of it will not work) or from inside of EG
If you like the work I have been doing then feel free to Image

jonib
Plugin Developer
Posts: 1280
Joined: Thu Mar 26, 2009 9:33 pm
Location: Sweden

Re: Blackout Display

Post by jonib » Tue Aug 08, 2017 7:21 pm

kgschlosser wrote:This is because of some fancy voodoo magic i am going to my displays. LOL its how you make 3 displays that have different max resolutions actually look right in a multi monitor setup
OK

But here is a test version if you want to have a poke at it. It will either run from an interpreter (tho the touchscreen bits of it will not work) or from inside of EG
My monitors

Code: Select all

Name: AOC Q2770, Number: 1, Width: 2560, Height: 1440, X: 0, Y: 0, Primary: False, Active: True, Blacked Out: False, Mirroring: False, Removable: False, VGA Compatible: False, EDID Data: EDID version: 1.4, Vendor_name: AOC, Vendor_code: 0x5e3, Product_id: 0x2770, Native Width: 2560, Native Height: 1440, Name: Q2770, Serial: FSUDBHA000481, MFG Year: 2013, MFG Month: November

Name: Generic PnP Monitor, Number: 2, Width: 1920, Height: 1080, X: 2560, Y: 0, Primary: False, Active: True, Blacked Out: False, Mirroring: False, Removable: False, VGA Compatible: False, EDID Data: EDID version: 1.3, Vendor_name: SAM, Vendor_code: 0x4c2d, Product_id: 0x470, Native Width: 1920, Native Height: 1080, Name: SAMSUNG, Serial: , MFG Year: 2008, MFG Month: June

Name: SyncMaster P2370(G)/P23700(G),Magic P2370G(Digital), Number: 3, Width: 1920, Height: 1080, X: -1920, Y: 0, Primary: False, Active: True, Blacked Out: False, Mirroring: False, Removable: False, VGA Compatible: False, EDID Data: EDID version: 1.3, Vendor_name: SAM, Vendor_code: 0x4c2d, Product_id: 0x52a, Native Width: 1920, Native Height: 1080, Name: SyncMaster, Serial: H1AK500000, MFG Year: 2008, MFG Month: December
Looks good

jonib
XBMC2 plugin to control XBMC. If you want to flatter me Image

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

Re: Blackout Display

Post by kgschlosser » Tue Aug 08, 2017 11:13 pm

I seem to have an issue with the primary monitor. I still have to fix that.

I have removed the EDID class and put everything into the same class.
I added a means to search for vendor name, description, model, serial as well as the display number
I corrected the display number so it matches what is seen in the screen resolution dialog.
if you use the display number and have any of the other parameters filled in it will default to trying to match based on those values first. and if it is unable to then it will match by display number
Changed formatting of print output
Added Vendor id -> name lookup
added __len__ to get the number of displays
Attachments
DesktopDisplay.py
(16.11 KiB) Downloaded 60 times
If you like the work I have been doing then feel free to Image

jonib
Plugin Developer
Posts: 1280
Joined: Thu Mar 26, 2009 9:33 pm
Location: Sweden

Re: Blackout Display

Post by jonib » Wed Aug 09, 2017 1:52 am

kgschlosser wrote:Added Vendor id -> name lookup
I don't really like having a partial list in the code, I think it would be better to have it in a separate file, that way it's easy to update, and could be compressed as the full list is kinda big. I believe the ids are not display specific so other modules could have a use for it too

No vendor name for me: :cry:

Code: Select all

Vendor Name:
Vendor Id: AOC
Model: Q2770
Description: AOC Q2770
Display Number: 1
jonib
XBMC2 plugin to control XBMC. If you want to flatter me Image

Post Reply