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 (Line
== NULL
|| 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
;
957 HBufferImage
.BufferType
= BufferType
;
960 // three types of buffer supported
965 BufferTypeBackup
= HBufferImage
.BufferType
;
967 switch (BufferType
) {
968 case FileTypeFileBuffer
:
969 Status
= HFileImageRead (FileName
, Recover
);
972 case FileTypeDiskBuffer
:
973 Status
= HDiskImageRead (DiskName
, DiskOffset
, DiskSize
, Recover
);
976 case FileTypeMemBuffer
:
977 Status
= HMemImageRead (MemOffset
, MemSize
, Recover
);
981 if (EFI_ERROR (Status
)) {
982 HBufferImage
.BufferType
= BufferTypeBackup
;
996 IN EDIT_FILE_TYPE BufferType
1000 EDIT_FILE_TYPE BufferTypeBackup
;
1003 // variable initialization
1005 Status
= EFI_SUCCESS
;
1006 BufferTypeBackup
= HBufferImage
.BufferType
;
1008 switch (HBufferImage
.BufferType
) {
1012 case FileTypeFileBuffer
:
1013 Status
= HFileImageSave (FileName
);
1019 case FileTypeDiskBuffer
:
1020 Status
= HDiskImageSave (DiskName
, DiskOffset
, DiskSize
);
1026 case FileTypeMemBuffer
:
1027 Status
= HMemImageSave (MemOffset
, MemSize
);
1031 if (EFI_ERROR (Status
)) {
1032 HBufferImage
.BufferType
= BufferTypeBackup
;
1039 HBufferImageCreateLine (
1044 Routine Description:
1046 Create a new line and append it to the line list
1057 NULL -- create line failed
1058 Not NULL -- the line created
1062 HEFI_EDITOR_LINE
*Line
;
1065 // allocate for line structure
1067 Line
= AllocateZeroPool (sizeof (HEFI_EDITOR_LINE
));
1072 Line
->Signature
= EFI_EDITOR_LINE_LIST
;
1075 HBufferImage
.NumLines
++;
1078 // insert to line list
1080 InsertTailList (HBufferImage
.ListHead
, &Line
->Link
);
1082 if (HBufferImage
.Lines
== NULL
) {
1083 HBufferImage
.Lines
= CR (
1084 HBufferImage
.ListHead
->ForwardLink
,
1087 EFI_EDITOR_LINE_LIST
1100 Routine Description:
1102 Function called when load a new file in. It will free all the old lines
1103 and set FileModified field to FALSE
1118 HBufferImageFreeLines ();
1124 HBufferImageHandleInput (
1125 IN EFI_INPUT_KEY
*Key
1129 Routine Description:
1131 Dispatch input to different handler
1139 Direction key: up/down/left/right/pgup/pgdn
1147 EFI_OUT_OF_RESOURCES
1153 Status
= EFI_SUCCESS
;
1155 switch (Key
->ScanCode
) {
1160 Status
= HBufferImageDoCharInput (Key
->UnicodeChar
);
1167 Status
= HBufferImageScrollUp ();
1174 Status
= HBufferImageScrollDown ();
1181 Status
= HBufferImageScrollRight ();
1188 Status
= HBufferImageScrollLeft ();
1195 Status
= HBufferImagePageUp ();
1201 case SCAN_PAGE_DOWN
:
1202 Status
= HBufferImagePageDown ();
1209 Status
= HBufferImageDoDelete ();
1216 Status
= HBufferImageHome ();
1223 Status
= HBufferImageEnd ();
1227 Status
= StatusBarSetStatusString (L
"Unknown Command");
1235 HBufferImageDoCharInput (
1240 Routine Description:
1242 ASCII key + Backspace + return
1252 EFI_OUT_OF_RESOURCES
1258 Status
= EFI_SUCCESS
;
1265 Status
= HBufferImageDoBackspace ();
1272 // Tabs, Returns are thought as nothing
1278 // DEAL WITH ASCII CHAR, filter out thing like ctrl+f
1280 if (Char
> 127 || Char
< 32) {
1281 Status
= StatusBarSetStatusString (L
"Unknown Command");
1283 Status
= HBufferImageAddChar (Char
);
1293 HBufferImageCharToHex (
1298 Routine Description:
1300 change char to int value based on Hex
1314 // change the character to hex
1316 if (Char
>= L
'0' && Char
<= L
'9') {
1317 return (INTN
) (Char
- L
'0');
1320 if (Char
>= L
'a' && Char
<= L
'f') {
1321 return (INTN
) (Char
- L
'a' + 10);
1324 if (Char
>= L
'A' && Char
<= L
'F') {
1325 return (INTN
) (Char
- L
'A' + 10);
1332 HBufferImageAddChar (
1337 Routine Description:
1348 EFI_OUT_OF_RESOURCES
1352 HEFI_EDITOR_LINE
*Line
;
1353 HEFI_EDITOR_LINE
*NewLine
;
1360 Value
= HBufferImageCharToHex (Char
);
1369 Line
= HBufferImage
.CurrentLine
;
1370 FRow
= HBufferImage
.BufferPosition
.Row
;
1371 FCol
= HBufferImage
.BufferPosition
.Column
;
1372 High
= HBufferImage
.HighBits
;
1375 // only needs to refresh current line
1377 HBufferImageOnlyLineNeedRefresh
= TRUE
;
1380 // not a full line and beyond the last character
1382 if (FCol
> Line
->Size
) {
1384 // cursor always at high 4 bits
1385 // and always put input to the low 4 bits
1387 Line
->Buffer
[Line
->Size
] = (UINT8
) Value
;
1392 Old
= Line
->Buffer
[FCol
- 1];
1395 // always put the input to the low 4 bits
1397 Old
= (UINT8
) (Old
& 0x0f);
1398 Old
= (UINT8
) (Old
<< 4);
1399 Old
= (UINT8
) (Value
+ Old
);
1400 Line
->Buffer
[FCol
- 1] = Old
;
1403 // at the low 4 bits of the last character of a full line
1404 // so if no next line, need to create a new line
1406 if (High
== FALSE
&& FCol
== 0x10) {
1408 HBufferImageOnlyLineNeedRefresh
= FALSE
;
1409 HBufferImageNeedRefresh
= TRUE
;
1411 if (Line
->Link
.ForwardLink
== HBufferImage
.ListHead
) {
1415 // create a new line
1417 NewLine
= HBufferImageCreateLine ();
1418 if (NewLine
== NULL
) {
1419 return EFI_OUT_OF_RESOURCES
;
1426 // end of == ListHead
1432 // if already at end of this line, scroll it to the start of next line
1434 if (FCol
== 0x10 && High
== FALSE
) {
1436 // definitely has next line
1443 // if not at end of this line, just move to next column
1461 // move cursor to right
1463 HBufferImageMovePosition (FRow
, FCol
, High
);
1465 if (!HBufferImage
.Modified
) {
1466 HBufferImage
.Modified
= TRUE
;
1478 Routine Description:
1480 Check user specified FileRow and FileCol is in current screen
1484 FileRow -- Row of file position ( start from 1 )
1494 if (FileRow
>= HBufferImage
.LowVisibleRow
&& FileRow
<= HBufferImage
.LowVisibleRow
+ (HMainEditor
.ScreenSize
.Row
- 5) - 1) {
1502 HAboveCurrentScreen (
1507 Routine Description:
1509 Check user specified FileRow is above current screen
1513 FileRow -- Row of file position ( start from 1 )
1522 if (FileRow
< HBufferImage
.LowVisibleRow
) {
1530 HUnderCurrentScreen (
1535 Routine Description:
1537 Check user specified FileRow is under current screen
1541 FileRow -- Row of file position ( start from 1 )
1550 if (FileRow
> HBufferImage
.LowVisibleRow
+ (HMainEditor
.ScreenSize
.Row
- 5) - 1) {
1558 HBufferImageMovePosition (
1559 IN UINTN NewFilePosRow
,
1560 IN UINTN NewFilePosCol
,
1565 Routine Description:
1567 According to cursor's file position, adjust screen display
1571 NewFilePosRow -- Row of file position ( start from 1 )
1572 NewFilePosCol -- Column of file position ( start from 1 )
1573 HighBits -- cursor will on high4 bits or low4 bits
1585 UINTN NewDisplayCol
;
1588 // CALCULATE gap between current file position and new file position
1590 RowGap
= NewFilePosRow
- HBufferImage
.BufferPosition
.Row
;
1592 Under
= HUnderCurrentScreen (NewFilePosRow
);
1593 Above
= HAboveCurrentScreen (NewFilePosRow
);
1595 HBufferImage
.HighBits
= HighBits
;
1598 // if is below current screen
1602 // display row will be unchanged
1604 HBufferImage
.BufferPosition
.Row
= NewFilePosRow
;
1608 // has enough above line, so display row unchanged
1609 // not has enough above lines, so the first line is
1610 // at the first display line
1612 if (NewFilePosRow
< (HBufferImage
.DisplayPosition
.Row
- 2 + 1)) {
1613 HBufferImage
.DisplayPosition
.Row
= NewFilePosRow
+ 2 - 1;
1616 HBufferImage
.BufferPosition
.Row
= NewFilePosRow
;
1619 // in current screen
1621 HBufferImage
.BufferPosition
.Row
= NewFilePosRow
;
1623 Abs
= (UINTN
)ABS(RowGap
);
1624 HBufferImage
.DisplayPosition
.Row
-= Abs
;
1626 HBufferImage
.DisplayPosition
.Row
+= RowGap
;
1632 HBufferImage
.LowVisibleRow
= HBufferImage
.BufferPosition
.Row
- (HBufferImage
.DisplayPosition
.Row
- 2);
1635 // always in current screen
1637 HBufferImage
.BufferPosition
.Column
= NewFilePosCol
;
1639 NewDisplayCol
= 10 + (NewFilePosCol
- 1) * 3;
1640 if (NewFilePosCol
> 0x8) {
1644 if (HighBits
== FALSE
) {
1648 HBufferImage
.DisplayPosition
.Column
= NewDisplayCol
;
1651 // let CurrentLine point to correct line;
1653 HBufferImage
.CurrentLine
= HMoveCurrentLine (RowGap
);
1658 HBufferImageScrollRight (
1663 Routine Description:
1665 Scroll cursor to right
1677 HEFI_EDITOR_LINE
*Line
;
1682 // scroll right will always move to the high4 bits of the next character
1684 HBufferImageNeedRefresh
= FALSE
;
1685 HBufferImageOnlyLineNeedRefresh
= FALSE
;
1687 Line
= HBufferImage
.CurrentLine
;
1689 FRow
= HBufferImage
.BufferPosition
.Row
;
1690 FCol
= HBufferImage
.BufferPosition
.Column
;
1693 // this line is not full and no next line
1695 if (FCol
> Line
->Size
) {
1699 // if already at end of this line, scroll it to the start of next line
1705 if (Line
->Link
.ForwardLink
!= HBufferImage
.ListHead
) {
1714 // if not at end of this line, just move to next column
1720 HBufferImageMovePosition (FRow
, FCol
, TRUE
);
1726 HBufferImageScrollLeft (
1731 Routine Description:
1733 Scroll cursor to left
1746 HEFI_EDITOR_LINE
*Line
;
1750 HBufferImageNeedRefresh
= FALSE
;
1751 HBufferImageOnlyLineNeedRefresh
= FALSE
;
1753 Line
= HBufferImage
.CurrentLine
;
1755 FRow
= HBufferImage
.BufferPosition
.Row
;
1756 FCol
= HBufferImage
.BufferPosition
.Column
;
1759 // if already at start of this line, so move to the end of previous line
1763 // has previous line
1765 if (Line
->Link
.BackLink
!= HBufferImage
.ListHead
) {
1767 Line
= CR (Line
->Link
.BackLink
, HEFI_EDITOR_LINE
, Link
, EFI_EDITOR_LINE_LIST
);
1774 // if not at start of this line, just move to previous column
1779 HBufferImageMovePosition (FRow
, FCol
, TRUE
);
1785 HBufferImageScrollDown (
1790 Routine Description:
1792 Scroll cursor to the next line
1804 HEFI_EDITOR_LINE
*Line
;
1809 Line
= HBufferImage
.CurrentLine
;
1811 FRow
= HBufferImage
.BufferPosition
.Row
;
1812 FCol
= HBufferImage
.BufferPosition
.Column
;
1813 HighBits
= HBufferImage
.HighBits
;
1818 if (Line
->Link
.ForwardLink
!= HBufferImage
.ListHead
) {
1820 Line
= CR (Line
->Link
.ForwardLink
, HEFI_EDITOR_LINE
, Link
, EFI_EDITOR_LINE_LIST
);
1823 // if the next line is not that long, so move to end of next line
1825 if (FCol
> Line
->Size
) {
1826 FCol
= Line
->Size
+ 1;
1834 HBufferImageMovePosition (FRow
, FCol
, HighBits
);
1840 HBufferImageScrollUp (
1845 Routine Description:
1847 Scroll cursor to previous line
1859 HEFI_EDITOR_LINE
*Line
;
1863 Line
= HBufferImage
.CurrentLine
;
1865 FRow
= HBufferImage
.BufferPosition
.Row
;
1866 FCol
= HBufferImage
.BufferPosition
.Column
;
1869 // has previous line
1871 if (Line
->Link
.BackLink
!= HBufferImage
.ListHead
) {
1878 HBufferImageMovePosition (FRow
, FCol
, HBufferImage
.HighBits
);
1884 HBufferImagePageDown (
1889 Routine Description:
1891 Scroll cursor to next page
1903 HEFI_EDITOR_LINE
*Line
;
1909 Line
= HBufferImage
.CurrentLine
;
1911 FRow
= HBufferImage
.BufferPosition
.Row
;
1912 FCol
= HBufferImage
.BufferPosition
.Column
;
1913 HighBits
= HBufferImage
.HighBits
;
1918 if (HBufferImage
.NumLines
>= FRow
+ (HMainEditor
.ScreenSize
.Row
- 5)) {
1919 Gap
= (HMainEditor
.ScreenSize
.Row
- 5);
1922 // MOVE CURSOR TO LAST LINE
1924 Gap
= HBufferImage
.NumLines
- FRow
;
1929 Line
= HMoveLine (Gap
);
1932 // if that line, is not that long, so move to the end of that line
1934 if (Line
!= NULL
&& FCol
> Line
->Size
) {
1935 FCol
= Line
->Size
+ 1;
1941 HBufferImageMovePosition (FRow
, FCol
, HighBits
);
1947 HBufferImagePageUp (
1952 Routine Description:
1954 Scroll cursor to previous page
1966 HEFI_EDITOR_LINE
*Line
;
1972 Line
= HBufferImage
.CurrentLine
;
1974 FRow
= HBufferImage
.BufferPosition
.Row
;
1975 FCol
= HBufferImage
.BufferPosition
.Column
;
1978 // has previous page
1980 if (FRow
> (HMainEditor
.ScreenSize
.Row
- 5)) {
1981 Gap
= (HMainEditor
.ScreenSize
.Row
- 5);
1984 // the first line of file will displayed on the first line of screen
1995 Line
= HMoveLine (Retreat
);
1999 HBufferImageMovePosition (FRow
, FCol
, HBufferImage
.HighBits
);
2010 Routine Description:
2012 Scroll cursor to start of line
2024 HEFI_EDITOR_LINE
*Line
;
2029 Line
= HBufferImage
.CurrentLine
;
2032 // curosr will at the high bit
2034 FRow
= HBufferImage
.BufferPosition
.Row
;
2039 // move cursor position
2041 HBufferImageMovePosition (FRow
, FCol
, HighBits
);
2052 Routine Description:
2054 Scroll cursor to end of line
2066 HEFI_EDITOR_LINE
*Line
;
2072 // need refresh mouse
2074 HBufferImageMouseNeedRefresh
= TRUE
;
2076 Line
= HBufferImage
.CurrentLine
;
2078 FRow
= HBufferImage
.BufferPosition
.Row
;
2080 if (Line
->Size
== 0x10) {
2084 FCol
= Line
->Size
+ 1;
2088 // move cursor position
2090 HBufferImageMovePosition (FRow
, FCol
, HighBits
);
2096 HBufferImageGetTotalSize (
2102 HEFI_EDITOR_LINE
*Line
;
2105 // calculate the total size of whole line list's buffer
2107 if (HBufferImage
.Lines
== NULL
) {
2112 HBufferImage
.ListHead
->BackLink
,
2115 EFI_EDITOR_LINE_LIST
2118 // one line at most 0x10
2120 Size
= 0x10 * (HBufferImage
.NumLines
- 1) + Line
->Size
;
2126 HBufferImageDeleteCharacterFromBuffer (
2129 OUT UINT8
*DeleteBuffer
2132 Routine Description:
2134 Delete character from buffer
2138 Pos - Position, Pos starting from 0
2140 DeleteBuffer - DeleteBuffer
2154 HEFI_EDITOR_LINE
*Line
;
2167 // get the line that start position is at
2169 StartRow
= Pos
/ 0x10;
2171 Size
= HBufferImageGetTotalSize ();
2174 return EFI_LOAD_ERROR
;
2182 // relocate all the HBufferImage fields
2184 OldFRow
= HBufferImage
.BufferPosition
.Row
;
2185 OldFCol
= HBufferImage
.BufferPosition
.Column
;
2186 OldPos
= (OldFRow
- 1) * 0x10 + OldFCol
- 1;
2190 // has character before it,
2191 // so locate according to block's previous character
2197 // has no character before it,
2198 // so locate according to block's next character
2203 HBufferImageMovePosition (NewPos
/ 0x10 + 1, NewPos
% 0x10 + 1, TRUE
);
2205 Buffer
= AllocateZeroPool (Size
);
2206 if (Buffer
== NULL
) {
2207 return EFI_OUT_OF_RESOURCES
;
2210 HBufferImageListToBuffer (Buffer
, Size
);
2212 BufferPtr
= (UINT8
*) Buffer
;
2215 // pass deleted buffer out
2217 if (DeleteBuffer
!= NULL
) {
2218 for (Index
= 0; Index
< Count
; Index
++) {
2219 DeleteBuffer
[Index
] = BufferPtr
[Pos
+ Index
];
2223 // delete the part from Pos
2225 for (Index
= Pos
; Index
< Size
- Count
; Index
++) {
2226 BufferPtr
[Index
] = BufferPtr
[Index
+ Count
];
2231 HBufferImageFreeLines ();
2233 Status
= HBufferImageBufferToList (Buffer
, Size
);
2236 if (EFI_ERROR (Status
)) {
2240 Link
= HMainEditor
.BufferImage
->ListHead
->ForwardLink
;
2241 for (Index
= 0; Index
< NewPos
/ 0x10; Index
++) {
2242 Link
= Link
->ForwardLink
;
2245 Line
= CR (Link
, HEFI_EDITOR_LINE
, Link
, EFI_EDITOR_LINE_LIST
);
2246 HBufferImage
.CurrentLine
= Line
;
2249 // if current cursor position if inside select area
2250 // then move it to the block's NEXT character
2252 if (OldPos
>= Pos
&& OldPos
< (Pos
+ Count
)) {
2258 NewPos
= OldPos
- Count
;
2262 HBufferImageMovePosition (NewPos
/ 0x10 + 1, NewPos
% 0x10 + 1, TRUE
);
2268 HBufferImageAddCharacterToBuffer (
2274 Routine Description:
2276 Add character to buffer, add before pos
2280 Pos - Position, Pos starting from 0
2282 AddBuffer - Add buffer
2296 HEFI_EDITOR_LINE
*Line
;
2308 // get the line that start position is at
2310 StartRow
= Pos
/ 0x10;
2312 Size
= HBufferImageGetTotalSize ();
2315 // relocate all the HBufferImage fields
2317 OldFRow
= HBufferImage
.BufferPosition
.Row
;
2318 OldFCol
= HBufferImage
.BufferPosition
.Column
;
2319 OldPos
= (OldFRow
- 1) * 0x10 + OldFCol
- 1;
2322 // move cursor before Pos
2330 HBufferImageMovePosition (NewPos
/ 0x10 + 1, NewPos
% 0x10 + 1, TRUE
);
2332 Buffer
= AllocateZeroPool (Size
+ Count
);
2333 if (Buffer
== NULL
) {
2334 return EFI_OUT_OF_RESOURCES
;
2337 HBufferImageListToBuffer (Buffer
, Size
);
2339 BufferPtr
= (UINT8
*) Buffer
;
2342 // get a place to add
2344 for (Index
= (INTN
) (Size
+ Count
- 1); Index
>= (INTN
) Pos
; Index
--) {
2345 BufferPtr
[Index
] = BufferPtr
[Index
- Count
];
2350 for (Index
= (INTN
) 0; Index
< (INTN
) Count
; Index
++) {
2351 BufferPtr
[Index
+ Pos
] = AddBuffer
[Index
];
2356 HBufferImageFreeLines ();
2358 HBufferImageBufferToList (Buffer
, Size
);
2362 Link
= HMainEditor
.BufferImage
->ListHead
->ForwardLink
;
2363 for (Index
= 0; Index
< (INTN
) NewPos
/ 0x10; Index
++) {
2364 Link
= Link
->ForwardLink
;
2367 Line
= CR (Link
, HEFI_EDITOR_LINE
, Link
, EFI_EDITOR_LINE_LIST
);
2368 HBufferImage
.CurrentLine
= Line
;
2370 if (OldPos
>= Pos
) {
2371 NewPos
= OldPos
+ Count
;
2376 HBufferImageMovePosition (NewPos
/ 0x10 + 1, NewPos
% 0x10 + 1, TRUE
);
2382 HBufferImageDoBackspace (
2387 Routine Description:
2389 delete the previous character
2401 HEFI_EDITOR_LINE
*Line
;
2408 // variable initialization
2413 // already the first character
2415 if (HBufferImage
.BufferPosition
.Row
== 1 && HBufferImage
.BufferPosition
.Column
== 1) {
2419 FPos
= (HBufferImage
.BufferPosition
.Row
- 1) * 0x10 + HBufferImage
.BufferPosition
.Column
- 1;
2421 FileColumn
= HBufferImage
.BufferPosition
.Column
;
2423 Line
= HBufferImage
.CurrentLine
;
2425 if (Line
->Link
.ForwardLink
== HBufferImage
.ListHead
&& FileColumn
> 1) {
2429 HBufferImageDeleteCharacterFromBuffer (FPos
- 1, 1, NULL
);
2432 // if is the last line
2433 // then only this line need to be refreshed
2436 HBufferImageNeedRefresh
= FALSE
;
2437 HBufferImageOnlyLineNeedRefresh
= TRUE
;
2439 HBufferImageNeedRefresh
= TRUE
;
2440 HBufferImageOnlyLineNeedRefresh
= FALSE
;
2443 if (!HBufferImage
.Modified
) {
2444 HBufferImage
.Modified
= TRUE
;
2451 HBufferImageDoDelete (
2456 Routine Description:
2458 Delete current character from line
2471 HEFI_EDITOR_LINE
*Line
;
2477 FPos
= (HBufferImage
.BufferPosition
.Row
- 1) * 0x10 + HBufferImage
.BufferPosition
.Column
- 1;
2479 FileColumn
= HBufferImage
.BufferPosition
.Column
;
2481 Line
= HBufferImage
.CurrentLine
;
2484 // if beyond the last character
2486 if (FileColumn
> Line
->Size
) {
2491 if (Line
->Link
.ForwardLink
== HBufferImage
.ListHead
) {
2495 HBufferImageDeleteCharacterFromBuffer (FPos
, 1, NULL
);
2498 // if is the last line
2499 // then only this line need to be refreshed
2502 HBufferImageNeedRefresh
= FALSE
;
2503 HBufferImageOnlyLineNeedRefresh
= TRUE
;
2505 HBufferImageNeedRefresh
= TRUE
;
2506 HBufferImageOnlyLineNeedRefresh
= FALSE
;
2509 if (!HBufferImage
.Modified
) {
2510 HBufferImage
.Modified
= TRUE
;
2517 HBufferImageBufferToList (
2525 HEFI_EDITOR_LINE
*Line
;
2530 BufferPtr
= (UINT8
*) Buffer
;
2533 // parse file content line by line
2536 if (Bytes
- i
>= 0x10) {
2543 // allocate a new line
2545 Line
= HBufferImageCreateLine ();
2547 return EFI_OUT_OF_RESOURCES
;
2552 for (j
= 0; j
< Left
; j
++) {
2553 Line
->Buffer
[j
] = BufferPtr
[i
];
2560 // last line is a full line, SO create a new line
2562 if (Left
== 0x10 || Bytes
== 0) {
2563 Line
= HBufferImageCreateLine ();
2565 return EFI_OUT_OF_RESOURCES
;
2573 HBufferImageListToBuffer (
2580 HEFI_EDITOR_LINE
*Line
;
2585 // change the line list to a large buffer
2587 if (HBufferImage
.Lines
== NULL
) {
2591 Link
= &HBufferImage
.Lines
->Link
;
2593 BufferPtr
= (UINT8
*) Buffer
;
2596 // deal line by line
2598 while (Link
!= HBufferImage
.ListHead
) {
2600 Line
= CR (Link
, HEFI_EDITOR_LINE
, Link
, EFI_EDITOR_LINE_LIST
);
2602 if (Count
+ Line
->Size
> Bytes
) {
2606 for (Index
= 0; Index
< Line
->Size
; Index
++) {
2607 BufferPtr
[Index
] = Line
->Buffer
[Index
];
2610 Count
+= Line
->Size
;
2611 BufferPtr
+= Line
->Size
;
2613 Link
= Link
->ForwardLink
;
2620 HBufferImageAdjustMousePosition (
2631 // TextX and TextY is mouse movement data returned by mouse driver
2632 // This function will change it to MousePosition
2635 // get absolute X value
2643 // get absolute Y value
2651 X
= HBufferImage
.MousePosition
.Column
;
2652 Y
= HBufferImage
.MousePosition
.Row
;
2674 // check whether new mouse column position is beyond screen
2675 // if not, adjust it
2677 if (X
>= 10 && X
<= (10 + 0x10 * 3 - 1)) {
2678 HBufferImage
.MousePosition
.Column
= X
;
2679 } else if (X
< 10) {
2680 HBufferImage
.MousePosition
.Column
= 10;
2681 } else if (X
> (10 + 0x10 * 3 - 1)) {
2682 HBufferImage
.MousePosition
.Column
= 10 + 0x10 * 3 - 1;
2685 // check whether new mouse row position is beyond screen
2686 // if not, adjust it
2688 if (Y
>= 2 && Y
<= (HMainEditor
.ScreenSize
.Row
- 4)) {
2689 HBufferImage
.MousePosition
.Row
= Y
;
2691 HBufferImage
.MousePosition
.Row
= 2;
2692 } else if (Y
> (HMainEditor
.ScreenSize
.Row
- 4)) {
2693 HBufferImage
.MousePosition
.Row
= (HMainEditor
.ScreenSize
.Row
- 4);