2 Defines HBufferImage - the view of the file that is visible at any point,
3 as well as the event handlers for editing the file
5 Copyright (c) 2005 - 2011, Intel Corporation. All rights reserved. <BR>
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16 #include "HexEditor.h"
18 extern EFI_HANDLE HImageHandleBackup
;
20 extern HEFI_EDITOR_FILE_IMAGE HFileImage
;
21 extern HEFI_EDITOR_DISK_IMAGE HDiskImage
;
22 extern HEFI_EDITOR_MEM_IMAGE HMemImage
;
24 extern HEFI_EDITOR_FILE_IMAGE HFileImageBackupVar
;
25 extern HEFI_EDITOR_DISK_IMAGE HDiskImageBackupVar
;
26 extern HEFI_EDITOR_MEM_IMAGE HMemImageBackupVar
;
28 extern BOOLEAN HEditorMouseAction
;
30 extern HEFI_EDITOR_GLOBAL_EDITOR HMainEditor
;
31 extern HEFI_EDITOR_GLOBAL_EDITOR HMainEditorBackupVar
;
33 HEFI_EDITOR_BUFFER_IMAGE HBufferImage
;
34 HEFI_EDITOR_BUFFER_IMAGE HBufferImageBackupVar
;
37 // for basic initialization of HBufferImage
39 HEFI_EDITOR_BUFFER_IMAGE HBufferImageConst
= {
66 // the whole edit area needs to be refreshed
68 BOOLEAN HBufferImageNeedRefresh
;
71 // only the current line in edit area needs to be refresh
73 BOOLEAN HBufferImageOnlyLineNeedRefresh
;
75 BOOLEAN HBufferImageMouseNeedRefresh
;
85 Initialization function for HBufferImage
101 // basically initialize the HBufferImage
103 CopyMem (&HBufferImage
, &HBufferImageConst
, sizeof (HBufferImage
));
108 HBufferImage
.ListHead
= AllocateZeroPool (sizeof (LIST_ENTRY
));
109 if (HBufferImage
.ListHead
== NULL
) {
110 return EFI_LOAD_ERROR
;
113 InitializeListHead (HBufferImage
.ListHead
);
115 HBufferImage
.DisplayPosition
.Row
= 2;
116 HBufferImage
.DisplayPosition
.Column
= 10;
117 HBufferImage
.MousePosition
.Row
= 2;
118 HBufferImage
.MousePosition
.Column
= 10;
120 HBufferImage
.FileImage
= &HFileImage
;
121 HBufferImage
.DiskImage
= &HDiskImage
;
122 HBufferImage
.MemImage
= &HMemImage
;
124 HBufferImageNeedRefresh
= FALSE
;
125 HBufferImageOnlyLineNeedRefresh
= FALSE
;
126 HBufferImageMouseNeedRefresh
= FALSE
;
128 HBufferImageBackupVar
.FileImage
= &HFileImageBackupVar
;
129 HBufferImageBackupVar
.DiskImage
= &HDiskImageBackupVar
;
130 HBufferImageBackupVar
.MemImage
= &HMemImageBackupVar
;
132 Status
= HFileImageInit ();
133 if (EFI_ERROR (Status
)) {
134 return EFI_LOAD_ERROR
;
137 Status
= HDiskImageInit ();
138 if (EFI_ERROR (Status
)) {
139 return EFI_LOAD_ERROR
;
142 Status
= HMemImageInit ();
143 if (EFI_ERROR (Status
)) {
144 return EFI_LOAD_ERROR
;
158 Backup function for HBufferImage
159 Only a few fields need to be backup.
160 This is for making the file buffer refresh
173 HBufferImageBackupVar
.MousePosition
= HBufferImage
.MousePosition
;
175 HBufferImageBackupVar
.BufferPosition
= HBufferImage
.BufferPosition
;
177 HBufferImageBackupVar
.Modified
= HBufferImage
.Modified
;
179 HBufferImageBackupVar
.BufferType
= HBufferImage
.BufferType
;
180 HBufferImageBackupVar
.LowVisibleRow
= HBufferImage
.LowVisibleRow
;
181 HBufferImageBackupVar
.HighBits
= HBufferImage
.HighBits
;
184 // three kinds of buffer supported
189 switch (HBufferImage
.BufferType
) {
190 case FileTypeFileBuffer
:
194 case FileTypeDiskBuffer
:
198 case FileTypeMemBuffer
:
207 HBufferImageFreeLines (
214 Free all the lines in HBufferImage
231 HFreeLines (HBufferImage
.ListHead
, HBufferImage
.Lines
);
233 HBufferImage
.Lines
= NULL
;
234 HBufferImage
.CurrentLine
= NULL
;
235 HBufferImage
.NumLines
= 0;
241 HBufferImageCleanup (
248 Cleanup function for HBufferImage
263 // free all the lines
265 Status
= HBufferImageFreeLines ();
267 SHELL_FREE_NON_NULL (HBufferImage
.ListHead
);
268 HBufferImage
.ListHead
= NULL
;
270 HFileImageCleanup ();
271 HDiskImageCleanup ();
279 HBufferImagePrintLine (
280 IN HEFI_EDITOR_LINE
*Line
,
283 IN HEFI_EDITOR_COLOR_UNION Orig
,
284 IN HEFI_EDITOR_COLOR_UNION New
296 Row - Row on screen ( begin from 1 )
318 // variable initialization
325 // print the selected area in opposite color
327 if (HMainEditor
.SelectStart
!= 0 && HMainEditor
.SelectEnd
!= 0) {
328 RowStart
= (HMainEditor
.SelectStart
- 1) / 0x10 + 1;
329 RowEnd
= (HMainEditor
.SelectEnd
- 1) / 0x10 + 1;
331 ColStart
= (HMainEditor
.SelectStart
- 1) % 0x10 + 1;
332 ColEnd
= (HMainEditor
.SelectEnd
- 1) % 0x10 + 1;
334 if (FRow
>= RowStart
&& FRow
<= RowEnd
) {
338 if (FRow
> RowStart
) {
348 if (HEditorMouseAction
== FALSE
) {
353 ((INT32
)Row
- 2 + HBufferImage
.LowVisibleRow
- 1) * 0x10
358 for (Index
= 0; Index
< 0x08 && Index
< Line
->Size
; Index
++) {
363 if (Index
+ 1 >= ColStart
&& Index
+ 1 <= ColEnd
) {
369 gST
->ConOut
->SetAttribute (gST
->ConOut
, New
.Data
);
371 gST
->ConOut
->SetAttribute (gST
->ConOut
, Orig
.Data
);
374 Pos
= 10 + (Index
* 3);
375 if (Line
->Buffer
[Index
] < 0x10) {
376 ShellPrintEx ((INT32
)Pos
- 1, (INT32
)Row
- 1, L
"0");
381 ShellPrintEx ((INT32
)Pos
- 1, (INT32
)Row
- 1, L
"%x ", Line
->Buffer
[Index
]);
383 ShellPrintEx ((INT32
)Pos
- 1, (INT32
)Row
- 1, L
"%x ", Line
->Buffer
[Index
]);
388 gST
->ConOut
->SetAttribute (gST
->ConOut
, Orig
.Data
);
389 while (Index
< 0x08) {
390 Pos
= 10 + (Index
* 3);
391 ShellPrintEx ((INT32
)Pos
- 1, (INT32
)Row
- 1, L
" ");
395 while (Index
< 0x10 && Index
< Line
->Size
) {
400 if (Index
+ 1 >= ColStart
&& Index
+ 1 <= ColEnd
) {
406 gST
->ConOut
->SetAttribute (gST
->ConOut
, New
.Data
);
408 gST
->ConOut
->SetAttribute (gST
->ConOut
, Orig
.Data
);
411 Pos
= 10 + (Index
* 3) + 1;
412 if (Line
->Buffer
[Index
] < 0x10) {
413 ShellPrintEx ((INT32
)Pos
- 1, (INT32
)Row
- 1, L
"0");
417 ShellPrintEx ((INT32
)Pos
- 1, (INT32
)Row
- 1, L
"%x ", Line
->Buffer
[Index
]);
421 gST
->ConOut
->SetAttribute (gST
->ConOut
, Orig
.Data
);
422 while (Index
< 0x10) {
423 Pos
= 10 + (Index
* 3) + 1;
424 ShellPrintEx ((INT32
)Pos
- 1, (INT32
)Row
- 1, L
" ");
428 // restore the original color
430 gST
->ConOut
->SetAttribute (gST
->ConOut
, Orig
.Data
);
433 // PRINT the buffer content
435 if (HEditorMouseAction
== FALSE
) {
436 for (Index
= 0; Index
< 0x10 && Index
< Line
->Size
; Index
++) {
437 Pos
= ASCII_POSITION
+ Index
;
440 // learned from shelle.h -- IsValidChar
442 if (Line
->Buffer
[Index
] >= L
' ') {
443 ShellPrintEx ((INT32
)Pos
- 1, (INT32
)Row
- 1, L
"%c", (CHAR16
) Line
->Buffer
[Index
]);
445 ShellPrintEx ((INT32
)Pos
- 1, (INT32
)Row
- 1, L
"%c", '.');
449 while (Index
< 0x10) {
450 Pos
= ASCII_POSITION
+ Index
;
451 ShellPrintEx ((INT32
)Pos
- 1, (INT32
)Row
- 1, L
" ");
456 // restore the abundant blank in hex edit area to original color
460 Pos
= 10 + (ColEnd
- 1) * 3 + 2;
461 ShellPrintEx ((INT32
)Pos
- 1, (INT32
)Row
- 1, L
" ");
462 } else if (ColEnd
== 8) {
463 Pos
= 10 + (ColEnd
- 1) * 3 + 2;
464 ShellPrintEx ((INT32
)Pos
- 1, (INT32
)Row
- 1, L
" ");
466 Pos
= 10 + (ColEnd
- 1) * 3 + 3;
467 ShellPrintEx ((INT32
)Pos
- 1, (INT32
)Row
- 1, L
" ");
475 HBufferImageIsAtHighBits (
483 // NOW AFTER THE SUB, Column start from 0
484 // 23 AND 24 ARE BOTH BLANK
495 *FCol
= (Column
/ 3) + 1;
501 if ((Column
% 3 == 2)) {
509 HBufferImageIsInSelectedArea (
523 // judge mouse position whether is in selected area
528 if (HMainEditor
.SelectStart
== 0 || HMainEditor
.SelectEnd
== 0) {
532 // calculate the select area
534 RowStart
= (HMainEditor
.SelectStart
- 1) / 0x10 + 1;
535 RowEnd
= (HMainEditor
.SelectEnd
- 1) / 0x10 + 1;
537 ColStart
= (HMainEditor
.SelectStart
- 1) % 0x10 + 1;
538 ColEnd
= (HMainEditor
.SelectEnd
- 1) % 0x10 + 1;
540 FRow
= HBufferImage
.LowVisibleRow
+ MouseRow
- 2;
541 if (FRow
< RowStart
|| FRow
> RowEnd
) {
545 if (FRow
> RowStart
) {
553 MouseColStart
= 10 + (ColStart
- 1) * 3;
558 MouseColEnd
= 10 + (ColEnd
- 1) * 3 + 1;
563 if (MouseCol
< MouseColStart
|| MouseCol
> MouseColEnd
) {
571 HBufferImageRestoreMousePosition (
575 HEFI_EDITOR_COLOR_UNION Orig
;
576 HEFI_EDITOR_COLOR_UNION New
;
579 BOOLEAN HasCharacter
;
580 HEFI_EDITOR_LINE
*CurrentLine
;
581 HEFI_EDITOR_LINE
*Line
;
586 if (HMainEditor
.MouseSupported
) {
588 if (HBufferImageMouseNeedRefresh
) {
590 HBufferImageMouseNeedRefresh
= FALSE
;
593 // if mouse position not moved and only mouse action
594 // so do not need to refresh mouse position
597 HBufferImage
.MousePosition
.Row
== HBufferImageBackupVar
.MousePosition
.Row
&&
598 HBufferImage
.MousePosition
.Column
== HBufferImageBackupVar
.MousePosition
.Column
605 // backup the old screen attributes
607 Orig
= HMainEditor
.ColorAttributes
;
608 New
.Colors
.Foreground
= Orig
.Colors
.Background
;
609 New
.Colors
.Background
= Orig
.Colors
.Foreground
;
612 // if in selected area,
613 // so do not need to refresh mouse
615 if (!HBufferImageIsInSelectedArea (
616 HBufferImageBackupVar
.MousePosition
.Row
,
617 HBufferImageBackupVar
.MousePosition
.Column
619 gST
->ConOut
->SetAttribute (gST
->ConOut
, Orig
.Data
);
621 gST
->ConOut
->SetAttribute (gST
->ConOut
, New
.Data
);
624 // clear the old mouse position
626 FRow
= HBufferImage
.LowVisibleRow
+ HBufferImageBackupVar
.MousePosition
.Row
- 2;
628 HighBits
= HBufferImageIsAtHighBits (
629 HBufferImageBackupVar
.MousePosition
.Column
,
634 if (FRow
> HBufferImage
.NumLines
|| FColumn
== 0) {
635 HasCharacter
= FALSE
;
637 CurrentLine
= HBufferImage
.CurrentLine
;
638 Line
= HMoveLine (FRow
- HBufferImage
.BufferPosition
.Row
);
640 if (FColumn
> Line
->Size
) {
641 HasCharacter
= FALSE
;
644 HBufferImage
.CurrentLine
= CurrentLine
;
648 (INT32
)HBufferImageBackupVar
.MousePosition
.Column
- 1,
649 (INT32
)HBufferImageBackupVar
.MousePosition
.Row
- 1,
655 Value
= (UINT8
) (Line
->Buffer
[FColumn
- 1] & 0xf0);
656 Value
= (UINT8
) (Value
>> 4);
658 Value
= (UINT8
) (Line
->Buffer
[FColumn
- 1] & 0xf);
662 (INT32
)HBufferImageBackupVar
.MousePosition
.Column
- 1,
663 (INT32
)HBufferImageBackupVar
.MousePosition
.Row
- 1,
669 if (!HBufferImageIsInSelectedArea (
670 HBufferImage
.MousePosition
.Row
,
671 HBufferImage
.MousePosition
.Column
673 gST
->ConOut
->SetAttribute (gST
->ConOut
, New
.Data
);
675 gST
->ConOut
->SetAttribute (gST
->ConOut
, Orig
.Data
);
678 // clear the old mouse position
680 FRow
= HBufferImage
.LowVisibleRow
+ HBufferImage
.MousePosition
.Row
- 2;
682 HighBits
= HBufferImageIsAtHighBits (
683 HBufferImage
.MousePosition
.Column
,
688 if (FRow
> HBufferImage
.NumLines
|| FColumn
== 0) {
689 HasCharacter
= FALSE
;
691 CurrentLine
= HBufferImage
.CurrentLine
;
692 Line
= HMoveLine (FRow
- HBufferImage
.BufferPosition
.Row
);
694 if (FColumn
> Line
->Size
) {
695 HasCharacter
= FALSE
;
698 HBufferImage
.CurrentLine
= CurrentLine
;
702 (INT32
)HBufferImage
.MousePosition
.Column
- 1,
703 (INT32
)HBufferImage
.MousePosition
.Row
- 1,
709 Value
= (UINT8
) (Line
->Buffer
[FColumn
- 1] & 0xf0);
710 Value
= (UINT8
) (Value
>> 4);
712 Value
= (UINT8
) (Line
->Buffer
[FColumn
- 1] & 0xf);
716 (INT32
)HBufferImage
.MousePosition
.Column
- 1,
717 (INT32
)HBufferImage
.MousePosition
.Row
- 1,
723 // end of HasCharacter
725 gST
->ConOut
->SetAttribute (gST
->ConOut
, Orig
.Data
);
728 // end of MouseNeedRefresh
732 // end of MouseSupported
738 HBufferImageRestorePosition (
745 Set cursor position according to HBufferImage.DisplayPosition.
758 // set cursor position
760 gST
->ConOut
->SetCursorPosition (
762 HBufferImage
.DisplayPosition
.Column
- 1,
763 HBufferImage
.DisplayPosition
.Row
- 1
770 HBufferImageRefresh (
777 Refresh function for HBufferImage
791 HEFI_EDITOR_LINE
*Line
;
793 HEFI_EDITOR_COLOR_UNION Orig
;
794 HEFI_EDITOR_COLOR_UNION New
;
802 Orig
= HMainEditor
.ColorAttributes
;
803 New
.Colors
.Foreground
= Orig
.Colors
.Background
;
804 New
.Colors
.Background
= Orig
.Colors
.Foreground
;
807 // if it's the first time after editor launch, so should refresh
809 if (HEditorFirst
== FALSE
) {
811 // no definite required refresh
812 // and file position displayed on screen has not been changed
814 if (HBufferImageNeedRefresh
== FALSE
&&
815 HBufferImageOnlyLineNeedRefresh
== FALSE
&&
816 HBufferImageBackupVar
.LowVisibleRow
== HBufferImage
.LowVisibleRow
818 HBufferImageRestoreMousePosition ();
819 HBufferImageRestorePosition ();
824 gST
->ConOut
->EnableCursor (gST
->ConOut
, FALSE
);
827 // only need to refresh current line
829 if (HBufferImageOnlyLineNeedRefresh
== TRUE
&& HBufferImageBackupVar
.LowVisibleRow
== HBufferImage
.LowVisibleRow
) {
831 HBufferImagePrintLine (
832 HBufferImage
.CurrentLine
,
833 HBufferImage
.DisplayPosition
.Row
,
834 HBufferImage
.BufferPosition
.Row
,
840 // the whole edit area need refresh
842 if (HEditorMouseAction
&& HMainEditor
.SelectStart
!= 0 && HMainEditor
.SelectEnd
!= 0) {
843 if (HMainEditor
.SelectStart
!= HMainEditorBackupVar
.SelectStart
) {
844 if (HMainEditor
.SelectStart
>= HMainEditorBackupVar
.SelectStart
&& HMainEditorBackupVar
.SelectStart
!= 0) {
845 StartRow
= (HMainEditorBackupVar
.SelectStart
- 1) / 0x10 + 1;
847 StartRow
= (HMainEditor
.SelectStart
- 1) / 0x10 + 1;
850 StartRow
= (HMainEditor
.SelectStart
- 1) / 0x10 + 1;
853 if (HMainEditor
.SelectEnd
<= HMainEditorBackupVar
.SelectEnd
) {
854 EndRow
= (HMainEditorBackupVar
.SelectEnd
- 1) / 0x10 + 1;
856 EndRow
= (HMainEditor
.SelectEnd
- 1) / 0x10 + 1;
861 if (StartRow
> EndRow
) {
867 FStartRow
= StartRow
;
870 StartRow
= 2 + StartRow
- HBufferImage
.LowVisibleRow
;
871 EndRow
= 2 + EndRow
- HBufferImage
.LowVisibleRow
;
875 // not mouse selection actions
877 FStartRow
= HBufferImage
.LowVisibleRow
;
879 EndRow
= (HMainEditor
.ScreenSize
.Row
- 4);
884 if (HBufferImage
.Lines
== NULL
) {
885 HBufferImageRestoreMousePosition ();
886 HBufferImageRestorePosition ();
887 gST
->ConOut
->EnableCursor (gST
->ConOut
, TRUE
);
891 // get the first line that will be displayed
893 Line
= HMoveLine (FStartRow
- HBufferImage
.BufferPosition
.Row
);
895 gST
->ConOut
->EnableCursor (gST
->ConOut
, TRUE
);
896 return EFI_LOAD_ERROR
;
899 Link
= &(Line
->Link
);
902 Line
= CR (Link
, HEFI_EDITOR_LINE
, Link
, EFI_EDITOR_LINE_LIST
);
907 HBufferImagePrintLine (
910 HBufferImage
.LowVisibleRow
+ Row
- 2,
915 Link
= Link
->ForwardLink
;
917 } while (Link
!= HBufferImage
.ListHead
&& Row
<= EndRow
);
919 while (Row
<= EndRow
) {
920 HEditorClearLine (Row
);
924 // while not file end and not screen full
928 HBufferImageRestoreMousePosition ();
929 HBufferImageRestorePosition ();
931 HBufferImageNeedRefresh
= FALSE
;
932 HBufferImageOnlyLineNeedRefresh
= FALSE
;
933 gST
->ConOut
->EnableCursor (gST
->ConOut
, TRUE
);
940 IN CONST CHAR16
*FileName
,
941 IN CONST CHAR16
*DiskName
,
946 IN EDIT_FILE_TYPE BufferType
,
951 EDIT_FILE_TYPE BufferTypeBackup
;
954 // variable initialization
956 Status
= EFI_SUCCESS
;
959 // three types of buffer supported
964 BufferTypeBackup
= HBufferImage
.BufferType
;
966 switch (BufferType
) {
967 case FileTypeFileBuffer
:
968 Status
= HFileImageRead (FileName
, Recover
);
971 case FileTypeDiskBuffer
:
972 Status
= HDiskImageRead (DiskName
, DiskOffset
, DiskSize
, Recover
);
975 case FileTypeMemBuffer
:
976 Status
= HMemImageRead (MemOffset
, MemSize
, Recover
);
980 if (EFI_ERROR (Status
)) {
981 HBufferImage
.BufferType
= BufferTypeBackup
;
995 IN EDIT_FILE_TYPE BufferType
999 EDIT_FILE_TYPE BufferTypeBackup
;
1002 // variable initialization
1004 Status
= EFI_SUCCESS
;
1005 BufferTypeBackup
= HBufferImage
.BufferType
;
1007 switch (HBufferImage
.BufferType
) {
1011 case FileTypeFileBuffer
:
1012 Status
= HFileImageSave (FileName
);
1018 case FileTypeDiskBuffer
:
1019 Status
= HDiskImageSave (DiskName
, DiskOffset
, DiskSize
);
1025 case FileTypeMemBuffer
:
1026 Status
= HMemImageSave (MemOffset
, MemSize
);
1030 if (EFI_ERROR (Status
)) {
1031 HBufferImage
.BufferType
= BufferTypeBackup
;
1038 HBufferImageCreateLine (
1043 Routine Description:
1045 Create a new line and append it to the line list
1056 NULL -- create line failed
1057 Not NULL -- the line created
1061 HEFI_EDITOR_LINE
*Line
;
1064 // allocate for line structure
1066 Line
= AllocateZeroPool (sizeof (HEFI_EDITOR_LINE
));
1071 Line
->Signature
= EFI_EDITOR_LINE_LIST
;
1074 HBufferImage
.NumLines
++;
1077 // insert to line list
1079 InsertTailList (HBufferImage
.ListHead
, &Line
->Link
);
1081 if (HBufferImage
.Lines
== NULL
) {
1082 HBufferImage
.Lines
= CR (
1083 HBufferImage
.ListHead
->ForwardLink
,
1086 EFI_EDITOR_LINE_LIST
1099 Routine Description:
1101 Function called when load a new file in. It will free all the old lines
1102 and set FileModified field to FALSE
1117 HBufferImageFreeLines ();
1123 HBufferImageHandleInput (
1124 IN EFI_INPUT_KEY
*Key
1128 Routine Description:
1130 Dispatch input to different handler
1138 Direction key: up/down/left/right/pgup/pgdn
1146 EFI_OUT_OF_RESOURCES
1152 Status
= EFI_SUCCESS
;
1154 switch (Key
->ScanCode
) {
1159 Status
= HBufferImageDoCharInput (Key
->UnicodeChar
);
1166 Status
= HBufferImageScrollUp ();
1173 Status
= HBufferImageScrollDown ();
1180 Status
= HBufferImageScrollRight ();
1187 Status
= HBufferImageScrollLeft ();
1194 Status
= HBufferImagePageUp ();
1200 case SCAN_PAGE_DOWN
:
1201 Status
= HBufferImagePageDown ();
1208 Status
= HBufferImageDoDelete ();
1215 Status
= HBufferImageHome ();
1222 Status
= HBufferImageEnd ();
1226 Status
= StatusBarSetStatusString (L
"Unknown Command");
1234 HBufferImageDoCharInput (
1239 Routine Description:
1241 ASCII key + Backspace + return
1251 EFI_OUT_OF_RESOURCES
1257 Status
= EFI_SUCCESS
;
1264 Status
= HBufferImageDoBackspace ();
1271 // Tabs, Returns are thought as nothing
1277 // DEAL WITH ASCII CHAR, filter out thing like ctrl+f
1279 if (Char
> 127 || Char
< 32) {
1280 Status
= StatusBarSetStatusString (L
"Unknown Command");
1282 Status
= HBufferImageAddChar (Char
);
1292 HBufferImageCharToHex (
1297 Routine Description:
1299 change char to int value based on Hex
1313 // change the character to hex
1315 if (Char
>= L
'0' && Char
<= L
'9') {
1316 return (INTN
) (Char
- L
'0');
1319 if (Char
>= L
'a' && Char
<= L
'f') {
1320 return (INTN
) (Char
- L
'a' + 10);
1323 if (Char
>= L
'A' && Char
<= L
'F') {
1324 return (INTN
) (Char
- L
'A' + 10);
1331 HBufferImageAddChar (
1336 Routine Description:
1347 EFI_OUT_OF_RESOURCES
1351 HEFI_EDITOR_LINE
*Line
;
1352 HEFI_EDITOR_LINE
*NewLine
;
1359 Value
= HBufferImageCharToHex (Char
);
1368 Line
= HBufferImage
.CurrentLine
;
1369 FRow
= HBufferImage
.BufferPosition
.Row
;
1370 FCol
= HBufferImage
.BufferPosition
.Column
;
1371 High
= HBufferImage
.HighBits
;
1374 // only needs to refresh current line
1376 HBufferImageOnlyLineNeedRefresh
= TRUE
;
1379 // not a full line and beyond the last character
1381 if (FCol
> Line
->Size
) {
1383 // cursor always at high 4 bits
1384 // and always put input to the low 4 bits
1386 Line
->Buffer
[Line
->Size
] = (UINT8
) Value
;
1391 Old
= Line
->Buffer
[FCol
- 1];
1394 // always put the input to the low 4 bits
1396 Old
= (UINT8
) (Old
& 0x0f);
1397 Old
= (UINT8
) (Old
<< 4);
1398 Old
= (UINT8
) (Value
+ Old
);
1399 Line
->Buffer
[FCol
- 1] = Old
;
1402 // at the low 4 bits of the last character of a full line
1403 // so if no next line, need to create a new line
1405 if (High
== FALSE
&& FCol
== 0x10) {
1407 HBufferImageOnlyLineNeedRefresh
= FALSE
;
1408 HBufferImageNeedRefresh
= TRUE
;
1410 if (Line
->Link
.ForwardLink
== HBufferImage
.ListHead
) {
1414 // create a new line
1416 NewLine
= HBufferImageCreateLine ();
1417 if (NewLine
== NULL
) {
1418 return EFI_OUT_OF_RESOURCES
;
1425 // end of == ListHead
1431 // if already at end of this line, scroll it to the start of next line
1433 if (FCol
== 0x10 && High
== FALSE
) {
1435 // definitely has next line
1442 // if not at end of this line, just move to next column
1460 // move cursor to right
1462 HBufferImageMovePosition (FRow
, FCol
, High
);
1464 if (!HBufferImage
.Modified
) {
1465 HBufferImage
.Modified
= TRUE
;
1477 Routine Description:
1479 Check user specified FileRow and FileCol is in current screen
1483 FileRow -- Row of file position ( start from 1 )
1493 if (FileRow
>= HBufferImage
.LowVisibleRow
&& FileRow
<= HBufferImage
.LowVisibleRow
+ (HMainEditor
.ScreenSize
.Row
- 5) - 1) {
1501 HAboveCurrentScreen (
1506 Routine Description:
1508 Check user specified FileRow is above current screen
1512 FileRow -- Row of file position ( start from 1 )
1521 if (FileRow
< HBufferImage
.LowVisibleRow
) {
1529 HUnderCurrentScreen (
1534 Routine Description:
1536 Check user specified FileRow is under current screen
1540 FileRow -- Row of file position ( start from 1 )
1549 if (FileRow
> HBufferImage
.LowVisibleRow
+ (HMainEditor
.ScreenSize
.Row
- 5) - 1) {
1557 HBufferImageMovePosition (
1558 IN UINTN NewFilePosRow
,
1559 IN UINTN NewFilePosCol
,
1564 Routine Description:
1566 According to cursor's file position, adjust screen display
1570 NewFilePosRow -- Row of file position ( start from 1 )
1571 NewFilePosCol -- Column of file position ( start from 1 )
1572 HighBits -- cursor will on high4 bits or low4 bits
1584 UINTN NewDisplayCol
;
1587 // CALCULATE gap between current file position and new file position
1589 RowGap
= NewFilePosRow
- HBufferImage
.BufferPosition
.Row
;
1591 Under
= HUnderCurrentScreen (NewFilePosRow
);
1592 Above
= HAboveCurrentScreen (NewFilePosRow
);
1594 HBufferImage
.HighBits
= HighBits
;
1597 // if is below current screen
1601 // display row will be unchanged
1603 HBufferImage
.BufferPosition
.Row
= NewFilePosRow
;
1607 // has enough above line, so display row unchanged
1608 // not has enough above lines, so the first line is
1609 // at the first display line
1611 if (NewFilePosRow
< (HBufferImage
.DisplayPosition
.Row
- 2 + 1)) {
1612 HBufferImage
.DisplayPosition
.Row
= NewFilePosRow
+ 2 - 1;
1615 HBufferImage
.BufferPosition
.Row
= NewFilePosRow
;
1618 // in current screen
1620 HBufferImage
.BufferPosition
.Row
= NewFilePosRow
;
1623 HBufferImage
.DisplayPosition
.Row
-= Abs
;
1625 HBufferImage
.DisplayPosition
.Row
+= RowGap
;
1631 HBufferImage
.LowVisibleRow
= HBufferImage
.BufferPosition
.Row
- (HBufferImage
.DisplayPosition
.Row
- 2);
1634 // always in current screen
1636 HBufferImage
.BufferPosition
.Column
= NewFilePosCol
;
1638 NewDisplayCol
= 10 + (NewFilePosCol
- 1) * 3;
1639 if (NewFilePosCol
> 0x8) {
1643 if (HighBits
== FALSE
) {
1647 HBufferImage
.DisplayPosition
.Column
= NewDisplayCol
;
1650 // let CurrentLine point to correct line;
1652 HBufferImage
.CurrentLine
= HMoveCurrentLine (RowGap
);
1657 HBufferImageScrollRight (
1662 Routine Description:
1664 Scroll cursor to right
1676 HEFI_EDITOR_LINE
*Line
;
1681 // scroll right will always move to the high4 bits of the next character
1683 HBufferImageNeedRefresh
= FALSE
;
1684 HBufferImageOnlyLineNeedRefresh
= FALSE
;
1686 Line
= HBufferImage
.CurrentLine
;
1688 FRow
= HBufferImage
.BufferPosition
.Row
;
1689 FCol
= HBufferImage
.BufferPosition
.Column
;
1692 // this line is not full and no next line
1694 if (FCol
> Line
->Size
) {
1698 // if already at end of this line, scroll it to the start of next line
1704 if (Line
->Link
.ForwardLink
!= HBufferImage
.ListHead
) {
1713 // if not at end of this line, just move to next column
1719 HBufferImageMovePosition (FRow
, FCol
, TRUE
);
1725 HBufferImageScrollLeft (
1730 Routine Description:
1732 Scroll cursor to left
1745 HEFI_EDITOR_LINE
*Line
;
1749 HBufferImageNeedRefresh
= FALSE
;
1750 HBufferImageOnlyLineNeedRefresh
= FALSE
;
1752 Line
= HBufferImage
.CurrentLine
;
1754 FRow
= HBufferImage
.BufferPosition
.Row
;
1755 FCol
= HBufferImage
.BufferPosition
.Column
;
1758 // if already at start of this line, so move to the end of previous line
1762 // has previous line
1764 if (Line
->Link
.BackLink
!= HBufferImage
.ListHead
) {
1766 Line
= CR (Line
->Link
.BackLink
, HEFI_EDITOR_LINE
, Link
, EFI_EDITOR_LINE_LIST
);
1773 // if not at start of this line, just move to previous column
1778 HBufferImageMovePosition (FRow
, FCol
, TRUE
);
1784 HBufferImageScrollDown (
1789 Routine Description:
1791 Scroll cursor to the next line
1803 HEFI_EDITOR_LINE
*Line
;
1808 Line
= HBufferImage
.CurrentLine
;
1810 FRow
= HBufferImage
.BufferPosition
.Row
;
1811 FCol
= HBufferImage
.BufferPosition
.Column
;
1812 HighBits
= HBufferImage
.HighBits
;
1817 if (Line
->Link
.ForwardLink
!= HBufferImage
.ListHead
) {
1819 Line
= CR (Line
->Link
.ForwardLink
, HEFI_EDITOR_LINE
, Link
, EFI_EDITOR_LINE_LIST
);
1822 // if the next line is not that long, so move to end of next line
1824 if (FCol
> Line
->Size
) {
1825 FCol
= Line
->Size
+ 1;
1833 HBufferImageMovePosition (FRow
, FCol
, HighBits
);
1839 HBufferImageScrollUp (
1844 Routine Description:
1846 Scroll cursor to previous line
1858 HEFI_EDITOR_LINE
*Line
;
1862 Line
= HBufferImage
.CurrentLine
;
1864 FRow
= HBufferImage
.BufferPosition
.Row
;
1865 FCol
= HBufferImage
.BufferPosition
.Column
;
1868 // has previous line
1870 if (Line
->Link
.BackLink
!= HBufferImage
.ListHead
) {
1877 HBufferImageMovePosition (FRow
, FCol
, HBufferImage
.HighBits
);
1883 HBufferImagePageDown (
1888 Routine Description:
1890 Scroll cursor to next page
1902 HEFI_EDITOR_LINE
*Line
;
1908 Line
= HBufferImage
.CurrentLine
;
1910 FRow
= HBufferImage
.BufferPosition
.Row
;
1911 FCol
= HBufferImage
.BufferPosition
.Column
;
1912 HighBits
= HBufferImage
.HighBits
;
1917 if (HBufferImage
.NumLines
>= FRow
+ (HMainEditor
.ScreenSize
.Row
- 5)) {
1918 Gap
= (HMainEditor
.ScreenSize
.Row
- 5);
1921 // MOVE CURSOR TO LAST LINE
1923 Gap
= HBufferImage
.NumLines
- FRow
;
1928 Line
= HMoveLine (Gap
);
1931 // if that line, is not that long, so move to the end of that line
1933 if (FCol
> Line
->Size
) {
1934 FCol
= Line
->Size
+ 1;
1940 HBufferImageMovePosition (FRow
, FCol
, HighBits
);
1946 HBufferImagePageUp (
1951 Routine Description:
1953 Scroll cursor to previous page
1965 HEFI_EDITOR_LINE
*Line
;
1971 Line
= HBufferImage
.CurrentLine
;
1973 FRow
= HBufferImage
.BufferPosition
.Row
;
1974 FCol
= HBufferImage
.BufferPosition
.Column
;
1977 // has previous page
1979 if (FRow
> (HMainEditor
.ScreenSize
.Row
- 5)) {
1980 Gap
= (HMainEditor
.ScreenSize
.Row
- 5);
1983 // the first line of file will displayed on the first line of screen
1994 Line
= HMoveLine (Retreat
);
1998 HBufferImageMovePosition (FRow
, FCol
, HBufferImage
.HighBits
);
2009 Routine Description:
2011 Scroll cursor to start of line
2023 HEFI_EDITOR_LINE
*Line
;
2028 Line
= HBufferImage
.CurrentLine
;
2031 // curosr will at the high bit
2033 FRow
= HBufferImage
.BufferPosition
.Row
;
2038 // move cursor position
2040 HBufferImageMovePosition (FRow
, FCol
, HighBits
);
2051 Routine Description:
2053 Scroll cursor to end of line
2065 HEFI_EDITOR_LINE
*Line
;
2071 // need refresh mouse
2073 HBufferImageMouseNeedRefresh
= TRUE
;
2075 Line
= HBufferImage
.CurrentLine
;
2077 FRow
= HBufferImage
.BufferPosition
.Row
;
2079 if (Line
->Size
== 0x10) {
2083 FCol
= Line
->Size
+ 1;
2087 // move cursor position
2089 HBufferImageMovePosition (FRow
, FCol
, HighBits
);
2095 HBufferImageGetTotalSize (
2101 HEFI_EDITOR_LINE
*Line
;
2104 // calculate the total size of whole line list's buffer
2106 if (HBufferImage
.Lines
== NULL
) {
2111 HBufferImage
.ListHead
->BackLink
,
2114 EFI_EDITOR_LINE_LIST
2117 // one line at most 0x10
2119 Size
= 0x10 * (HBufferImage
.NumLines
- 1) + Line
->Size
;
2125 HBufferImageDeleteCharacterFromBuffer (
2128 OUT UINT8
*DeleteBuffer
2131 Routine Description:
2133 Delete character from buffer
2137 Pos - Position, Pos starting from 0
2139 DeleteBuffer - DeleteBuffer
2153 HEFI_EDITOR_LINE
*Line
;
2166 // get the line that start position is at
2168 StartRow
= Pos
/ 0x10;
2170 Size
= HBufferImageGetTotalSize ();
2173 return EFI_LOAD_ERROR
;
2181 // relocate all the HBufferImage fields
2183 OldFRow
= HBufferImage
.BufferPosition
.Row
;
2184 OldFCol
= HBufferImage
.BufferPosition
.Column
;
2185 OldPos
= (OldFRow
- 1) * 0x10 + OldFCol
- 1;
2189 // has character before it,
2190 // so locate according to block's previous character
2196 // has no character before it,
2197 // so locate according to block's next character
2202 HBufferImageMovePosition (NewPos
/ 0x10 + 1, NewPos
% 0x10 + 1, TRUE
);
2204 Buffer
= AllocateZeroPool (Size
);
2205 if (Buffer
== NULL
) {
2206 return EFI_OUT_OF_RESOURCES
;
2209 HBufferImageListToBuffer (Buffer
, Size
);
2211 BufferPtr
= (UINT8
*) Buffer
;
2214 // pass deleted buffer out
2216 if (DeleteBuffer
!= NULL
) {
2217 for (Index
= 0; Index
< Count
; Index
++) {
2218 DeleteBuffer
[Index
] = BufferPtr
[Pos
+ Index
];
2222 // delete the part from Pos
2224 for (Index
= Pos
; Index
< Size
- Count
; Index
++) {
2225 BufferPtr
[Index
] = BufferPtr
[Index
+ Count
];
2230 HBufferImageFreeLines ();
2232 Status
= HBufferImageBufferToList (Buffer
, Size
);
2235 if (EFI_ERROR (Status
)) {
2239 Link
= HMainEditor
.BufferImage
->ListHead
->ForwardLink
;
2240 for (Index
= 0; Index
< NewPos
/ 0x10; Index
++) {
2241 Link
= Link
->ForwardLink
;
2244 Line
= CR (Link
, HEFI_EDITOR_LINE
, Link
, EFI_EDITOR_LINE_LIST
);
2245 HBufferImage
.CurrentLine
= Line
;
2248 // if current cursor position if inside select area
2249 // then move it to the block's NEXT character
2251 if (OldPos
>= Pos
&& OldPos
< (Pos
+ Count
)) {
2257 NewPos
= OldPos
- Count
;
2261 HBufferImageMovePosition (NewPos
/ 0x10 + 1, NewPos
% 0x10 + 1, TRUE
);
2267 HBufferImageAddCharacterToBuffer (
2273 Routine Description:
2275 Add character to buffer, add before pos
2279 Pos - Position, Pos starting from 0
2281 AddBuffer - Add buffer
2295 HEFI_EDITOR_LINE
*Line
;
2307 // get the line that start position is at
2309 StartRow
= Pos
/ 0x10;
2311 Size
= HBufferImageGetTotalSize ();
2314 // relocate all the HBufferImage fields
2316 OldFRow
= HBufferImage
.BufferPosition
.Row
;
2317 OldFCol
= HBufferImage
.BufferPosition
.Column
;
2318 OldPos
= (OldFRow
- 1) * 0x10 + OldFCol
- 1;
2321 // move cursor before Pos
2329 HBufferImageMovePosition (NewPos
/ 0x10 + 1, NewPos
% 0x10 + 1, TRUE
);
2331 Buffer
= AllocateZeroPool (Size
+ Count
);
2332 if (Buffer
== NULL
) {
2333 return EFI_OUT_OF_RESOURCES
;
2336 HBufferImageListToBuffer (Buffer
, Size
);
2338 BufferPtr
= (UINT8
*) Buffer
;
2341 // get a place to add
2343 for (Index
= (INTN
) (Size
+ Count
- 1); Index
>= (INTN
) Pos
; Index
--) {
2344 BufferPtr
[Index
] = BufferPtr
[Index
- Count
];
2349 for (Index
= (INTN
) 0; Index
< (INTN
) Count
; Index
++) {
2350 BufferPtr
[Index
+ Pos
] = AddBuffer
[Index
];
2355 HBufferImageFreeLines ();
2357 HBufferImageBufferToList (Buffer
, Size
);
2361 Link
= HMainEditor
.BufferImage
->ListHead
->ForwardLink
;
2362 for (Index
= 0; Index
< (INTN
) NewPos
/ 0x10; Index
++) {
2363 Link
= Link
->ForwardLink
;
2366 Line
= CR (Link
, HEFI_EDITOR_LINE
, Link
, EFI_EDITOR_LINE_LIST
);
2367 HBufferImage
.CurrentLine
= Line
;
2369 if (OldPos
>= Pos
) {
2370 NewPos
= OldPos
+ Count
;
2375 HBufferImageMovePosition (NewPos
/ 0x10 + 1, NewPos
% 0x10 + 1, TRUE
);
2381 HBufferImageDoBackspace (
2386 Routine Description:
2388 delete the previous character
2400 HEFI_EDITOR_LINE
*Line
;
2407 // variable initialization
2412 // already the first character
2414 if (HBufferImage
.BufferPosition
.Row
== 1 && HBufferImage
.BufferPosition
.Column
== 1) {
2418 FPos
= (HBufferImage
.BufferPosition
.Row
- 1) * 0x10 + HBufferImage
.BufferPosition
.Column
- 1;
2420 FileColumn
= HBufferImage
.BufferPosition
.Column
;
2422 Line
= HBufferImage
.CurrentLine
;
2424 if (Line
->Link
.ForwardLink
== HBufferImage
.ListHead
&& FileColumn
> 1) {
2428 HBufferImageDeleteCharacterFromBuffer (FPos
- 1, 1, NULL
);
2431 // if is the last line
2432 // then only this line need to be refreshed
2435 HBufferImageNeedRefresh
= FALSE
;
2436 HBufferImageOnlyLineNeedRefresh
= TRUE
;
2438 HBufferImageNeedRefresh
= TRUE
;
2439 HBufferImageOnlyLineNeedRefresh
= FALSE
;
2442 if (!HBufferImage
.Modified
) {
2443 HBufferImage
.Modified
= TRUE
;
2450 HBufferImageDoDelete (
2455 Routine Description:
2457 Delete current character from line
2470 HEFI_EDITOR_LINE
*Line
;
2476 FPos
= (HBufferImage
.BufferPosition
.Row
- 1) * 0x10 + HBufferImage
.BufferPosition
.Column
- 1;
2478 FileColumn
= HBufferImage
.BufferPosition
.Column
;
2480 Line
= HBufferImage
.CurrentLine
;
2483 // if beyond the last character
2485 if (FileColumn
> Line
->Size
) {
2490 if (Line
->Link
.ForwardLink
== HBufferImage
.ListHead
) {
2494 HBufferImageDeleteCharacterFromBuffer (FPos
, 1, NULL
);
2497 // if is the last line
2498 // then only this line need to be refreshed
2501 HBufferImageNeedRefresh
= FALSE
;
2502 HBufferImageOnlyLineNeedRefresh
= TRUE
;
2504 HBufferImageNeedRefresh
= TRUE
;
2505 HBufferImageOnlyLineNeedRefresh
= FALSE
;
2508 if (!HBufferImage
.Modified
) {
2509 HBufferImage
.Modified
= TRUE
;
2516 HBufferImageBufferToList (
2524 HEFI_EDITOR_LINE
*Line
;
2529 BufferPtr
= (UINT8
*) Buffer
;
2532 // parse file content line by line
2535 if (Bytes
- i
>= 0x10) {
2542 // allocate a new line
2544 Line
= HBufferImageCreateLine ();
2546 return EFI_OUT_OF_RESOURCES
;
2551 for (j
= 0; j
< Left
; j
++) {
2552 Line
->Buffer
[j
] = BufferPtr
[i
];
2559 // last line is a full line, SO create a new line
2561 if (Left
== 0x10 || Bytes
== 0) {
2562 Line
= HBufferImageCreateLine ();
2564 return EFI_OUT_OF_RESOURCES
;
2572 HBufferImageListToBuffer (
2579 HEFI_EDITOR_LINE
*Line
;
2584 // change the line list to a large buffer
2586 if (HBufferImage
.Lines
== NULL
) {
2590 Link
= &HBufferImage
.Lines
->Link
;
2592 BufferPtr
= (UINT8
*) Buffer
;
2595 // deal line by line
2597 while (Link
!= HBufferImage
.ListHead
) {
2599 Line
= CR (Link
, HEFI_EDITOR_LINE
, Link
, EFI_EDITOR_LINE_LIST
);
2601 if (Count
+ Line
->Size
> Bytes
) {
2605 for (Index
= 0; Index
< Line
->Size
; Index
++) {
2606 BufferPtr
[Index
] = Line
->Buffer
[Index
];
2609 Count
+= Line
->Size
;
2610 BufferPtr
+= Line
->Size
;
2612 Link
= Link
->ForwardLink
;
2619 HBufferImageAdjustMousePosition (
2630 // TextX and TextY is mouse movement data returned by mouse driver
2631 // This function will change it to MousePosition
2634 // get absolute X value
2642 // get absolute Y value
2650 X
= HBufferImage
.MousePosition
.Column
;
2651 Y
= HBufferImage
.MousePosition
.Row
;
2673 // check whether new mouse column position is beyond screen
2674 // if not, adjust it
2676 if (X
>= 10 && X
<= (10 + 0x10 * 3 - 1)) {
2677 HBufferImage
.MousePosition
.Column
= X
;
2678 } else if (X
< 10) {
2679 HBufferImage
.MousePosition
.Column
= 10;
2680 } else if (X
> (10 + 0x10 * 3 - 1)) {
2681 HBufferImage
.MousePosition
.Column
= 10 + 0x10 * 3 - 1;
2684 // check whether new mouse row position is beyond screen
2685 // if not, adjust it
2687 if (Y
>= 2 && Y
<= (HMainEditor
.ScreenSize
.Row
- 4)) {
2688 HBufferImage
.MousePosition
.Row
= Y
;
2690 HBufferImage
.MousePosition
.Row
= 2;
2691 } else if (Y
> (HMainEditor
.ScreenSize
.Row
- 4)) {
2692 HBufferImage
.MousePosition
.Row
= (HMainEditor
.ScreenSize
.Row
- 4);