Leaked source code of windows server 2003
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.

760 lines
17 KiB

  1. /*++
  2. Copyright (c) 1999 Intel Corporation
  3. Module Name:
  4. libFileBuffer.c
  5. --*/
  6. #ifndef _LIB_FILE_BUFFER
  7. #define _LIB_FILE_BUFFER
  8. #include "libMisc.h"
  9. #define ABSOLUTE_MAX_COLUMNS 132
  10. STATIC CHAR16 BlankLine[ABSOLUTE_MAX_COLUMNS];
  11. STATIC EFI_STATUS FileBufferScrollUp (VOID);
  12. STATIC EFI_STATUS FileBufferScrollDown (VOID);
  13. STATIC EFI_STATUS FileBufferScrollLeft (VOID);
  14. STATIC EFI_STATUS FileBufferScrollRight (VOID);
  15. STATIC EFI_STATUS FileBufferPageUp (VOID);
  16. STATIC EFI_STATUS FileBufferPageDown (VOID);
  17. STATIC EFI_STATUS FileBufferHome (VOID);
  18. STATIC EFI_STATUS FileBufferEnd (VOID);
  19. STATIC EFI_STATUS FileBufferDoDelete (VOID);
  20. STATIC EFI_STATUS FileBufferDoBackspace (VOID);
  21. STATIC EFI_STATUS FileBufferDoHexInput (CHAR16);
  22. STATIC EFI_STATUS FileBufferRefreshCurrentLine(VOID);
  23. STATIC EFI_STATUS FileBufferRefreshDown (VOID);
  24. STATIC EFI_STATUS FileBufferInit (VOID);
  25. STATIC EFI_STATUS FileBufferCleanup (VOID);
  26. STATIC EFI_STATUS FileBufferRefresh (VOID);
  27. STATIC EFI_STATUS FileBufferHide (VOID);
  28. STATIC EFI_STATUS FileBufferHandleInput (EFI_INPUT_KEY*);
  29. STATIC EFI_STATUS FileBufferClearLine (UINTN);
  30. STATIC EFI_STATUS FileBufferSetPosition (UINTN,UINTN);
  31. STATIC EFI_STATUS FileBufferRestorePosition (VOID);
  32. STATIC UINTN DisplayPosition();
  33. EE_FILE_BUFFER FileBuffer = {
  34. {0,0},
  35. 0x00,
  36. 0x00,
  37. 0x00,
  38. 0x00,
  39. NULL,
  40. FileBufferInit,
  41. FileBufferCleanup,
  42. FileBufferRefresh,
  43. FileBufferHide,
  44. FileBufferHandleInput,
  45. FileBufferClearLine,
  46. FileBufferSetPosition,
  47. FileBufferRestorePosition,
  48. };
  49. STATIC
  50. EFI_STATUS
  51. FileBufferInit (
  52. VOID
  53. )
  54. {
  55. UINTN i;
  56. FileBuffer.DisplayPosition.Row = TEXT_START_ROW;
  57. FileBuffer.DisplayPosition.Column = HEX_POSITION;
  58. FileBuffer.MaxVisibleBytes = MAX_TEXT_ROWS * 0x10;
  59. for (i = 0; i < ABSOLUTE_MAX_COLUMNS; i++) {
  60. BlankLine[i] = ' ';
  61. }
  62. LineCreateNode(MainEditor.BufferImage->ListHead);
  63. FileBuffer.CurrentLine = MainEditor.BufferImage->ListHead->Flink;
  64. return EFI_SUCCESS;
  65. }
  66. STATIC
  67. EFI_STATUS
  68. FileBufferCleanup (
  69. VOID
  70. )
  71. {
  72. return EFI_SUCCESS;
  73. }
  74. STATIC
  75. VOID
  76. RefreshOffset (
  77. VOID
  78. )
  79. {
  80. PrintAt(0,FileBuffer.DisplayPosition.Row,L"%X",FileBuffer.Offset&0xfffffff0);
  81. FileBufferRestorePosition();
  82. }
  83. STATIC
  84. EFI_STATUS
  85. FileBufferRefresh (
  86. VOID
  87. )
  88. {
  89. UINTN i;
  90. UINTN Limit;
  91. LIST_ENTRY *Item;
  92. UINTN Offset = 0x00;
  93. UINTN Row;
  94. Item = MainEditor.BufferImage->ListHead->Flink;
  95. FileBuffer.HighVisibleOffset = FileBuffer.MaxVisibleBytes;
  96. Row = FileBuffer.LowVisibleOffset / 0x10;
  97. for (i = 0; i < Row && Item != MainEditor.BufferImage->ListHead; i++) {
  98. Item = Item->Flink;
  99. FileBuffer.HighVisibleOffset += 0x10;
  100. Offset += 0x10;
  101. }
  102. Limit = FileBuffer.MaxVisibleBytes / 0x10;
  103. i = TEXT_START_ROW;
  104. for (i = TEXT_START_ROW; i <= Limit; i++) {
  105. if (Item->Flink != MainEditor.BufferImage->ListHead) {
  106. LinePrint (Item,Offset,i);
  107. Offset += 0x10;
  108. Item = Item->Flink;
  109. } else {
  110. FileBufferClearLine(i);
  111. }
  112. }
  113. RefreshOffset();
  114. FileBufferRestorePosition();
  115. return EFI_SUCCESS;
  116. }
  117. STATIC
  118. EFI_STATUS
  119. FileBufferRefreshDown (
  120. VOID
  121. )
  122. {
  123. UINTN Limit;
  124. LIST_ENTRY *Link;
  125. UINTN i;
  126. UINTN Offset;
  127. Limit = FileBuffer.MaxVisibleBytes / 0x10;
  128. Offset = FileBuffer.Offset & 0xfffffff0;
  129. Link = FileBuffer.CurrentLine;
  130. /* while (Link != MainEditor.BufferImage->ListHead) { */
  131. for (i = FileBuffer.DisplayPosition.Row; i < TEXT_END_ROW; i++) {
  132. if (Link->Flink != MainEditor.BufferImage->ListHead) {
  133. LinePrint (Link,Offset,i);
  134. Link = Link->Flink;
  135. Offset += 0x10;
  136. } else {
  137. FileBufferClearLine(i);
  138. }
  139. }
  140. FileBufferRestorePosition();
  141. return EFI_SUCCESS;
  142. }
  143. STATIC
  144. EFI_STATUS
  145. FileBufferHandleInput (
  146. IN EFI_INPUT_KEY* Key
  147. )
  148. {
  149. switch (Key->ScanCode) {
  150. case SCAN_CODE_NULL:
  151. FileBufferDoHexInput (Key->UnicodeChar);
  152. break;
  153. case SCAN_CODE_UP:
  154. FileBufferScrollUp();
  155. break;
  156. case SCAN_CODE_DOWN:
  157. FileBufferScrollDown();
  158. break;
  159. case SCAN_CODE_RIGHT:
  160. FileBufferScrollRight();
  161. break;
  162. case SCAN_CODE_LEFT:
  163. FileBufferScrollLeft();
  164. break;
  165. case SCAN_CODE_PGUP:
  166. FileBufferPageUp();
  167. break;
  168. case SCAN_CODE_PGDN:
  169. FileBufferPageDown();
  170. break;
  171. case SCAN_CODE_DEL:
  172. FileBufferDoDelete();
  173. break;
  174. case SCAN_CODE_HOME:
  175. FileBufferHome();
  176. break;
  177. case SCAN_CODE_END:
  178. FileBufferEnd();
  179. break;
  180. default:
  181. break;
  182. }
  183. return EFI_SUCCESS;
  184. }
  185. STATIC
  186. EFI_STATUS
  187. FileBufferHide (
  188. VOID
  189. )
  190. {
  191. UINTN i;
  192. UINTN NumLines;
  193. NumLines = FileBuffer.MaxVisibleBytes / 0x10;
  194. for (i = TEXT_START_ROW; i <= NumLines; i++) {
  195. FileBufferClearLine(i);
  196. }
  197. return EFI_SUCCESS;
  198. }
  199. STATIC
  200. EFI_STATUS
  201. FileBufferRefreshCurrentLine (
  202. VOID
  203. )
  204. {
  205. UINTN Where;
  206. Where = FileBuffer.DisplayPosition.Row;
  207. LinePrint(FileBuffer.CurrentLine,(FileBuffer.Offset & 0xfffffff0),Where);
  208. FileBufferRestorePosition();
  209. return EFI_SUCCESS;
  210. }
  211. STATIC
  212. EFI_STATUS
  213. FileBufferRefreshCurrentDigit (
  214. VOID
  215. )
  216. {
  217. UINTN Row;
  218. UINTN Pos;
  219. Row = FileBuffer.DisplayPosition.Row;
  220. Pos = FileBuffer.Offset % 0x10;
  221. DigitPrint(FileBuffer.CurrentLine,Pos,Row);
  222. FileBufferRestorePosition();
  223. return EFI_SUCCESS;
  224. }
  225. STATIC
  226. EFI_STATUS
  227. FileBufferClearLine (
  228. UINTN Line
  229. )
  230. {
  231. BlankLine[MAX_TEXT_COLUMNS-1] = 0;
  232. PrintAt(0,Line,BlankLine);
  233. return EFI_SUCCESS;
  234. }
  235. STATIC
  236. EFI_STATUS
  237. FileBufferSetPosition (
  238. IN UINTN Row,
  239. IN UINTN Column
  240. )
  241. {
  242. FileBuffer.DisplayPosition.Row = Row;
  243. FileBuffer.DisplayPosition.Column = Column;
  244. return EFI_SUCCESS;
  245. }
  246. STATIC
  247. EFI_STATUS
  248. FileBufferRestorePosition (
  249. VOID
  250. )
  251. {
  252. Out->SetCursorPosition (Out,FileBuffer.DisplayPosition.Column,FileBuffer.DisplayPosition.Row);
  253. return EFI_SUCCESS;
  254. }
  255. STATIC
  256. EFI_STATUS
  257. FileBufferScrollDown (
  258. VOID
  259. )
  260. {
  261. UINTN MaxBytes;
  262. UINTN HighOffset;
  263. UINTN CurrentRow;
  264. UINTN CurrentOffset;
  265. UINTN MaxRows;
  266. UINTN HighRow;
  267. UINTN NumBytes;
  268. UINTN NumLines;
  269. UINTN DisplayOffset;
  270. EE_LINE *Line;
  271. CurrentRow = FileBuffer.DisplayPosition.Row;
  272. Line = LineCurrent();
  273. MaxBytes = FileBuffer.MaxVisibleBytes;
  274. HighOffset = FileBuffer.HighVisibleOffset;
  275. MaxRows = TEXT_END_ROW;
  276. HighRow = HighOffset/0x10;
  277. NumBytes = MainEditor.BufferImage->NumBytes;
  278. NumLines = NumBytes / 0x10;
  279. if (Line->Link.Flink == MainEditor.BufferImage->ListHead->Blink) {
  280. return EFI_SUCCESS;
  281. }
  282. CurrentOffset = FileBuffer.Offset + 0x10;
  283. FileBuffer.Offset = CurrentOffset;
  284. if (CurrentRow == (MaxRows - 1)) {
  285. FileBuffer.LowVisibleOffset += 0x10;
  286. FileBuffer.HighVisibleOffset += 0x10;
  287. CurrentRow = MaxRows - 1;
  288. FileBuffer.Refresh();
  289. } else if (CurrentRow == HighRow) {
  290. return EFI_SUCCESS;
  291. } else {
  292. ++CurrentRow;
  293. }
  294. Line = LineNext ();
  295. if ((CurrentOffset % 0x10) < Line->Size) {
  296. DisplayOffset = FileBuffer.DisplayPosition.Column;
  297. } else {
  298. CurrentOffset = NumBytes;
  299. DisplayOffset = (Line->Size*3) + HEX_POSITION;
  300. if (Line->Size > 0x07) {
  301. ++DisplayOffset;
  302. }
  303. }
  304. FileBuffer.SetPosition(CurrentRow,DisplayOffset);
  305. MainEditor.StatusBar->SetOffset(CurrentOffset);
  306. return EFI_SUCCESS;
  307. }
  308. STATIC
  309. EFI_STATUS
  310. FileBufferScrollUp (
  311. VOID
  312. )
  313. {
  314. UINTN CurrentRow;
  315. UINTN MaxRows;
  316. UINTN LowRow;
  317. UINTN MaxBytes;
  318. UINTN LowOffset;
  319. UINTN CurrentOffset;
  320. CurrentOffset = FileBuffer.Offset;
  321. if ( CurrentOffset < 0x10 ) {
  322. return EFI_SUCCESS;
  323. }
  324. MaxBytes = FileBuffer.MaxVisibleBytes;
  325. MaxRows = MaxBytes / 0x10;
  326. LowOffset = FileBuffer.LowVisibleOffset;
  327. LowRow = LowOffset / 0x10;
  328. CurrentRow = FileBuffer.DisplayPosition.Row;
  329. CurrentOffset -= 0x10;
  330. FileBuffer.Offset -= 0x10;
  331. if (CurrentRow == 1) {
  332. FileBuffer.HighVisibleOffset -= 0x10;
  333. FileBuffer.LowVisibleOffset -= 0x10;
  334. CurrentRow = 1;
  335. FileBuffer.Refresh();
  336. } else {
  337. CurrentRow--;
  338. }
  339. LinePrevious ();
  340. FileBuffer.SetPosition(CurrentRow,FileBuffer.DisplayPosition.Column);
  341. MainEditor.StatusBar->SetOffset(CurrentOffset);
  342. return EFI_SUCCESS;
  343. }
  344. STATIC
  345. EFI_STATUS
  346. FileBufferPageUp (
  347. VOID
  348. )
  349. {
  350. UINTN MaxBytes;
  351. UINTN LowOffset;
  352. UINTN CurrentOffset;
  353. BOOLEAN Refresh = FALSE;
  354. CurrentOffset = FileBuffer.Offset;
  355. MaxBytes = FileBuffer.MaxVisibleBytes;
  356. LowOffset = FileBuffer.LowVisibleOffset;
  357. if (LowOffset <= MaxBytes) {
  358. FileBuffer.HighVisibleOffset = MaxBytes - 0x10;
  359. FileBuffer.LowVisibleOffset = 0x00;
  360. if (LowOffset > 0x00) {
  361. if (CurrentOffset < MaxBytes) {
  362. FileBuffer.Offset = 0x00;
  363. } else {
  364. FileBuffer.Offset -= (MaxBytes - 0x10);
  365. }
  366. } else {
  367. FileBuffer.Offset = 0x00;
  368. }
  369. Refresh = TRUE;
  370. FileBuffer.DisplayPosition.Row = FileBuffer.Offset/0x10 + TEXT_START_ROW;
  371. } else {
  372. FileBuffer.HighVisibleOffset = LowOffset - 0x10;
  373. FileBuffer.LowVisibleOffset -= (MaxBytes - 0x10);
  374. FileBuffer.Offset -= (MaxBytes - 0x10);
  375. Refresh = TRUE;
  376. }
  377. CurrentOffset -= FileBuffer.Offset;
  378. CurrentOffset /= 0x10;
  379. LineRetreat(CurrentOffset);
  380. if (Refresh) {
  381. FileBufferRefresh();
  382. }
  383. FileBuffer.DisplayPosition.Column = DisplayPosition();
  384. MainEditor.StatusBar->SetOffset(FileBuffer.Offset);
  385. return EFI_SUCCESS;
  386. }
  387. STATIC
  388. EFI_STATUS
  389. FileBufferPageDown (
  390. VOID
  391. )
  392. {
  393. UINTN NumBytes;
  394. UINTN MaxBytes;
  395. UINTN HighOffset;
  396. UINTN CurrentOffset;
  397. NumBytes = MainEditor.BufferImage->NumBytes;
  398. MaxBytes = FileBuffer.MaxVisibleBytes;
  399. HighOffset = FileBuffer.HighVisibleOffset;
  400. CurrentOffset = FileBuffer.Offset;
  401. FileBuffer.Offset = min(NumBytes,CurrentOffset+MaxBytes-0x10);
  402. if (HighOffset < NumBytes) {
  403. FileBuffer.LowVisibleOffset = HighOffset-0x10;
  404. FileBuffer.HighVisibleOffset += (MaxBytes - 0x10);
  405. FileBuffer.Refresh();
  406. LineAdvance((FileBuffer.Offset-CurrentOffset)/0x10);
  407. } else if (FileBuffer.Offset >= NumBytes-1) {
  408. FileBuffer.Offset &= 0xfffffff0;
  409. FileBuffer.Offset |= ((NumBytes-1) & 0x00000001f);
  410. FileBuffer.CurrentLine = LineLast()->Link.Blink;
  411. }
  412. FileBuffer.DisplayPosition.Column = DisplayPosition();
  413. FileBuffer.DisplayPosition.Row = (FileBuffer.Offset-FileBuffer.LowVisibleOffset)/0x10 + TEXT_START_ROW;
  414. MainEditor.StatusBar->SetOffset (FileBuffer.Offset);
  415. return EFI_SUCCESS;
  416. }
  417. STATIC
  418. EFI_STATUS
  419. FileBufferScrollLeft (
  420. VOID
  421. )
  422. {
  423. UINTN LineOffset;
  424. LineOffset = FileBuffer.Offset % 0x10;
  425. if (FileBuffer.Offset == 0x00) {
  426. return EFI_SUCCESS;
  427. }
  428. if (LineOffset == 0x00) {
  429. FileBufferScrollUp ();
  430. FileBuffer.Offset += 0x10;
  431. LineOffset = 0x0f;
  432. } else {
  433. --LineOffset;
  434. }
  435. FileBuffer.DisplayPosition.Column = HEX_POSITION + (LineOffset*3);
  436. if (LineOffset > 0x07) {
  437. ++FileBuffer.DisplayPosition.Column;
  438. }
  439. --FileBuffer.Offset;
  440. MainEditor.StatusBar->SetOffset(FileBuffer.Offset);
  441. return EFI_SUCCESS;
  442. }
  443. STATIC
  444. EFI_STATUS
  445. FileBufferScrollRight (
  446. VOID
  447. )
  448. {
  449. UINTN CurrentOffset;
  450. UINTN LineOffset;
  451. EE_LINE *Line;
  452. Line = LineCurrent();
  453. CurrentOffset = FileBuffer.Offset;
  454. LineOffset = CurrentOffset % 0x10;
  455. if (CurrentOffset >= MainEditor.BufferImage->NumBytes){
  456. return EFI_SUCCESS;
  457. }
  458. if (LineOffset > Line->Size) {
  459. return EFI_SUCCESS;
  460. }
  461. if (LineOffset == 0x0f) {
  462. FileBufferScrollDown();
  463. FileBuffer.Offset &= 0xfffffff0;
  464. FileBuffer.DisplayPosition.Column = HEX_POSITION;
  465. RefreshOffset();
  466. } else {
  467. ++LineOffset;
  468. FileBuffer.DisplayPosition.Column = HEX_POSITION + (LineOffset*3);
  469. if (LineOffset > 0x07) {
  470. ++FileBuffer.DisplayPosition.Column;
  471. }
  472. ++FileBuffer.Offset;
  473. }
  474. MainEditor.StatusBar->SetOffset(FileBuffer.Offset);
  475. return EFI_SUCCESS;
  476. }
  477. STATIC
  478. EFI_STATUS
  479. FileBufferHome (
  480. VOID
  481. )
  482. {
  483. FileBuffer.DisplayPosition.Column = HEX_POSITION;
  484. FileBuffer.Offset &= 0xfffffff0;
  485. MainEditor.StatusBar->SetOffset(FileBuffer.Offset);
  486. return EFI_SUCCESS;
  487. }
  488. STATIC
  489. EFI_STATUS
  490. FileBufferEnd (
  491. VOID
  492. )
  493. {
  494. EE_LINE *Line;
  495. Line = LineCurrent();
  496. FileBuffer.Offset &= 0xfffffff0;
  497. if (Line->Size > 0) {
  498. FileBuffer.Offset |= ((Line->Size-1) & 0x0000000f);
  499. }
  500. FileBuffer.DisplayPosition.Column = DisplayPosition();
  501. MainEditor.StatusBar->SetOffset(FileBuffer.Offset);
  502. return EFI_SUCCESS;
  503. }
  504. STATIC
  505. EFI_STATUS
  506. FileBufferDoHexInput (
  507. IN CHAR16 Char
  508. )
  509. {
  510. EE_LINE *Line;
  511. UINTN LineOffset;
  512. UINTN Pos;
  513. UINTN Num;
  514. if (Char == CHAR_BS) {
  515. FileBufferDoBackspace();
  516. return EFI_SUCCESS;
  517. }
  518. if (Char >= 'A' && Char <= 'F') {
  519. Num = Char - 'A' + 0xa;
  520. } else if (Char >= 'a' && Char <= 'f') {
  521. Num = Char - 'a' + 0xa;
  522. } else if (Char >= '0' && Char <= '9') {
  523. Num = Char - '0';
  524. } else {
  525. return EFI_SUCCESS;
  526. }
  527. LineOffset = FileBuffer.Offset % 0x10;
  528. Pos = FileBuffer.DisplayPosition.Column - HEX_POSITION;
  529. if (LineOffset > 0x07) {
  530. Pos -= (0x07*3)+1;
  531. }
  532. if (FileBuffer.CurrentLine == MainEditor.BufferImage->ListHead->Blink) {
  533. Line = LineCreateNode(MainEditor.BufferImage->ListHead);
  534. FileBuffer.CurrentLine = Line->Link.Blink;
  535. }
  536. Line = LineCurrent();
  537. Line->Buffer[LineOffset] <<= 4;
  538. Line->Buffer[LineOffset] |= Num;
  539. if (FileBuffer.Offset == MainEditor.BufferImage->NumBytes) {
  540. ++Line->Size;
  541. ++MainEditor.BufferImage->NumBytes;
  542. } else if (FileBuffer.Offset == (MainEditor.BufferImage->NumBytes - 1)) {
  543. if ((Pos%3) != 0 && Line->Size == 0x10) {
  544. Line = LineCreateNode(MainEditor.BufferImage->ListHead);
  545. }
  546. }
  547. FileBufferRefreshCurrentDigit();
  548. if ((Pos % 3) != 0) {
  549. FileBufferScrollRight();
  550. } else {
  551. ++FileBuffer.DisplayPosition.Column;
  552. }
  553. FileBufferRestorePosition();
  554. FileModification();
  555. return EFI_SUCCESS;
  556. }
  557. STATIC
  558. EFI_STATUS
  559. FileBufferDoBackspace (
  560. VOID
  561. )
  562. {
  563. UINTN LinePos;
  564. if (FileBuffer.Offset == 0x00) {
  565. return EFI_SUCCESS;
  566. }
  567. FileBufferScrollLeft();
  568. LinePos = FileBuffer.Offset % 0x10;
  569. LineDeleteAt(FileBuffer.CurrentLine,LinePos,1);
  570. FileBufferRefreshDown();
  571. FileModification();
  572. return EFI_SUCCESS;
  573. }
  574. STATIC
  575. EFI_STATUS
  576. FileBufferDoDelete (
  577. VOID
  578. )
  579. {
  580. LIST_ENTRY *Link;
  581. UINTN LinePos;
  582. if (FileBuffer.Offset == MainEditor.BufferImage->NumBytes) {
  583. return EFI_SUCCESS;
  584. }
  585. LinePos = FileBuffer.Offset % 0x10;
  586. Link = FileBuffer.CurrentLine;
  587. LineDeleteAt(Link,LinePos,1);
  588. if (FileBuffer.Offset == MainEditor.BufferImage->NumBytes) {
  589. FileBufferScrollLeft();
  590. }
  591. FileBufferRefreshDown();
  592. FileModification();
  593. return EFI_SUCCESS;
  594. }
  595. STATIC
  596. UINTN
  597. DisplayPosition (
  598. VOID
  599. )
  600. {
  601. EE_LINE *Line;
  602. UINTN Pos = 0;
  603. Line = LineCurrent();
  604. Pos = FileBuffer.Offset & 0x0000000f;
  605. Pos = Pos * 3 + HEX_POSITION;
  606. if (Line->Size > 0x07) {
  607. Pos++;
  608. }
  609. return Pos;
  610. }
  611. #endif /* _LIB_FILE_BUFFER */