@@ -47,24 +47,30 @@ module System.Win32.Console (
47
47
commandLineToArgv ,
48
48
-- * Screen buffer
49
49
CONSOLE_SCREEN_BUFFER_INFO (.. ),
50
+ CONSOLE_SCREEN_BUFFER_INFOEX (.. ),
50
51
COORD (.. ),
51
52
SMALL_RECT (.. ),
53
+ COLORREF ,
52
54
getConsoleScreenBufferInfo ,
53
- getCurrentConsoleScreenBufferInfo
55
+ getCurrentConsoleScreenBufferInfo ,
56
+ getConsoleScreenBufferInfoEx ,
57
+ getCurrentConsoleScreenBufferInfoEx
54
58
) where
55
59
56
60
#include <windows.h>
57
61
#include "alignment.h"
58
62
##include "windows_cconv.h"
63
+ #include "wincon_compat.h"
59
64
60
65
import System.Win32.Types
61
66
import Graphics.Win32.Misc
67
+ import Graphics.Win32.GDI.Types (COLORREF )
62
68
63
69
import Foreign.C.Types (CInt (.. ))
64
70
import Foreign.C.String (withCWString , CWString )
65
- import Foreign.Ptr (Ptr )
71
+ import Foreign.Ptr (Ptr , plusPtr )
66
72
import Foreign.Storable (Storable (.. ))
67
- import Foreign.Marshal.Array (peekArray )
73
+ import Foreign.Marshal.Array (peekArray , pokeArray )
68
74
import Foreign.Marshal.Alloc (alloca )
69
75
70
76
foreign import WINDOWS_CCONV unsafe " windows.h GetConsoleMode"
@@ -169,6 +175,50 @@ instance Storable CONSOLE_SCREEN_BUFFER_INFO where
169
175
(# poke CONSOLE_SCREEN_BUFFER_INFO , srWindow) buf (srWindow info)
170
176
(# poke CONSOLE_SCREEN_BUFFER_INFO , dwMaximumWindowSize) buf (dwMaximumWindowSize info)
171
177
178
+ data CONSOLE_SCREEN_BUFFER_INFOEX = CONSOLE_SCREEN_BUFFER_INFOEX
179
+ { dwSizeEx :: COORD
180
+ , dwCursorPositionEx :: COORD
181
+ , wAttributesEx :: WORD
182
+ , srWindowEx :: SMALL_RECT
183
+ , dwMaximumWindowSizeEx :: COORD
184
+ , wPopupAttributes :: WORD
185
+ , bFullscreenSupported :: BOOL
186
+ , colorTable :: [COLORREF ]
187
+ -- ^ Only the first 16 'COLORREF' values passed to the Windows Console
188
+ -- API. If fewer than 16 values, the remainder are padded with @0@ when
189
+ -- passed to the API.
190
+ } deriving (Show , Eq )
191
+
192
+ instance Storable CONSOLE_SCREEN_BUFFER_INFOEX where
193
+ sizeOf = const # {size CONSOLE_SCREEN_BUFFER_INFOEX }
194
+ alignment = const # {alignment CONSOLE_SCREEN_BUFFER_INFOEX }
195
+ peek buf = do
196
+ dwSize' <- (# peek CONSOLE_SCREEN_BUFFER_INFOEX , dwSize) buf
197
+ dwCursorPosition' <- (# peek CONSOLE_SCREEN_BUFFER_INFOEX , dwCursorPosition) buf
198
+ wAttributes' <- (# peek CONSOLE_SCREEN_BUFFER_INFOEX , wAttributes) buf
199
+ srWindow' <- (# peek CONSOLE_SCREEN_BUFFER_INFOEX , srWindow) buf
200
+ dwMaximumWindowSize' <- (# peek CONSOLE_SCREEN_BUFFER_INFOEX , dwMaximumWindowSize) buf
201
+ wPopupAttributes' <- (# peek CONSOLE_SCREEN_BUFFER_INFOEX , wPopupAttributes) buf
202
+ bFullscreenSupported' <- (# peek CONSOLE_SCREEN_BUFFER_INFOEX , bFullscreenSupported) buf
203
+ colorTable' <- peekArray 16 ((# ptr CONSOLE_SCREEN_BUFFER_INFOEX , ColorTable ) buf)
204
+ return $ CONSOLE_SCREEN_BUFFER_INFOEX dwSize' dwCursorPosition'
205
+ wAttributes' srWindow' dwMaximumWindowSize' wPopupAttributes'
206
+ bFullscreenSupported' colorTable'
207
+ poke buf info = do
208
+ (# poke CONSOLE_SCREEN_BUFFER_INFOEX , cbSize) buf cbSize
209
+ (# poke CONSOLE_SCREEN_BUFFER_INFOEX , dwSize) buf (dwSizeEx info)
210
+ (# poke CONSOLE_SCREEN_BUFFER_INFOEX , dwCursorPosition) buf (dwCursorPositionEx info)
211
+ (# poke CONSOLE_SCREEN_BUFFER_INFOEX , wAttributes) buf (wAttributesEx info)
212
+ (# poke CONSOLE_SCREEN_BUFFER_INFOEX , srWindow) buf (srWindowEx info)
213
+ (# poke CONSOLE_SCREEN_BUFFER_INFOEX , dwMaximumWindowSize) buf (dwMaximumWindowSizeEx info)
214
+ (# poke CONSOLE_SCREEN_BUFFER_INFOEX , wPopupAttributes) buf (wPopupAttributes info)
215
+ (# poke CONSOLE_SCREEN_BUFFER_INFOEX , bFullscreenSupported) buf (bFullscreenSupported info)
216
+ pokeArray ((# ptr CONSOLE_SCREEN_BUFFER_INFOEX , ColorTable ) buf) colorTable'
217
+ where
218
+ cbSize :: ULONG
219
+ cbSize = # {size CONSOLE_SCREEN_BUFFER_INFOEX }
220
+ colorTable' = take 16 $ colorTable info ++ repeat 0
221
+
172
222
data COORD = COORD
173
223
{ xPos :: SHORT
174
224
, yPos :: SHORT
@@ -210,6 +260,9 @@ instance Storable SMALL_RECT where
210
260
foreign import WINDOWS_CCONV safe " windows.h GetConsoleScreenBufferInfo"
211
261
c_GetConsoleScreenBufferInfo :: HANDLE -> Ptr CONSOLE_SCREEN_BUFFER_INFO -> IO BOOL
212
262
263
+ foreign import WINDOWS_CCONV safe " windows.h GetConsoleScreenBufferInfoEx"
264
+ c_GetConsoleScreenBufferInfoEx :: HANDLE -> Ptr CONSOLE_SCREEN_BUFFER_INFOEX -> IO BOOL
265
+
213
266
getConsoleScreenBufferInfo :: HANDLE -> IO CONSOLE_SCREEN_BUFFER_INFO
214
267
getConsoleScreenBufferInfo h = alloca $ \ ptr -> do
215
268
failIfFalse_ " GetConsoleScreenBufferInfo" $ c_GetConsoleScreenBufferInfo h ptr
@@ -219,3 +272,19 @@ getCurrentConsoleScreenBufferInfo :: IO CONSOLE_SCREEN_BUFFER_INFO
219
272
getCurrentConsoleScreenBufferInfo = do
220
273
h <- failIf (== nullHANDLE) " getStdHandle" $ getStdHandle sTD_OUTPUT_HANDLE
221
274
getConsoleScreenBufferInfo h
275
+
276
+ getConsoleScreenBufferInfoEx :: HANDLE -> IO CONSOLE_SCREEN_BUFFER_INFOEX
277
+ getConsoleScreenBufferInfoEx h = alloca $ \ ptr -> do
278
+ -- The cbSize member must be set or GetConsoleScreenBufferInfoEx fails with
279
+ -- ERROR_INVALID_PARAMETER (87).
280
+ (# poke CONSOLE_SCREEN_BUFFER_INFOEX , cbSize) ptr cbSize
281
+ failIfFalse_ " GetConsoleScreenBufferInfoEx" $ c_GetConsoleScreenBufferInfoEx h ptr
282
+ peek ptr
283
+ where
284
+ cbSize :: ULONG
285
+ cbSize = # {size CONSOLE_SCREEN_BUFFER_INFOEX }
286
+
287
+ getCurrentConsoleScreenBufferInfoEx :: IO CONSOLE_SCREEN_BUFFER_INFOEX
288
+ getCurrentConsoleScreenBufferInfoEx = do
289
+ h <- failIf (== nullHANDLE) " getStdHandle" $ getStdHandle sTD_OUTPUT_HANDLE
290
+ getConsoleScreenBufferInfoEx h
0 commit comments