1 /*
2  * COPYRIGHT:       See COPYING in the top level directory
3  * PROJECT:         ReactOS Console Server DLL
4  * FILE:            win32ss/user/winsrv/consrv/frontendctl.c
5  * PURPOSE:         Terminal Front-Ends Control
6  * PROGRAMMERS:     Hermes Belusca-Maito (hermes.belusca@sfr.fr)
7  */
8 
9 /* INCLUDES *******************************************************************/
10 
11 #include "consrv.h"
12 
13 #define NDEBUG
14 #include <debug.h>
15 
16 /* PUBLIC SERVER APIS *********************************************************/
17 
18 /**********************************************************************
19  *  HardwareStateProperty
20  *
21  *  DESCRIPTION
22  *      Set/Get the value of the HardwareState and switch
23  *      between direct video buffer ouput and GDI windowed
24  *      output.
25  *  ARGUMENTS
26  *      Client hands us a CONSOLE_GETSETHWSTATE object.
27  *      We use the same object to Request.
28  *  NOTE
29  *      ConsoleHwState has the correct size to be compatible
30  *      with NT's, but values are not.
31  */
32 #if 0
33 static NTSTATUS
34 SetConsoleHardwareState(PCONSRV_CONSOLE Console, ULONG ConsoleHwState)
35 {
36     DPRINT1("Console Hardware State: %d\n", ConsoleHwState);
37 
38     if ((CONSOLE_HARDWARE_STATE_GDI_MANAGED == ConsoleHwState)
39             ||(CONSOLE_HARDWARE_STATE_DIRECT == ConsoleHwState))
40     {
41         if (Console->HardwareState != ConsoleHwState)
42         {
43             /* TODO: implement switching from full screen to windowed mode */
44             /* TODO: or back; now simply store the hardware state */
45             Console->HardwareState = ConsoleHwState;
46         }
47 
48         return STATUS_SUCCESS;
49     }
50 
51     return STATUS_INVALID_PARAMETER_3; /* Client: (handle, set_get, [mode]) */
52 }
53 #endif
54 
55 CSR_API(SrvGetConsoleHardwareState)
56 {
57 #if 0
58     NTSTATUS Status;
59     PCONSOLE_GETSETHWSTATE HardwareStateRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.HardwareStateRequest;
60     PCONSOLE_SCREEN_BUFFER Buff;
61     PCONSRV_CONSOLE Console;
62 
63     Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
64                                    HardwareStateRequest->OutputHandle,
65                                    &Buff,
66                                    GENERIC_READ,
67                                    TRUE);
68     if (!NT_SUCCESS(Status))
69     {
70         DPRINT1("Failed to get console handle in SrvGetConsoleHardwareState\n");
71         return Status;
72     }
73 
74     Console = Buff->Header.Console;
75     HardwareStateRequest->State = Console->HardwareState;
76 
77     ConSrvReleaseScreenBuffer(Buff, TRUE);
78     return Status;
79 #else
80     UNIMPLEMENTED;
81     return STATUS_NOT_IMPLEMENTED;
82 #endif
83 }
84 
85 CSR_API(SrvSetConsoleHardwareState)
86 {
87 #if 0
88     NTSTATUS Status;
89     PCONSOLE_GETSETHWSTATE HardwareStateRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.HardwareStateRequest;
90     PCONSOLE_SCREEN_BUFFER Buff;
91     PCONSRV_CONSOLE Console;
92 
93     Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
94                                    HardwareStateRequest->OutputHandle,
95                                    &Buff,
96                                    GENERIC_WRITE,
97                                    TRUE);
98     if (!NT_SUCCESS(Status))
99     {
100         DPRINT1("Failed to get console handle in SrvSetConsoleHardwareState\n");
101         return Status;
102     }
103 
104     DPRINT("Setting console hardware state.\n");
105     Console = Buff->Header.Console;
106     Status = SetConsoleHardwareState(Console, HardwareStateRequest->State);
107 
108     ConSrvReleaseScreenBuffer(Buff, TRUE);
109     return Status;
110 #else
111     UNIMPLEMENTED;
112     return STATUS_NOT_IMPLEMENTED;
113 #endif
114 }
115 
116 CSR_API(SrvGetConsoleDisplayMode)
117 {
118     NTSTATUS Status;
119     PCONSOLE_GETDISPLAYMODE GetDisplayModeRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetDisplayModeRequest;
120     PCONSRV_CONSOLE Console;
121 
122     Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
123                               &Console, TRUE);
124     if (!NT_SUCCESS(Status)) return Status;
125 
126     GetDisplayModeRequest->DisplayMode = TermGetDisplayMode(Console);
127 
128     ConSrvReleaseConsole(Console, TRUE);
129     return STATUS_SUCCESS;
130 }
131 
132 CSR_API(SrvSetConsoleDisplayMode)
133 {
134     NTSTATUS Status;
135     PCONSOLE_SETDISPLAYMODE SetDisplayModeRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.SetDisplayModeRequest;
136     PCONSRV_CONSOLE Console;
137     PCONSOLE_SCREEN_BUFFER Buff;
138 
139     Status = ConSrvGetScreenBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
140                                    SetDisplayModeRequest->OutputHandle,
141                                    &Buff,
142                                    GENERIC_WRITE,
143                                    TRUE);
144     if (!NT_SUCCESS(Status)) return Status;
145 
146     Console = (PCONSRV_CONSOLE)Buff->Header.Console;
147 
148     if (TermSetDisplayMode(Console, SetDisplayModeRequest->DisplayMode))
149     {
150         SetDisplayModeRequest->NewSBDim = Buff->ScreenBufferSize;
151         Status = STATUS_SUCCESS;
152     }
153     else
154     {
155         Status = STATUS_INVALID_PARAMETER;
156     }
157 
158     ConSrvReleaseScreenBuffer(Buff, TRUE);
159     return Status;
160 }
161 
162 CSR_API(SrvGetLargestConsoleWindowSize)
163 {
164     NTSTATUS Status;
165     PCONSOLE_GETLARGESTWINDOWSIZE GetLargestWindowSizeRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetLargestWindowSizeRequest;
166     PCONSOLE /*PCONSRV_CONSOLE*/ Console;
167     PCONSOLE_SCREEN_BUFFER Buff;
168 
169     Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
170                                      GetLargestWindowSizeRequest->OutputHandle,
171                                      &Buff,
172                                      GENERIC_READ,
173                                      TRUE);
174     if (!NT_SUCCESS(Status)) return Status;
175 
176     Console = Buff->Header.Console;
177 
178     /*
179      * Retrieve the largest possible console window size, without
180      * taking into account the size of the console screen buffer
181      * (thus differs from ConDrvGetConsoleScreenBufferInfo).
182      */
183     TermGetLargestConsoleWindowSize(Console, &GetLargestWindowSizeRequest->Size);
184 
185     ConSrvReleaseScreenBuffer(Buff, TRUE);
186     return STATUS_SUCCESS;
187 }
188 
189 CSR_API(SrvShowConsoleCursor)
190 {
191     NTSTATUS Status;
192     PCONSOLE_SHOWCURSOR ShowCursorRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ShowCursorRequest;
193     PCONSOLE /*PCONSRV_CONSOLE*/ Console;
194     PCONSOLE_SCREEN_BUFFER Buff;
195 
196     Status = ConSrvGetScreenBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
197                                    ShowCursorRequest->OutputHandle,
198                                    &Buff,
199                                    GENERIC_WRITE,
200                                    TRUE);
201     if (!NT_SUCCESS(Status)) return Status;
202 
203     Console = Buff->Header.Console;
204 
205     ShowCursorRequest->RefCount = TermShowMouseCursor(Console, ShowCursorRequest->Show);
206 
207     ConSrvReleaseScreenBuffer(Buff, TRUE);
208     return STATUS_SUCCESS;
209 }
210 
211 CSR_API(SrvSetConsoleCursor)
212 {
213     NTSTATUS Status;
214     BOOL Success;
215     PCONSOLE_SETCURSOR SetCursorRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.SetCursorRequest;
216     PCONSRV_CONSOLE Console;
217     PCONSOLE_SCREEN_BUFFER Buff;
218 
219     // NOTE: Tests show that this function is used only for graphics screen buffers
220     // and otherwise it returns FALSE and sets last error to ERROR_INVALID_HANDLE.
221     // I find that behaviour is ridiculous but ok, let's accept it at the moment...
222     Status = ConSrvGetGraphicsBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
223                                      SetCursorRequest->OutputHandle,
224                                      &Buff,
225                                      GENERIC_WRITE,
226                                      TRUE);
227     if (!NT_SUCCESS(Status)) return Status;
228 
229     Console = (PCONSRV_CONSOLE)Buff->Header.Console;
230 
231     Success = TermSetMouseCursor(Console, SetCursorRequest->CursorHandle);
232 
233     ConSrvReleaseScreenBuffer(Buff, TRUE);
234     return (Success ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL);
235 }
236 
237 CSR_API(SrvConsoleMenuControl)
238 {
239     NTSTATUS Status;
240     PCONSOLE_MENUCONTROL MenuControlRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.MenuControlRequest;
241     PCONSRV_CONSOLE Console;
242     PCONSOLE_SCREEN_BUFFER Buff;
243 
244     Status = ConSrvGetScreenBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
245                                    MenuControlRequest->OutputHandle,
246                                    &Buff,
247                                    GENERIC_WRITE,
248                                    TRUE);
249     if (!NT_SUCCESS(Status)) return Status;
250 
251     Console = (PCONSRV_CONSOLE)Buff->Header.Console;
252 
253     MenuControlRequest->MenuHandle = TermMenuControl(Console,
254                                                      MenuControlRequest->CmdIdLow,
255                                                      MenuControlRequest->CmdIdHigh);
256 
257     ConSrvReleaseScreenBuffer(Buff, TRUE);
258     return STATUS_SUCCESS;
259 }
260 
261 CSR_API(SrvSetConsoleMenuClose)
262 {
263     NTSTATUS Status;
264     BOOL Success;
265     PCONSOLE_SETMENUCLOSE SetMenuCloseRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.SetMenuCloseRequest;
266     PCONSRV_CONSOLE Console;
267 
268     Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
269                               &Console, TRUE);
270     if (!NT_SUCCESS(Status)) return Status;
271 
272     Success = TermSetMenuClose(Console, SetMenuCloseRequest->Enable);
273 
274     ConSrvReleaseConsole(Console, TRUE);
275     return (Success ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL);
276 }
277 
278 CSR_API(SrvGetConsoleWindow)
279 {
280     NTSTATUS Status;
281     PCONSOLE_GETWINDOW GetWindowRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetWindowRequest;
282     PCONSRV_CONSOLE Console;
283 
284     Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
285                               &Console, TRUE);
286     if (!NT_SUCCESS(Status)) return Status;
287 
288     GetWindowRequest->WindowHandle = TermGetConsoleWindowHandle(Console);
289 
290     ConSrvReleaseConsole(Console, TRUE);
291     return STATUS_SUCCESS;
292 }
293 
294 CSR_API(SrvSetConsoleIcon)
295 {
296     NTSTATUS Status;
297     PCONSOLE_SETICON SetIconRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.SetIconRequest;
298     PCONSRV_CONSOLE Console;
299 
300     Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
301                               &Console, TRUE);
302     if (!NT_SUCCESS(Status)) return Status;
303 
304     Status = (TermChangeIcon(Console, SetIconRequest->IconHandle)
305                 ? STATUS_SUCCESS
306                 : STATUS_UNSUCCESSFUL);
307 
308     ConSrvReleaseConsole(Console, TRUE);
309     return Status;
310 }
311 
312 CSR_API(SrvGetConsoleSelectionInfo)
313 {
314     NTSTATUS Status;
315     PCONSOLE_GETSELECTIONINFO GetSelectionInfoRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetSelectionInfoRequest;
316     PCONSRV_CONSOLE Console;
317 
318     Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
319                               &Console, TRUE);
320     if (!NT_SUCCESS(Status)) return Status;
321 
322     Status = (TermGetSelectionInfo(Console, &GetSelectionInfoRequest->Info)
323                 ? STATUS_SUCCESS
324                 : STATUS_UNSUCCESSFUL);
325 
326     ConSrvReleaseConsole(Console, TRUE);
327     return Status;
328 }
329 
330 
331 
332 CSR_API(SrvGetConsoleNumberOfFonts)
333 {
334     NTSTATUS Status;
335     PCONSOLE_GETNUMFONTS GetNumFontsRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetNumFontsRequest;
336     PCONSOLE /*PCONSRV_CONSOLE*/ Console;
337 
338     Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
339                               &Console, TRUE);
340     if (!NT_SUCCESS(Status)) return Status;
341 
342     // FIXME!
343     // TermGetNumberOfFonts(Console, ...);
344     DPRINT1("%s not yet implemented\n", __FUNCTION__);
345     GetNumFontsRequest->NumFonts = 0;
346 
347     ConSrvReleaseConsole(Console, TRUE);
348     return STATUS_SUCCESS;
349 }
350 
351 CSR_API(SrvGetConsoleFontInfo)
352 {
353     NTSTATUS Status;
354     PCONSOLE_GETFONTINFO GetFontInfoRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetFontInfoRequest;
355     // PCONSOLE /*PCONSRV_CONSOLE*/ Console;
356     PCONSOLE_SCREEN_BUFFER Buff;
357 
358     Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
359                                      GetFontInfoRequest->OutputHandle,
360                                      &Buff,
361                                      GENERIC_READ,
362                                      TRUE);
363     if (!NT_SUCCESS(Status)) return Status;
364 
365     // FIXME!
366     // Console = Buff->Header.Console;
367     // TermGetFontInfo(Console, ...);
368     DPRINT1("%s not yet implemented\n", __FUNCTION__);
369     GetFontInfoRequest->NumFonts = 0;
370 
371     ConSrvReleaseScreenBuffer(Buff, TRUE);
372     return STATUS_SUCCESS;
373 }
374 
375 CSR_API(SrvGetConsoleFontSize)
376 {
377     NTSTATUS Status;
378     PCONSOLE_GETFONTSIZE GetFontSizeRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetFontSizeRequest;
379     // PCONSOLE /*PCONSRV_CONSOLE*/ Console;
380     PCONSOLE_SCREEN_BUFFER Buff;
381 
382     Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
383                                      GetFontSizeRequest->OutputHandle,
384                                      &Buff,
385                                      GENERIC_READ,
386                                      TRUE);
387     if (!NT_SUCCESS(Status)) return Status;
388 
389     // FIXME!
390     // Console = Buff->Header.Console;
391     // TermGetFontSize(Console, ...);
392     DPRINT1("%s not yet implemented\n", __FUNCTION__);
393 
394     ConSrvReleaseScreenBuffer(Buff, TRUE);
395     return STATUS_SUCCESS;
396 }
397 
398 CSR_API(SrvGetConsoleCurrentFont)
399 {
400     NTSTATUS Status;
401     PCONSOLE_GETCURRENTFONT GetCurrentFontRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetCurrentFontRequest;
402     // PCONSOLE /*PCONSRV_CONSOLE*/ Console;
403     PCONSOLE_SCREEN_BUFFER Buff;
404 
405     Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
406                                      GetCurrentFontRequest->OutputHandle,
407                                      &Buff,
408                                      GENERIC_READ,
409                                      TRUE);
410     if (!NT_SUCCESS(Status)) return Status;
411 
412     // FIXME!
413     // Console = Buff->Header.Console;
414     // TermGetCurrentFont(Console, ...);
415     DPRINT1("%s not yet implemented\n", __FUNCTION__);
416     GetCurrentFontRequest->FontIndex = 0;
417 
418     ConSrvReleaseScreenBuffer(Buff, TRUE);
419     return STATUS_SUCCESS;
420 }
421 
422 CSR_API(SrvSetConsoleFont)
423 {
424     NTSTATUS Status;
425     PCONSOLE_SETFONT SetFontRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.SetFontRequest;
426     // PCONSOLE /*PCONSRV_CONSOLE*/ Console;
427     PCONSOLE_SCREEN_BUFFER Buff;
428 
429     Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
430                                      SetFontRequest->OutputHandle,
431                                      &Buff,
432                                      GENERIC_WRITE,
433                                      TRUE);
434     if (!NT_SUCCESS(Status)) return Status;
435 
436     // FIXME!
437     // Console = Buff->Header.Console;
438     // TermSetFont(Console, ...);
439     DPRINT1("%s not yet implemented\n", __FUNCTION__);
440 
441     ConSrvReleaseScreenBuffer(Buff, TRUE);
442     return STATUS_SUCCESS;
443 }
444 
445 /* EOF */
446