Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

private.c

Go to the documentation of this file.
00001 /*++ 00002 00003 Copyright (c) 1985 - 1999, Microsoft Corporation 00004 00005 Module Name: 00006 00007 private.c 00008 00009 Abstract: 00010 00011 This file implements private APIs for Hardware Desktop Support. 00012 00013 Author: 00014 00015 Therese Stowell (thereses) 12-13-1991 00016 00017 Revision History: 00018 00019 Notes: 00020 00021 --*/ 00022 00023 #include "precomp.h" 00024 #pragma hdrstop 00025 00026 #if defined(FE_SB) 00027 BOOL fFullScreenGraphics ; // Do not trun graphics mode. 00028 #if defined(i386) 00029 extern ULONG gdwMachineId; 00030 #endif // i386 00031 #endif 00032 00033 // 00034 // initial palette registers 00035 // 00036 00037 #define PAL_BLACK 0 00038 #define PAL_BLUE 1 00039 #define PAL_GREEN 2 00040 #define PAL_RED 4 00041 #define PAL_YELLOW (PAL_RED | PAL_GREEN) 00042 #define PAL_CYAN (PAL_GREEN | PAL_BLUE) 00043 #define PAL_MAGENTA (PAL_BLUE | PAL_RED) 00044 #define PAL_WHITE (PAL_RED | PAL_GREEN | PAL_BLUE) 00045 00046 #define PAL_I_BLACK (PAL_BLACK + (PAL_WHITE << 3)) 00047 #define PAL_I_RED (PAL_RED + (PAL_RED << 3)) 00048 #define PAL_I_GREEN (PAL_GREEN + (PAL_GREEN << 3)) 00049 #define PAL_I_YELLOW (PAL_YELLOW + (PAL_YELLOW << 3)) 00050 #define PAL_I_BLUE (PAL_BLUE + (PAL_BLUE << 3)) 00051 #define PAL_I_CYAN (PAL_CYAN + (PAL_CYAN << 3)) 00052 #define PAL_I_MAGENTA (PAL_MAGENTA + (PAL_MAGENTA << 3)) 00053 #define PAL_I_WHITE (PAL_WHITE + (PAL_WHITE << 3)) 00054 00055 #define INITIAL_PALETTE_SIZE 18 00056 00057 USHORT InitialPalette[INITIAL_PALETTE_SIZE] = { 00058 00059 16, // 16 entries 00060 0, // start with first palette register 00061 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F 00062 }; 00063 00064 #if defined(FE_SB) 00065 PUSHORT RegInitialPalette = InitialPalette; 00066 #endif 00067 00068 UCHAR ColorBuffer[] = { 00069 00070 16, // 16 entries 00071 0, 00072 0, 00073 0, // start with first palette register 00074 0x00, 0x00, 0x00, 0x00, // black 00075 0x00, 0x00, 0x2A, 0x00, // blue 00076 0x00, 0x2A, 0x00, 0x00, // green 00077 0x00, 0x2A, 0x2A, 0x00, // cyan 00078 0x2A, 0x00, 0x00, 0x00, // red 00079 0x2A, 0x00, 0x2A, 0x00, // magenta 00080 0x2A, 0x2A, 0x00, 0x00, // mustard/brown 00081 0x36, 0x36, 0x36, 0x00, // light gray 39 00082 0x28, 0x28, 0x28, 0x00, // dark gray 2A 00083 0x00, 0x00, 0x3F, 0x00, // bright blue 00084 0x00, 0x3F, 0x00, 0x00, // bright green 00085 0x00, 0x3F, 0x3F, 0x00, // bright cyan 00086 0x3F, 0x00, 0x00, 0x00, // bright red 00087 0x3F, 0x00, 0x3F, 0x00, // bright magenta 00088 0x3F, 0x3F, 0x00, 0x00, // bright yellow 00089 0x3F, 0x3F, 0x3F, 0x00 // bright white 00090 }; 00091 00092 #if defined(FE_SB) 00093 PUCHAR RegColorBuffer = ColorBuffer; 00094 PUCHAR RegColorBufferNoTranslate = NULL; 00095 #endif 00096 00097 #if defined(FE_SB) 00098 MODE_FONT_PAIR ModeFontPairs[] = { 00099 {FS_MODE_TEXT, 80, 21, 640, 350, 8, 16}, 00100 {FS_MODE_TEXT, 80, 25, 720, 400, 8, 16}, 00101 {FS_MODE_TEXT, 80, 28, 720, 400, 8, 14}, 00102 {FS_MODE_TEXT, 80, 43, 640, 350, 8, 8 }, 00103 {FS_MODE_TEXT, 80, 50, 720, 400, 8, 8 } 00104 }; 00105 00106 DWORD NUMBER_OF_MODE_FONT_PAIRS = sizeof(ModeFontPairs)/sizeof(MODE_FONT_PAIR); 00107 PMODE_FONT_PAIR RegModeFontPairs = ModeFontPairs; 00108 00109 SINGLE_LIST_ENTRY gRegFullScreenCodePage; // This list contain FS_CODEPAGE data. 00110 00111 #else 00112 typedef struct _MODE_FONT_PAIR { 00113 ULONG Height; 00114 COORD Resolution; 00115 COORD FontSize; 00116 } MODE_FONT_PAIR, PMODE_FONT_PAIR; 00117 00118 #define NUMBER_OF_MODE_FONT_PAIRS 5 00119 00120 MODE_FONT_PAIR ModeFontPairs[NUMBER_OF_MODE_FONT_PAIRS] = { 00121 {21, 640, 350, 8, 16}, 00122 {25, 720, 400, 8, 16}, 00123 {28, 720, 400, 8, 14}, 00124 {43, 640, 350, 8, 8 }, 00125 {50, 720, 400, 8, 8 } 00126 }; 00127 #endif 00128 00129 00130 HANDLE hCPIFile; // handle to font file 00131 00132 typedef struct _FONTFILEHEADER { 00133 BYTE ffhFileTag[8]; // SHOULD BE 0FFH,"FONT___" 00134 BYTE ffhReserved[8]; 00135 WORD ffhPointers; 00136 BYTE ffhPointerType; 00137 BYTE ffhOffset1; 00138 WORD ffhOffset2; 00139 BYTE ffhOffset3; 00140 } FONTFILEHEADER, *LPFONTFILEHEADER; 00141 00142 typedef struct _FONTINFOHEADER { 00143 WORD fihCodePages; 00144 } FONTINFOHEADER, *LPFONTINFOHEADER; 00145 00146 typedef struct _CPENTRYHEADER { 00147 WORD cpeLength; 00148 WORD cpeNext1; 00149 WORD cpeNext2; 00150 WORD cpeDevType; 00151 BYTE cpeDevSubtype[8]; 00152 WORD cpeCodepageID; 00153 BYTE cpeReserved[6]; 00154 DWORD cpeOffset; 00155 } CPENTRYHEADER, *LPCPENTRYHEADER; 00156 00157 typedef struct _FONTDATAHEADER { 00158 WORD fdhReserved; 00159 WORD fdhFonts; 00160 WORD fdhLength; 00161 } FONTDATAHEADER, *LPFONTDATAHEADER; 00162 00163 typedef struct _SCREENFONTHEADER { 00164 BYTE sfhHeight; 00165 BYTE sfhWidth; 00166 WORD sfhAspect; 00167 WORD sfhCharacters; 00168 } SCREENFONTHEADER, *LPSCREENFONTHEADER; 00169 00170 #define CONSOLE_WINDOWS_DIR_LENGTH 256 00171 #define CONSOLE_EGACPI_LENGTH 9 // includes NULL 00172 #define CONSOLE_EGACPI "\\ega.cpi" 00173 #define CONSOLE_FONT_BUFFER_LENGTH 50 00174 #define CONSOLE_DEFAULT_ROM_FONT 437 00175 00176 00177 #ifdef i386 00178 VOID 00179 ReverseMousePointer( 00180 IN PSCREEN_INFORMATION ScreenInfo, 00181 IN PSMALL_RECT Region 00182 ); 00183 00184 VOID 00185 ReadRectFromScreenBuffer( 00186 IN PSCREEN_INFORMATION ScreenInfo, 00187 IN COORD SourcePoint, 00188 IN PCHAR_INFO Target, 00189 IN COORD TargetSize, 00190 IN PSMALL_RECT TargetRect 00191 ); 00192 00193 #endif 00194 00195 NTSTATUS 00196 MapViewOfSection( 00197 PHANDLE SectionHandle, 00198 ULONG CommitSize, 00199 PVOID *BaseAddress, 00200 PSIZE_T ViewSize, 00201 HANDLE ClientHandle, 00202 PVOID *BaseClientAddress 00203 ); 00204 00205 NTSTATUS 00206 ConnectToEmulator( 00207 IN BOOL Connect, 00208 IN PCONSOLE_INFORMATION Console 00209 ); 00210 00211 00212 ULONG 00213 SrvSetConsoleCursor( 00214 IN OUT PCSR_API_MSG m, 00215 IN OUT PCSR_REPLY_STATUS ReplyStatus 00216 ) 00217 00218 /*++ 00219 00220 Description: 00221 00222 Sets the mouse pointer for the specified screen buffer. 00223 00224 Parameters: 00225 00226 hConsoleOutput - Supplies a console output handle. 00227 00228 hCursor - win32 cursor handle, should be NULL to set the default 00229 cursor. 00230 00231 Return value: 00232 00233 TRUE - The operation was successful. 00234 00235 FALSE/NULL - The operation failed. Extended error status is available 00236 using GetLastError. 00237 00238 --*/ 00239 00240 { 00241 PCONSOLE_SETCURSOR_MSG a = (PCONSOLE_SETCURSOR_MSG)&m->u.ApiMessageData; 00242 NTSTATUS Status; 00243 PCONSOLE_INFORMATION Console; 00244 PHANDLE_DATA HandleData; 00245 00246 Status = ApiPreamble(a->ConsoleHandle, 00247 &Console 00248 ); 00249 if (!NT_SUCCESS(Status)) { 00250 return Status; 00251 } 00252 Status = DereferenceIoHandle(CONSOLE_PERPROCESSDATA(), 00253 a->OutputHandle, 00254 CONSOLE_GRAPHICS_OUTPUT_HANDLE, 00255 GENERIC_WRITE, 00256 &HandleData 00257 ); 00258 if (NT_SUCCESS(Status)) { 00259 if (a->CursorHandle == NULL) { 00260 HandleData->Buffer.ScreenBuffer->CursorHandle = ghNormalCursor; 00261 } else { 00262 HandleData->Buffer.ScreenBuffer->CursorHandle = a->CursorHandle; 00263 } 00264 PostMessage(HandleData->Buffer.ScreenBuffer->Console->hWnd, 00265 WM_SETCURSOR, 00266 0, 00267 -1 00268 ); 00269 } 00270 UnlockConsole(Console); 00271 return Status; 00272 UNREFERENCED_PARAMETER(ReplyStatus); // get rid of unreferenced parameter warning message 00273 } 00274 00275 #ifdef i386 00276 VOID 00277 FullScreenCursor( 00278 IN PSCREEN_INFORMATION ScreenInfo, 00279 IN BOOL On 00280 ) 00281 { 00282 if (On) { 00283 if (ScreenInfo->CursorDisplayCount < 0) { 00284 ScreenInfo->CursorDisplayCount = 0; 00285 ReverseMousePointer(ScreenInfo, &ScreenInfo->Window); 00286 } 00287 } else { 00288 if (ScreenInfo->CursorDisplayCount >= 0) { 00289 ReverseMousePointer(ScreenInfo, &ScreenInfo->Window); 00290 ScreenInfo->CursorDisplayCount = -1; 00291 } 00292 } 00293 00294 } 00295 #endif 00296 00297 ULONG 00298 SrvShowConsoleCursor( 00299 IN OUT PCSR_API_MSG m, 00300 IN OUT PCSR_REPLY_STATUS ReplyStatus 00301 ) 00302 00303 /*++ 00304 00305 Description: 00306 00307 Sets the mouse pointer visibility counter. If the counter is less than 00308 zero, the mouse pointer is not shown. 00309 00310 Parameters: 00311 00312 hOutput - Supplies a console output handle. 00313 00314 bShow - if TRUE, the display count is to be increased. if FALSE, 00315 decreased. 00316 00317 Return value: 00318 00319 The return value specifies the new display count. 00320 00321 --*/ 00322 00323 { 00324 PCONSOLE_SHOWCURSOR_MSG a = (PCONSOLE_SHOWCURSOR_MSG)&m->u.ApiMessageData; 00325 NTSTATUS Status; 00326 PCONSOLE_INFORMATION Console; 00327 PHANDLE_DATA HandleData; 00328 00329 Status = ApiPreamble(a->ConsoleHandle, 00330 &Console 00331 ); 00332 if (!NT_SUCCESS(Status)) { 00333 return Status; 00334 } 00335 Status = DereferenceIoHandle(CONSOLE_PERPROCESSDATA(), 00336 a->OutputHandle, 00337 CONSOLE_OUTPUT_HANDLE | CONSOLE_GRAPHICS_OUTPUT_HANDLE, 00338 GENERIC_WRITE, 00339 &HandleData 00340 ); 00341 if (NT_SUCCESS(Status)) { 00342 if (!(Console->FullScreenFlags & CONSOLE_FULLSCREEN_HARDWARE) ) { 00343 if (a->bShow) { 00344 HandleData->Buffer.ScreenBuffer->CursorDisplayCount += 1; 00345 } else { 00346 HandleData->Buffer.ScreenBuffer->CursorDisplayCount -= 1; 00347 } 00348 if (HandleData->Buffer.ScreenBuffer == Console->CurrentScreenBuffer) { 00349 PostMessage(HandleData->Buffer.ScreenBuffer->Console->hWnd, 00350 WM_SETCURSOR, 00351 0, 00352 -1 00353 ); 00354 } 00355 } else { 00356 #ifdef i386 00357 if (HandleData->HandleType != CONSOLE_GRAPHICS_OUTPUT_HANDLE && 00358 Console->FullScreenFlags & CONSOLE_FULLSCREEN_HARDWARE && 00359 HandleData->Buffer.ScreenBuffer == Console->CurrentScreenBuffer) { 00360 FullScreenCursor(HandleData->Buffer.ScreenBuffer,a->bShow); 00361 } 00362 #endif 00363 } 00364 a->DisplayCount = HandleData->Buffer.ScreenBuffer->CursorDisplayCount; 00365 } 00366 UnlockConsole(Console); 00367 return Status; 00368 UNREFERENCED_PARAMETER(ReplyStatus); // get rid of unreferenced parameter warning message 00369 } 00370 00371 00372 ULONG 00373 SrvConsoleMenuControl( 00374 IN OUT PCSR_API_MSG m, 00375 IN OUT PCSR_REPLY_STATUS ReplyStatus 00376 ) 00377 00378 /*++ 00379 00380 Description: 00381 00382 Sets the command id range for the current screen buffer and returns the 00383 menu handle. 00384 00385 Parameters: 00386 00387 hConsoleOutput - Supplies a console output handle. 00388 00389 dwCommandIdLow - Specifies the lowest command id to store in the input buffer. 00390 00391 dwCommandIdHigh - Specifies the highest command id to store in the input 00392 buffer. 00393 00394 Return value: 00395 00396 TRUE - The operation was successful. 00397 00398 FALSE/NULL - The operation failed. Extended error status is available 00399 using GetLastError. 00400 00401 --*/ 00402 00403 { 00404 PCONSOLE_MENUCONTROL_MSG a = (PCONSOLE_MENUCONTROL_MSG)&m->u.ApiMessageData; 00405 NTSTATUS Status; 00406 PCONSOLE_INFORMATION Console; 00407 PHANDLE_DATA HandleData; 00408 00409 Status = ApiPreamble(a->ConsoleHandle, 00410 &Console 00411 ); 00412 if (!NT_SUCCESS(Status)) { 00413 return Status; 00414 } 00415 Status = DereferenceIoHandle(CONSOLE_PERPROCESSDATA(), 00416 a->OutputHandle, 00417 CONSOLE_OUTPUT_HANDLE | CONSOLE_GRAPHICS_OUTPUT_HANDLE, 00418 GENERIC_WRITE, 00419 &HandleData 00420 ); 00421 if (NT_SUCCESS(Status)) { 00422 a->hMenu = HandleData->Buffer.ScreenBuffer->Console->hMenu; 00423 HandleData->Buffer.ScreenBuffer->CommandIdLow = a->CommandIdLow; 00424 HandleData->Buffer.ScreenBuffer->CommandIdHigh = a->CommandIdHigh; 00425 } 00426 UnlockConsole(Console); 00427 return Status; 00428 UNREFERENCED_PARAMETER(ReplyStatus); // get rid of unreferenced parameter warning message 00429 } 00430 00431 ULONG 00432 SrvSetConsolePalette( 00433 IN OUT PCSR_API_MSG m, 00434 IN OUT PCSR_REPLY_STATUS ReplyStatus 00435 ) 00436 00437 /*++ 00438 00439 Description: 00440 00441 Sets the palette for the console screen buffer. 00442 00443 Parameters: 00444 00445 hOutput - Supplies a console output handle. 00446 00447 hPalette - Supplies a handle to the palette to set. 00448 00449 dwUsage - Specifies use of the system palette. 00450 00451 SYSPAL_NOSTATIC - System palette contains no static colors 00452 except black and white. 00453 00454 SYSPAL_STATIC - System palette contains static colors 00455 which will not change when an application 00456 realizes its logical palette. 00457 00458 Return value: 00459 00460 TRUE - The operation was successful. 00461 00462 FALSE/NULL - The operation failed. Extended error status is available 00463 using GetLastError. 00464 00465 --*/ 00466 00467 { 00468 PCONSOLE_SETPALETTE_MSG a = (PCONSOLE_SETPALETTE_MSG)&m->u.ApiMessageData; 00469 NTSTATUS Status; 00470 PCONSOLE_INFORMATION Console; 00471 PHANDLE_DATA HandleData; 00472 HPALETTE hOldPalette; 00473 00474 Status = ApiPreamble(a->ConsoleHandle, 00475 &Console 00476 ); 00477 if (!NT_SUCCESS(Status)) { 00478 return Status; 00479 } 00480 Status = DereferenceIoHandle(CONSOLE_PERPROCESSDATA(), 00481 a->OutputHandle, 00482 CONSOLE_GRAPHICS_OUTPUT_HANDLE, 00483 GENERIC_WRITE, 00484 &HandleData 00485 ); 00486 if (NT_SUCCESS(Status)) { 00487 USERTHREAD_USEDESKTOPINFO utudi; 00488 BOOL bReset = FALSE; 00489 00490 /* 00491 * Palette handle was converted in the client. 00492 */ 00493 if (GetCurrentThreadId() != HandleData->Buffer.ScreenBuffer-> 00494 Console->InputThreadInfo->ThreadId) { 00495 bReset = TRUE; 00496 utudi.hThread = HandleData->Buffer.ScreenBuffer->Console->InputThreadInfo->ThreadHandle; 00497 utudi.drdRestore.pdeskRestore = NULL; 00498 NtUserSetInformationThread(NtCurrentThread(), 00499 UserThreadUseDesktop, 00500 &utudi, sizeof(utudi)); 00501 } 00502 00503 NtUserConsoleControl(ConsolePublicPalette, &(a->hPalette), sizeof(HPALETTE)); 00504 00505 hOldPalette = SelectPalette( 00506 HandleData->Buffer.ScreenBuffer->Console->hDC, 00507 a->hPalette, 00508 FALSE); 00509 00510 if (hOldPalette == NULL) { 00511 Status = STATUS_INVALID_PARAMETER; 00512 } else { 00513 if ((HandleData->Buffer.ScreenBuffer->hPalette != NULL) && 00514 (a->hPalette != HandleData->Buffer.ScreenBuffer->hPalette)) { 00515 DeleteObject(HandleData->Buffer.ScreenBuffer->hPalette); 00516 } 00517 HandleData->Buffer.ScreenBuffer->hPalette = a->hPalette; 00518 HandleData->Buffer.ScreenBuffer->dwUsage = a->dwUsage; 00519 if (!(HandleData->Buffer.ScreenBuffer->Console->Flags & CONSOLE_IS_ICONIC) && 00520 HandleData->Buffer.ScreenBuffer->Console->FullScreenFlags == 0) { 00521 00522 SetSystemPaletteUse(HandleData->Buffer.ScreenBuffer->Console->hDC, 00523 HandleData->Buffer.ScreenBuffer->dwUsage); 00524 RealizePalette(HandleData->Buffer.ScreenBuffer->Console->hDC); 00525 } 00526 if (HandleData->Buffer.ScreenBuffer->Console->hSysPalette == NULL) { 00527 HandleData->Buffer.ScreenBuffer->Console->hSysPalette = hOldPalette; 00528 } 00529 } 00530 00531 if (bReset) { 00532 utudi.hThread = NULL; 00533 NtUserSetInformationThread(NtCurrentThread(), 00534 UserThreadUseDesktop, &utudi, sizeof(utudi)); 00535 } 00536 } 00537 UnlockConsole(Console); 00538 return Status; 00539 UNREFERENCED_PARAMETER(ReplyStatus); // get rid of unreferenced parameter warning message 00540 } 00541 00542 00543 VOID 00544 SetActivePalette( 00545 IN PSCREEN_INFORMATION ScreenInfo 00546 ) 00547 { 00548 USERTHREAD_USEDESKTOPINFO utudi; 00549 BOOL bReset = FALSE; 00550 00551 if (GetCurrentThreadId() != ScreenInfo->Console->InputThreadInfo->ThreadId) { 00552 bReset = TRUE; 00553 utudi.hThread = ScreenInfo->Console->InputThreadInfo->ThreadHandle; 00554 utudi.drdRestore.pdeskRestore = NULL; 00555 NtUserSetInformationThread(NtCurrentThread(), 00556 UserThreadUseDesktop, 00557 &utudi, sizeof(utudi)); 00558 } 00559 00560 SetSystemPaletteUse(ScreenInfo->Console->hDC, 00561 ScreenInfo->dwUsage 00562 ); 00563 RealizePalette(ScreenInfo->Console->hDC); 00564 00565 if (bReset == TRUE) { 00566 utudi.hThread = NULL; 00567 NtUserSetInformationThread(NtCurrentThread(), 00568 UserThreadUseDesktop, &utudi, sizeof(utudi)); 00569 } 00570 } 00571 00572 VOID 00573 UnsetActivePalette( 00574 IN PSCREEN_INFORMATION ScreenInfo 00575 ) 00576 { 00577 USERTHREAD_USEDESKTOPINFO utudi; 00578 BOOL bReset = FALSE; 00579 00580 if (GetCurrentThreadId() != ScreenInfo->Console->InputThreadInfo->ThreadId) { 00581 bReset = TRUE; 00582 utudi.hThread = ScreenInfo->Console->InputThreadInfo->ThreadHandle; 00583 utudi.drdRestore.pdeskRestore = NULL; 00584 NtUserSetInformationThread(NtCurrentThread(), 00585 UserThreadUseDesktop, 00586 &utudi, sizeof(utudi)); 00587 } 00588 00589 SetSystemPaletteUse(ScreenInfo->Console->hDC, 00590 SYSPAL_STATIC 00591 ); 00592 RealizePalette(ScreenInfo->Console->hDC); 00593 00594 00595 if (bReset == TRUE) { 00596 utudi.hThread = NULL; 00597 NtUserSetInformationThread(NtCurrentThread(), 00598 UserThreadUseDesktop, &utudi, sizeof(utudi)); 00599 } 00600 } 00601 00602 NTSTATUS 00603 ConvertToFullScreen( 00604 IN PCONSOLE_INFORMATION Console 00605 ) 00606 { 00607 #ifdef i386 00608 PSCREEN_INFORMATION Cur; 00609 COORD WindowedWindowSize, WindowSize; 00610 00611 // for each charmode screenbuffer 00612 // match window size to a mode/font 00613 // grow screen buffer if necessary 00614 // save old window dimensions 00615 // set new window dimensions 00616 00617 for (Cur=Console->ScreenBuffers;Cur!=NULL;Cur=Cur->Next) { 00618 00619 if (Cur->Flags & CONSOLE_GRAPHICS_BUFFER) { 00620 continue; 00621 } 00622 00623 // save old window dimensions 00624 00625 WindowedWindowSize.X = CONSOLE_WINDOW_SIZE_X(Cur); 00626 WindowedWindowSize.Y = CONSOLE_WINDOW_SIZE_Y(Cur); 00627 00628 Cur->BufferInfo.TextInfo.WindowedWindowSize = WindowedWindowSize; 00629 Cur->BufferInfo.TextInfo.WindowedScreenSize = Cur->ScreenBufferSize; 00630 00631 // match window size to a mode/font 00632 00633 Cur->BufferInfo.TextInfo.ModeIndex = MatchWindowSize( 00634 Console->OutputCP, 00635 Cur->ScreenBufferSize, &WindowSize); 00636 00637 // grow screen buffer if necessary 00638 00639 if (WindowSize.X > Cur->ScreenBufferSize.X || 00640 WindowSize.Y > Cur->ScreenBufferSize.Y) { 00641 COORD NewScreenSize; 00642 00643 NewScreenSize.X = max(WindowSize.X,Cur->ScreenBufferSize.X); 00644 NewScreenSize.Y = max(WindowSize.Y,Cur->ScreenBufferSize.Y); 00645 00646 if (ResizeScreenBuffer(Cur, NewScreenSize, FALSE) == STATUS_INVALID_HANDLE) { 00647 return STATUS_INVALID_HANDLE; 00648 } 00649 } 00650 00651 #if 0 00652 DbgPrint("new window size is %d %d\n",WindowSize.X,WindowSize.Y); 00653 DbgPrint("existing window size is %d %d\n",WindowedWindowSize.X,WindowedWindowSize.Y); 00654 DbgPrint("existing window is %d %d %d %d\n",Cur->Window.Left,Cur->Window.Top,Cur->Window.Right,Cur->Window.Bottom); 00655 DbgPrint("screenbuffersize is %d %d\n",Cur->ScreenBufferSize.X,Cur->ScreenBufferSize.Y); 00656 #endif 00657 // set new window dimensions 00658 // we always resize horizontally from the right (change the 00659 // right edge). 00660 // we resize vertically from the bottom, keeping the cursor visible. 00661 00662 if (WindowedWindowSize.X != WindowSize.X) { 00663 Cur->Window.Right -= WindowedWindowSize.X - WindowSize.X; 00664 if (Cur->Window.Right >= Cur->ScreenBufferSize.X) { 00665 Cur->Window.Left -= Cur->Window.Right - Cur->ScreenBufferSize.X + 1; 00666 Cur->Window.Right -= Cur->Window.Right - Cur->ScreenBufferSize.X + 1; 00667 } 00668 } 00669 if (WindowedWindowSize.Y > WindowSize.Y) { 00670 Cur->Window.Bottom -= WindowedWindowSize.Y - WindowSize.Y; 00671 if (Cur->Window.Bottom >= Cur->ScreenBufferSize.Y) { 00672 Cur->Window.Top -= Cur->Window.Bottom - Cur->ScreenBufferSize.Y + 1; 00673 Cur->Window.Bottom = Cur->ScreenBufferSize.Y - 1; 00674 } 00675 } else if (WindowedWindowSize.Y < WindowSize.Y) { 00676 Cur->Window.Top -= WindowSize.Y - WindowedWindowSize.Y; 00677 if (Cur->Window.Top < 0) { 00678 Cur->Window.Bottom -= Cur->Window.Top; 00679 Cur->Window.Top = 0; 00680 } 00681 } 00682 if (Cur->BufferInfo.TextInfo.CursorPosition.Y > Cur->Window.Bottom) { 00683 Cur->Window.Top += Cur->BufferInfo.TextInfo.CursorPosition.Y - Cur->Window.Bottom; 00684 Cur->Window.Bottom = Cur->BufferInfo.TextInfo.CursorPosition.Y; 00685 } 00686 #if 0 00687 DbgPrint("new window is %d %d %d %d\n",Cur->Window.Left,Cur->Window.Top,Cur->Window.Right,Cur->Window.Bottom); 00688 DbgPrint("cursor is %d %d\n",Cur->BufferInfo.TextInfo.CursorPosition.X,Cur->BufferInfo.TextInfo.CursorPosition.Y); 00689 #endif 00690 ASSERT(WindowSize.X == CONSOLE_WINDOW_SIZE_X(Cur)); 00691 ASSERT(WindowSize.Y == CONSOLE_WINDOW_SIZE_Y(Cur)); 00692 Cur->BufferInfo.TextInfo.MousePosition.X = Cur->Window.Left; 00693 Cur->BufferInfo.TextInfo.MousePosition.Y = Cur->Window.Top; 00694 00695 if (Cur->Flags & CONSOLE_OEMFONT_DISPLAY) { 00696 DBGCHARS(("ConvertToFullScreen converts UnicodeOem -> Unicode\n")); 00697 FalseUnicodeToRealUnicode( 00698 Cur->BufferInfo.TextInfo.TextRows, 00699 Cur->ScreenBufferSize.X * Cur->ScreenBufferSize.Y, 00700 Console->OutputCP); 00701 } else { 00702 DBGCHARS(("ConvertToFullScreen needs no conversion\n")); 00703 } 00704 DBGCHARS(("Cur->BufferInfo.TextInfo.Rows = %lx\n", 00705 Cur->BufferInfo.TextInfo.Rows)); 00706 DBGCHARS(("Cur->BufferInfo.TextInfo.TextRows = %lx\n", 00707 Cur->BufferInfo.TextInfo.TextRows)); 00708 } 00709 00710 Cur = Console->CurrentScreenBuffer; 00711 00712 if (Cur->Flags & CONSOLE_TEXTMODE_BUFFER) { 00713 if (CONSOLE_IS_DBCS_OUTPUTCP(Console)) { 00714 PCONVERSIONAREA_INFORMATION ConvAreaInfo; 00715 ConvAreaInfo = Console->ConsoleIme.ConvAreaRoot; 00716 while (ConvAreaInfo) { 00717 NTSTATUS Status; 00718 00719 Status = StoreTextBufferFontInfo(ConvAreaInfo->ScreenBuffer, 00720 SCR_FONTNUMBER(Cur), 00721 SCR_FONTSIZE(Cur), 00722 SCR_FAMILY(Cur), 00723 SCR_FONTWEIGHT(Cur), 00724 SCR_FACENAME(Cur), 00725 SCR_FONTCODEPAGE(Cur)); 00726 if (!NT_SUCCESS(Status)) { 00727 return((ULONG) Status); 00728 } 00729 00730 ConvAreaInfo->ScreenBuffer->BufferInfo.TextInfo.ModeIndex = Cur->BufferInfo.TextInfo.ModeIndex; 00731 ConvAreaInfo = ConvAreaInfo->ConvAreaNext; 00732 } 00733 } 00734 Cur->BufferInfo.TextInfo.Flags &= ~TEXT_VALID_HINT; 00735 } 00736 00737 SetWindowSize(Cur); 00738 WriteToScreen(Cur, &Console->CurrentScreenBuffer->Window); 00739 00740 #else 00741 UNREFERENCED_PARAMETER(Console); 00742 #endif 00743 return STATUS_SUCCESS; 00744 } 00745 00746 NTSTATUS 00747 ConvertToWindowed( 00748 IN PCONSOLE_INFORMATION Console 00749 ) 00750 { 00751 #ifdef i386 00752 PSCREEN_INFORMATION Cur; 00753 SMALL_RECT WindowedWindow; 00754 00755 // for each charmode screenbuffer 00756 // restore window dimensions 00757 00758 for (Cur=Console->ScreenBuffers;Cur!=NULL;Cur=Cur->Next) { 00759 if ((Cur->Flags & CONSOLE_TEXTMODE_BUFFER) == 0) { 00760 continue; 00761 } 00762 00763 if (ResizeScreenBuffer(Cur, 00764 Cur->BufferInfo.TextInfo.WindowedScreenSize, 00765 FALSE) == STATUS_INVALID_HANDLE) { 00766 /* 00767 * Something really went wrong. All we can do is just to 00768 * bail out. 00769 */ 00770 return STATUS_INVALID_HANDLE; 00771 } 00772 00773 WindowedWindow.Right = Cur->Window.Right; 00774 WindowedWindow.Bottom = Cur->Window.Bottom; 00775 WindowedWindow.Left = Cur->Window.Right + 1 - 00776 Cur->BufferInfo.TextInfo.WindowedWindowSize.X; 00777 WindowedWindow.Top = Cur->Window.Bottom + 1 - 00778 Cur->BufferInfo.TextInfo.WindowedWindowSize.Y; 00779 if (WindowedWindow.Left > Cur->Window.Left) { 00780 WindowedWindow.Right -= WindowedWindow.Left - Cur->Window.Left; 00781 WindowedWindow.Left = Cur->Window.Left; 00782 } 00783 if (WindowedWindow.Right < Cur->BufferInfo.TextInfo.CursorPosition.X) { 00784 WindowedWindow.Left += Cur->BufferInfo.TextInfo.CursorPosition.X - WindowedWindow.Right; 00785 WindowedWindow.Right = Cur->BufferInfo.TextInfo.CursorPosition.X; 00786 } 00787 if (WindowedWindow.Top > Cur->Window.Top) { 00788 WindowedWindow.Bottom -= WindowedWindow.Top - Cur->Window.Top; 00789 WindowedWindow.Top = Cur->Window.Top; 00790 } 00791 if (WindowedWindow.Bottom < Cur->BufferInfo.TextInfo.CursorPosition.Y) { 00792 WindowedWindow.Top += Cur->BufferInfo.TextInfo.CursorPosition.Y - WindowedWindow.Bottom; 00793 WindowedWindow.Bottom = Cur->BufferInfo.TextInfo.CursorPosition.Y; 00794 } 00795 ResizeWindow(Cur, &WindowedWindow, FALSE); 00796 00797 if (CONSOLE_IS_DBCS_OUTPUTCP(Console)) { 00798 SetFont(Cur); 00799 } 00800 00801 if (Cur->Flags & CONSOLE_OEMFONT_DISPLAY) { 00802 DBGCHARS(("ConvertToWindowed converts Unicode -> UnicodeOem\n")); 00803 RealUnicodeToFalseUnicode( 00804 Cur->BufferInfo.TextInfo.TextRows, 00805 Cur->ScreenBufferSize.X * Cur->ScreenBufferSize.Y, 00806 Console->OutputCP); 00807 } else { 00808 DBGCHARS(("ConvertToWindowed needs no conversion\n")); 00809 } 00810 DBGCHARS(("Cur->BufferInfo.TextInfo.Rows = %lx\n", 00811 Cur->BufferInfo.TextInfo.Rows)); 00812 DBGCHARS(("Cur->BufferInfo.TextInfo.TextRows = %lx\n", 00813 Cur->BufferInfo.TextInfo.TextRows)); 00814 } 00815 00816 Cur = Console->CurrentScreenBuffer; 00817 00818 if (Cur->Flags & CONSOLE_TEXTMODE_BUFFER) { 00819 if (CONSOLE_IS_DBCS_OUTPUTCP(Console)) { 00820 PCONVERSIONAREA_INFORMATION ConvAreaInfo; 00821 ConvAreaInfo = Console->ConsoleIme.ConvAreaRoot; 00822 while (ConvAreaInfo) { 00823 NTSTATUS Status; 00824 00825 Status = StoreTextBufferFontInfo(ConvAreaInfo->ScreenBuffer, 00826 SCR_FONTNUMBER(Cur), 00827 SCR_FONTSIZE(Cur), 00828 SCR_FAMILY(Cur), 00829 SCR_FONTWEIGHT(Cur), 00830 SCR_FACENAME(Cur), 00831 SCR_FONTCODEPAGE(Cur)); 00832 if (!NT_SUCCESS(Status)) { 00833 return((ULONG) Status); 00834 } 00835 00836 ConvAreaInfo->ScreenBuffer->BufferInfo.TextInfo.ModeIndex = Cur->BufferInfo.TextInfo.ModeIndex; 00837 ConvAreaInfo = ConvAreaInfo->ConvAreaNext; 00838 } 00839 } 00840 Cur->BufferInfo.TextInfo.Flags &= ~TEXT_VALID_HINT; 00841 } 00842 00843 SetWindowSize(Cur); 00844 WriteToScreen(Cur, &Console->CurrentScreenBuffer->Window); 00845 00846 #else 00847 UNREFERENCED_PARAMETER(Console); 00848 #endif 00849 return STATUS_SUCCESS; 00850 } 00851 00852 ULONG 00853 SrvSetConsoleDisplayMode( 00854 IN OUT PCSR_API_MSG m, 00855 IN OUT PCSR_REPLY_STATUS ReplyStatus 00856 ) 00857 00858 /*++ 00859 00860 Description: 00861 00862 This routine sets the console display mode for an output buffer. 00863 This API is only supported on x86 machines. Jazz consoles are always 00864 windowed. 00865 00866 Parameters: 00867 00868 hConsoleOutput - Supplies a console output handle. 00869 00870 dwFlags - Specifies the display mode. Options are: 00871 00872 CONSOLE_FULLSCREEN_MODE - data is displayed fullscreen 00873 00874 CONSOLE_WINDOWED_MODE - data is displayed in a window 00875 00876 lpNewScreenBufferDimensions - On output, contains the new dimensions of 00877 the screen buffer. The dimensions are in rows and columns for 00878 textmode screen buffers. 00879 00880 Return value: 00881 00882 TRUE - The operation was successful. 00883 00884 FALSE/NULL - The operation failed. Extended error status is available 00885 using GetLastError. 00886 00887 --*/ 00888 00889 { 00890 PCONSOLE_SETDISPLAYMODE_MSG a = (PCONSOLE_SETDISPLAYMODE_MSG)&m->u.ApiMessageData; 00891 NTSTATUS Status; 00892 PCONSOLE_INFORMATION Console; 00893 PHANDLE_DATA HandleData; 00894 PSCREEN_INFORMATION ScreenInfo; 00895 UINT State; 00896 HANDLE hEvent = NULL; 00897 00898 Status = ApiPreamble(a->ConsoleHandle, 00899 &Console 00900 ); 00901 if (!NT_SUCCESS(Status)) { 00902 return Status; 00903 } 00904 00905 Status = NtDuplicateObject(CONSOLE_CLIENTPROCESSHANDLE(), 00906 a->hEvent, 00907 NtCurrentProcess(), 00908 &hEvent, 00909 0, 00910 FALSE, 00911 DUPLICATE_SAME_ACCESS 00912 ); 00913 if (!NT_SUCCESS(Status)) { 00914 goto SrvSetConsoleDisplayModeFailure; 00915 } 00916 Status = DereferenceIoHandle(CONSOLE_PERPROCESSDATA(), 00917 a->OutputHandle, 00918 CONSOLE_OUTPUT_HANDLE | CONSOLE_GRAPHICS_OUTPUT_HANDLE, 00919 GENERIC_WRITE, 00920 &HandleData 00921 ); 00922 if (NT_SUCCESS(Status)) { 00923 ScreenInfo = HandleData->Buffer.ScreenBuffer; 00924 if (!ACTIVE_SCREEN_BUFFER(ScreenInfo)) { 00925 Status = STATUS_INVALID_PARAMETER; 00926 goto SrvSetConsoleDisplayModeFailure; 00927 } 00928 if (a->dwFlags == CONSOLE_FULLSCREEN_MODE) { 00929 #if !defined(_X86_) 00930 if (ScreenInfo->Flags & CONSOLE_TEXTMODE_BUFFER) { 00931 Status = STATUS_INVALID_PARAMETER; 00932 goto SrvSetConsoleDisplayModeFailure; 00933 } 00934 #else 00935 if (!FullScreenInitialized) { 00936 Status = STATUS_INVALID_PARAMETER; 00937 goto SrvSetConsoleDisplayModeFailure; 00938 } 00939 #endif 00940 if (Console->FullScreenFlags & CONSOLE_FULLSCREEN) { 00941 KdPrint(("CONSRV: VDM converting to fullscreen twice\n")); 00942 ASSERT(FALSE); 00943 Status = STATUS_INVALID_PARAMETER; 00944 goto SrvSetConsoleDisplayModeFailure; 00945 } 00946 State = FULLSCREEN; 00947 } else { 00948 if (Console->FullScreenFlags == 0) { 00949 KdPrint(("CONSRV: VDM converting to windowed twice\n")); 00950 ASSERT(FALSE); 00951 Status = STATUS_INVALID_PARAMETER; 00952 goto SrvSetConsoleDisplayModeFailure; 00953 } 00954 State = WINDOWED; 00955 } 00956 Status = QueueConsoleMessage(Console, 00957 CM_MODE_TRANSITION, 00958 State, 00959 (LPARAM)hEvent 00960 ); 00961 if (!NT_SUCCESS(Status)) { 00962 goto SrvSetConsoleDisplayModeFailure; 00963 } 00964 } 00965 UnlockConsole(Console); 00966 return Status; 00967 00968 SrvSetConsoleDisplayModeFailure: 00969 if (hEvent) { 00970 NtSetEvent(hEvent, NULL); 00971 NtClose(hEvent); 00972 } 00973 UnlockConsole(Console); 00974 return Status; 00975 00976 UNREFERENCED_PARAMETER(ReplyStatus); // get rid of unreferenced parameter warning message 00977 } 00978 00979 VOID 00980 UnregisterVDM( 00981 IN PCONSOLE_INFORMATION Console 00982 ) 00983 { 00984 // williamh, Feb 2 1994. 00985 // catch multiple calls to unregister vdm. Believe it or not, this could 00986 // happen 00987 ASSERT(Console->Flags & CONSOLE_VDM_REGISTERED); 00988 if (!(Console->Flags & CONSOLE_VDM_REGISTERED)) 00989 return; 00990 00991 #if defined(FE_SB) && defined(i386) 00992 // When HDOS apps exit, console screen resolution is changed to 640*400. Because HBIOS set 00993 // Screen resolution to 640*400. So, we should replace current screen resoultion(640*480). 00994 // 09/11/96 bklee 00995 { 00996 00997 if ((Console->FullScreenFlags & CONSOLE_FULLSCREEN_HARDWARE) && 00998 ( Console->OutputCP == KOREAN_CP || 00999 (Console->OutputCP == JAPAN_CP && ISNECPC98(gdwMachineId) ) )) { 01000 01001 ULONG Index; 01002 DEVMODEW Devmode; 01003 BOOL fGraphics = fFullScreenGraphics ? IsAvailableFsCodePage(Console->OutputCP) : FALSE; 01004 01005 Index = Console->CurrentScreenBuffer->BufferInfo.TextInfo.ModeIndex; 01006 01007 ZeroMemory(&Devmode, sizeof(Devmode)); 01008 01009 Devmode.dmSize = sizeof(Devmode); 01010 Devmode.dmDriverExtra = 0; 01011 Devmode.dmFields = DM_BITSPERPEL | 01012 DM_PELSWIDTH | 01013 DM_PELSHEIGHT | 01014 DM_DISPLAYFLAGS; 01015 01016 Devmode.dmBitsPerPel = 4; 01017 01018 Devmode.dmPelsWidth = RegModeFontPairs[Index].Resolution.X; 01019 Devmode.dmPelsHeight = RegModeFontPairs[Index].Resolution.Y; 01020 Devmode.dmDisplayFlags = (fGraphics && (RegModeFontPairs[Index].Mode & FS_MODE_GRAPHICS)) ? 0 : DMDISPLAYFLAGS_TEXTMODE; 01021 01022 GdiFullscreenControl(FullscreenControlSetMode, 01023 &Devmode, 01024 sizeof(Devmode), 01025 NULL, 01026 NULL); 01027 } 01028 } 01029 #endif 01030 #ifdef i386 01031 if (Console->FullScreenFlags & CONSOLE_FULLSCREEN_HARDWARE && 01032 Console->Flags & CONSOLE_CONNECTED_TO_EMULATOR) { 01033 NtUserConsoleControl(ConsoleSetVDMCursorBounds, NULL, 0); 01034 // connect emulator 01035 ConnectToEmulator(FALSE, Console); 01036 } 01037 01038 if (FullScreenInitialized) { 01039 CloseHandle(Console->VDMStartHardwareEvent); 01040 CloseHandle(Console->VDMEndHardwareEvent); 01041 NtUnmapViewOfSection(NtCurrentProcess(),Console->StateBuffer); 01042 NtUnmapViewOfSection(Console->VDMProcessHandle,Console->StateBufferClient); 01043 NtClose(Console->StateSectionHandle); 01044 Console->StateLength = 0; 01045 } 01046 01047 #endif 01048 01049 Console->Flags &= ~CONSOLE_VDM_REGISTERED; 01050 01051 if (Console->Flags & CONSOLE_HAS_FOCUS) { 01052 USERTHREAD_FLAGS Flags; 01053 01054 Flags.dwFlags = 0; 01055 Flags.dwMask = (TIF_VDMAPP | TIF_DOSEMULATOR); 01056 NtUserSetInformationThread(Console->InputThreadInfo->ThreadHandle, 01057 UserThreadFlags, &Flags, sizeof(Flags)); 01058 } 01059 Console->Flags &= ~CONSOLE_WOW_REGISTERED; 01060 ASSERT(Console->VDMBuffer != NULL); 01061 if (Console->VDMBuffer != NULL) { 01062 NtUnmapViewOfSection(Console->VDMProcessHandle,Console->VDMBufferClient); 01063 NtUnmapViewOfSection(NtCurrentProcess(),Console->VDMBuffer); 01064 NtClose(Console->VDMBufferSectionHandle); 01065 Console->VDMBuffer = NULL; 01066 } 01067 #ifdef i386 01068 if (Console->CurrentScreenBuffer && 01069 Console->CurrentScreenBuffer->Flags & CONSOLE_TEXTMODE_BUFFER) { 01070 Console->CurrentScreenBuffer->BufferInfo.TextInfo.MousePosition.X = 0; 01071 Console->CurrentScreenBuffer->BufferInfo.TextInfo.MousePosition.Y = 0; 01072 } 01073 #endif 01074 ASSERT(Console->VDMProcessHandle); 01075 CloseHandle(Console->VDMProcessHandle); 01076 Console->VDMProcessHandle = NULL; 01077 01078 #if defined(FE_SB) && defined(FE_IME) && defined(i386) 01079 { 01080 if (Console->FullScreenFlags & CONSOLE_FULLSCREEN) { 01081 Console->Flags |= CONSOLE_JUST_VDM_UNREGISTERED ; 01082 } 01083 else if (Console->CurrentScreenBuffer->Flags & CONSOLE_TEXTMODE_BUFFER) { 01084 AdjustCursorPosition(Console->CurrentScreenBuffer, 01085 Console->CurrentScreenBuffer->BufferInfo.TextInfo.CursorPosition, 01086 TRUE, 01087 NULL); 01088 } 01089 } 01090 #endif 01091 } 01092 01093 ULONG 01094 SrvRegisterConsoleVDM( 01095 IN OUT PCSR_API_MSG m, 01096 IN OUT PCSR_REPLY_STATUS ReplyStatus 01097 ) 01098 { 01099 PCONSOLE_REGISTERVDM_MSG a = (PCONSOLE_REGISTERVDM_MSG)&m->u.ApiMessageData; 01100 NTSTATUS Status; 01101 PCONSOLE_INFORMATION Console; 01102 SIZE_T ViewSize; 01103 #ifdef i386 01104 VIDEO_REGISTER_VDM RegisterVdm; 01105 ULONG RegisterVdmSize = sizeof(RegisterVdm); 01106 VIDEO_VDM Vdm; 01107 #endif //i386 01108 Status = ApiPreamble(a->ConsoleHandle, 01109 &Console 01110 ); 01111 if (!NT_SUCCESS(Status)) { 01112 return Status; 01113 } 01114 01115 01116 if (!a->RegisterFlags) { 01117 // williamh, Jan 28 1994 01118 // do not do an assert here because we may have unregistered the ntvdm 01119 // and the ntvdm doesn't necessarily know this(and it could post another 01120 // unregistervdm). Return error here so NTVDM knows what to do 01121 // ASSERT(Console->Flags & CONSOLE_VDM_REGISTERED); 01122 01123 if (Console->Flags & CONSOLE_VDM_REGISTERED) { 01124 ASSERT(!(Console->Flags & CONSOLE_FULLSCREEN_NOPAINT)); 01125 UnregisterVDM(Console); 01126 #ifdef i386 01127 if (Console->FullScreenFlags & CONSOLE_FULLSCREEN_HARDWARE && 01128 Console->CurrentScreenBuffer->Flags & CONSOLE_TEXTMODE_BUFFER) { 01129 // SetVideoMode(Console->CurrentScreenBuffer); 01130 //set up cursor 01131 SetCursorInformationHW(Console->CurrentScreenBuffer, 01132 Console->CurrentScreenBuffer->BufferInfo.TextInfo.CursorSize, 01133 Console->CurrentScreenBuffer->BufferInfo.TextInfo.CursorVisible); 01134 SetCursorPositionHW(Console->CurrentScreenBuffer, 01135 Console->CurrentScreenBuffer->BufferInfo.TextInfo.CursorPosition); 01136 } 01137 #endif 01138 Status = STATUS_SUCCESS; 01139 } else { 01140 Status = STATUS_ACCESS_DENIED; 01141 } 01142 UnlockConsole(Console); 01143 return Status; 01144 } 01145 01146 if (!CsrValidateMessageBuffer(m, &a->StateSectionName, a->StateSectionNameLength, sizeof(BYTE)) || 01147 !CsrValidateMessageBuffer(m, &a->VDMBufferSectionName, a->VDMBufferSectionNameLength, sizeof(BYTE))) { 01148 01149 UnlockConsole(Console); 01150 return STATUS_INVALID_PARAMETER; 01151 } 01152 01153 // check it out. A console should have only one VDM registered. 01154 ASSERT(!(Console->Flags & CONSOLE_VDM_REGISTERED)); 01155 01156 if (Console->Flags & CONSOLE_VDM_REGISTERED) { 01157 UnlockConsole(Console); 01158 return (ULONG) STATUS_ACCESS_DENIED; 01159 } 01160 01161 ASSERT(!Console->VDMProcessHandle); 01162 01163 Status = NtDuplicateObject(NtCurrentProcess(), CONSOLE_CLIENTPROCESSHANDLE(), 01164 NtCurrentProcess(), &Console->VDMProcessHandle, 01165 0, FALSE, DUPLICATE_SAME_ACCESS); 01166 if (!NT_SUCCESS(Status)) { 01167 UnlockConsole(Console); 01168 return Status; 01169 } 01170 Console->VDMProcessId = CONSOLE_CLIENTPROCESSID(); 01171 01172 #ifdef i386 01173 01174 Vdm.ProcessHandle = Console->VDMProcessHandle; 01175 01176 // 01177 // Assume fullscreen initialization will fail. 01178 // have state length set to zero so that NTVDM will know 01179 // full screen is disabled. 01180 // 01181 01182 a->StateLength = 0; 01183 Console->StateLength = 0; 01184 Console->StateBufferClient = NULL; 01185 01186 if (FullScreenInitialized) { 01187 01188 Status = NtDuplicateObject(CONSOLE_CLIENTPROCESSHANDLE(), 01189 a->StartEvent, 01190 NtCurrentProcess(), 01191 &Console->VDMStartHardwareEvent, 01192 0, 01193 FALSE, 01194 DUPLICATE_SAME_ACCESS 01195 ); 01196 if (NT_SUCCESS(Status)) { 01197 Status = NtDuplicateObject(CONSOLE_CLIENTPROCESSHANDLE(), 01198 a->EndEvent, 01199 NtCurrentProcess(), 01200 &Console->VDMEndHardwareEvent, 01201 0, 01202 FALSE, 01203 DUPLICATE_SAME_ACCESS 01204 ); 01205 if (NT_SUCCESS(Status)) { 01206 Status = GdiFullscreenControl(FullscreenControlRegisterVdm, 01207 &Vdm, 01208 sizeof(Vdm), 01209 &RegisterVdm, 01210 &RegisterVdmSize 01211 ); 01212 01213 if (NT_SUCCESS(Status)) { 01214 01215 // 01216 // create state section and map a view of it into server and vdm. 01217 // this section is used to get/set video hardware state during 01218 // the fullscreen<->windowed transition. we create the section 01219 // instead of the vdm for security purposes. 01220 // 01221 01222 Status = MapViewOfSection(&Console->StateSectionHandle, 01223 RegisterVdm.MinimumStateSize, 01224 &Console->StateBuffer, 01225 &ViewSize, 01226 Console->VDMProcessHandle, 01227 &a->StateBuffer 01228 ); 01229 01230 if (NT_SUCCESS(Status)) { 01231 a->StateLength = RegisterVdm.MinimumStateSize; 01232 Console->StateLength = RegisterVdm.MinimumStateSize; 01233 Console->StateBufferClient = a->StateBuffer; 01234 } 01235 01236 } else { 01237 01238 CloseHandle(Console->VDMStartHardwareEvent); 01239 CloseHandle(Console->VDMEndHardwareEvent); 01240 } 01241 01242 } else { 01243 01244 // ASSERT(FALSE); 01245 CloseHandle(Console->VDMStartHardwareEvent); 01246 CloseHandle(Console->VDMEndHardwareEvent); 01247 } 01248 01249 } else { 01250 CloseHandle(Console->VDMStartHardwareEvent); 01251 } 01252 // 01253 // if failed to duplicate screen switch events or map view 01254 // to video state shared buffer, fails this API 01255 // 01256 if (!NT_SUCCESS(Status)) { 01257 UnlockConsole(Console); 01258 return (Status); 01259 } 01260 } 01261 01262 #endif 01263 // 01264 // create vdm char section and map a view of it into server and vdm. 01265 // this section is used by the vdm to update the screen when in a 01266 // charmode window. this is a performance optimization. we create 01267 // the section instead of the vdm for security purposes. 01268 // 01269 01270 Status = MapViewOfSection(&Console->VDMBufferSectionHandle, 01271 #ifdef i386 01272 a->VDMBufferSize.X*a->VDMBufferSize.Y*2, 01273 #else //risc 01274 a->VDMBufferSize.X*a->VDMBufferSize.Y*4, 01275 #endif 01276 &Console->VDMBuffer, 01277 &ViewSize, 01278 Console->VDMProcessHandle, 01279 &a->VDMBuffer 01280 ); 01281 if (!NT_SUCCESS(Status)) { 01282 01283 Console->VDMBuffer = NULL; 01284 01285 #ifdef i386 01286 01287 if (FullScreenInitialized) { 01288 01289 NtUnmapViewOfSection(NtCurrentProcess(),Console->StateBuffer); 01290 NtUnmapViewOfSection(Console->VDMProcessHandle,Console->StateBufferClient); 01291 NtClose(Console->StateSectionHandle); 01292 CloseHandle(Console->VDMStartHardwareEvent); 01293 CloseHandle(Console->VDMEndHardwareEvent); 01294 } 01295 01296 #endif 01297 CloseHandle(Console->VDMProcessHandle); 01298 Console->VDMProcessHandle = NULL; 01299 UnlockConsole(Console); 01300 return((ULONG) Status); 01301 } 01302 Console->VDMBufferClient = a->VDMBuffer; 01303 01304 Console->Flags |= CONSOLE_VDM_REGISTERED; 01305 01306 if (Console->Flags & CONSOLE_HAS_FOCUS) { 01307 USERTHREAD_FLAGS Flags; 01308 01309 Flags.dwFlags = TIF_VDMAPP; 01310 Flags.dwMask = TIF_VDMAPP; 01311 NtUserSetInformationThread(Console->InputThreadInfo->ThreadHandle, 01312 UserThreadFlags, &Flags, sizeof(Flags)); 01313 } 01314 Console->VDMBufferSize = a->VDMBufferSize; 01315 01316 if (a->RegisterFlags & CONSOLE_REGISTER_WOW) 01317 Console->Flags |= CONSOLE_WOW_REGISTERED; 01318 else 01319 Console->Flags &= ~CONSOLE_WOW_REGISTERED; 01320 01321 // 01322 // if we're already in fullscreen and we run a DOS app for 01323 // the first time, connect the emulator. 01324 // 01325 01326 #ifdef i386 01327 if (Console->FullScreenFlags & CONSOLE_FULLSCREEN_HARDWARE) { 01328 RECT CursorRect; 01329 CursorRect.left = -32767; 01330 CursorRect.top = -32767; 01331 CursorRect.right = 32767; 01332 CursorRect.bottom = 32767; 01333 NtUserConsoleControl(ConsoleSetVDMCursorBounds, &CursorRect, sizeof(RECT)); 01334 // connect emulator 01335 ASSERT(!(Console->Flags & CONSOLE_CONNECTED_TO_EMULATOR)); 01336 ConnectToEmulator(TRUE, Console); 01337 } 01338 #endif 01339 01340 UnlockConsole(Console); 01341 return Status; 01342 UNREFERENCED_PARAMETER(ReplyStatus); // get rid of unreferenced parameter warning message 01343 } 01344 01345 NTSTATUS 01346 SrvConsoleNotifyLastClose( 01347 IN OUT PCSR_API_MSG m, 01348 IN OUT PCSR_REPLY_STATUS ReplyStatus 01349 ) 01350 { 01351 PCONSOLE_NOTIFYLASTCLOSE_MSG a = (PCONSOLE_NOTIFYLASTCLOSE_MSG)&m->u.ApiMessageData; 01352 NTSTATUS Status; 01353 PCONSOLE_INFORMATION Console; 01354 01355 Status = ApiPreamble(a->ConsoleHandle, 01356 &Console 01357 ); 01358 if (!NT_SUCCESS(Status)) { 01359 return Status; 01360 } 01361 // williamh, Feb 2 1994. 01362 // this non-X86 special case is not necessary. We expect 01363 // ntvdm to call RegisterConsoleVDM API and there we do duplicate 01364 // the vdm process handle and grab its process id. 01365 // If we continue to do this we may hit the assert below 01366 // because when RegisterConsoleVDM failed(short of memory, for example) 01367 // the VDMProcessHandle may have been set and next time a vdm application 01368 // was launched from the same console(ntvdm will do the NotifyLastClose 01369 // before RegisterConsoleVDM). 01370 #if 0 01371 #if !defined(_X86_) 01372 ASSERT(Console->VDMProcessHandle == NULL); 01373 Status = NtDuplicateObject(NtCurrentProcess(), CONSOLE_CLIENTPROCESSHANDLE(), 01374 NtCurrentProcess(), &Console->VDMProcessHandle, 01375 0, FALSE, DUPLICATE_SAME_ACCESS); 01376 if (!NT_SUCCESS(Status)) { 01377 return Status; 01378 } 01379 Console->VDMProcessId = CONSOLE_CLIENTPROCESSID(); 01380 #endif 01381 #endif 01382 // Doesn't allow two or more processes to have last-close notify on 01383 // the same console 01384 if (Console->Flags & CONSOLE_NOTIFY_LAST_CLOSE) { 01385 UnlockConsole(Console); 01386 return (ULONG)STATUS_ACCESS_DENIED; 01387 } 01388 01389 Status = NtDuplicateObject(NtCurrentProcess(), CONSOLE_CLIENTPROCESSHANDLE(), 01390 NtCurrentProcess(), 01391 &Console->hProcessLastNotifyClose, 01392 0, FALSE, DUPLICATE_SAME_ACCESS 01393 ); 01394 if (!NT_SUCCESS(Status)) { 01395 UnlockConsole(Console); 01396 return Status; 01397 } 01398 01399 Console->Flags |= CONSOLE_NOTIFY_LAST_CLOSE; 01400 Console->ProcessIdLastNotifyClose = CONSOLE_CLIENTPROCESSID(); 01401 UnlockConsole(Console); 01402 return Status; 01403 UNREFERENCED_PARAMETER(ReplyStatus); // get rid of unreferenced parameter warning message 01404 } 01405 01406 NTSTATUS 01407 MapViewOfSection( 01408 PHANDLE SectionHandle, 01409 ULONG CommitSize, 01410 PVOID *BaseAddress, 01411 PSIZE_T ViewSize, 01412 HANDLE ClientHandle, 01413 PVOID *BaseClientAddress 01414 ) 01415 { 01416 01417 OBJECT_ATTRIBUTES Obja; 01418 NTSTATUS Status; 01419 LARGE_INTEGER secSize; 01420 01421 // 01422 // open section and map a view of it. 01423 // 01424 InitializeObjectAttributes( 01425 &Obja, 01426 NULL, 01427 OBJ_CASE_INSENSITIVE, 01428 NULL, 01429 NULL 01430 ); 01431 01432 secSize.QuadPart = CommitSize; 01433 Status = NtCreateSection (SectionHandle, 01434 SECTION_ALL_ACCESS, 01435 &Obja, 01436 &secSize, 01437 PAGE_READWRITE, 01438 SEC_RESERVE, 01439 NULL 01440 ); 01441 if (!NT_SUCCESS(Status)) { 01442 return((ULONG) Status); 01443 } 01444 01445 *BaseAddress = 0; 01446 *ViewSize = 0; 01447 01448 Status = NtMapViewOfSection(*SectionHandle, 01449 NtCurrentProcess(), 01450 BaseAddress, // Receives the base 01451 // address of the section. 01452 01453 0, // No specific type of 01454 // address required. 01455 01456 CommitSize, // Commit size. It was 01457 // passed by the caller. 01458 // NULL for a save, and 01459 // size of the section 01460 // for a set. 01461 01462 NULL, // Section offset it NULL; 01463 // Map from the start. 01464 01465 ViewSize, // View Size is NULL since 01466 // we want to map the 01467 // entire section. 01468 01469 ViewUnmap, 01470 0L, 01471 PAGE_READWRITE 01472 ); 01473 if (!NT_SUCCESS(Status)) { 01474 NtClose(*SectionHandle); 01475 return Status; 01476 } 01477 01478 *BaseClientAddress = 0; 01479 *ViewSize = 0; 01480 Status = NtMapViewOfSection(*SectionHandle, 01481 ClientHandle, 01482 BaseClientAddress, // Receives the base 01483 // address of the section. 01484 01485 0, // No specific type of 01486 // address required. 01487 01488 CommitSize, // Commit size. It was 01489 // passed by the caller. 01490 // NULL for a save, and 01491 // size of the section 01492 // for a set. 01493 01494 NULL, // Section offset it NULL; 01495 // Map from the start. 01496 01497 ViewSize, // View Size is NULL since 01498 // we want to map the 01499 // entire section. 01500 01501 ViewUnmap, 01502 // williamh, Jan 28 1994 01503 // This MEM_TOP_DOWN is necessary. 01504 // if the console has VDM registered, ntvdm would have released its video memory 01505 // address space(0xA0000 ~ 0xBFFFF). Without the MEM_TOP_DOWN, the 01506 // NtMapViewOfSection can grab the address space and we will have trouble of 01507 // mapping the address space to the physical video ram. We don't do a test 01508 // for VDM because there is no harm of doing this for non-vdm application. 01509 MEM_TOP_DOWN, 01510 PAGE_READWRITE 01511 ); 01512 if (!NT_SUCCESS(Status)) { 01513 NtClose(*SectionHandle); 01514 } 01515 return((ULONG) Status); 01516 } 01517 01518 NTSTATUS 01519 ConnectToEmulator( 01520 IN BOOL Connect, 01521 IN PCONSOLE_INFORMATION Console 01522 ) 01523 { 01524 NTSTATUS Status; 01525 FULLSCREENCONTROL fsctl; 01526 VIDEO_VDM ConnectInfo; 01527 HANDLE ProcessHandle = Console->VDMProcessHandle; 01528 USERTHREAD_FLAGS Flags; 01529 01530 DBGFULLSCR(("ConnectToEmulator : %s - entering\n", Connect ? "CONNECT" : "DISCONNECT")); 01531 01532 Flags.dwMask = TIF_DOSEMULATOR; 01533 if (Connect) { 01534 fsctl = FullscreenControlEnable; 01535 Console->Flags |= CONSOLE_CONNECTED_TO_EMULATOR; 01536 Flags.dwFlags = TIF_DOSEMULATOR; 01537 } else { 01538 fsctl = FullscreenControlDisable; 01539 Console->Flags &= ~CONSOLE_CONNECTED_TO_EMULATOR; 01540 Flags.dwFlags = 0; 01541 } 01542 01543 if (Console->Flags & CONSOLE_HAS_FOCUS) { 01544 NtUserSetInformationThread(Console->InputThreadInfo->ThreadHandle, 01545 UserThreadFlags, &Flags, sizeof(Flags)); 01546 } 01547 01548 ConnectInfo.ProcessHandle = ProcessHandle; 01549 01550 01551 Status = GdiFullscreenControl(fsctl, 01552 &ConnectInfo, 01553 sizeof(ConnectInfo), 01554 NULL, 01555 NULL); 01556 01557 ASSERT(Status == STATUS_SUCCESS || Status == STATUS_PROCESS_IS_TERMINATING); 01558 01559 DBGFULLSCR(("ConnectToEmulator : leaving, staus = %08lx\n", Status)); 01560 01561 return Status; 01562 } 01563 01564 #define CONSOLE_VDM_TIMEOUT 200000 01565 01566 NTSTATUS 01567 DisplayModeTransition( 01568 IN BOOL bForeground, 01569 IN PCONSOLE_INFORMATION Console, 01570 IN PSCREEN_INFORMATION ScreenInfo 01571 ) 01572 { 01573 #ifdef i386 01574 NTSTATUS Status; 01575 LARGE_INTEGER li; 01576 01577 if (!FullScreenInitialized) 01578 return STATUS_SUCCESS; 01579 01580 if (bForeground) { 01581 01582 PSCREEN_INFORMATION ScreenInfo = Console->CurrentScreenBuffer; 01583 LARGE_INTEGER li; 01584 NTSTATUS Status; 01585 01586 KdPrint((" CONSRV - Display Mode transition to fullscreen \n")); 01587 01588 if (!(Console->FullScreenFlags & CONSOLE_FULLSCREEN)) { 01589 KdPrint(("CONSRV: received fullscreen message too early\n")); 01590 return STATUS_UNSUCCESSFUL; 01591 } 01592 01593 Console->FullScreenFlags |= CONSOLE_FULLSCREEN_HARDWARE; 01594 01595 if (!(ScreenInfo->Flags & CONSOLE_GRAPHICS_BUFFER)) { 01596 #if defined(FE_SB) 01597 BOOL fGraphics = fFullScreenGraphics ? IsAvailableFsCodePage(Console->OutputCP) : FALSE; 01598 #endif 01599 #if 1 01600 DEVMODEW Devmode; 01601 ULONG Index; 01602 01603 KdPrint(("CONSRV: ChangeDispSettings fullscreen\n")); 01604 01605 Index = Console->CurrentScreenBuffer->BufferInfo.TextInfo.ModeIndex; 01606 01607 // 01608 // set mode to go to full screen 01609 // 01610 01611 ZeroMemory(&Devmode, sizeof(Devmode)); 01612 01613 Devmode.dmSize = sizeof(Devmode); 01614 Devmode.dmDriverExtra = 0; 01615 Devmode.dmFields = DM_BITSPERPEL | 01616 DM_PELSWIDTH | 01617 DM_PELSHEIGHT | 01618 DM_DISPLAYFLAGS; 01619 01620 Devmode.dmBitsPerPel = 4; 01621 #if defined(FE_SB) 01622 Devmode.dmPelsWidth = RegModeFontPairs[Index].Resolution.X; 01623 Devmode.dmPelsHeight = RegModeFontPairs[Index].Resolution.Y; 01624 Devmode.dmDisplayFlags = (fGraphics && (RegModeFontPairs[Index].Mode & FS_MODE_GRAPHICS)) ? 0 : DMDISPLAYFLAGS_TEXTMODE; 01625 #else 01626 Devmode.dmPelsWidth = ModeFontPairs[Index].Resolution.X; 01627 Devmode.dmPelsHeight = ModeFontPairs[Index].Resolution.Y; 01628 Devmode.dmDisplayFlags = DMDISPLAYFLAGS_TEXTMODE; 01629 #endif 01630 01631 if (NT_SUCCESS(GdiFullscreenControl(FullscreenControlSetMode, 01632 &Devmode, 01633 sizeof(Devmode), 01634 NULL, 01635 NULL))) 01636 { 01637 #endif 01638 // set video mode and font 01639 if (SetVideoMode(ScreenInfo)) { 01640 01641 #if defined(FE_SB) 01642 if (!(Console->Flags & CONSOLE_VDM_REGISTERED)) { 01643 int i ; 01644 for (i = 0 ; i < ScreenInfo->ScreenBufferSize.Y; i++) { 01645 ScreenInfo->BufferInfo.TextInfo.Rows[i].CharRow.OldLeft = INVALID_OLD_LENGTH ; 01646 ScreenInfo->BufferInfo.TextInfo.Rows[i].CharRow.OldRight = INVALID_OLD_LENGTH ; 01647 } 01648 } 01649 #endif 01650 //set up cursor 01651 01652 SetCursorInformationHW(ScreenInfo, 01653 ScreenInfo->BufferInfo.TextInfo.CursorSize, 01654 ScreenInfo->BufferInfo.TextInfo.CursorVisible); 01655 SetCursorPositionHW(ScreenInfo, 01656 ScreenInfo->BufferInfo.TextInfo.CursorPosition); 01657 } 01658 } 01659 } 01660 01661 // tell VDM to unmap memory 01662 01663 if (Console->Flags & CONSOLE_VDM_REGISTERED) { 01664 li.QuadPart = (LONGLONG)-10000 * CONSOLE_VDM_TIMEOUT; 01665 Status = NtSignalAndWaitForSingleObject(Console->VDMStartHardwareEvent, 01666 Console->VDMEndHardwareEvent, 01667 FALSE, &li); 01668 if (Status != 0) { 01669 Console->Flags &= ~CONSOLE_FULLSCREEN_NOPAINT; 01670 UnregisterVDM(Console); 01671 KdPrint(("CONSRV: VDM not responding.\n")); 01672 } 01673 } 01674 01675 if (!(ScreenInfo->Flags & CONSOLE_GRAPHICS_BUFFER)) { 01676 01677 WriteRegionToScreen(ScreenInfo,&ScreenInfo->Window); 01678 } 01679 01680 if (Console->Flags & CONSOLE_VDM_REGISTERED) { 01681 01682 // connect emulator and map memory into the VDMs address space. 01683 ASSERT(!(Console->Flags & CONSOLE_CONNECTED_TO_EMULATOR)); 01684 01685 Status = ConnectToEmulator(TRUE, Console); 01686 01687 if (NT_SUCCESS(Status)) { 01688 01689 VIDEO_HARDWARE_STATE State; 01690 ULONG StateSize = sizeof(State); 01691 01692 State.StateHeader = Console->StateBuffer; 01693 State.StateLength = Console->StateLength; 01694 01695 01696 Status = GdiFullscreenControl(FullscreenControlRestoreHardwareState, 01697 &State, 01698 StateSize, 01699 &State, 01700 &StateSize); 01701 } 01702 01703 if (Status != STATUS_SUCCESS) { 01704 Console->Flags &= ~CONSOLE_FULLSCREEN_NOPAINT; 01705 UnregisterVDM(Console); 01706 KdPrint(("CONSRV: set hardware state failed.\n")); 01707 } else { 01708 01709 // 01710 // tell VDM that it's getting the hardware. 01711 // 01712 01713 RECT CursorRect; 01714 CursorRect.left = -32767; 01715 CursorRect.top = -32767; 01716 CursorRect.right = 32767; 01717 CursorRect.bottom = 32767; 01718 NtUserConsoleControl(ConsoleSetVDMCursorBounds, 01719 &CursorRect, sizeof(RECT)); 01720 01721 // wait for vdm to say ok. We could initiate another switch 01722 // (set hStartHardwareEvent which vdm is now waiting for to 01723 // complete the handshaking) when we return(WM_FULLSCREEN 01724 // could be in the message queue already). If we don't wait 01725 // for vdm to get signaled here, the hStartHardwareEvent 01726 // can get set twice and signaled once so the vdm will never 01727 // gets the newly switch request we may post after return. 01728 NtSignalAndWaitForSingleObject(Console->VDMStartHardwareEvent, 01729 Console->VDMEndHardwareEvent, 01730 FALSE, &li); 01731 // no need to check time out here 01732 01733 } 01734 01735 } 01736 01737 // 01738 // let the app know that it has the focus. 01739 // 01740 01741 HandleFocusEvent(Console,TRUE); 01742 01743 // unset palette 01744 01745 if (ScreenInfo->hPalette != NULL) { 01746 SelectPalette(ScreenInfo->Console->hDC, 01747 ScreenInfo->Console->hSysPalette, 01748 FALSE); 01749 UnsetActivePalette(ScreenInfo); 01750 } 01751 SetConsoleReserveKeys(Console->hWnd, Console->ReserveKeys); 01752 HandleFocusEvent(Console,TRUE); 01753 01754 } else { 01755 01756 KdPrint((" CONSRV - Display Mode transition to windowed \n")); 01757 01758 // 01759 // Check first to see if we're not already fullscreen. If we aren't, 01760 // don't allow this. Temporary BETA fix till USER gets fixed. 01761 // 01762 if (!(Console->FullScreenFlags & CONSOLE_FULLSCREEN_HARDWARE)) { 01763 KdPrint(("CONSRV: received multiple windowed messages\n")); 01764 return STATUS_SUCCESS; 01765 } 01766 01767 // turn off mouse pointer so VDM doesn't see it when saving 01768 // hardware 01769 if (!(ScreenInfo->Flags & CONSOLE_GRAPHICS_BUFFER)) { 01770 ReverseMousePointer(ScreenInfo, &ScreenInfo->Window); 01771 } 01772 01773 01774 Console->FullScreenFlags &= ~CONSOLE_FULLSCREEN_HARDWARE; 01775 if (Console->Flags & CONSOLE_VDM_REGISTERED) { 01776 01777 // 01778 // tell vdm that it's losing the hardware 01779 // 01780 01781 li.QuadPart = (LONGLONG)-10000 * CONSOLE_VDM_TIMEOUT; 01782 Status = NtSignalAndWaitForSingleObject(Console->VDMStartHardwareEvent, 01783 Console->VDMEndHardwareEvent, 01784 FALSE, &li); 01785 01786 // if ntvdm didn't respond or we failed to save the video hardware 01787 // states, kick ntvdm out of our world. The ntvdm process eventually 01788 // would die but what choice do have here? 01789 01790 if (NT_SUCCESS(Status)) { 01791 01792 VIDEO_HARDWARE_STATE State; 01793 ULONG StateSize = sizeof(State); 01794 01795 State.StateHeader = Console->StateBuffer; 01796 State.StateLength = Console->StateLength; 01797 01798 01799 Status = GdiFullscreenControl(FullscreenControlSaveHardwareState, 01800 &State, 01801 StateSize, 01802 &State, 01803 &StateSize); 01804 } 01805 01806 if (NT_SUCCESS(Status)) { 01807 01808 01809 NtUserConsoleControl(ConsoleSetVDMCursorBounds, NULL, 0); 01810 01811 // disconnect emulator and unmap video memory 01812 01813 ASSERT(Console->Flags & CONSOLE_CONNECTED_TO_EMULATOR); 01814 ConnectToEmulator(FALSE, Console); 01815 01816 } else { 01817 01818 Console->Flags &= ~CONSOLE_FULLSCREEN_NOPAINT; 01819 UnregisterVDM(Console); 01820 if (Status != 0) { 01821 KdPrint(("CONSRV: VDM not responding.\n")); 01822 } 01823 else 01824 KdPrint(("CONSRV: Save Video States Failed\n")); 01825 01826 } 01827 } 01828 01829 // tell VDM to map memory 01830 01831 if (Console->Flags & CONSOLE_VDM_REGISTERED) { 01832 01833 // make a special case for ntvdm during switching because 01834 // ntvdm has to make console api calls. We don't want to 01835 // unlock the console at this moment because as soon as 01836 // we release the lock, other theads which are waiting 01837 // for the lock will claim the lock and the ntvdm thread doing 01838 // the screen switch will have to wait for the lock. In an 01839 // extreme case, the following NtWaitForSingleObject will time 01840 // out because the ntvdm may be still waiting for the lock. 01841 // We keep this thing in a single global variable because 01842 // there is only one process who can own the screen at any moment. 01843 01844 RtlEnterCriticalSection(&ConsoleVDMCriticalSection); 01845 ConsoleVDMOnSwitching = Console; 01846 RtlLeaveCriticalSection(&ConsoleVDMCriticalSection); 01847 li.QuadPart = (LONGLONG)-10000 * CONSOLE_VDM_TIMEOUT; 01848 Status = NtSignalAndWaitForSingleObject(Console->VDMStartHardwareEvent, 01849 Console->VDMEndHardwareEvent, 01850 FALSE, &li); 01851 01852 // time to go back to normal 01853 RtlEnterCriticalSection(&ConsoleVDMCriticalSection); 01854 ConsoleVDMOnSwitching = NULL; 01855 RtlLeaveCriticalSection(&ConsoleVDMCriticalSection); 01856 01857 if (Status != 0) { 01858 Console->Flags &= ~CONSOLE_FULLSCREEN_NOPAINT; 01859 UnregisterVDM(Console); 01860 KdPrint(("CONSRV: VDM not responding. - second wait\n")); 01861 return Status; 01862 } 01863 ScreenInfo = Console->CurrentScreenBuffer; 01864 } 01865 01866 // set palette 01867 01868 if (ScreenInfo->hPalette != NULL) { 01869 SelectPalette(ScreenInfo->Console->hDC, 01870 ScreenInfo->hPalette, 01871 FALSE); 01872 SetActivePalette(ScreenInfo); 01873 } 01874 SetConsoleReserveKeys(Console->hWnd, CONSOLE_NOSHORTCUTKEY); 01875 HandleFocusEvent(Console,FALSE); 01876 01877 } 01878 01879 /* 01880 * Boost or lower the priority if we are going fullscreen or away. 01881 * 01882 * Note that console usually boosts and lowers its priority based 01883 * on WM_FOCUSS and WM_KILLFOCUS but when you switch to full screen 01884 * the implementation actually sends a WM_KILLFOCUS so we reboost the 01885 * correct console here. 01886 */ 01887 ModifyConsoleProcessFocus(Console, bForeground); 01888 01889 01890 #else 01891 UNREFERENCED_PARAMETER(bForeground); 01892 UNREFERENCED_PARAMETER(Console); 01893 UNREFERENCED_PARAMETER(ScreenInfo); 01894 #endif 01895 return STATUS_SUCCESS; 01896 } 01897 01898 #if defined(_X86_) 01899 01900 BOOL 01901 SetVideoMode( 01902 IN PSCREEN_INFORMATION ScreenInfo 01903 ) 01904 { 01905 NTSTATUS Status; 01906 UINT i, j; 01907 01908 #if defined(FE_SB) 01909 // 01910 // load RAM font 01911 // 01912 01913 Status = SetRAMFontCodePage(ScreenInfo); 01914 #endif 01915 01916 // 01917 // load ROM font 01918 // 01919 01920 Status = SetROMFontCodePage(ScreenInfo->Console->OutputCP, 01921 ScreenInfo->BufferInfo.TextInfo.ModeIndex); 01922 01923 if (Status == STATUS_INVALID_PARAMETER) { 01924 Status = SetROMFontCodePage(GetOEMCP(), 01925 ScreenInfo->BufferInfo.TextInfo.ModeIndex); 01926 01927 if (Status == STATUS_INVALID_PARAMETER) { 01928 Status = SetROMFontCodePage(CONSOLE_DEFAULT_ROM_FONT, 01929 ScreenInfo->BufferInfo.TextInfo.ModeIndex); 01930 } 01931 } 01932 01933 // 01934 // initialize palette 01935 // 01936 01937 #if defined(FE_SB) 01938 Status = GdiFullscreenControl(FullscreenControlSetPalette, 01939 (PVOID) RegInitialPalette, 01940 RegInitialPalette[0] * sizeof(USHORT) + sizeof(DWORD), 01941 NULL, 01942 NULL); 01943 #else 01944 Status = GdiFullscreenControl(FullscreenControlSetPalette, 01945 (PVOID) &InitialPalette, 01946 sizeof (InitialPalette), 01947 NULL, 01948 NULL); 01949 #endif 01950 01951 if (Status != STATUS_SUCCESS) { 01952 KdPrint(("CONSRV: FullscreenControlSetPalette failed - status = %x\n", 01953 Status)); 01954 ASSERT(FALSE); 01955 return FALSE; 01956 } 01957 01958 // 01959 // initialize color table 01960 // 01961 01962 #if defined(FE_SB) 01963 if (RegColorBufferNoTranslate) 01964 { 01965 Status = GdiFullscreenControl(FullscreenControlSetColors, 01966 (PVOID) RegColorBufferNoTranslate, 01967 RegColorBufferNoTranslate[0] * sizeof(DWORD) + sizeof(DWORD), 01968 NULL, 01969 NULL); 01970 } 01971 else 01972 { 01973 for (i = 0, j = 4; i < 16; i++) { 01974 RegColorBuffer[j++] = ((((GetRValue(ScreenInfo->Console->ColorTable[i]) + 01975 0x2A) * 0x02) / 0x55) * 0x15) / 0x02; 01976 RegColorBuffer[j++] = ((((GetGValue(ScreenInfo->Console->ColorTable[i]) + 01977 0x2A) * 0x02) / 0x55) * 0x15) / 0x02; 01978 RegColorBuffer[j++] = ((((GetBValue(ScreenInfo->Console->ColorTable[i]) + 01979 0x2A) * 0x02) / 0x55) * 0x15) / 0x02; 01980 RegColorBuffer[j++] = 0; 01981 } 01982 01983 Status = GdiFullscreenControl(FullscreenControlSetColors, 01984 (PVOID) RegColorBuffer, 01985 RegColorBuffer[0] * sizeof(DWORD) + sizeof(DWORD), 01986 NULL, 01987 NULL); 01988 } 01989 #else 01990 for (i = 0, j = 4; i < 16; i++) { 01991 ColorBuffer[j++] = ((((GetRValue(ScreenInfo->Console->ColorTable[i]) + 01992 0x2A) * 0x02) / 0x55) * 0x15) / 0x02; 01993 ColorBuffer[j++] = ((((GetGValue(ScreenInfo->Console->ColorTable[i]) + 01994 0x2A) * 0x02) / 0x55) * 0x15) / 0x02; 01995 ColorBuffer[j++] = ((((GetBValue(ScreenInfo->Console->ColorTable[i]) + 01996 0x2A) * 0x02) / 0x55) * 0x15) / 0x02; 01997 ColorBuffer[j++] = 0; 01998 } 01999 02000 Status = GdiFullscreenControl(FullscreenControlSetColors, 02001 (PVOID) &ColorBuffer, 02002 sizeof (ColorBuffer), 02003 NULL, 02004 NULL); 02005 #endif 02006 02007 if (Status != STATUS_SUCCESS) { 02008 KdPrint(("CONSRV: FullscreenControlSetColors failed - status = %x\n", 02009 Status)); 02010 ASSERT(FALSE); 02011 return FALSE; 02012 } 02013 02014 02015 return TRUE; 02016 } 02017 02018 #endif 02019 02020 02021 #if defined(_X86_) 02022 02023 NTSTATUS 02024 ChangeDispSettings( 02025 PCONSOLE_INFORMATION Console, 02026 HWND hwnd, 02027 DWORD dwFlags) 02028 { 02029 DEVMODEW Devmode; 02030 ULONG Index; 02031 CONSOLE_FULLSCREEN_SWITCH switchBlock; 02032 02033 if (dwFlags == CDS_FULLSCREEN) 02034 { 02035 #if defined(FE_SB) 02036 BOOL fGraphics = fFullScreenGraphics ? IsAvailableFsCodePage(Console->OutputCP) : FALSE; 02037 #endif 02038 02039 KdPrint(("CONSRV: ChangeDispSettings fullscreen\n")); 02040 02041 Index = Console->CurrentScreenBuffer->BufferInfo.TextInfo.ModeIndex; 02042 02043 // 02044 // set mode to go to full screen 02045 // 02046 02047 ZeroMemory(&Devmode, sizeof(Devmode)); 02048 02049 Devmode.dmSize = sizeof(Devmode); 02050 Devmode.dmDriverExtra = 0; 02051 Devmode.dmFields = DM_BITSPERPEL | 02052 DM_PELSWIDTH | 02053 DM_PELSHEIGHT | 02054 DM_DISPLAYFLAGS; 02055 02056 Devmode.dmBitsPerPel = 4; 02057 #if defined(FE_SB) 02058 Devmode.dmPelsWidth = RegModeFontPairs[Index].Resolution.X; 02059 Devmode.dmPelsHeight = RegModeFontPairs[Index].Resolution.Y; 02060 Devmode.dmDisplayFlags = (fGraphics && (RegModeFontPairs[Index].Mode & FS_MODE_GRAPHICS)) ? 0 : DMDISPLAYFLAGS_TEXTMODE; 02061 #else 02062 Devmode.dmPelsWidth = ModeFontPairs[Index].Resolution.X; 02063 Devmode.dmPelsHeight = ModeFontPairs[Index].Resolution.Y; 02064 Devmode.dmDisplayFlags = DMDISPLAYFLAGS_TEXTMODE; 02065 #endif 02066 02067 switchBlock.bFullscreenSwitch = TRUE; 02068 switchBlock.hwnd = hwnd; 02069 switchBlock.pNewMode = &Devmode; 02070 02071 } 02072 else 02073 { 02074 KdPrint(("CONSRV: ChangeDispSettings windowed\n")); 02075 02076 switchBlock.bFullscreenSwitch = FALSE; 02077 switchBlock.hwnd = hwnd; 02078 switchBlock.pNewMode = NULL; 02079 } 02080 02081 return NtUserConsoleControl(ConsoleFullscreenSwitch, 02082 &switchBlock, 02083 sizeof(CONSOLE_FULLSCREEN_SWITCH)); 02084 } 02085 02086 #endif 02087 02088 BOOL 02089 InitializeFullScreen( VOID ) 02090 { 02091 UNICODE_STRING vgaString; 02092 DEVMODEW devmode; 02093 ULONG i; 02094 #if !defined(FE_SB) 02095 BOOLEAN mode1 = FALSE; 02096 BOOLEAN mode2 = FALSE; 02097 #else 02098 DWORD mode1 = 0; 02099 DWORD mode2 = 0; 02100 #endif 02101 02102 CHAR WindowsDir[CONSOLE_WINDOWS_DIR_LENGTH+CONSOLE_EGACPI_LENGTH]; 02103 UINT WindowsDirLength; 02104 02105 // 02106 // query number of available modes 02107 // 02108 02109 ZeroMemory(&devmode, sizeof(DEVMODEW)); 02110 devmode.dmSize = sizeof(DEVMODEW); 02111 02112 RtlInitUnicodeString(&vgaString, L"VGACOMPATIBLE"); 02113 02114 DBGCHARS(("Number of modes = %d\n", NUMBER_OF_MODE_FONT_PAIRS)); 02115 02116 for (i=0; ; i++) 02117 { 02118 DBGCHARS(("EnumDisplaySettings %d\n", i)); 02119 02120 if (!(NT_SUCCESS(NtUserEnumDisplaySettings(&vgaString, 02121 i, 02122 &devmode, 02123 0)))) 02124 { 02125 break; 02126 } 02127 02128 #if defined(FE_SB) 02129 { 02130 ULONG Index; 02131 02132 DBGCHARS(("Mode X = %d, Y = %d\n", 02133 devmode.dmPelsWidth, devmode.dmPelsHeight)); 02134 02135 for (Index=0;Index<NUMBER_OF_MODE_FONT_PAIRS;Index++) 02136 { 02137 if ((SHORT)devmode.dmPelsWidth == RegModeFontPairs[Index].Resolution.X && 02138 (SHORT)devmode.dmPelsHeight == RegModeFontPairs[Index].Resolution.Y ) 02139 { 02140 if (devmode.dmDisplayFlags & DMDISPLAYFLAGS_TEXTMODE) 02141 { 02142 if (RegModeFontPairs[Index].Mode & FS_MODE_TEXT) 02143 { 02144 RegModeFontPairs[Index].Mode |= FS_MODE_FIND; 02145 mode1++; 02146 } 02147 } 02148 else 02149 { 02150 if (RegModeFontPairs[Index].Mode & FS_MODE_GRAPHICS) 02151 { 02152 RegModeFontPairs[Index].Mode |= FS_MODE_FIND; 02153 mode2++; 02154 } 02155 } 02156 } 02157 } 02158 02159 DBGCHARS(("mode1 = %d, mode2 = %d\n", mode1, mode2)); 02160 } 02161 #else 02162 02163 if (devmode.dmPelsWidth == 720 && 02164 devmode.dmPelsHeight == 400) 02165 { 02166 mode1 = TRUE; 02167 } 02168 if (devmode.dmPelsWidth == 640 && 02169 devmode.dmPelsHeight == 350) 02170 { 02171 mode2 = TRUE; 02172 } 02173 #endif 02174 } 02175 02176 #if !defined(FE_SB) 02177 if (!(mode1 && mode2)) 02178 #else 02179 if (mode1 < 2) 02180 #endif 02181 { 02182 // 02183 // One of the modes we expected to get was not returned. 02184 // lets just fail fullscreen initialization. 02185 // 02186 02187 KdPrint(("CONSRV: InitializeFullScreen Missing text mode\n")); 02188 return FALSE; 02189 } 02190 02191 #if defined(FE_SB) 02192 if (mode2 > 0) 02193 { 02194 // Can do trun graphics mode. 02195 fFullScreenGraphics = TRUE; 02196 } 02197 #endif 02198 02199 // 02200 // open ega.cpi 02201 // 02202 02203 WindowsDirLength = GetSystemDirectoryA(WindowsDir, 02204 CONSOLE_WINDOWS_DIR_LENGTH); 02205 if (WindowsDirLength == 0) 02206 { 02207 KdPrint(("CONSRV: InitializeFullScreen Finding Font file failed\n")); 02208 return FALSE; 02209 } 02210 02211 RtlCopyMemory(&WindowsDir[WindowsDirLength], 02212 CONSOLE_EGACPI, 02213 CONSOLE_EGACPI_LENGTH); 02214 02215 if ((hCPIFile = CreateFileA(WindowsDir, 02216 GENERIC_READ, 02217 FILE_SHARE_READ, 02218 NULL, 02219 OPEN_EXISTING, 02220 0, 02221 NULL)) == (HANDLE)-1) 02222 { 02223 KdPrint(("CONSRV: InitializeFullScreen Opening Font file failed\n")); 02224 return FALSE; 02225 } 02226 02227 return TRUE; 02228 } 02229 02230 02231 ULONG 02232 SrvGetConsoleHardwareState( 02233 IN OUT PCSR_API_MSG m, 02234 IN OUT PCSR_REPLY_STATUS ReplyStatus 02235 ) 02236 { 02237 #ifdef i386 02238 PCONSOLE_GETHARDWARESTATE_MSG a = (PCONSOLE_GETHARDWARESTATE_MSG)&m->u.ApiMessageData; 02239 NTSTATUS Status; 02240 PCONSOLE_INFORMATION Console; 02241 PHANDLE_DATA HandleData; 02242 PSCREEN_INFORMATION ScreenInfo; 02243 02244 Status = ApiPreamble(a->ConsoleHandle, 02245 &Console 02246 ); 02247 if (!NT_SUCCESS(Status)) { 02248 return Status; 02249 } 02250 Status = DereferenceIoHandle(CONSOLE_PERPROCESSDATA(), 02251 a->OutputHandle, 02252 CONSOLE_OUTPUT_HANDLE, 02253 GENERIC_READ, 02254 &HandleData 02255 ); 02256 if (NT_SUCCESS(Status)) { 02257 ScreenInfo = HandleData->Buffer.ScreenBuffer; 02258 if (ScreenInfo->BufferInfo.TextInfo.ModeIndex == -1) { 02259 UnlockConsole(Console); 02260 return (ULONG)STATUS_UNSUCCESSFUL; 02261 } 02262 #if defined(FE_SB) 02263 a->Resolution = RegModeFontPairs[ScreenInfo->BufferInfo.TextInfo.ModeIndex].Resolution; 02264 a->FontSize = RegModeFontPairs[ScreenInfo->BufferInfo.TextInfo.ModeIndex].FontSize; 02265 #else 02266 a->Resolution = ModeFontPairs[ScreenInfo->BufferInfo.TextInfo.ModeIndex].Resolution; 02267 a->FontSize = ModeFontPairs[ScreenInfo->BufferInfo.TextInfo.ModeIndex].FontSize; 02268 #endif 02269 } 02270 UnlockConsole(Console); 02271 return Status; 02272 #else 02273 return (ULONG)STATUS_UNSUCCESSFUL; 02274 UNREFERENCED_PARAMETER(m); // get rid of unreferenced parameter warning message 02275 #endif 02276 UNREFERENCED_PARAMETER(ReplyStatus); // get rid of unreferenced parameter warning message 02277 } 02278 02279 ULONG 02280 SrvSetConsoleHardwareState( 02281 IN OUT PCSR_API_MSG m, 02282 IN OUT PCSR_REPLY_STATUS ReplyStatus 02283 ) 02284 { 02285 #ifdef i386 02286 PCONSOLE_SETHARDWARESTATE_MSG a = (PCONSOLE_SETHARDWARESTATE_MSG)&m->u.ApiMessageData; 02287 NTSTATUS Status; 02288 PCONSOLE_INFORMATION Console; 02289 PHANDLE_DATA HandleData; 02290 PSCREEN_INFORMATION ScreenInfo; 02291 ULONG Index; 02292 02293 Status = ApiPreamble(a->ConsoleHandle, 02294 &Console 02295 ); 02296 if (!NT_SUCCESS(Status)) { 02297 return Status; 02298 } 02299 if (!(Console->FullScreenFlags & CONSOLE_FULLSCREEN_HARDWARE)) { 02300 UnlockConsole(Console); 02301 return (ULONG)STATUS_UNSUCCESSFUL; 02302 } 02303 Status = DereferenceIoHandle(CONSOLE_PERPROCESSDATA(), 02304 a->OutputHandle, 02305 CONSOLE_OUTPUT_HANDLE, 02306 GENERIC_READ, 02307 &HandleData 02308 ); 02309 if (NT_SUCCESS(Status)) { 02310 #if defined(FE_SB) 02311 BOOL fGraphics = fFullScreenGraphics ? IsAvailableFsCodePage(Console->OutputCP) : FALSE; 02312 #endif 02313 ScreenInfo = HandleData->Buffer.ScreenBuffer; 02314 02315 // match requested mode 02316 02317 for (Index=0;Index<NUMBER_OF_MODE_FONT_PAIRS;Index++) { 02318 #if defined(FE_SB) 02319 if (a->Resolution.X == RegModeFontPairs[Index].Resolution.X && 02320 a->Resolution.Y == RegModeFontPairs[Index].Resolution.Y && 02321 a->FontSize.Y == RegModeFontPairs[Index].FontSize.Y && 02322 a->FontSize.X == RegModeFontPairs[Index].FontSize.X && 02323 ( ( fGraphics && (RegModeFontPairs[Index].Mode & FS_GRAPHICS)==FS_GRAPHICS) || 02324 (!fGraphics && (RegModeFontPairs[Index].Mode & FS_TEXT)==FS_TEXT) ) 02325 ) { 02326 break; 02327 } 02328 #else 02329 if (a->Resolution.X == ModeFontPairs[Index].Resolution.X && 02330 a->Resolution.Y == ModeFontPairs[Index].Resolution.Y && 02331 a->FontSize.Y == ModeFontPairs[Index].FontSize.Y && 02332 a->FontSize.X == ModeFontPairs[Index].FontSize.X) { 02333 break; 02334 } 02335 #endif 02336 } 02337 if (Index == NUMBER_OF_MODE_FONT_PAIRS) { 02338 Status = STATUS_INVALID_PARAMETER; 02339 } else { 02340 // set requested mode 02341 ScreenInfo->BufferInfo.TextInfo.ModeIndex = Index; 02342 SetVideoMode(ScreenInfo); 02343 } 02344 } 02345 UnlockConsole(Console); 02346 return Status; 02347 #else 02348 return (ULONG)STATUS_UNSUCCESSFUL; 02349 UNREFERENCED_PARAMETER(m); // get rid of unreferenced parameter warning message 02350 #endif 02351 UNREFERENCED_PARAMETER(ReplyStatus); // get rid of unreferenced parameter warning message 02352 } 02353 02354 ULONG 02355 SrvGetConsoleDisplayMode( 02356 IN OUT PCSR_API_MSG m, 02357 IN OUT PCSR_REPLY_STATUS ReplyStatus 02358 ) 02359 { 02360 PCONSOLE_GETDISPLAYMODE_MSG a = (PCONSOLE_GETDISPLAYMODE_MSG)&m->u.ApiMessageData; 02361 NTSTATUS Status; 02362 PCONSOLE_INFORMATION Console; 02363 02364 Status = ApiPreamble(a->ConsoleHandle, 02365 &Console 02366 ); 02367 if (NT_SUCCESS(Status)) { 02368 a->ModeFlags = Console->FullScreenFlags; 02369 UnlockConsole(Console); 02370 } 02371 return Status; 02372 UNREFERENCED_PARAMETER(ReplyStatus); 02373 } 02374 02375 ULONG 02376 SrvSetConsoleMenuClose( 02377 IN OUT PCSR_API_MSG m, 02378 IN OUT PCSR_REPLY_STATUS ReplyStatus 02379 ) 02380 { 02381 PCONSOLE_SETMENUCLOSE_MSG a = (PCONSOLE_SETMENUCLOSE_MSG)&m->u.ApiMessageData; 02382 NTSTATUS Status; 02383 PCONSOLE_INFORMATION Console; 02384 02385 Status = ApiPreamble(a->ConsoleHandle, 02386 &Console 02387 ); 02388 if (!NT_SUCCESS(Status)) { 02389 return Status; 02390 } 02391 if (a->Enable) { 02392 Console->Flags &= ~CONSOLE_DISABLE_CLOSE; 02393 } else { 02394 Console->Flags |= CONSOLE_DISABLE_CLOSE; 02395 } 02396 UnlockConsole(Console); 02397 return Status; 02398 UNREFERENCED_PARAMETER(ReplyStatus); // get rid of unreferenced parameter warning message 02399 } 02400 02401 02402 DWORD 02403 ConvertHotKey( 02404 IN LPAPPKEY UserAppKey 02405 ) 02406 { 02407 DWORD wParam; 02408 02409 wParam = MapVirtualKey(UserAppKey->ScanCode,1); 02410 if (UserAppKey->Modifier & CONSOLE_MODIFIER_SHIFT) { 02411 wParam |= 0x0100; 02412 } 02413 if (UserAppKey->Modifier & CONSOLE_MODIFIER_CONTROL) { 02414 wParam |= 0x0200; 02415 } 02416 if (UserAppKey->Modifier & CONSOLE_MODIFIER_ALT) { 02417 wParam |= 0x0400; 02418 } 02419 return wParam; 02420 } 02421 02422 ULONG 02423 SrvSetConsoleKeyShortcuts( 02424 IN OUT PCSR_API_MSG m, 02425 IN OUT PCSR_REPLY_STATUS ReplyStatus 02426 ) 02427 { 02428 PCONSOLE_SETKEYSHORTCUTS_MSG a = (PCONSOLE_SETKEYSHORTCUTS_MSG)&m->u.ApiMessageData; 02429 NTSTATUS Status; 02430 PCONSOLE_INFORMATION Console; 02431 02432 Status = ApiPreamble(a->ConsoleHandle, 02433 &Console 02434 ); 02435 if (!NT_SUCCESS(Status)) { 02436 return Status; 02437 } 02438 02439 if (!CsrValidateMessageBuffer(m, &a->AppKeys, a->NumAppKeys, sizeof(*a->AppKeys))) { 02440 UnlockConsole(Console); 02441 return STATUS_INVALID_PARAMETER; 02442 } 02443 02444 if (a->NumAppKeys <= CONSOLE_MAX_APP_SHORTCUTS) { 02445 Console->ReserveKeys = a->ReserveKeys; 02446 if (Console->Flags & CONSOLE_HAS_FOCUS) { 02447 if (!(SetConsoleReserveKeys(Console->hWnd,a->ReserveKeys))) { 02448 Status = STATUS_INVALID_PARAMETER; 02449 } 02450 } 02451 if (a->NumAppKeys) { 02452 PostMessage(Console->hWnd, 02453 WM_SETHOTKEY, 02454 ConvertHotKey(a->AppKeys), 02455 0 02456 ); 02457 } 02458 } else { 02459 Status = STATUS_INVALID_PARAMETER; 02460 } 02461 UnlockConsole(Console); 02462 return Status; 02463 UNREFERENCED_PARAMETER(ReplyStatus); // get rid of unreferenced parameter warning message 02464 } 02465 02466 #ifdef i386 02467 ULONG 02468 MatchWindowSize( 02469 #if defined(FE_SB) 02470 IN UINT CodePage, 02471 #endif 02472 IN COORD WindowSize, 02473 OUT PCOORD pWindowSize 02474 ) 02475 02476 /*++ 02477 02478 find the best match font. it's the one that's the same size 02479 or slightly larger than the window size. 02480 02481 --*/ 02482 { 02483 ULONG i; 02484 #if defined(FE_SB) 02485 BOOL fGraphics = fFullScreenGraphics ? IsAvailableFsCodePage(CodePage) : FALSE; 02486 #endif 02487 02488 for (i=0;i<NUMBER_OF_MODE_FONT_PAIRS;i++) { 02489 #if defined(FE_SB) 02490 if (WindowSize.Y <= RegModeFontPairs[i].ScreenSize.Y && 02491 ( ( fGraphics && (RegModeFontPairs[i].Mode & FS_GRAPHICS)==FS_GRAPHICS) || 02492 (!fGraphics && (RegModeFontPairs[i].Mode & FS_TEXT)==FS_TEXT) ) 02493 ) 02494 #else 02495 if (WindowSize.Y <= (SHORT)ModeFontPairs[i].Height) 02496 #endif 02497 { 02498 break; 02499 } 02500 } 02501 if (i == NUMBER_OF_MODE_FONT_PAIRS) 02502 #if defined(FE_SB) 02503 { 02504 DWORD Find; 02505 ULONG FindIndex; 02506 COORD WindowSizeDelta; 02507 02508 FindIndex = 0; 02509 Find = (DWORD)-1; 02510 for (i=0; i<NUMBER_OF_MODE_FONT_PAIRS;i++) { 02511 if ( ( fGraphics && (RegModeFontPairs[i].Mode & FS_GRAPHICS)==FS_GRAPHICS) || 02512 (!fGraphics && (RegModeFontPairs[i].Mode & FS_TEXT)==FS_TEXT) ) 02513 { 02514 WindowSizeDelta.Y = abs(WindowSize.Y - RegModeFontPairs[i].ScreenSize.Y); 02515 if (Find > (DWORD)(WindowSizeDelta.Y)) 02516 { 02517 Find = (DWORD)(WindowSizeDelta.Y); 02518 FindIndex = i; 02519 } 02520 } 02521 } 02522 02523 i = FindIndex; 02524 } 02525 #else 02526 i-=1; 02527 #endif 02528 #if defined(FE_SB) 02529 *pWindowSize = RegModeFontPairs[i].ScreenSize; 02530 #else 02531 pWindowSize->X = 80; 02532 pWindowSize->Y = (SHORT)ModeFontPairs[i].Height; 02533 #endif 02534 return i; 02535 } 02536 02537 VOID 02538 ReadRegionFromScreenHW( 02539 IN PSCREEN_INFORMATION ScreenInfo, 02540 IN PSMALL_RECT Region, 02541 IN PCHAR_INFO ReadBufPtr 02542 ) 02543 { 02544 ULONG CurFrameBufPtr; // offset in frame buffer 02545 SHORT FrameY; 02546 SHORT WindowY, WindowX, WindowSizeX; 02547 02548 // 02549 // get pointer to start of region in frame buffer 02550 // 02551 02552 WindowY = Region->Top - ScreenInfo->Window.Top; 02553 WindowX = Region->Left - ScreenInfo->Window.Left; 02554 WindowSizeX = CONSOLE_WINDOW_SIZE_X(ScreenInfo); 02555 02556 // 02557 // copy the chars and attrs from the frame buffer 02558 // 02559 02560 for (FrameY = Region->Top; 02561 FrameY <= Region->Bottom; 02562 FrameY++, WindowY++) { 02563 02564 CurFrameBufPtr = SCREEN_BUFFER_POINTER(WindowX, 02565 WindowY, 02566 WindowSizeX, 02567 sizeof(VGA_CHAR)); 02568 02569 GdiFullscreenControl(FullscreenControlReadFromFrameBuffer, 02570 (PULONG) CurFrameBufPtr, 02571 (Region->Right - Region->Left + 1) * 02572 sizeof(VGA_CHAR), 02573 ReadBufPtr, NULL); 02574 ReadBufPtr += (Region->Right - Region->Left + 1); 02575 } 02576 } 02577 02578 VOID 02579 ReverseMousePointer( 02580 IN PSCREEN_INFORMATION ScreenInfo, 02581 IN PSMALL_RECT Region 02582 ) 02583 { 02584 ULONG CurFrameBufPtr; // offset in frame buffer 02585 SHORT WindowSizeX; 02586 02587 // if (ScreenInfo->Console->FullScreenFlags & CONSOLE_FULLSCREEN) { 02588 // ASSERT(FALSE); 02589 // } 02590 02591 #ifdef FE_SB 02592 // fail safe 02593 ASSERT(ScreenInfo->Flags & CONSOLE_TEXTMODE_BUFFER); 02594 if (!(ScreenInfo->Flags & CONSOLE_TEXTMODE_BUFFER)) { 02595 return; 02596 } 02597 #endif 02598 02599 WindowSizeX = CONSOLE_WINDOW_SIZE_X(ScreenInfo); 02600 02601 if (ScreenInfo->BufferInfo.TextInfo.MousePosition.X < Region->Left || 02602 ScreenInfo->BufferInfo.TextInfo.MousePosition.X > Region->Right || 02603 ScreenInfo->BufferInfo.TextInfo.MousePosition.Y < Region->Top || 02604 ScreenInfo->BufferInfo.TextInfo.MousePosition.Y > Region->Bottom || 02605 ScreenInfo->CursorDisplayCount < 0 || 02606 !(ScreenInfo->Console->InputBuffer.InputMode & ENABLE_MOUSE_INPUT) || 02607 ScreenInfo->Console->Flags & CONSOLE_VDM_REGISTERED) { 02608 return; 02609 } 02610 02611 #if defined(FE_SB) 02612 { 02613 FSVIDEO_REVERSE_MOUSE_POINTER MousePointer; 02614 SHORT RowIndex; 02615 PROW Row; 02616 COORD TargetPoint; 02617 02618 TargetPoint.X = ScreenInfo->BufferInfo.TextInfo.MousePosition.X; 02619 TargetPoint.Y = ScreenInfo->BufferInfo.TextInfo.MousePosition.Y; 02620 02621 RowIndex = (ScreenInfo->BufferInfo.TextInfo.FirstRow+TargetPoint.Y) % ScreenInfo->ScreenBufferSize.Y; 02622 Row = &ScreenInfo->BufferInfo.TextInfo.Rows[RowIndex]; 02623 if (!CONSOLE_IS_DBCS_CP(ScreenInfo->Console)) 02624 MousePointer.dwType = CHAR_TYPE_SBCS; 02625 else if (Row->CharRow.KAttrs[TargetPoint.X] & ATTR_TRAILING_BYTE) 02626 MousePointer.dwType = CHAR_TYPE_TRAILING; 02627 else if (Row->CharRow.KAttrs[TargetPoint.X] & ATTR_LEADING_BYTE) 02628 MousePointer.dwType = CHAR_TYPE_LEADING; 02629 else 02630 MousePointer.dwType = CHAR_TYPE_SBCS; 02631 02632 MousePointer.Screen.Position.X = TargetPoint.X - ScreenInfo->Window.Left; 02633 MousePointer.Screen.Position.Y = TargetPoint.Y - ScreenInfo->Window.Top; 02634 MousePointer.Screen.ScreenSize.X = WindowSizeX; 02635 MousePointer.Screen.ScreenSize.Y = CONSOLE_WINDOW_SIZE_Y(ScreenInfo); 02636 MousePointer.Screen.nNumberOfChars = 0; 02637 02638 GdiFullscreenControl(FullscreenControlReverseMousePointerDB, 02639 &MousePointer, 02640 sizeof(MousePointer), 02641 NULL, 02642 NULL); 02643 02644 UNREFERENCED_PARAMETER(CurFrameBufPtr); 02645 } 02646 #else 02647 CurFrameBufPtr = SCREEN_BUFFER_POINTER(ScreenInfo->BufferInfo.TextInfo.MousePosition.X - ScreenInfo->Window.Left, 02648 ScreenInfo->BufferInfo.TextInfo.MousePosition.Y - ScreenInfo->Window.Top, 02649 WindowSizeX, 02650 sizeof(VGA_CHAR)); 02651 02652 GdiFullscreenControl(FullscreenControlReverseMousePointer, 02653 (PULONG) CurFrameBufPtr, 02654 0, 02655 NULL, 02656 NULL); 02657 #endif 02658 } 02659 02660 VOID 02661 CopyVideoMemory( 02662 SHORT SourceY, 02663 SHORT TargetY, 02664 SHORT Length, 02665 IN PSCREEN_INFORMATION ScreenInfo 02666 ) 02667 02668 /*++ 02669 02670 Routine Description: 02671 02672 This routine copies rows of characters in video memory. It only copies 02673 complete rows. 02674 02675 Arguments: 02676 02677 SourceY - Row to copy from. 02678 02679 TargetY - Row to copy to. 02680 02681 Length - Number of rows to copy. 02682 02683 Return Value: 02684 02685 --*/ 02686 02687 { 02688 ULONG SourcePtr, TargetPtr; 02689 SHORT WindowSizeX, WindowSizeY; 02690 02691 WindowSizeX = CONSOLE_WINDOW_SIZE_X(ScreenInfo); 02692 WindowSizeY = CONSOLE_WINDOW_SIZE_Y(ScreenInfo); 02693 02694 if (max(SourceY, TargetY) + Length > WindowSizeY) { 02695 Length = WindowSizeY - max(SourceY, TargetY); 02696 if (Length <= 0 ) { 02697 return; 02698 } 02699 } 02700 02701 #if defined(FE_SB) 02702 { 02703 FSCNTL_SCREEN_INFO FsCntlSrc; 02704 FSCNTL_SCREEN_INFO FsCntlDest; 02705 02706 FsCntlSrc.Position.X = 0; 02707 FsCntlSrc.Position.Y = SourceY; 02708 FsCntlSrc.ScreenSize.X = WindowSizeX; 02709 FsCntlSrc.ScreenSize.Y = CONSOLE_WINDOW_SIZE_Y(ScreenInfo); 02710 FsCntlSrc.nNumberOfChars = Length * WindowSizeX; 02711 02712 FsCntlDest.Position.X = 0; 02713 FsCntlDest.Position.Y = TargetY; 02714 FsCntlDest.ScreenSize.X = WindowSizeX; 02715 FsCntlDest.ScreenSize.Y = CONSOLE_WINDOW_SIZE_Y(ScreenInfo); 02716 FsCntlDest.nNumberOfChars = Length * WindowSizeX; 02717 02718 GdiFullscreenControl(FullscreenControlCopyFrameBufferDB, 02719 &FsCntlSrc, 02720 sizeof(FsCntlSrc), 02721 &FsCntlDest, 02722 (PULONG)sizeof(FsCntlDest)); 02723 02724 UNREFERENCED_PARAMETER(SourcePtr); 02725 UNREFERENCED_PARAMETER(TargetPtr); 02726 } 02727 #else 02728 SourcePtr = SCREEN_BUFFER_POINTER(0, 02729 SourceY, 02730 WindowSizeX, 02731 sizeof(VGA_CHAR)); 02732 02733 TargetPtr = SCREEN_BUFFER_POINTER(0, 02734 TargetY, 02735 WindowSizeX, 02736 sizeof(VGA_CHAR)); 02737 02738 GdiFullscreenControl(FullscreenControlCopyFrameBuffer, 02739 (PULONG) SourcePtr, 02740 Length * WindowSizeX * sizeof(VGA_CHAR), 02741 (PULONG) TargetPtr, 02742 (PULONG) (Length * WindowSizeX * sizeof(VGA_CHAR))); 02743 #endif 02744 } 02745 02746 VOID 02747 ScrollHW( 02748 IN PSCREEN_INFORMATION ScreenInfo, 02749 IN PSMALL_RECT ScrollRect, 02750 IN PSMALL_RECT MergeRect, 02751 IN COORD TargetPoint 02752 ) 02753 { 02754 SMALL_RECT TargetRectangle; 02755 if (ScreenInfo->Console->Flags & CONSOLE_VDM_REGISTERED) 02756 return; 02757 02758 TargetRectangle.Left = TargetPoint.X; 02759 TargetRectangle.Top = TargetPoint.Y; 02760 TargetRectangle.Right = TargetPoint.X + ScrollRect->Right - ScrollRect->Left; 02761 TargetRectangle.Bottom = TargetPoint.Y + ScrollRect->Bottom - ScrollRect->Top; 02762 02763 // 02764 // if the scroll region is as wide as the screen, we can update 02765 // the screen by copying the video memory. if we scroll this 02766 // way, we then must clip and update the fill region. 02767 // 02768 02769 if (ScrollRect->Left == ScreenInfo->Window.Left && 02770 TargetRectangle.Left == ScreenInfo->Window.Left && 02771 ScrollRect->Right == ScreenInfo->Window.Right && 02772 TargetRectangle.Right == ScreenInfo->Window.Right && 02773 ScrollRect->Top >= ScreenInfo->Window.Top && 02774 TargetRectangle.Top >= ScreenInfo->Window.Top && 02775 ScrollRect->Bottom <= ScreenInfo->Window.Bottom && 02776 TargetRectangle.Bottom <= ScreenInfo->Window.Bottom) { 02777 02778 // 02779 // we must first make the mouse pointer invisible because 02780 // otherwise it would get copied to another place on the 02781 // screen if it were part of the scroll region. 02782 // 02783 02784 ReverseMousePointer(ScreenInfo, &ScreenInfo->Window); 02785 02786 CopyVideoMemory((SHORT) (ScrollRect->Top - ScreenInfo->Window.Top), 02787 (SHORT) (TargetRectangle.Top - ScreenInfo->Window.Top), 02788 (SHORT) (TargetRectangle.Bottom - TargetRectangle.Top + 1), 02789 ScreenInfo); 02790 02791 // 02792 // update the fill region. first we ensure that the scroll and 02793 // target regions aren't the same. if they are, we don't fill. 02794 // 02795 02796 if (TargetRectangle.Top != ScrollRect->Top) { 02797 02798 // 02799 // if scroll and target regions overlap, with scroll 02800 // region above target region, clip scroll region. 02801 // 02802 02803 if (TargetRectangle.Top <= ScrollRect->Bottom && 02804 TargetRectangle.Bottom >= ScrollRect->Bottom) { 02805 ScrollRect->Bottom = (SHORT)(TargetRectangle.Top-1); 02806 } 02807 else if (TargetRectangle.Top <= ScrollRect->Top && 02808 TargetRectangle.Bottom >= ScrollRect->Top) { 02809 ScrollRect->Top = (SHORT)(TargetRectangle.Bottom+1); 02810 } 02811 WriteToScreen(ScreenInfo,ScrollRect); 02812 02813 // 02814 // WriteToScreen should take care of writing the mouse pointer. 02815 // however, the update region may be clipped so that the 02816 // mouse pointer is not written. in that case, we draw the 02817 // mouse pointer here. 02818 // 02819 02820 if (ScreenInfo->BufferInfo.TextInfo.MousePosition.Y < ScrollRect->Top || 02821 ScreenInfo->BufferInfo.TextInfo.MousePosition.Y > ScrollRect->Bottom) { 02822 ReverseMousePointer(ScreenInfo, &ScreenInfo->Window); 02823 } 02824 } 02825 if (MergeRect) { 02826 WriteToScreen(ScreenInfo,MergeRect); 02827 } 02828 } 02829 else { 02830 if (MergeRect) { 02831 WriteToScreen(ScreenInfo,MergeRect); 02832 } 02833 WriteToScreen(ScreenInfo,ScrollRect); 02834 WriteToScreen(ScreenInfo,&TargetRectangle); 02835 } 02836 } 02837 02838 VOID 02839 UpdateMousePosition( 02840 PSCREEN_INFORMATION ScreenInfo, 02841 COORD Position 02842 ) 02843 02844 /*++ 02845 02846 Routine Description: 02847 02848 This routine moves the mouse pointer. 02849 02850 Arguments: 02851 02852 ScreenInfo - Pointer to screen buffer information. 02853 02854 Position - Contains the new position of the mouse in screen buffer 02855 coordinates. 02856 02857 Return Value: 02858 02859 none. 02860 02861 --*/ 02862 02863 // Note: CurrentConsole lock must be held in share mode when calling this routine 02864 { 02865 SMALL_RECT CursorRegion; 02866 #ifdef FE_SB 02867 SHORT RowIndex; 02868 PROW Row; 02869 BOOL fOneMore = FALSE; 02870 #endif 02871 02872 if ((ScreenInfo->Console->Flags & CONSOLE_VDM_REGISTERED) || 02873 (ScreenInfo->Flags & CONSOLE_GRAPHICS_BUFFER)) { 02874 return; 02875 } 02876 02877 if (Position.X < ScreenInfo->Window.Left || 02878 Position.X > ScreenInfo->Window.Right || 02879 Position.Y < ScreenInfo->Window.Top || 02880 Position.Y > ScreenInfo->Window.Bottom) { 02881 return; 02882 } 02883 02884 if (Position.X == ScreenInfo->BufferInfo.TextInfo.MousePosition.X && 02885 Position.Y == ScreenInfo->BufferInfo.TextInfo.MousePosition.Y) { 02886 return; 02887 } 02888 02889 #ifdef FE_SB 02890 if (CONSOLE_IS_DBCS_CP(ScreenInfo->Console)) { 02891 RowIndex = (ScreenInfo->BufferInfo.TextInfo.FirstRow+Position.Y) % ScreenInfo->ScreenBufferSize.Y; 02892 Row = &ScreenInfo->BufferInfo.TextInfo.Rows[RowIndex]; 02893 if (Row->CharRow.KAttrs[Position.X] & ATTR_LEADING_BYTE) { 02894 if (Position.X != ScreenInfo->ScreenBufferSize.X - 1) { 02895 fOneMore = TRUE; 02896 } 02897 } else if (Row->CharRow.KAttrs[Position.X] & ATTR_TRAILING_BYTE) { 02898 if (Position.X != 0) { 02899 fOneMore = TRUE; 02900 Position.X--; 02901 } 02902 } 02903 02904 } 02905 #endif 02906 02907 if (ScreenInfo->CursorDisplayCount < 0 || !(ScreenInfo->Console->InputBuffer.InputMode & ENABLE_MOUSE_INPUT)) { 02908 ScreenInfo->BufferInfo.TextInfo.MousePosition = Position; 02909 return; 02910 } 02911 02912 02913 // turn off old mouse position. 02914 02915 CursorRegion.Left = CursorRegion.Right = ScreenInfo->BufferInfo.TextInfo.MousePosition.X; 02916 CursorRegion.Top = CursorRegion.Bottom = ScreenInfo->BufferInfo.TextInfo.MousePosition.Y; 02917 02918 #ifdef FE_SB 02919 if (CONSOLE_IS_DBCS_CP(ScreenInfo->Console)) { 02920 RowIndex = (ScreenInfo->BufferInfo.TextInfo.FirstRow+CursorRegion.Top) % ScreenInfo->ScreenBufferSize.Y; 02921 Row = &ScreenInfo->BufferInfo.TextInfo.Rows[RowIndex]; 02922 if (Row->CharRow.KAttrs[CursorRegion.Left] & ATTR_LEADING_BYTE) { 02923 if (CursorRegion.Left != ScreenInfo->ScreenBufferSize.X - 1) { 02924 CursorRegion.Right++; 02925 } 02926 } 02927 } 02928 #endif 02929 02930 // store new mouse position 02931 02932 ScreenInfo->BufferInfo.TextInfo.MousePosition.X = Position.X; 02933 ScreenInfo->BufferInfo.TextInfo.MousePosition.Y = Position.Y; 02934 WriteToScreen(ScreenInfo,&CursorRegion); 02935 02936 // turn on new mouse position 02937 02938 CursorRegion.Left = CursorRegion.Right = Position.X; 02939 CursorRegion.Top = CursorRegion.Bottom = Position.Y; 02940 #ifdef FE_SB 02941 if (fOneMore) 02942 CursorRegion.Right++; 02943 #endif 02944 WriteToScreen(ScreenInfo,&CursorRegion); 02945 } 02946 02947 NTSTATUS 02948 SetROMFontCodePage( 02949 IN UINT wCodePage, 02950 IN ULONG ModeIndex 02951 ) 02952 02953 /* 02954 02955 this function opens ega.cpi and looks for the desired font in the 02956 specified codepage. if found, it loads it into the video ROM. 02957 02958 */ 02959 02960 { 02961 BYTE Buffer[CONSOLE_FONT_BUFFER_LENGTH]; 02962 DWORD dwBytesRead; 02963 LPFONTFILEHEADER lpFontFileHeader=(LPFONTFILEHEADER)Buffer; 02964 LPFONTINFOHEADER lpFontInfoHeader=(LPFONTINFOHEADER)Buffer; 02965 LPFONTDATAHEADER lpFontDataHeader=(LPFONTDATAHEADER)Buffer; 02966 LPCPENTRYHEADER lpCPEntryHeader=(LPCPENTRYHEADER)Buffer; 02967 LPSCREENFONTHEADER lpScreenFontHeader=(LPSCREENFONTHEADER)Buffer; 02968 WORD NumEntries; 02969 COORD FontDimensions; 02970 NTSTATUS Status; 02971 BOOL Found; 02972 LONG FilePtr; 02973 BOOL bDOS = FALSE; 02974 02975 FontDimensions = ModeFontPairs[ModeIndex].FontSize; 02976 02977 // 02978 // read FONTINFOHEADER 02979 // 02980 // do { 02981 // read CPENTRYHEADER 02982 // if (correct codepage) 02983 // break; 02984 // } while (codepages) 02985 // if (codepage found) 02986 // read FONTDATAHEADER 02987 // 02988 02989 // read FONTFILEHEADER 02990 02991 FilePtr = 0; 02992 if (SetFilePointer(hCPIFile,FilePtr,NULL,FILE_BEGIN) == -1) { 02993 Status = STATUS_INVALID_PARAMETER; 02994 goto DoExit; 02995 } 02996 02997 if (!ReadFile(hCPIFile,Buffer,sizeof(FONTFILEHEADER),&dwBytesRead,NULL) || 02998 dwBytesRead != sizeof(FONTFILEHEADER)) { 02999 Status = STATUS_INVALID_PARAMETER; 03000 goto DoExit; 03001 } 03002 03003 // verify signature 03004 03005 if (memcmp(lpFontFileHeader->ffhFileTag, "\xFF""FONT.NT",8) ) { 03006 if (memcmp(lpFontFileHeader->ffhFileTag, "\xFF""FONT ",8) ) { 03007 Status = STATUS_INVALID_PARAMETER; 03008 goto DoExit; 03009 } else { 03010 bDOS = TRUE; 03011 } 03012 } 03013 03014 // seek to FONTINFOHEADER. jump through hoops to get the offset value. 03015 03016 FilePtr = lpFontFileHeader->ffhOffset1; 03017 FilePtr |= (lpFontFileHeader->ffhOffset2 << 8); 03018 FilePtr |= (lpFontFileHeader->ffhOffset3 << 24); 03019 03020 if (SetFilePointer(hCPIFile,FilePtr,NULL,FILE_BEGIN) == -1) { 03021 Status = STATUS_INVALID_PARAMETER; 03022 goto DoExit; 03023 } 03024 03025 // read FONTINFOHEADER 03026 03027 if (!ReadFile(hCPIFile,Buffer,sizeof(FONTINFOHEADER),&dwBytesRead,NULL) || 03028 dwBytesRead != sizeof(FONTINFOHEADER)) { 03029 Status = STATUS_INVALID_PARAMETER; 03030 goto DoExit; 03031 } 03032 FilePtr += dwBytesRead; 03033 NumEntries = lpFontInfoHeader->fihCodePages; 03034 03035 Found = FALSE; 03036 while (NumEntries && 03037 ReadFile(hCPIFile,Buffer,sizeof(CPENTRYHEADER),&dwBytesRead,NULL) && 03038 dwBytesRead == sizeof(CPENTRYHEADER)) { 03039 if (lpCPEntryHeader->cpeCodepageID == wCodePage) { 03040 Found = TRUE; 03041 break; 03042 } 03043 // seek to next CPEENTRYHEADER 03044 03045 if (bDOS) { 03046 FilePtr = MAKELONG(lpCPEntryHeader->cpeNext1,lpCPEntryHeader->cpeNext2); 03047 } else { 03048 FilePtr += MAKELONG(lpCPEntryHeader->cpeNext1,lpCPEntryHeader->cpeNext2); 03049 } 03050 if (SetFilePointer(hCPIFile, FilePtr, NULL,FILE_BEGIN) == -1) { 03051 Status = STATUS_INVALID_PARAMETER; 03052 goto DoExit; 03053 } 03054 NumEntries-=1; 03055 } 03056 if (!Found) { 03057 Status = STATUS_INVALID_PARAMETER; 03058 goto DoExit; 03059 } 03060 03061 // seek to FONTDATAHEADER 03062 03063 if (bDOS) { 03064 FilePtr = lpCPEntryHeader->cpeOffset; 03065 } else { 03066 FilePtr += lpCPEntryHeader->cpeOffset; 03067 } 03068 if (SetFilePointer(hCPIFile, FilePtr, NULL,FILE_BEGIN) == -1) { 03069 Status = STATUS_INVALID_PARAMETER; 03070 goto DoExit; 03071 } 03072 03073 // read FONTDATAHEADER 03074 03075 if (!ReadFile(hCPIFile,Buffer,sizeof(FONTDATAHEADER),&dwBytesRead,NULL) || 03076 dwBytesRead != sizeof(FONTDATAHEADER)) { 03077 Status = STATUS_INVALID_PARAMETER; 03078 goto DoExit; 03079 } 03080 FilePtr += dwBytesRead; 03081 03082 NumEntries = lpFontDataHeader->fdhFonts; 03083 03084 while (NumEntries) { 03085 if (!ReadFile(hCPIFile,Buffer,sizeof(SCREENFONTHEADER),&dwBytesRead,NULL) || 03086 dwBytesRead != sizeof(SCREENFONTHEADER)) { 03087 Status = STATUS_INVALID_PARAMETER; 03088 goto DoExit; 03089 } 03090 03091 if (lpScreenFontHeader->sfhHeight == (BYTE)FontDimensions.Y && 03092 lpScreenFontHeader->sfhWidth == (BYTE)FontDimensions.X) { 03093 PVIDEO_LOAD_FONT_INFORMATION FontInformation; 03094 03095 FontInformation = (PVIDEO_LOAD_FONT_INFORMATION)ConsoleHeapAlloc(MAKE_TAG( TMP_TAG ), 03096 lpScreenFontHeader->sfhCharacters* 03097 lpScreenFontHeader->sfhHeight+ 03098 sizeof(VIDEO_LOAD_FONT_INFORMATION)); 03099 if (FontInformation == NULL) { 03100 RIPMSG1(RIP_WARNING, "SetROMFontCodePage: failed to memory allocation %d bytes", 03101 lpScreenFontHeader->sfhCharacters * lpScreenFontHeader->sfhHeight + 03102 sizeof(VIDEO_LOAD_FONT_INFORMATION)); 03103 return STATUS_NO_MEMORY; 03104 } 03105 if (!ReadFile(hCPIFile,FontInformation->Font, 03106 lpScreenFontHeader->sfhCharacters*lpScreenFontHeader->sfhHeight, 03107 &dwBytesRead,NULL) || 03108 dwBytesRead != (DWORD)(lpScreenFontHeader->sfhCharacters*lpScreenFontHeader->sfhHeight)) { 03109 ConsoleHeapFree(FontInformation); 03110 return STATUS_INVALID_PARAMETER; 03111 } 03112 FontInformation->WidthInPixels = FontDimensions.X; 03113 FontInformation->HeightInPixels = FontDimensions.Y; 03114 FontInformation->FontSize = lpScreenFontHeader->sfhCharacters*lpScreenFontHeader->sfhHeight; 03115 03116 Status = GdiFullscreenControl(FullscreenControlLoadFont, 03117 FontInformation, 03118 lpScreenFontHeader->sfhCharacters*lpScreenFontHeader->sfhHeight+sizeof(VIDEO_LOAD_FONT_INFORMATION), 03119 NULL, 03120 NULL); 03121 03122 ConsoleHeapFree(FontInformation); 03123 return Status; 03124 } else { 03125 FilePtr = lpScreenFontHeader->sfhCharacters*lpScreenFontHeader->sfhHeight; 03126 if (SetFilePointer(hCPIFile, FilePtr, NULL,FILE_CURRENT) == -1) { 03127 Status = STATUS_INVALID_PARAMETER; 03128 goto DoExit; 03129 } 03130 } 03131 NumEntries -= 1; 03132 } 03133 DoExit: 03134 return Status; 03135 } 03136 #endif 03137 03138 NTSTATUS 03139 GetThreadConsoleDesktop( 03140 DWORD dwThreadId, 03141 HDESK *phdeskConsole) 03142 { 03143 PCSR_THREAD pcsrt; 03144 PCONSOLE_PER_PROCESS_DATA ProcessData; 03145 PCONSOLE_INFORMATION Console; 03146 NTSTATUS Status; 03147 HANDLE ConsoleHandle = NULL; 03148 03149 *phdeskConsole = NULL; 03150 Status = CsrLockThreadByClientId((HANDLE)dwThreadId, &pcsrt); 03151 if (NT_SUCCESS(Status)) { 03152 ProcessData = CONSOLE_FROMTHREADPERPROCESSDATA(pcsrt); 03153 ConsoleHandle = ProcessData->ConsoleHandle; 03154 CsrUnlockThread(pcsrt); 03155 } 03156 03157 // 03158 // If this process is a console app, return the 03159 // handle to its desktop. Otherwise, return NULL. 03160 // 03161 03162 if (ConsoleHandle != NULL) { 03163 Status = RevalidateConsole(ConsoleHandle, &Console); 03164 if (NT_SUCCESS(Status)) { 03165 *phdeskConsole = Console->hDesk; 03166 } 03167 UnlockConsole(Console); 03168 } 03169 03170 return STATUS_SUCCESS; 03171 } 03172 03173 03174 NTSTATUS 03175 SetRAMFontCodePage( 03176 IN PSCREEN_INFORMATION ScreenInfo 03177 ) 03178 { 03179 FSVIDEO_SCREEN_INFORMATION ScreenInformation; 03180 ULONG ModeIndex = ScreenInfo->BufferInfo.TextInfo.ModeIndex; 03181 COORD FontSize; 03182 WCHAR wChar; 03183 WCHAR wCharBuf[2]; 03184 LPSTRINGBITMAP StringBitmap; 03185 DWORD BufferSize; 03186 PWORD FontImage; 03187 PFONT_CACHE_INFORMATION FontCache; 03188 WCHAR AltFaceName[LF_FACESIZE]; 03189 COORD AltFontSize; 03190 BYTE AltFontFamily; 03191 ULONG AltFontIndex = 0; 03192 HFONT hOldFont; 03193 NTSTATUS Status; 03194 03195 ScreenInformation.ScreenSize = RegModeFontPairs[ModeIndex].ScreenSize; 03196 ScreenInformation.FontSize = RegModeFontPairs[ModeIndex].FontSize; 03197 if (ScreenInfo->Console->FontCacheInformation == NULL) 03198 { 03199 Status = CreateFontCache(&FontCache); 03200 if (!NT_SUCCESS(Status)) { 03201 RIPMSG1(RIP_WARNING, "SetRAMFontCodePage: failed in CreateFontCache. Status=%08x", Status); 03202 return STATUS_UNSUCCESSFUL; 03203 } 03204 (PFONT_CACHE_INFORMATION)ScreenInfo->Console->FontCacheInformation = FontCache; 03205 03206 MakeAltRasterFont(SCR_FONTCODEPAGE(ScreenInfo), 03207 RegModeFontPairs[ModeIndex].FontSize, 03208 &AltFontSize, &AltFontFamily, &AltFontIndex, AltFaceName); 03209 FontCache->FullScreenFontIndex = AltFontIndex; 03210 FontCache->FullScreenFontSize = AltFontSize; 03211 03212 BufferSize = CalcBitmapBufferSize(FontCache->FullScreenFontSize,BYTE_ALIGN); 03213 StringBitmap = ConsoleHeapAlloc( MAKE_TAG(TMP_DBCS_TAG), 03214 sizeof(STRINGBITMAP) + sizeof(StringBitmap->ajBits) * BufferSize); 03215 if (StringBitmap==NULL) 03216 { 03217 RIPMSG0(RIP_WARNING, "SetRAMFontCodePage: failed to allocate StringBitmap"); 03218 return STATUS_UNSUCCESSFUL; 03219 } 03220 03221 03222 /* 03223 * Change GDI font to full screen font that best matched. 03224 */ 03225 hOldFont = SelectObject(ScreenInfo->Console->hDC,FontInfo[FontCache->FullScreenFontIndex].hFont); 03226 03227 03228 for (wChar=0x00; wChar < 0x80; wChar++) { 03229 wCharBuf[0] = wChar; 03230 wCharBuf[1] = TEXT('\0'); 03231 GetStringBitmapW(ScreenInfo->Console->hDC, 03232 wCharBuf, 03233 1, 03234 (ULONG)ConsoleHeapSize(StringBitmap), 03235 (BYTE*)StringBitmap 03236 ); 03237 03238 FontSize.X = (SHORT)StringBitmap->uiWidth; 03239 FontSize.Y = (SHORT)StringBitmap->uiHeight; 03240 03241 #if defined(LATER_DBCS_FOR_GRID_CHAR) // by kazum 03242 BufferSize = CalcBitmapBufferSize(FontSize,BYTE_ALIGN); 03243 *(StringBitmap->ajBits + BufferSize) = 0; 03244 *(StringBitmap->ajBits + BufferSize + 1) = 0; 03245 03246 if (gpGridCharacter) { 03247 PGRID_CHARACTER_INFORMATION GridCharacter; 03248 PWCHAR CodePoint; 03249 03250 GridCharacter = gpGridCharacter; 03251 do { 03252 if (GridCharacter->CodePage == OEMCP) { 03253 CodePoint = GridCharacter->CodePoint; 03254 while (*CodePoint) { 03255 if (*CodePoint == wChar) { 03256 if (FontSize.X <= 8) 03257 *(StringBitmap->ajBits + BufferSize) = *(StringBitmap->ajBits + BufferSize - 1); 03258 else { 03259 *(StringBitmap->ajBits + BufferSize) = *(StringBitmap->ajBits + BufferSize - 2); 03260 *(StringBitmap->ajBits + BufferSize + 1) = *(StringBitmap->ajBits + BufferSize - 1); 03261 } 03262 break; 03263 } 03264 else 03265 CodePoint++; 03266 } 03267 break; 03268 } 03269 } while (GridCharacter = GridCharacter->pNext); 03270 } 03271 #endif // LATER_DBCS_FOR_GRID_CHAR // by kazum 03272 03273 Status = SetFontImage(ScreenInfo->Console->FontCacheInformation, 03274 wChar, 03275 FontSize, 03276 BYTE_ALIGN, 03277 StringBitmap->ajBits 03278 ); 03279 if (! NT_SUCCESS(Status)) { 03280 RIPMSG3(RIP_WARNING, "SetRAMFontCodePage: failed to set font image. wc=%04x sz=(%x, %x).", 03281 wChar, FontSize.X, FontSize.Y); 03282 } 03283 03284 if (FontSize.X != ScreenInformation.FontSize.X || 03285 FontSize.Y != ScreenInformation.FontSize.Y) 03286 { 03287 BufferSize = CalcBitmapBufferSize(ScreenInformation.FontSize,WORD_ALIGN); 03288 FontImage = ConsoleHeapAlloc( MAKE_TAG(TMP_DBCS_TAG), 03289 BufferSize 03290 ); 03291 if (FontImage!=NULL) { 03292 03293 GetExpandFontImage(ScreenInfo->Console->FontCacheInformation, 03294 wChar, 03295 FontSize, 03296 ScreenInformation.FontSize, 03297 FontImage 03298 ); 03299 03300 Status = SetFontImage(ScreenInfo->Console->FontCacheInformation, 03301 wChar, 03302 ScreenInformation.FontSize, 03303 WORD_ALIGN, 03304 FontImage 03305 ); 03306 if (! NT_SUCCESS(Status)) { 03307 RIPMSG3(RIP_WARNING, "SetRAMFontCodePage: failed to set font image. wc=%04x, sz=(%x,%x)", 03308 wChar, ScreenInformation.FontSize.X, ScreenInformation.FontSize.Y); 03309 } 03310 03311 ConsoleHeapFree(FontImage); 03312 } else { 03313 RIPMSG0(RIP_WARNING, "SetRAMFontCodePage: failed to allocate FontImage."); 03314 } 03315 } 03316 } 03317 03318 ConsoleHeapFree(StringBitmap); 03319 03320 /* 03321 * Back to GDI font 03322 */ 03323 SelectObject(ScreenInfo->Console->hDC,hOldFont); 03324 } 03325 03326 Status = GdiFullscreenControl(FullscreenControlSetScreenInformation, 03327 &ScreenInformation, 03328 sizeof(ScreenInformation), 03329 NULL, 03330 NULL); 03331 03332 return Status; 03333 } 03334 03335 NTSTATUS 03336 SetRAMFont( 03337 IN PSCREEN_INFORMATION ScreenInfo, 03338 IN PCHAR_INFO ScreenBufPtr, 03339 IN DWORD Length 03340 ) 03341 { 03342 ULONG ModeIndex = ScreenInfo->BufferInfo.TextInfo.ModeIndex; 03343 COORD FsFontSize1 = RegModeFontPairs[ModeIndex].FontSize; 03344 COORD FsFontSize2 = FsFontSize1; 03345 COORD GdiFontSize1; 03346 COORD GdiFontSize2; 03347 COORD RetFontSize; 03348 WCHAR wCharBuf[2]; 03349 LPSTRINGBITMAP StringBitmap; 03350 DWORD BufferSize; 03351 PWORD FontImage; 03352 PFONT_CACHE_INFORMATION FontCache; 03353 HFONT hOldFont; 03354 NTSTATUS Status; 03355 03356 FontCache = (PFONT_CACHE_INFORMATION)ScreenInfo->Console->FontCacheInformation; 03357 if (FontCache==NULL) 03358 { 03359 RIPMSG0(RIP_ERROR, "SetRAMFont: ScreenInfo->Console->FontCacheInformation == NULL."); 03360 return STATUS_UNSUCCESSFUL; 03361 } 03362 03363 GdiFontSize1 = FontCache->FullScreenFontSize; 03364 GdiFontSize2 = GdiFontSize1; 03365 GdiFontSize2.X *= 2; 03366 FsFontSize2.X *= 2; 03367 03368 BufferSize = CalcBitmapBufferSize(GdiFontSize2,BYTE_ALIGN); 03369 StringBitmap = ConsoleHeapAlloc( MAKE_TAG(TMP_DBCS_TAG), 03370 sizeof(STRINGBITMAP) + sizeof(StringBitmap->ajBits) * BufferSize); 03371 if (StringBitmap==NULL) 03372 { 03373 RIPMSG0(RIP_WARNING, "SetRAMFont: failed to allocate StringBitmap"); 03374 return STATUS_UNSUCCESSFUL; 03375 } 03376 03377 /* 03378 * Change GDI font to full screen font that best matched. 03379 */ 03380 hOldFont = SelectObject(ScreenInfo->Console->hDC,FontInfo[FontCache->FullScreenFontIndex].hFont); 03381 03382 while (Length--) 03383 { 03384 Status = GetFontImage(ScreenInfo->Console->FontCacheInformation, 03385 ScreenBufPtr->Char.UnicodeChar, 03386 (ScreenBufPtr->Attributes & COMMON_LVB_SBCSDBCS) ? FsFontSize2 : FsFontSize1, 03387 0, 03388 NULL); 03389 if (! NT_SUCCESS(Status) ) 03390 { 03391 wCharBuf[0] = ScreenBufPtr->Char.UnicodeChar; 03392 wCharBuf[1] = TEXT('\0'); 03393 GetStringBitmapW(ScreenInfo->Console->hDC, 03394 wCharBuf, 03395 1, 03396 (ULONG)ConsoleHeapSize(StringBitmap), 03397 (BYTE*)StringBitmap 03398 ); 03399 03400 RetFontSize.X = (SHORT)StringBitmap->uiWidth; 03401 RetFontSize.Y = (SHORT)StringBitmap->uiHeight; 03402 03403 Status = SetFontImage(ScreenInfo->Console->FontCacheInformation, 03404 ScreenBufPtr->Char.UnicodeChar, 03405 RetFontSize, 03406 BYTE_ALIGN, 03407 StringBitmap->ajBits 03408 ); 03409 if (! NT_SUCCESS(Status)) { 03410 RIPMSG3(RIP_WARNING, "SetRAMFont: failed to set font image. wc=%04x sz=(%x,%x)", 03411 ScreenBufPtr->Char.UnicodeChar, RetFontSize.X, RetFontSize.Y); 03412 } 03413 03414 if ( ( (ScreenBufPtr->Attributes & COMMON_LVB_SBCSDBCS) && 03415 (GdiFontSize2.X != FsFontSize2.X || GdiFontSize2.Y != FsFontSize2.Y)) || 03416 (!(ScreenBufPtr->Attributes & COMMON_LVB_SBCSDBCS) && 03417 (GdiFontSize1.X != FsFontSize1.X || GdiFontSize1.Y != FsFontSize1.Y)) ) 03418 { 03419 BufferSize = CalcBitmapBufferSize(FsFontSize2,WORD_ALIGN); 03420 FontImage = ConsoleHeapAlloc( MAKE_TAG(TMP_DBCS_TAG), 03421 BufferSize 03422 ); 03423 if (FontImage!=NULL) { 03424 03425 GetExpandFontImage(ScreenInfo->Console->FontCacheInformation, 03426 ScreenBufPtr->Char.UnicodeChar, 03427 (ScreenBufPtr->Attributes & COMMON_LVB_SBCSDBCS) ? GdiFontSize2 : GdiFontSize1, 03428 (ScreenBufPtr->Attributes & COMMON_LVB_SBCSDBCS) ? FsFontSize2 : FsFontSize1, 03429 FontImage 03430 ); 03431 03432 Status = SetFontImage(ScreenInfo->Console->FontCacheInformation, 03433 ScreenBufPtr->Char.UnicodeChar, 03434 (ScreenBufPtr->Attributes & COMMON_LVB_SBCSDBCS) ? FsFontSize2 : FsFontSize1, 03435 WORD_ALIGN, 03436 FontImage 03437 ); 03438 if (! NT_SUCCESS(Status)) { 03439 RIPMSG3(RIP_WARNING, "SetRAMFont: failed to set font image. wc=%04x sz=(%x,%x)", 03440 ScreenBufPtr->Char.UnicodeChar, 03441 ((ScreenBufPtr->Attributes & COMMON_LVB_SBCSDBCS) ? FsFontSize2 : FsFontSize1).X, 03442 ((ScreenBufPtr->Attributes & COMMON_LVB_SBCSDBCS) ? FsFontSize2 : FsFontSize1).Y); 03443 } 03444 03445 ConsoleHeapFree(FontImage); 03446 } else { 03447 RIPMSG0(RIP_WARNING, "SetRAMFont: failed to allocate FontImage."); 03448 } 03449 } 03450 } 03451 03452 if (ScreenBufPtr->Attributes & COMMON_LVB_SBCSDBCS) 03453 { 03454 ScreenBufPtr += 2; 03455 if (Length >= 1) 03456 Length -= 1; 03457 else 03458 break; 03459 } 03460 else 03461 { 03462 ScreenBufPtr++; 03463 } 03464 } 03465 03466 ConsoleHeapFree(StringBitmap); 03467 03468 /* 03469 * Back to GDI font 03470 */ 03471 SelectObject(ScreenInfo->Console->hDC,hOldFont); 03472 03473 return Status; 03474 } 03475 03476 #ifdef i386 03477 #if defined(FE_SB) 03478 03479 #define WWSB_NOFE 03480 #include "_priv.h" 03481 #undef WWSB_NOFE 03482 #define WWSB_FE 03483 #include "_priv.h" 03484 #undef WWSB_FE 03485 03486 #endif // FE_SB 03487 #endif // i386

Generated on Sat May 15 19:41:26 2004 for test by doxygen 1.3.7