Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

470 lines
8.2 KiB

  1. /*++
  2. Copyright (c) 1990 Microsoft Corporation
  3. Module Name:
  4. Con
  5. Abstract:
  6. Takes care of request involving the console ( CON: )
  7. Author:
  8. Ramon Juan San Andres (ramonsa) 26-Jun-1991
  9. Notes:
  10. This module issues direct calls to USER, because having ULIB doing
  11. so causes programs to crash.
  12. Revision History:
  13. --*/
  14. #include "mode.hxx"
  15. #include "cons.hxx"
  16. #include "keyboard.hxx"
  17. #include "path.hxx"
  18. #include "screen.hxx"
  19. #include "stream.hxx"
  20. #include "system.hxx"
  21. //
  22. // Local prototypes
  23. //
  24. BOOLEAN
  25. ConStatus(
  26. IN PREQUEST_HEADER Request,
  27. IN BOOLEAN JustCodePage
  28. );
  29. BOOLEAN
  30. ConCodePage(
  31. IN PREQUEST_HEADER Request
  32. );
  33. BOOLEAN
  34. ConSetRowCol(
  35. IN PREQUEST_HEADER Request
  36. );
  37. BOOLEAN
  38. ConSetTypematic(
  39. IN PREQUEST_HEADER Request
  40. );
  41. BOOLEAN
  42. ConHandler(
  43. IN PREQUEST_HEADER Request
  44. )
  45. /*++
  46. Routine Description:
  47. Handles console requests
  48. Arguments:
  49. Request - Supplies pointer to request
  50. Return Value:
  51. None.
  52. Notes:
  53. --*/
  54. {
  55. BOOLEAN Served = TRUE; // TRUE if request served OK.
  56. DebugPtrAssert( Request );
  57. DebugAssert( Request->DeviceType == DEVICE_TYPE_CON );
  58. //
  59. // So the device is valid. Now serve the request
  60. //
  61. switch( Request->RequestType ) {
  62. case REQUEST_TYPE_STATUS:
  63. //
  64. // Display state of CON device
  65. //
  66. Served = ConStatus( Request, FALSE );
  67. break;
  68. case REQUEST_TYPE_CODEPAGE_PREPARE:
  69. case REQUEST_TYPE_CODEPAGE_SELECT:
  70. case REQUEST_TYPE_CODEPAGE_REFRESH:
  71. //
  72. // Handle Codepage requests
  73. //
  74. Served = ConCodePage( Request );
  75. break;
  76. case REQUEST_TYPE_CODEPAGE_STATUS:
  77. //
  78. // Display codepage status
  79. //
  80. Served = ConStatus( Request, TRUE );
  81. break;
  82. case REQUEST_TYPE_CON_SET_ROWCOL:
  83. //
  84. // Set rows & columns
  85. //
  86. Served = ConSetRowCol( Request );
  87. break;
  88. case REQUEST_TYPE_CON_SET_TYPEMATIC:
  89. //
  90. // Set typematic rate
  91. //
  92. Served = ConSetTypematic( Request );
  93. break;
  94. default:
  95. DisplayMessageAndExit( MODE_ERROR_INVALID_PARAMETER,
  96. NULL,
  97. (ULONG)EXIT_ERROR );
  98. }
  99. return Served;
  100. }
  101. BOOLEAN
  102. ConStatus(
  103. IN PREQUEST_HEADER Request,
  104. IN BOOLEAN JustCodePage
  105. )
  106. /*++
  107. Routine Description:
  108. Displays status of a console
  109. Arguments:
  110. Request - Supplies pointer to request
  111. JustCodePage- Supplies a flag which if TRUE means that only
  112. the codepage status should be displayed.
  113. Return Value:
  114. BOOLEAN - TRUE if status displayed successfully,
  115. FALSE otherwise
  116. Notes:
  117. --*/
  118. {
  119. SCREEN Screen;
  120. PATH ConPath;
  121. USHORT Rows;
  122. USHORT Cols;
  123. ULONG Delay = 0;
  124. ULONG Speed = 0;
  125. DSTRING CodepageName;
  126. ULONG Language;
  127. ULONG Country;
  128. ULONG Codepage;
  129. DSTRING CodepageString;
  130. PSTR S1, S2;
  131. if ( !ConPath.Initialize( (LPWSTR)L"CON" ) ) {
  132. DisplayMessageAndExit( MODE_ERROR_NO_MEMORY, NULL, (ULONG)EXIT_ERROR );
  133. }
  134. //
  135. // Write the Header
  136. //
  137. WriteStatusHeader( &ConPath );
  138. if ( !Screen.Initialize() ) {
  139. DisplayMessageAndExit( MODE_ERROR_NO_MEMORY, NULL, (ULONG)EXIT_ERROR );
  140. }
  141. if ( !JustCodePage ) {
  142. //
  143. // Display non-codepage information
  144. //
  145. Screen.QueryScreenSize( &Rows, &Cols );
  146. Message->Set( MODE_MESSAGE_STATUS_LINES );
  147. Message->Display( "%d", Rows );
  148. Message->Set( MODE_MESSAGE_STATUS_COLS );
  149. Message->Display( "%d", Cols );
  150. if (!SystemParametersInfo( SPI_GETKEYBOARDSPEED, 0, (PVOID)&Speed, 0 )) {
  151. ExitWithError( GetLastError() );
  152. }
  153. Message->Set( MODE_MESSAGE_STATUS_RATE );
  154. Message->Display( "%d", Speed );
  155. if (!SystemParametersInfo( SPI_GETKEYBOARDDELAY, 0, (PVOID)&Delay, 0 )) {
  156. ExitWithError( GetLastError() );
  157. }
  158. Message->Set( MODE_MESSAGE_STATUS_DELAY );
  159. Message->Display( "%d", Delay );
  160. }
  161. Message->Set( MODE_MESSAGE_STATUS_CODEPAGE );
  162. Message->Display( "%d", Screen.QueryCodePage( ) );
  163. Get_Standard_Output_Stream()->WriteChar( '\r' );
  164. Get_Standard_Output_Stream()->WriteChar( '\n' );
  165. return TRUE;
  166. }
  167. BOOLEAN
  168. ConCodePage(
  169. IN PREQUEST_HEADER Request
  170. )
  171. /*++
  172. Routine Description:
  173. Handles Codepage requests for the console
  174. Arguments:
  175. Request - Supplies pointer to request
  176. Return Value:
  177. BOOLEAN - TRUE if request handled successfully,
  178. FALSE otherwise
  179. Notes:
  180. --*/
  181. {
  182. SCREEN Screen;
  183. PREQUEST_DATA_CON_CODEPAGE_SELECT Data;
  184. //
  185. // We only process Codepage Select requests, all other requests
  186. // are No-Ops. Note that the Codepage Status request is not
  187. // processed here.
  188. //
  189. if ( Request->RequestType == REQUEST_TYPE_CODEPAGE_SELECT ) {
  190. Data = (PREQUEST_DATA_CON_CODEPAGE_SELECT)&(((PCON_REQUEST)Request)->
  191. Data.CpSelect);
  192. if ( !Screen.Initialize() ) {
  193. DisplayMessageAndExit( MODE_ERROR_NO_MEMORY, NULL, (ULONG)EXIT_ERROR );
  194. }
  195. if ( !Screen.SetCodePage( Data->Codepage ) ||
  196. !Screen.SetOutputCodePage( Data->Codepage) ) {
  197. DisplayMessageAndExit( MODE_ERROR_INVALID_CODEPAGE, NULL, (ULONG)EXIT_ERROR );
  198. }
  199. #ifdef FE_SB
  200. LANGID LangId;
  201. switch (GetConsoleOutputCP()) {
  202. case 932:
  203. LangId = MAKELANGID( LANG_JAPANESE, SUBLANG_DEFAULT );
  204. break;
  205. case 949:
  206. LangId = MAKELANGID( LANG_KOREAN, SUBLANG_KOREAN );
  207. break;
  208. case 936:
  209. LangId = MAKELANGID( LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED );
  210. break;
  211. case 950:
  212. LangId = MAKELANGID( LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL );
  213. break;
  214. default:
  215. LangId = PRIMARYLANGID(LANGIDFROMLCID( GetUserDefaultLCID() ));
  216. if (LangId == LANG_JAPANESE ||
  217. LangId == LANG_KOREAN ||
  218. LangId == LANG_CHINESE ) {
  219. LangId = MAKELANGID( LANG_ENGLISH, SUBLANG_ENGLISH_US );
  220. }
  221. else {
  222. LangId = MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT );
  223. }
  224. break;
  225. }
  226. SetThreadLocale( MAKELCID(LangId, SORT_DEFAULT) );
  227. #endif
  228. ConStatus( Request, FALSE );
  229. } else {
  230. DisplayMessageAndExit( MODE_MESSAGE_NOT_NEEDED, NULL, EXIT_SUCCESS );
  231. }
  232. return TRUE;
  233. }
  234. BOOLEAN
  235. ConSetRowCol(
  236. IN PREQUEST_HEADER Request
  237. )
  238. /*++
  239. Routine Description:
  240. Sets number of rows and columns in the console window.
  241. Arguments:
  242. Request - Supplies pointer to request
  243. Return Value:
  244. BOOLEAN - TRUE if Number of Rows & Columns set successfully,
  245. FALSE otherwise
  246. Notes:
  247. --*/
  248. {
  249. PREQUEST_DATA_CON_ROWCOL Data;
  250. SCREEN Screen;
  251. USHORT Rows;
  252. USHORT Cols;
  253. BOOLEAN IsFullScreen;
  254. DebugPtrAssert( Request);
  255. Data = (PREQUEST_DATA_CON_ROWCOL)&(((PCON_REQUEST)Request)->Data.RowCol);
  256. if ( !Screen.Initialize() ) {
  257. DisplayMessageAndExit( MODE_ERROR_NO_MEMORY, NULL, (ULONG)EXIT_ERROR );
  258. }
  259. if ( !Data->SetCol || !Data->SetLines ) {
  260. //
  261. // Since we don't have both values, take the current ones.
  262. //
  263. Screen.QueryScreenSize( &Rows, &Cols );
  264. }
  265. //
  266. // Set the number of rows and columns
  267. //
  268. if ( Data->SetCol ) {
  269. Cols = (USHORT)Data->Col;
  270. }
  271. if ( Data->SetLines ) {
  272. Rows = (USHORT)Data->Lines;
  273. }
  274. if ( !Screen.ChangeScreenSize( Rows, Cols, &IsFullScreen ) ) {
  275. //
  276. // Cannot change the screen size
  277. //
  278. if ( IsFullScreen ) {
  279. DisplayMessageAndExit( MODE_ERROR_FULL_SCREEN, NULL, (ULONG)EXIT_ERROR );
  280. } else {
  281. DisplayMessageAndExit( MODE_ERROR_INVALID_SCREEN_SIZE, NULL, (ULONG)EXIT_ERROR );
  282. }
  283. }
  284. return TRUE;
  285. }
  286. BOOLEAN
  287. ConSetTypematic(
  288. IN PREQUEST_HEADER Request
  289. )
  290. /*++
  291. Routine Description:
  292. Sets thje typematic rate
  293. Arguments:
  294. DevicePath - Supplies pointer to path of device
  295. Request - Supplies pointer to request
  296. Return Value:
  297. BOOLEAN - TRUE if typematic rate set successfully,
  298. FALSE otherwise
  299. Notes:
  300. --*/
  301. {
  302. PREQUEST_DATA_CON_TYPEMATIC Data;
  303. DebugPtrAssert( Request);
  304. Data = (PREQUEST_DATA_CON_TYPEMATIC)&(((PCON_REQUEST)Request)->Data.Typematic);
  305. if ( Data->SetRate ) {
  306. if (!SystemParametersInfo( SPI_SETKEYBOARDSPEED, (UINT)Data->Rate, NULL, SPIF_UPDATEINIFILE | SPIF_SENDWININICHANGE )) {
  307. DisplayMessageAndExit( MODE_ERROR_INVALID_RATE, NULL, (ULONG)EXIT_ERROR);
  308. }
  309. }
  310. if ( Data->SetDelay ) {
  311. if (!SystemParametersInfo( SPI_SETKEYBOARDDELAY, (UINT)Data->Delay, NULL, SPIF_UPDATEINIFILE | SPIF_SENDWININICHANGE )) {
  312. DisplayMessageAndExit( MODE_ERROR_INVALID_DELAY, NULL, (ULONG)EXIT_ERROR);
  313. }
  314. }
  315. return TRUE;
  316. }