11# A part of NonVisual Desktop Access (NVDA)
22# This file is covered by the GNU General Public License.
33# See the file COPYING for more details.
4- # Copyright (C) 2018-2023 NV Access Limited, Babbage B.V., Leonard de Ruijter
4+ # Copyright (C) 2018-2024 NV Access Limited, Babbage B.V., Leonard de Ruijter
55
66"""Screen curtain implementation based on the windows magnification API.
77The Magnification API has been marked by MS as unsupported for WOW64 applications such as NVDA. (#12491)
1010import os
1111from vision import providerBase
1212from ctypes import Structure , windll , c_float , POINTER , WINFUNCTYPE , WinError
13- from ctypes .wintypes import BOOL
13+ from ctypes .wintypes import BOOL , FLOAT , HWND , RECT , INT
1414from autoSettingsUtils .driverSetting import BooleanDriverSetting
1515from autoSettingsUtils .autoSettings import SupportedSettingType
1616import wx
@@ -30,6 +30,24 @@ class MAGCOLOREFFECT(Structure):
3030 _fields_ = (("transform" , c_float * 5 * 5 ),)
3131
3232
33+ class MAGTRANSFORM (Structure ):
34+ _fields_ = (("v" , c_float * 3 * 3 ),)
35+
36+ def __init__ (self , magnificationFactor : float = 1.0 ):
37+ """
38+ https://learn.microsoft.com/en-us/windows/win32/api/magnification/ns-magnification-magtransform
39+
40+ :param magnificationFactor: defaults to 1.0.
41+ The minimum value of this parameter is 1.0, and the maximum value is 4096.0.
42+ If this value is 1.0, the screen content is not magnified and no offsets are applied.
43+ """
44+ super ().__init__ ()
45+ assert 1.0 <= magnificationFactor <= 4096.0
46+ self .v [0 ][0 ] = magnificationFactor
47+ self .v [1 ][1 ] = magnificationFactor
48+ self .v [2 ][2 ] = 1.0
49+
50+
3351# homogeneous matrix for a 4-space transformation (red, green, blue, opacity).
3452# https://docs.microsoft.com/en-gb/windows/win32/gdiplus/-gdiplus-using-a-color-matrix-to-transform-a-single-color-use
3553TRANSFORM_BLACK = MAGCOLOREFFECT () # empty transformation
@@ -51,14 +69,29 @@ class Magnification:
5169 # Set full screen color effect
5270 _MagSetFullscreenColorEffectFuncType = WINFUNCTYPE (BOOL , POINTER (MAGCOLOREFFECT ))
5371 _MagSetFullscreenColorEffectArgTypes = ((1 , "effect" ),)
72+ MagSetFullscreenColorEffect = _MagSetFullscreenColorEffectFuncType (
73+ ("MagSetFullscreenColorEffect" , _magnification ),
74+ _MagSetFullscreenColorEffectArgTypes ,
75+ )
76+ MagSetFullscreenColorEffect .errcheck = _errCheck
5477
5578 # Get full screen color effect
5679 _MagGetFullscreenColorEffectFuncType = WINFUNCTYPE (BOOL , POINTER (MAGCOLOREFFECT ))
5780 _MagGetFullscreenColorEffectArgTypes = ((2 , "effect" ),)
81+ MagGetFullscreenColorEffect = _MagGetFullscreenColorEffectFuncType (
82+ ("MagGetFullscreenColorEffect" , _magnification ),
83+ _MagGetFullscreenColorEffectArgTypes ,
84+ )
85+ MagGetFullscreenColorEffect .errcheck = _errCheck
5886
5987 # show system cursor
6088 _MagShowSystemCursorFuncType = WINFUNCTYPE (BOOL , BOOL )
6189 _MagShowSystemCursorArgTypes = ((1 , "showCursor" ),)
90+ MagShowSystemCursor = _MagShowSystemCursorFuncType (
91+ ("MagShowSystemCursor" , _magnification ),
92+ _MagShowSystemCursorArgTypes ,
93+ )
94+ MagShowSystemCursor .errcheck = _errCheck
6295
6396 # initialize
6497 _MagInitializeFuncType = WINFUNCTYPE (BOOL )
@@ -70,28 +103,72 @@ class Magnification:
70103 MagUninitialize = _MagUninitializeFuncType (("MagUninitialize" , _magnification ))
71104 MagUninitialize .errcheck = _errCheck
72105
73- # These magnification functions are not available on versions of Windows prior to Windows 8,
74- # and therefore looking them up from the magnification library will raise an AttributeError.
75- try :
76- MagSetFullscreenColorEffect = _MagSetFullscreenColorEffectFuncType (
77- ("MagSetFullscreenColorEffect" , _magnification ),
78- _MagSetFullscreenColorEffectArgTypes ,
79- )
80- MagSetFullscreenColorEffect .errcheck = _errCheck
81- MagGetFullscreenColorEffect = _MagGetFullscreenColorEffectFuncType (
82- ("MagGetFullscreenColorEffect" , _magnification ),
83- _MagGetFullscreenColorEffectArgTypes ,
84- )
85- MagGetFullscreenColorEffect .errcheck = _errCheck
86- MagShowSystemCursor = _MagShowSystemCursorFuncType (
87- ("MagShowSystemCursor" , _magnification ),
88- _MagShowSystemCursorArgTypes ,
89- )
90- MagShowSystemCursor .errcheck = _errCheck
91- except AttributeError :
92- MagSetFullscreenColorEffect = None
93- MagGetFullscreenColorEffect = None
94- MagShowSystemCursor = None
106+ _MagSetWindowSourceFuncType = WINFUNCTYPE (BOOL , HWND , POINTER (RECT ))
107+ _MagSetWindowSourceArgTypes = ((1 , "hwnd" ), (1 , "rect" ))
108+ MagSetWindowSource = _MagSetWindowSourceFuncType (
109+ ("MagSetWindowSource" , _magnification ),
110+ _MagSetWindowSourceArgTypes ,
111+ )
112+ MagSetWindowSource .errcheck = _errCheck
113+
114+ _MagGetWindowSourceFuncType = WINFUNCTYPE (BOOL , HWND , POINTER (RECT ))
115+ _MagGetWindowSourceArgTypes = ((1 , "hwnd" ), (2 , "rect" ))
116+ MagGetWindowSource = _MagGetWindowSourceFuncType (
117+ ("MagGetWindowSource" , _magnification ),
118+ _MagGetWindowSourceArgTypes ,
119+ )
120+ MagGetWindowSource .errcheck = _errCheck
121+
122+ _MagSetWindowTransformFuncType = WINFUNCTYPE (BOOL , HWND , POINTER (MAGTRANSFORM ))
123+ _MagSetWindowTransformArgTypes = ((1 , "hwnd" ), (1 , "transform" ))
124+ MagSetWindowTransform = _MagSetWindowTransformFuncType (
125+ ("MagSetWindowTransform" , _magnification ),
126+ _MagSetWindowTransformArgTypes ,
127+ )
128+ MagSetWindowTransform .errcheck = _errCheck
129+
130+ # Create transformation window
131+ _MagGetWindowTransformFuncType = WINFUNCTYPE (BOOL , HWND , POINTER (MAGTRANSFORM ))
132+ _MagGetWindowTransformArgTypes = ((1 , "hwnd" ), (2 , "transform" ))
133+ MagGetWindowTransform = _MagGetWindowTransformFuncType (
134+ ("MagGetWindowTransform" , _magnification ),
135+ _MagGetWindowTransformArgTypes ,
136+ )
137+ MagGetWindowTransform .errcheck = _errCheck
138+
139+ _MagSetFullscreenTransformFuncType = WINFUNCTYPE (BOOL , POINTER (FLOAT ), POINTER (INT ), POINTER (INT ))
140+ _MagSetFullscreenTransformArgTypes = ((1 , "magLevel" ), (1 , "offsetX" ), (1 , "offsetY" ))
141+ MagSetFullscreenTransform = _MagSetFullscreenTransformFuncType (
142+ ("MagSetFullscreenTransform" , _magnification ),
143+ _MagSetFullscreenTransformArgTypes ,
144+ )
145+ MagSetFullscreenTransform .errcheck = _errCheck
146+
147+ _MagGetFullscreenTransformFuncType = WINFUNCTYPE (BOOL , POINTER (FLOAT ), POINTER (INT ), POINTER (INT ))
148+ _MagGetFullscreenTransformArgTypes = ((2 , "magLevel" ), (2 , "offsetX" ), (2 , "offsetY" ))
149+ MagGetFullscreenTransform = _MagGetFullscreenTransformFuncType (
150+ ("MagGetFullscreenTransform" , _magnification ),
151+ _MagGetFullscreenTransformArgTypes ,
152+ )
153+ MagGetFullscreenTransform .errcheck = _errCheck
154+
155+ # # Create transformation window
156+ # _MagGetInputTransformFuncType = WINFUNCTYPE(BOOL, POINTER(BOOL), POINTER(RECT), POINTER(RECT))
157+ # _MagGetInputTransformArgTypes = ((2, "enabled"), (2, "src"), (2, "dest"))
158+ # MagGetInputTransform = _MagGetInputTransformFuncType(
159+ # ("MagGetInputTransform", _magnification),
160+ # _MagGetInputTransformArgTypes,
161+ # )
162+ # MagGetInputTransform.errcheck = _errCheck
163+
164+ # # Create transformation window
165+ # _MagSetInputTransformFuncType = WINFUNCTYPE(BOOL, POINTER(BOOL), POINTER(RECT), POINTER(RECT))
166+ # _MagSetInputTransformArgTypes = ((1, "enabled"), (1, "src"), (1, "dest"))
167+ # MagSetInputTransform = _MagGetInputTransformFuncType(
168+ # ("MagSetInputTransform", _magnification),
169+ # _MagSetInputTransformArgTypes,
170+ # )
171+ # MagSetInputTransform.errcheck = _errCheck
95172
96173
97174# Translators: Name for a vision enhancement provider that disables output to the screen,
0 commit comments