ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

tuiconsole.c
Go to the documentation of this file.
00001 /* $Id: tuiconsole.c 47693 2010-06-08 06:38:14Z jmorlan $
00002  *
00003  * COPYRIGHT:       See COPYING in the top level directory
00004  * PROJECT:         ReactOS system libraries
00005  * FILE:            subsys/csrss/win32csr/tuiconsole.c
00006  * PURPOSE:         Implementation of text-mode consoles
00007  */
00008 
00009 #define NDEBUG
00010 #include "w32csr.h"
00011 #include <debug.h>
00012 
00013 CRITICAL_SECTION ActiveConsoleLock;
00014 static COORD PhysicalConsoleSize;
00015 static HANDLE ConsoleDeviceHandle;
00016 static PCSRSS_CONSOLE ActiveConsole;
00017 
00018 static BOOL ConsInitialized = FALSE;
00019 
00020 static LRESULT CALLBACK
00021 TuiConsoleWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
00022 {
00023     if (msg == WM_ACTIVATE)
00024     {
00025         if (LOWORD(wParam) != WA_INACTIVE)
00026         {
00027             SetFocus(hWnd);
00028             ConioDrawConsole(ActiveConsole);
00029         }
00030     }
00031     return DefWindowProcW(hWnd, msg, wParam, lParam);
00032 }
00033 
00034 static BOOL FASTCALL
00035 TuiStartService(LPCWSTR lpServiceName)
00036 {
00037     SC_HANDLE hSCManager = NULL;
00038     SC_HANDLE hService = NULL;
00039     BOOL ret = FALSE;
00040 
00041     hSCManager = OpenSCManagerW(NULL, NULL, 0);
00042     if (hSCManager == NULL)
00043         goto cleanup;
00044 
00045     hService = OpenServiceW(hSCManager, lpServiceName, SERVICE_START);
00046     if (hService == NULL)
00047         goto cleanup;
00048 
00049     ret = StartServiceW(hService, 0, NULL);
00050     if (!ret)
00051         goto cleanup;
00052 
00053     ret = TRUE;
00054 
00055 cleanup:
00056     if (hSCManager != NULL)
00057         CloseServiceHandle(hSCManager);
00058     if (hService != NULL)
00059         CloseServiceHandle(hService);
00060     return ret;
00061 }
00062 
00063 static BOOL FASTCALL
00064 TuiInit(DWORD OemCP)
00065 {
00066     CONSOLE_SCREEN_BUFFER_INFO ScrInfo;
00067     DWORD BytesReturned;
00068     WNDCLASSEXW wc;
00069     USHORT TextAttribute = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED;
00070 
00071     TuiStartService(L"Blue");
00072 
00073     ConsoleDeviceHandle = CreateFileW(L"\\\\.\\BlueScreen", FILE_ALL_ACCESS, 0, NULL,
00074                                       OPEN_EXISTING, 0, NULL);
00075     if (INVALID_HANDLE_VALUE == ConsoleDeviceHandle)
00076     {
00077         DPRINT1("Failed to open BlueScreen.\n");
00078         return FALSE;
00079     }
00080 
00081     if (!DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_LOADFONT,
00082                          &OemCP, sizeof(OemCP), NULL, 0,
00083                          &BytesReturned, NULL))
00084     {
00085         DPRINT1("Failed to load the font for codepage %d\n", OemCP);
00086         /* Let's suppose the font is good enough to continue */
00087     }
00088 
00089     if (!DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_SET_TEXT_ATTRIBUTE,
00090                          &TextAttribute, sizeof(TextAttribute), NULL, 0,
00091                          &BytesReturned, NULL))
00092     {
00093         DPRINT1("Failed to set text attribute\n");
00094     }
00095 
00096     ActiveConsole = NULL;
00097     InitializeCriticalSection(&ActiveConsoleLock);
00098     if (! DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_GET_SCREEN_BUFFER_INFO,
00099                           NULL, 0, &ScrInfo, sizeof(ScrInfo), &BytesReturned, NULL))
00100     {
00101         DPRINT1("Failed to get console info\n");
00102         return FALSE;
00103     }
00104     PhysicalConsoleSize = ScrInfo.dwSize;
00105 
00106     RtlZeroMemory(&wc, sizeof(WNDCLASSEXW));
00107     wc.cbSize = sizeof(WNDCLASSEXW);
00108     wc.lpszClassName = L"TuiConsoleWindowClass";
00109     wc.lpfnWndProc = TuiConsoleWndProc;
00110     wc.hInstance = (HINSTANCE) GetModuleHandleW(NULL);
00111     if (RegisterClassExW(&wc) == 0)
00112     {
00113         DPRINT1("Failed to register console wndproc\n");
00114         return FALSE;
00115     }
00116 
00117     return TRUE;
00118 }
00119 
00120 static VOID WINAPI
00121 TuiInitScreenBuffer(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buffer)
00122 {
00123     Buffer->DefaultAttrib = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED;
00124 }
00125 
00126 static void FASTCALL
00127 TuiCopyRect(char *Dest, PCSRSS_SCREEN_BUFFER Buff, SMALL_RECT *Region)
00128 {
00129     UINT SrcDelta, DestDelta;
00130     LONG i;
00131     PBYTE Src, SrcEnd;
00132 
00133     Src = ConioCoordToPointer(Buff, Region->Left, Region->Top);
00134     SrcDelta = Buff->MaxX * 2;
00135     SrcEnd = Buff->Buffer + Buff->MaxY * Buff->MaxX * 2;
00136     DestDelta = ConioRectWidth(Region) * 2;
00137     for (i = Region->Top; i <= Region->Bottom; i++)
00138     {
00139         memcpy(Dest, Src, DestDelta);
00140         Src += SrcDelta;
00141         if (SrcEnd <= Src)
00142         {
00143             Src -= Buff->MaxY * Buff->MaxX * 2;
00144         }
00145         Dest += DestDelta;
00146     }
00147 }
00148 
00149 static VOID WINAPI
00150 TuiDrawRegion(PCSRSS_CONSOLE Console, SMALL_RECT *Region)
00151 {
00152     DWORD BytesReturned;
00153     PCSRSS_SCREEN_BUFFER Buff = Console->ActiveBuffer;
00154     PCONSOLE_DRAW ConsoleDraw;
00155     UINT ConsoleDrawSize;
00156 
00157     if (ActiveConsole != Console)
00158     {
00159         return;
00160     }
00161 
00162     ConsoleDrawSize = sizeof(CONSOLE_DRAW) +
00163                       (ConioRectWidth(Region) * ConioRectHeight(Region)) * 2;
00164     ConsoleDraw = HeapAlloc(Win32CsrApiHeap, 0, ConsoleDrawSize);
00165     if (NULL == ConsoleDraw)
00166     {
00167         DPRINT1("HeapAlloc failed\n");
00168         return;
00169     }
00170     ConsoleDraw->X = Region->Left;
00171     ConsoleDraw->Y = Region->Top;
00172     ConsoleDraw->SizeX = ConioRectWidth(Region);
00173     ConsoleDraw->SizeY = ConioRectHeight(Region);
00174     ConsoleDraw->CursorX = Buff->CurrentX;
00175     ConsoleDraw->CursorY = Buff->CurrentY;
00176 
00177     TuiCopyRect((char *) (ConsoleDraw + 1), Buff, Region);
00178 
00179     if (! DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_DRAW,
00180                           NULL, 0, ConsoleDraw, ConsoleDrawSize, &BytesReturned, NULL))
00181     {
00182         DPRINT1("Failed to draw console\n");
00183         HeapFree(Win32CsrApiHeap, 0, ConsoleDraw);
00184         return;
00185     }
00186 
00187     HeapFree(Win32CsrApiHeap, 0, ConsoleDraw);
00188 }
00189 
00190 static VOID WINAPI
00191 TuiWriteStream(PCSRSS_CONSOLE Console, SMALL_RECT *Region, LONG CursorStartX, LONG CursorStartY,
00192                UINT ScrolledLines, CHAR *Buffer, UINT Length)
00193 {
00194     DWORD BytesWritten;
00195     PCSRSS_SCREEN_BUFFER Buff = Console->ActiveBuffer;
00196 
00197     if (ActiveConsole->ActiveBuffer != Buff)
00198     {
00199         return;
00200     }
00201 
00202     if (! WriteFile(ConsoleDeviceHandle, Buffer, Length, &BytesWritten, NULL))
00203     {
00204         DPRINT1("Error writing to BlueScreen\n");
00205     }
00206 }
00207 
00208 static BOOL WINAPI
00209 TuiSetCursorInfo(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buff)
00210 {
00211     CONSOLE_CURSOR_INFO Info;
00212     DWORD BytesReturned;
00213 
00214     if (ActiveConsole->ActiveBuffer != Buff)
00215     {
00216         return TRUE;
00217     }
00218 
00219     Info.dwSize = ConioEffectiveCursorSize(Console, 100);
00220     Info.bVisible = Buff->CursorInfo.bVisible;
00221 
00222     if (! DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_SET_CURSOR_INFO,
00223                           &Info, sizeof(Info), NULL, 0, &BytesReturned, NULL))
00224     {
00225         DPRINT1( "Failed to set cursor info\n" );
00226         return FALSE;
00227     }
00228 
00229     return TRUE;
00230 }
00231 
00232 static BOOL WINAPI
00233 TuiSetScreenInfo(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buff, UINT OldCursorX, UINT OldCursorY)
00234 {
00235     CONSOLE_SCREEN_BUFFER_INFO Info;
00236     DWORD BytesReturned;
00237 
00238     if (ActiveConsole->ActiveBuffer != Buff)
00239     {
00240         return TRUE;
00241     }
00242 
00243     Info.dwCursorPosition.X = Buff->CurrentX;
00244     Info.dwCursorPosition.Y = Buff->CurrentY;
00245     Info.wAttributes = Buff->DefaultAttrib;
00246 
00247     if (! DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_SET_SCREEN_BUFFER_INFO,
00248                           &Info, sizeof(CONSOLE_SCREEN_BUFFER_INFO), NULL, 0,
00249                           &BytesReturned, NULL))
00250     {
00251         DPRINT1( "Failed to set cursor position\n" );
00252         return FALSE;
00253     }
00254 
00255     return TRUE;
00256 }
00257 
00258 static BOOL WINAPI
00259 TuiUpdateScreenInfo(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buff)
00260 {
00261     return TRUE;
00262 }
00263 
00264 static BOOL WINAPI
00265 TuiChangeTitle(PCSRSS_CONSOLE Console)
00266 {
00267     return TRUE;
00268 }
00269 
00270 static VOID WINAPI
00271 TuiCleanupConsole(PCSRSS_CONSOLE Console)
00272 {
00273     DestroyWindow(Console->hWindow);
00274 
00275     EnterCriticalSection(&ActiveConsoleLock);
00276 
00277     /* Switch to next console */
00278     if (ActiveConsole == Console)
00279     {
00280         ActiveConsole = Console->Next != Console ? Console->Next : NULL;
00281     }
00282 
00283     if (Console->Next != Console)
00284     {
00285         Console->Prev->Next = Console->Next;
00286         Console->Next->Prev = Console->Prev;
00287     }
00288     LeaveCriticalSection(&ActiveConsoleLock);
00289 
00290     if (NULL != ActiveConsole)
00291     {
00292         ConioDrawConsole(ActiveConsole);
00293     }
00294 }
00295 
00296 static BOOL WINAPI
00297 TuiChangeIcon(PCSRSS_CONSOLE Console, HICON hWindowIcon)
00298 {
00299   return TRUE;
00300 }
00301 
00302 static NTSTATUS WINAPI
00303 TuiResizeBuffer(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER ScreenBuffer, COORD Size)
00304 {
00305   UNIMPLEMENTED;
00306   return STATUS_NOT_IMPLEMENTED;
00307 }
00308 
00309 DWORD WINAPI
00310 TuiConsoleThread (PVOID Data)
00311 {
00312     PCSRSS_CONSOLE Console = (PCSRSS_CONSOLE) Data;
00313     HWND NewWindow;
00314     MSG msg;
00315 
00316     NewWindow = CreateWindowW(L"TuiConsoleWindowClass",
00317                               Console->Title.Buffer,
00318                               0,
00319                               -32000, -32000, 0, 0,
00320                               NULL, NULL,
00321                               (HINSTANCE) GetModuleHandleW(NULL),
00322                               (PVOID) Console);
00323     Console->hWindow = NewWindow;
00324     if (NULL == NewWindow)
00325     {
00326         DPRINT1("CSR: Unable to create console window\n");
00327         return 1;
00328     }
00329 
00330     SetForegroundWindow(Console->hWindow);
00331 
00332     while (TRUE)
00333     {
00334         GetMessageW(&msg, 0, 0, 0);
00335         DispatchMessage(&msg);
00336         TranslateMessage(&msg);
00337 
00338         if (msg.message == WM_CHAR || msg.message == WM_SYSCHAR ||
00339                 msg.message == WM_KEYDOWN || msg.message == WM_KEYUP ||
00340                 msg.message == WM_SYSKEYDOWN || msg.message == WM_SYSKEYUP)
00341         {
00342             ConioProcessKey(&msg, Console, TRUE);
00343         }
00344     }
00345 
00346     return 0;
00347 }
00348 
00349 static CSRSS_CONSOLE_VTBL TuiVtbl =
00350 {
00351     TuiInitScreenBuffer,
00352     TuiWriteStream,
00353     TuiDrawRegion,
00354     TuiSetCursorInfo,
00355     TuiSetScreenInfo,
00356     TuiUpdateScreenInfo,
00357     TuiChangeTitle,
00358     TuiCleanupConsole,
00359     TuiChangeIcon,
00360     TuiResizeBuffer,
00361 };
00362 
00363 NTSTATUS FASTCALL
00364 TuiInitConsole(PCSRSS_CONSOLE Console)
00365 {
00366     HANDLE ThreadHandle;
00367 
00368     if (! ConsInitialized)
00369     {
00370         ConsInitialized = TRUE;
00371         if (! TuiInit(Console->CodePage))
00372         {
00373             ConsInitialized = FALSE;
00374             return STATUS_UNSUCCESSFUL;
00375         }
00376     }
00377 
00378     Console->Vtbl = &TuiVtbl;
00379     Console->hWindow = NULL;
00380     Console->Size = PhysicalConsoleSize;
00381     Console->ActiveBuffer->MaxX = PhysicalConsoleSize.X;
00382     Console->ActiveBuffer->MaxY = PhysicalConsoleSize.Y;
00383 
00384     ThreadHandle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) TuiConsoleThread,
00385                                 Console, 0, NULL);
00386     if (NULL == ThreadHandle)
00387     {
00388         DPRINT1("CSR: Unable to create console thread\n");
00389         return STATUS_UNSUCCESSFUL;
00390     }
00391     CloseHandle(ThreadHandle);
00392 
00393     EnterCriticalSection(&ActiveConsoleLock);
00394     if (NULL != ActiveConsole)
00395     {
00396         Console->Prev = ActiveConsole;
00397         Console->Next = ActiveConsole->Next;
00398         ActiveConsole->Next->Prev = Console;
00399         ActiveConsole->Next = Console;
00400     }
00401     else
00402     {
00403         Console->Prev = Console;
00404         Console->Next = Console;
00405     }
00406     ActiveConsole = Console;
00407     LeaveCriticalSection(&ActiveConsoleLock);
00408 
00409     return STATUS_SUCCESS;
00410 }
00411 
00412 PCSRSS_CONSOLE FASTCALL
00413 TuiGetFocusConsole(VOID)
00414 {
00415     return ActiveConsole;
00416 }
00417 
00418 BOOL FASTCALL
00419 TuiSwapConsole(int Next)
00420 {
00421     static PCSRSS_CONSOLE SwapConsole = NULL; /* console we are thinking about swapping with */
00422     DWORD BytesReturned;
00423     ANSI_STRING Title;
00424     void * Buffer;
00425     COORD *pos;
00426 
00427     if (0 != Next)
00428     {
00429         /* alt-tab, swap consoles */
00430         /* move SwapConsole to next console, and print its title */
00431         EnterCriticalSection(&ActiveConsoleLock);
00432         if (! SwapConsole)
00433         {
00434             SwapConsole = ActiveConsole;
00435         }
00436 
00437         SwapConsole = (0 < Next ? SwapConsole->Next : SwapConsole->Prev);
00438         Title.MaximumLength = RtlUnicodeStringToAnsiSize(&SwapConsole->Title);
00439         Title.Length = 0;
00440         Buffer = HeapAlloc(Win32CsrApiHeap,
00441                            0,
00442                            sizeof(COORD) + Title.MaximumLength);
00443         pos = (COORD *)Buffer;
00444         Title.Buffer = (PVOID)((ULONG_PTR)Buffer + sizeof( COORD ));
00445 
00446         RtlUnicodeStringToAnsiString(&Title, &SwapConsole->Title, FALSE);
00447         pos->Y = PhysicalConsoleSize.Y / 2;
00448         pos->X = (PhysicalConsoleSize.X - Title.Length) / 2;
00449         /* redraw the console to clear off old title */
00450         ConioDrawConsole(ActiveConsole);
00451         if (! DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_WRITE_OUTPUT_CHARACTER,
00452                               NULL, 0, Buffer, sizeof(COORD) + Title.Length,
00453                               &BytesReturned, NULL))
00454         {
00455             DPRINT1( "Error writing to console\n" );
00456         }
00457         HeapFree(Win32CsrApiHeap, 0, Buffer);
00458         LeaveCriticalSection(&ActiveConsoleLock);
00459 
00460         return TRUE;
00461     }
00462     else if (NULL != SwapConsole)
00463     {
00464         EnterCriticalSection(&ActiveConsoleLock);
00465         if (SwapConsole != ActiveConsole)
00466         {
00467             /* first remove swapconsole from the list */
00468             SwapConsole->Prev->Next = SwapConsole->Next;
00469             SwapConsole->Next->Prev = SwapConsole->Prev;
00470             /* now insert before activeconsole */
00471             SwapConsole->Next = ActiveConsole;
00472             SwapConsole->Prev = ActiveConsole->Prev;
00473             ActiveConsole->Prev->Next = SwapConsole;
00474             ActiveConsole->Prev = SwapConsole;
00475         }
00476         ActiveConsole = SwapConsole;
00477         SwapConsole = NULL;
00478         ConioDrawConsole(ActiveConsole);
00479         LeaveCriticalSection(&ActiveConsoleLock);
00480         return TRUE;
00481     }
00482     else
00483     {
00484         return FALSE;
00485     }
00486 }
00487 
00488 /* EOF */

Generated on Sun May 27 2012 04:38:45 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.