Salome HOME
style: black format
[tools/sat.git] / src / colorama / win32.py
1 # Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file.
2
3 # from winbase.h
4 STDOUT = -11
5 STDERR = -12
6
7 try:
8     import ctypes
9     from ctypes import LibraryLoader
10
11     windll = LibraryLoader(ctypes.WinDLL)
12     from ctypes import wintypes
13 except (AttributeError, ImportError):
14     windll = None
15     SetConsoleTextAttribute = lambda *_: None
16     winapi_test = lambda *_: None
17 else:
18     from ctypes import byref, Structure, c_char, POINTER
19
20     COORD = wintypes._COORD
21
22     class CONSOLE_SCREEN_BUFFER_INFO(Structure):
23         """struct in wincon.h."""
24
25         _fields_ = [
26             ("dwSize", COORD),
27             ("dwCursorPosition", COORD),
28             ("wAttributes", wintypes.WORD),
29             ("srWindow", wintypes.SMALL_RECT),
30             ("dwMaximumWindowSize", COORD),
31         ]
32
33         def __str__(self):
34             return "(%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d)" % (
35                 self.dwSize.Y,
36                 self.dwSize.X,
37                 self.dwCursorPosition.Y,
38                 self.dwCursorPosition.X,
39                 self.wAttributes,
40                 self.srWindow.Top,
41                 self.srWindow.Left,
42                 self.srWindow.Bottom,
43                 self.srWindow.Right,
44                 self.dwMaximumWindowSize.Y,
45                 self.dwMaximumWindowSize.X,
46             )
47
48     _GetStdHandle = windll.kernel32.GetStdHandle
49     _GetStdHandle.argtypes = [
50         wintypes.DWORD,
51     ]
52     _GetStdHandle.restype = wintypes.HANDLE
53
54     _GetConsoleScreenBufferInfo = windll.kernel32.GetConsoleScreenBufferInfo
55     _GetConsoleScreenBufferInfo.argtypes = [
56         wintypes.HANDLE,
57         POINTER(CONSOLE_SCREEN_BUFFER_INFO),
58     ]
59     _GetConsoleScreenBufferInfo.restype = wintypes.BOOL
60
61     _SetConsoleTextAttribute = windll.kernel32.SetConsoleTextAttribute
62     _SetConsoleTextAttribute.argtypes = [
63         wintypes.HANDLE,
64         wintypes.WORD,
65     ]
66     _SetConsoleTextAttribute.restype = wintypes.BOOL
67
68     _SetConsoleCursorPosition = windll.kernel32.SetConsoleCursorPosition
69     _SetConsoleCursorPosition.argtypes = [
70         wintypes.HANDLE,
71         COORD,
72     ]
73     _SetConsoleCursorPosition.restype = wintypes.BOOL
74
75     _FillConsoleOutputCharacterA = windll.kernel32.FillConsoleOutputCharacterA
76     _FillConsoleOutputCharacterA.argtypes = [
77         wintypes.HANDLE,
78         c_char,
79         wintypes.DWORD,
80         COORD,
81         POINTER(wintypes.DWORD),
82     ]
83     _FillConsoleOutputCharacterA.restype = wintypes.BOOL
84
85     _FillConsoleOutputAttribute = windll.kernel32.FillConsoleOutputAttribute
86     _FillConsoleOutputAttribute.argtypes = [
87         wintypes.HANDLE,
88         wintypes.WORD,
89         wintypes.DWORD,
90         COORD,
91         POINTER(wintypes.DWORD),
92     ]
93     _FillConsoleOutputAttribute.restype = wintypes.BOOL
94
95     _SetConsoleTitleW = windll.kernel32.SetConsoleTitleA
96     _SetConsoleTitleW.argtypes = [wintypes.LPCSTR]
97     _SetConsoleTitleW.restype = wintypes.BOOL
98
99     handles = {
100         STDOUT: _GetStdHandle(STDOUT),
101         STDERR: _GetStdHandle(STDERR),
102     }
103
104     def winapi_test():
105         handle = handles[STDOUT]
106         csbi = CONSOLE_SCREEN_BUFFER_INFO()
107         success = _GetConsoleScreenBufferInfo(handle, byref(csbi))
108         return bool(success)
109
110     def GetConsoleScreenBufferInfo(stream_id=STDOUT):
111         handle = handles[stream_id]
112         csbi = CONSOLE_SCREEN_BUFFER_INFO()
113         success = _GetConsoleScreenBufferInfo(handle, byref(csbi))
114         return csbi
115
116     def SetConsoleTextAttribute(stream_id, attrs):
117         handle = handles[stream_id]
118         return _SetConsoleTextAttribute(handle, attrs)
119
120     def SetConsoleCursorPosition(stream_id, position, adjust=True):
121         position = COORD(*position)
122         # If the position is out of range, do nothing.
123         if position.Y <= 0 or position.X <= 0:
124             return
125         # Adjust for Windows' SetConsoleCursorPosition:
126         #    1. being 0-based, while ANSI is 1-based.
127         #    2. expecting (x,y), while ANSI uses (y,x).
128         adjusted_position = COORD(position.Y - 1, position.X - 1)
129         if adjust:
130             # Adjust for viewport's scroll position
131             sr = GetConsoleScreenBufferInfo(STDOUT).srWindow
132             adjusted_position.Y += sr.Top
133             adjusted_position.X += sr.Left
134         # Resume normal processing
135         handle = handles[stream_id]
136         return _SetConsoleCursorPosition(handle, adjusted_position)
137
138     def FillConsoleOutputCharacter(stream_id, char, length, start):
139         handle = handles[stream_id]
140         char = c_char(char.encode())
141         length = wintypes.DWORD(length)
142         num_written = wintypes.DWORD(0)
143         # Note that this is hard-coded for ANSI (vs wide) bytes.
144         success = _FillConsoleOutputCharacterA(
145             handle, char, length, start, byref(num_written)
146         )
147         return num_written.value
148
149     def FillConsoleOutputAttribute(stream_id, attr, length, start):
150         """FillConsoleOutputAttribute( hConsole, csbi.wAttributes, dwConSize, coordScreen, &cCharsWritten )"""
151         handle = handles[stream_id]
152         attribute = wintypes.WORD(attr)
153         length = wintypes.DWORD(length)
154         num_written = wintypes.DWORD(0)
155         # Note that this is hard-coded for ANSI (vs wide) bytes.
156         return _FillConsoleOutputAttribute(
157             handle, attribute, length, start, byref(num_written)
158         )
159
160     def SetConsoleTitle(title):
161         return _SetConsoleTitleW(title)