2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Console Driver DLL
4 * FILE: win32ss/user/winsrv/consrv/condrv/conoutput.c
5 * PURPOSE: General Console Output Functions
6 * PROGRAMMERS: Jeffrey Morlan
7 * Hermes Belusca-Maito (hermes.belusca@sfr.fr)
10 /* INCLUDES *******************************************************************/
17 /* PRIVATE FUNCTIONS **********************************************************/
20 TEXTMODE_BUFFER_Initialize(OUT PCONSOLE_SCREEN_BUFFER
* Buffer
,
21 IN OUT PCONSOLE Console
,
22 IN PTEXTMODE_BUFFER_INFO TextModeInfo
);
24 GRAPHICS_BUFFER_Initialize(OUT PCONSOLE_SCREEN_BUFFER
* Buffer
,
25 IN OUT PCONSOLE Console
,
26 IN PGRAPHICS_BUFFER_INFO GraphicsInfo
);
29 TEXTMODE_BUFFER_Destroy(IN OUT PCONSOLE_SCREEN_BUFFER Buffer
);
31 GRAPHICS_BUFFER_Destroy(IN OUT PCONSOLE_SCREEN_BUFFER Buffer
);
35 CONSOLE_SCREEN_BUFFER_Initialize(OUT PCONSOLE_SCREEN_BUFFER
* Buffer
,
36 IN OUT PCONSOLE Console
,
39 if (Buffer
== NULL
|| Console
== NULL
)
40 return STATUS_INVALID_PARAMETER
;
42 *Buffer
= ConsoleAllocHeap(HEAP_ZERO_MEMORY
, max(sizeof(CONSOLE_SCREEN_BUFFER
), Size
));
43 if (*Buffer
== NULL
) return STATUS_INSUFFICIENT_RESOURCES
;
45 /* Initialize the header with the default type */
46 ConSrvInitObject(&(*Buffer
)->Header
, SCREEN_BUFFER
, Console
);
47 (*Buffer
)->Vtbl
= NULL
;
48 return STATUS_SUCCESS
;
52 CONSOLE_SCREEN_BUFFER_Destroy(IN OUT PCONSOLE_SCREEN_BUFFER Buffer
)
54 if (Buffer
->Header
.Type
== TEXTMODE_BUFFER
)
56 TEXTMODE_BUFFER_Destroy(Buffer
);
58 else if (Buffer
->Header
.Type
== GRAPHICS_BUFFER
)
60 GRAPHICS_BUFFER_Destroy(Buffer
);
62 else if (Buffer
->Header
.Type
== SCREEN_BUFFER
)
64 // TODO: Free Buffer->Data
66 /* Free the palette handle */
67 if (Buffer
->PaletteHandle
!= NULL
) DeleteObject(Buffer
->PaletteHandle
);
69 /* Free the screen buffer memory */
70 ConsoleFreeHeap(Buffer
);
76 // ConDrvCreateConsoleScreenBuffer
78 ConDrvCreateScreenBuffer(OUT PCONSOLE_SCREEN_BUFFER
* Buffer
,
79 IN OUT PCONSOLE Console
,
81 IN PVOID ScreenBufferInfo
)
83 NTSTATUS Status
= STATUS_SUCCESS
;
85 if ( Console
== NULL
|| Buffer
== NULL
||
86 (BufferType
!= CONSOLE_TEXTMODE_BUFFER
&& BufferType
!= CONSOLE_GRAPHICS_BUFFER
) )
88 return STATUS_INVALID_PARAMETER
;
91 if (BufferType
== CONSOLE_TEXTMODE_BUFFER
)
93 Status
= TEXTMODE_BUFFER_Initialize(Buffer
, Console
,
94 (PTEXTMODE_BUFFER_INFO
)ScreenBufferInfo
);
96 else if (BufferType
== CONSOLE_GRAPHICS_BUFFER
)
98 Status
= GRAPHICS_BUFFER_Initialize(Buffer
, Console
,
99 (PGRAPHICS_BUFFER_INFO
)ScreenBufferInfo
);
103 /* Never ever go there!! */
107 /* Insert the newly created screen buffer into the list, if succeeded */
108 if (NT_SUCCESS(Status
)) InsertHeadList(&Console
->BufferList
, &(*Buffer
)->ListEntry
);
114 ConioSetActiveScreenBuffer(PCONSOLE_SCREEN_BUFFER Buffer
);
117 ConioDeleteScreenBuffer(PCONSOLE_SCREEN_BUFFER Buffer
)
119 PCONSOLE Console
= Buffer
->Header
.Console
;
120 PCONSOLE_SCREEN_BUFFER NewBuffer
;
123 * We should notify temporarily the frontend because we are susceptible
124 * to delete the screen buffer it is using (which may be different from
125 * the active screen buffer in some cases), and because, if it actually
126 * uses the active screen buffer, we are going to nullify its pointer to
129 TermReleaseScreenBuffer(Console
, Buffer
);
131 RemoveEntryList(&Buffer
->ListEntry
);
132 if (Buffer
== Console
->ActiveBuffer
)
134 /* Delete active buffer; switch to most recently created */
135 if (!IsListEmpty(&Console
->BufferList
))
137 NewBuffer
= CONTAINING_RECORD(Console
->BufferList
.Flink
,
138 CONSOLE_SCREEN_BUFFER
,
141 /* Tie console to new buffer and signal the change to the frontend */
142 ConioSetActiveScreenBuffer(NewBuffer
);
146 Console
->ActiveBuffer
= NULL
;
147 // InterlockedExchangePointer(&Console->ActiveBuffer, NULL);
151 CONSOLE_SCREEN_BUFFER_Destroy(Buffer
);
155 ConioDrawConsole(PCONSOLE Console
)
158 PCONSOLE_SCREEN_BUFFER ActiveBuffer
= Console
->ActiveBuffer
;
162 ConioInitRect(&Region
, 0, 0, ActiveBuffer
->ViewSize
.Y
- 1, ActiveBuffer
->ViewSize
.X
- 1);
163 TermDrawRegion(Console
, &Region
);
168 ConioSetActiveScreenBuffer(PCONSOLE_SCREEN_BUFFER Buffer
)
170 PCONSOLE Console
= Buffer
->Header
.Console
;
171 Console
->ActiveBuffer
= Buffer
;
172 // InterlockedExchangePointer(&Console->ActiveBuffer, Buffer);
173 TermSetActiveScreenBuffer(Console
);
177 ConDrvSetConsoleActiveScreenBuffer(IN PCONSOLE Console
,
178 IN PCONSOLE_SCREEN_BUFFER Buffer
)
180 if (Console
== NULL
|| Buffer
== NULL
)
181 return STATUS_INVALID_PARAMETER
;
184 ASSERT(Console
== Buffer
->Header
.Console
);
186 if (Buffer
== Console
->ActiveBuffer
) return STATUS_SUCCESS
;
188 /* If old buffer has no handles, it's now unreferenced */
189 if (Console
->ActiveBuffer
->Header
.HandleCount
== 0)
191 ConioDeleteScreenBuffer(Console
->ActiveBuffer
);
194 /* Tie console to new buffer and signal the change to the frontend */
195 ConioSetActiveScreenBuffer(Buffer
);
197 return STATUS_SUCCESS
;
200 PCONSOLE_SCREEN_BUFFER
201 ConDrvGetActiveScreenBuffer(IN PCONSOLE Console
)
203 return (Console
? Console
->ActiveBuffer
: NULL
);
206 /* PUBLIC DRIVER APIS *********************************************************/
209 ConDrvInvalidateBitMapRect(IN PCONSOLE Console
,
210 IN PCONSOLE_SCREEN_BUFFER Buffer
,
211 IN PSMALL_RECT Region
)
213 if (Console
== NULL
|| Buffer
== NULL
|| Region
== NULL
)
214 return STATUS_INVALID_PARAMETER
;
217 ASSERT(Console
== Buffer
->Header
.Console
);
219 /* If the output buffer is the current one, redraw the correct portion of the screen */
220 if (Buffer
== Console
->ActiveBuffer
) TermDrawRegion(Console
, Region
);
222 return STATUS_SUCCESS
;
226 ConDrvSetConsolePalette(IN PCONSOLE Console
,
227 // IN PGRAPHICS_SCREEN_BUFFER Buffer,
228 IN PCONSOLE_SCREEN_BUFFER Buffer
,
229 IN HPALETTE PaletteHandle
,
230 IN UINT PaletteUsage
)
235 * Parameters validation
237 if (Console
== NULL
|| Buffer
== NULL
)
238 return STATUS_INVALID_PARAMETER
;
240 if ( PaletteUsage
!= SYSPAL_STATIC
&&
241 PaletteUsage
!= SYSPAL_NOSTATIC
&&
242 PaletteUsage
!= SYSPAL_NOSTATIC256
)
244 return STATUS_INVALID_PARAMETER
;
248 ASSERT(Console
== Buffer
->Header
.Console
);
250 /* Change the palette */
251 Success
= TermSetPalette(Console
, PaletteHandle
, PaletteUsage
);
254 /* Free the old palette handle if there was already one set */
255 if ( Buffer
->PaletteHandle
!= NULL
&&
256 Buffer
->PaletteHandle
!= PaletteHandle
)
258 DeleteObject(Buffer
->PaletteHandle
);
261 /* Save the new palette in the screen buffer */
262 Buffer
->PaletteHandle
= PaletteHandle
;
263 Buffer
->PaletteUsage
= PaletteUsage
;
266 return (Success
? STATUS_SUCCESS
: STATUS_UNSUCCESSFUL
);
270 ConDrvGetConsoleCursorInfo(IN PCONSOLE Console
,
271 IN PTEXTMODE_SCREEN_BUFFER Buffer
,
272 OUT PCONSOLE_CURSOR_INFO CursorInfo
)
274 if (Console
== NULL
|| Buffer
== NULL
|| CursorInfo
== NULL
)
275 return STATUS_INVALID_PARAMETER
;
278 ASSERT(Console
== Buffer
->Header
.Console
);
280 *CursorInfo
= Buffer
->CursorInfo
;
281 // CursorInfo->bVisible = Buffer->CursorInfo.bVisible;
282 // CursorInfo->dwSize = Buffer->CursorInfo.dwSize;
284 return STATUS_SUCCESS
;
288 ConDrvSetConsoleCursorInfo(IN PCONSOLE Console
,
289 IN PTEXTMODE_SCREEN_BUFFER Buffer
,
290 IN PCONSOLE_CURSOR_INFO CursorInfo
)
293 BOOLEAN Visible
, Success
= TRUE
;
295 if (Console
== NULL
|| Buffer
== NULL
|| CursorInfo
== NULL
)
296 return STATUS_INVALID_PARAMETER
;
299 ASSERT(Console
== Buffer
->Header
.Console
);
301 Size
= min(max(CursorInfo
->dwSize
, 1), 100);
302 Visible
= CursorInfo
->bVisible
;
304 if ( (Size
!= Buffer
->CursorInfo
.dwSize
) ||
305 (Visible
&& !Buffer
->CursorInfo
.bVisible
) ||
306 (!Visible
&& Buffer
->CursorInfo
.bVisible
) )
308 Buffer
->CursorInfo
.dwSize
= Size
;
309 Buffer
->CursorInfo
.bVisible
= Visible
;
311 Success
= TermSetCursorInfo(Console
, (PCONSOLE_SCREEN_BUFFER
)Buffer
);
314 return (Success
? STATUS_SUCCESS
: STATUS_UNSUCCESSFUL
);
318 ConDrvSetConsoleCursorPosition(IN PCONSOLE Console
,
319 IN PTEXTMODE_SCREEN_BUFFER Buffer
,
322 SHORT OldCursorX
, OldCursorY
;
324 if (Console
== NULL
|| Buffer
== NULL
|| Position
== NULL
)
325 return STATUS_INVALID_PARAMETER
;
328 ASSERT(Console
== Buffer
->Header
.Console
);
330 if ( Position
->X
< 0 || Position
->X
>= Buffer
->ScreenBufferSize
.X
||
331 Position
->Y
< 0 || Position
->Y
>= Buffer
->ScreenBufferSize
.Y
)
333 return STATUS_INVALID_PARAMETER
;
336 OldCursorX
= Buffer
->CursorPosition
.X
;
337 OldCursorY
= Buffer
->CursorPosition
.Y
;
338 Buffer
->CursorPosition
= *Position
;
339 // Buffer->CursorPosition.X = Position->X;
340 // Buffer->CursorPosition.Y = Position->Y;
341 if ( ((PCONSOLE_SCREEN_BUFFER
)Buffer
== Console
->ActiveBuffer
) &&
342 (!TermSetScreenInfo(Console
, (PCONSOLE_SCREEN_BUFFER
)Buffer
, OldCursorX
, OldCursorY
)) )
344 return STATUS_UNSUCCESSFUL
;
347 return STATUS_SUCCESS
;