]> git.proxmox.com Git - mirror_edk2.git/blob - ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/BufferImage.c
add comments to function declarations and definitions and updated to match coding...
[mirror_edk2.git] / ShellPkg / Library / UefiShellDebug1CommandsLib / HexEdit / BufferImage.c
1 /** @file
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
4
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
10
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.
13
14 **/
15
16 #include "HexEditor.h"
17
18 extern EFI_HANDLE HImageHandleBackup;
19
20 extern HEFI_EDITOR_FILE_IMAGE HFileImage;
21 extern HEFI_EDITOR_DISK_IMAGE HDiskImage;
22 extern HEFI_EDITOR_MEM_IMAGE HMemImage;
23
24 extern HEFI_EDITOR_FILE_IMAGE HFileImageBackupVar;
25 extern HEFI_EDITOR_DISK_IMAGE HDiskImageBackupVar;
26 extern HEFI_EDITOR_MEM_IMAGE HMemImageBackupVar;
27
28 extern BOOLEAN HEditorMouseAction;
29
30 extern HEFI_EDITOR_GLOBAL_EDITOR HMainEditor;
31 extern HEFI_EDITOR_GLOBAL_EDITOR HMainEditorBackupVar;
32
33 HEFI_EDITOR_BUFFER_IMAGE HBufferImage;
34 HEFI_EDITOR_BUFFER_IMAGE HBufferImageBackupVar;
35
36 //
37 // for basic initialization of HBufferImage
38 //
39 HEFI_EDITOR_BUFFER_IMAGE HBufferImageConst = {
40 NULL,
41 NULL,
42 0,
43 NULL,
44 {
45 0,
46 0
47 },
48 {
49 0,
50 0
51 },
52 {
53 0,
54 0
55 },
56 0,
57 TRUE,
58 FALSE,
59 FileTypeNone,
60 NULL,
61 NULL,
62 NULL
63 };
64
65 //
66 // the whole edit area needs to be refreshed
67 //
68 BOOLEAN HBufferImageNeedRefresh;
69
70 //
71 // only the current line in edit area needs to be refresh
72 //
73 BOOLEAN HBufferImageOnlyLineNeedRefresh;
74
75 BOOLEAN HBufferImageMouseNeedRefresh;
76
77 /**
78 Initialization function for HBufferImage
79
80 @retval EFI_SUCCESS The operation was successful.
81 @retval EFI_LOAD_ERROR A load error occured.
82 **/
83 EFI_STATUS
84 HBufferImageInit (
85 VOID
86 )
87 {
88 EFI_STATUS Status;
89
90 //
91 // basically initialize the HBufferImage
92 //
93 CopyMem (&HBufferImage, &HBufferImageConst, sizeof (HBufferImage));
94
95 //
96 // INIT listhead
97 //
98 HBufferImage.ListHead = AllocateZeroPool (sizeof (LIST_ENTRY));
99 if (HBufferImage.ListHead == NULL) {
100 return EFI_LOAD_ERROR;
101 }
102
103 InitializeListHead (HBufferImage.ListHead);
104
105 HBufferImage.DisplayPosition.Row = 2;
106 HBufferImage.DisplayPosition.Column = 10;
107 HBufferImage.MousePosition.Row = 2;
108 HBufferImage.MousePosition.Column = 10;
109
110 HBufferImage.FileImage = &HFileImage;
111 HBufferImage.DiskImage = &HDiskImage;
112 HBufferImage.MemImage = &HMemImage;
113
114 HBufferImageNeedRefresh = FALSE;
115 HBufferImageOnlyLineNeedRefresh = FALSE;
116 HBufferImageMouseNeedRefresh = FALSE;
117
118 HBufferImageBackupVar.FileImage = &HFileImageBackupVar;
119 HBufferImageBackupVar.DiskImage = &HDiskImageBackupVar;
120 HBufferImageBackupVar.MemImage = &HMemImageBackupVar;
121
122 Status = HFileImageInit ();
123 if (EFI_ERROR (Status)) {
124 return EFI_LOAD_ERROR;
125 }
126
127 Status = HDiskImageInit ();
128 if (EFI_ERROR (Status)) {
129 return EFI_LOAD_ERROR;
130 }
131
132 Status = HMemImageInit ();
133 if (EFI_ERROR (Status)) {
134 return EFI_LOAD_ERROR;
135 }
136
137 return EFI_SUCCESS;
138 }
139
140 /**
141 Backup function for HBufferImage. Only a few fields need to be backup.
142 This is for making the file buffer refresh as few as possible.
143
144 @retval EFI_SUCCESS The operation was successful.
145 **/
146 EFI_STATUS
147 HBufferImageBackup (
148 VOID
149 )
150 {
151 HBufferImageBackupVar.MousePosition = HBufferImage.MousePosition;
152
153 HBufferImageBackupVar.BufferPosition = HBufferImage.BufferPosition;
154
155 HBufferImageBackupVar.Modified = HBufferImage.Modified;
156
157 HBufferImageBackupVar.BufferType = HBufferImage.BufferType;
158 HBufferImageBackupVar.LowVisibleRow = HBufferImage.LowVisibleRow;
159 HBufferImageBackupVar.HighBits = HBufferImage.HighBits;
160
161 //
162 // three kinds of buffer supported
163 // file buffer
164 // disk buffer
165 // memory buffer
166 //
167 switch (HBufferImage.BufferType) {
168 case FileTypeFileBuffer:
169 HFileImageBackup ();
170 break;
171
172 case FileTypeDiskBuffer:
173 HDiskImageBackup ();
174 break;
175
176 case FileTypeMemBuffer:
177 HMemImageBackup ();
178 break;
179 }
180
181 return EFI_SUCCESS;
182 }
183
184 /**
185 Free all the lines in HBufferImage.
186 Fields affected:
187 Lines
188 CurrentLine
189 NumLines
190 ListHead
191
192 @retval EFI_SUCCESS The operation was successful.
193 **/
194 EFI_STATUS
195 HBufferImageFreeLines (
196 VOID
197 )
198 {
199 HFreeLines (HBufferImage.ListHead, HBufferImage.Lines);
200
201 HBufferImage.Lines = NULL;
202 HBufferImage.CurrentLine = NULL;
203 HBufferImage.NumLines = 0;
204
205 return EFI_SUCCESS;
206 }
207
208 /**
209 Cleanup function for HBufferImage
210
211 @retval EFI_SUCCESS The operation was successful.
212 **/
213 EFI_STATUS
214 HBufferImageCleanup (
215 VOID
216 )
217 {
218 EFI_STATUS Status;
219
220 //
221 // free all the lines
222 //
223 Status = HBufferImageFreeLines ();
224
225 SHELL_FREE_NON_NULL (HBufferImage.ListHead);
226 HBufferImage.ListHead = NULL;
227
228 HFileImageCleanup ();
229 HDiskImageCleanup ();
230
231 return Status;
232
233 }
234
235 /**
236 Print Line on Row
237
238 @param[in] Line The lline to print.
239 @param[in] Row The row on screen ( begin from 1 ).
240 @param[in] FRow The FRow.
241 @param[in] Orig The original color.
242 @param[in] New The color to print with.
243
244 @retval EFI_SUCCESS The operation was successful.
245 **/
246 EFI_STATUS
247 HBufferImagePrintLine (
248 IN HEFI_EDITOR_LINE *Line,
249 IN UINTN Row,
250 IN UINTN FRow,
251 IN HEFI_EDITOR_COLOR_UNION Orig,
252 IN HEFI_EDITOR_COLOR_UNION New
253
254 )
255 {
256
257 UINTN Index;
258 UINTN Pos;
259 BOOLEAN Selected;
260 BOOLEAN BeNewColor;
261 UINTN RowStart;
262 UINTN RowEnd;
263 UINTN ColStart;
264 UINTN ColEnd;
265
266 //
267 // variable initialization
268 //
269 ColStart = 0;
270 ColEnd = 0;
271 Selected = FALSE;
272
273 //
274 // print the selected area in opposite color
275 //
276 if (HMainEditor.SelectStart != 0 && HMainEditor.SelectEnd != 0) {
277 RowStart = (HMainEditor.SelectStart - 1) / 0x10 + 1;
278 RowEnd = (HMainEditor.SelectEnd - 1) / 0x10 + 1;
279
280 ColStart = (HMainEditor.SelectStart - 1) % 0x10 + 1;
281 ColEnd = (HMainEditor.SelectEnd - 1) % 0x10 + 1;
282
283 if (FRow >= RowStart && FRow <= RowEnd) {
284 Selected = TRUE;
285 }
286
287 if (FRow > RowStart) {
288 ColStart = 1;
289 }
290
291 if (FRow < RowEnd) {
292 ColEnd = 0x10;
293 }
294
295 }
296
297 if (!HEditorMouseAction) {
298 ShellPrintEx (
299 0,
300 (INT32)Row - 1,
301 L"%8X ",
302 ((INT32)Row - 2 + HBufferImage.LowVisibleRow - 1) * 0x10
303 );
304
305 }
306
307 for (Index = 0; Index < 0x08 && Index < Line->Size; Index++) {
308
309 BeNewColor = FALSE;
310
311 if (Selected) {
312 if (Index + 1 >= ColStart && Index + 1 <= ColEnd) {
313 BeNewColor = TRUE;
314 }
315 }
316
317 if (BeNewColor) {
318 gST->ConOut->SetAttribute (gST->ConOut, New.Data);
319 } else {
320 gST->ConOut->SetAttribute (gST->ConOut, Orig.Data);
321 }
322
323 Pos = 10 + (Index * 3);
324 if (Line->Buffer[Index] < 0x10) {
325 ShellPrintEx ((INT32)Pos - 1, (INT32)Row - 1, L"0");
326 Pos++;
327 }
328
329 if (Index < 0x07) {
330 ShellPrintEx ((INT32)Pos - 1, (INT32)Row - 1, L"%x ", Line->Buffer[Index]);
331 } else {
332 ShellPrintEx ((INT32)Pos - 1, (INT32)Row - 1, L"%x ", Line->Buffer[Index]);
333 }
334
335 }
336
337 gST->ConOut->SetAttribute (gST->ConOut, Orig.Data);
338 while (Index < 0x08) {
339 Pos = 10 + (Index * 3);
340 ShellPrintEx ((INT32)Pos - 1, (INT32)Row - 1, L" ");
341 Index++;
342 }
343
344 while (Index < 0x10 && Index < Line->Size) {
345
346 BeNewColor = FALSE;
347
348 if (Selected) {
349 if (Index + 1 >= ColStart && Index + 1 <= ColEnd) {
350 BeNewColor = TRUE;
351 }
352 }
353
354 if (BeNewColor) {
355 gST->ConOut->SetAttribute (gST->ConOut, New.Data);
356 } else {
357 gST->ConOut->SetAttribute (gST->ConOut, Orig.Data);
358 }
359
360 Pos = 10 + (Index * 3) + 1;
361 if (Line->Buffer[Index] < 0x10) {
362 ShellPrintEx ((INT32)Pos - 1, (INT32)Row - 1, L"0");
363 Pos++;
364 }
365
366 ShellPrintEx ((INT32)Pos - 1, (INT32)Row - 1, L"%x ", Line->Buffer[Index]);
367 Index++;
368 }
369
370 gST->ConOut->SetAttribute (gST->ConOut, Orig.Data);
371 while (Index < 0x10) {
372 Pos = 10 + (Index * 3) + 1;
373 ShellPrintEx ((INT32)Pos - 1, (INT32)Row - 1, L" ");
374 Index++;
375 }
376 //
377 // restore the original color
378 //
379 gST->ConOut->SetAttribute (gST->ConOut, Orig.Data);
380
381 //
382 // PRINT the buffer content
383 //
384 if (!HEditorMouseAction) {
385 for (Index = 0; Index < 0x10 && Index < Line->Size; Index++) {
386 Pos = ASCII_POSITION + Index;
387
388 //
389 // learned from shelle.h -- IsValidChar
390 //
391 if (Line->Buffer[Index] >= L' ') {
392 ShellPrintEx ((INT32)Pos - 1, (INT32)Row - 1, L"%c", (CHAR16) Line->Buffer[Index]);
393 } else {
394 ShellPrintEx ((INT32)Pos - 1, (INT32)Row - 1, L"%c", '.');
395 }
396 }
397
398 while (Index < 0x10) {
399 Pos = ASCII_POSITION + Index;
400 ShellPrintEx ((INT32)Pos - 1, (INT32)Row - 1, L" ");
401 Index++;
402 }
403 }
404 //
405 // restore the abundant blank in hex edit area to original color
406 //
407 if (Selected) {
408 if (ColEnd <= 7) {
409 Pos = 10 + (ColEnd - 1) * 3 + 2;
410 ShellPrintEx ((INT32)Pos - 1, (INT32)Row - 1, L" ");
411 } else if (ColEnd == 8) {
412 Pos = 10 + (ColEnd - 1) * 3 + 2;
413 ShellPrintEx ((INT32)Pos - 1, (INT32)Row - 1, L" ");
414 } else {
415 Pos = 10 + (ColEnd - 1) * 3 + 3;
416 ShellPrintEx ((INT32)Pos - 1, (INT32)Row - 1, L" ");
417 }
418 }
419
420 return EFI_SUCCESS;
421 }
422
423 /**
424 Function to decide if a column number is stored in the high bits.
425
426 @param[in] Column The column to examine.
427 @param[out] FCol The actual column number.
428
429 @retval TRUE The actual column was in high bits and is now in FCol.
430 @retval FALSE There was not a column number in the high bits.
431 **/
432 BOOLEAN
433 HBufferImageIsAtHighBits (
434 IN UINTN Column,
435 OUT UINTN *FCol
436 )
437 {
438 Column -= 10;
439
440 //
441 // NOW AFTER THE SUB, Column start from 0
442 // 23 AND 24 ARE BOTH BLANK
443 //
444 if (Column == 24) {
445 *FCol = 0;
446 return FALSE;
447 }
448
449 if (Column > 24) {
450 Column--;
451 }
452
453 *FCol = (Column / 3) + 1;
454
455 if (Column % 3 == 0) {
456 return TRUE;
457 }
458
459 if ((Column % 3 == 2)) {
460 *FCol = 0;
461 }
462
463 return FALSE;
464 }
465
466 /**
467 Decide if a point is in the already selected area.
468
469 @param[in] MouseRow The row of the point to test.
470 @param[in] MouseCol The col of the point to test.
471
472 @retval TRUE The point is in the selected area.
473 @retval FALSE The point is not in the selected area.
474 **/
475 BOOLEAN
476 HBufferImageIsInSelectedArea (
477 IN UINTN MouseRow,
478 IN UINTN MouseCol
479 )
480 {
481 UINTN FRow;
482 UINTN RowStart;
483 UINTN RowEnd;
484 UINTN ColStart;
485 UINTN ColEnd;
486 UINTN MouseColStart;
487 UINTN MouseColEnd;
488
489 //
490 // judge mouse position whether is in selected area
491 //
492 //
493 // not select
494 //
495 if (HMainEditor.SelectStart == 0 || HMainEditor.SelectEnd == 0) {
496 return FALSE;
497 }
498 //
499 // calculate the select area
500 //
501 RowStart = (HMainEditor.SelectStart - 1) / 0x10 + 1;
502 RowEnd = (HMainEditor.SelectEnd - 1) / 0x10 + 1;
503
504 ColStart = (HMainEditor.SelectStart - 1) % 0x10 + 1;
505 ColEnd = (HMainEditor.SelectEnd - 1) % 0x10 + 1;
506
507 FRow = HBufferImage.LowVisibleRow + MouseRow - 2;
508 if (FRow < RowStart || FRow > RowEnd) {
509 return FALSE;
510 }
511
512 if (FRow > RowStart) {
513 ColStart = 1;
514 }
515
516 if (FRow < RowEnd) {
517 ColEnd = 0x10;
518 }
519
520 MouseColStart = 10 + (ColStart - 1) * 3;
521 if (ColStart > 8) {
522 MouseColStart++;
523 }
524
525 MouseColEnd = 10 + (ColEnd - 1) * 3 + 1;
526 if (ColEnd > 8) {
527 MouseColEnd++;
528 }
529
530 if (MouseCol < MouseColStart || MouseCol > MouseColEnd) {
531 return FALSE;
532 }
533
534 return TRUE;
535 }
536
537 /**
538 Set mouse position according to HBufferImage.MousePosition.
539
540 @retval EFI_SUCCESS The operation was successful.
541 **/
542 EFI_STATUS
543 HBufferImageRestoreMousePosition (
544 VOID
545 )
546 {
547 HEFI_EDITOR_COLOR_UNION Orig;
548 HEFI_EDITOR_COLOR_UNION New;
549 UINTN FRow;
550 UINTN FColumn;
551 BOOLEAN HasCharacter;
552 HEFI_EDITOR_LINE *CurrentLine;
553 HEFI_EDITOR_LINE *Line;
554 UINT8 Value;
555 BOOLEAN HighBits;
556
557 Line = NULL;
558 if (HMainEditor.MouseSupported) {
559
560 if (HBufferImageMouseNeedRefresh) {
561
562 HBufferImageMouseNeedRefresh = FALSE;
563
564 //
565 // if mouse position not moved and only mouse action
566 // so do not need to refresh mouse position
567 //
568 if ((
569 HBufferImage.MousePosition.Row == HBufferImageBackupVar.MousePosition.Row &&
570 HBufferImage.MousePosition.Column == HBufferImageBackupVar.MousePosition.Column
571 ) &&
572 HEditorMouseAction
573 ) {
574 return EFI_SUCCESS;
575 }
576 //
577 // backup the old screen attributes
578 //
579 Orig = HMainEditor.ColorAttributes;
580 New.Colors.Foreground = Orig.Colors.Background;
581 New.Colors.Background = Orig.Colors.Foreground;
582
583 //
584 // if in selected area,
585 // so do not need to refresh mouse
586 //
587 if (!HBufferImageIsInSelectedArea (
588 HBufferImageBackupVar.MousePosition.Row,
589 HBufferImageBackupVar.MousePosition.Column
590 )) {
591 gST->ConOut->SetAttribute (gST->ConOut, Orig.Data);
592 } else {
593 gST->ConOut->SetAttribute (gST->ConOut, New.Data);
594 }
595 //
596 // clear the old mouse position
597 //
598 FRow = HBufferImage.LowVisibleRow + HBufferImageBackupVar.MousePosition.Row - 2;
599
600 HighBits = HBufferImageIsAtHighBits (
601 HBufferImageBackupVar.MousePosition.Column,
602 &FColumn
603 );
604
605 HasCharacter = TRUE;
606 if (FRow > HBufferImage.NumLines || FColumn == 0) {
607 HasCharacter = FALSE;
608 } else {
609 CurrentLine = HBufferImage.CurrentLine;
610 Line = HMoveLine (FRow - HBufferImage.BufferPosition.Row);
611
612 if (Line == NULL || FColumn > Line->Size) {
613 HasCharacter = FALSE;
614 }
615
616 HBufferImage.CurrentLine = CurrentLine;
617 }
618
619 ShellPrintEx (
620 (INT32)HBufferImageBackupVar.MousePosition.Column - 1,
621 (INT32)HBufferImageBackupVar.MousePosition.Row - 1,
622 L" "
623 );
624
625 if (HasCharacter) {
626 if (HighBits) {
627 Value = (UINT8) (Line->Buffer[FColumn - 1] & 0xf0);
628 Value = (UINT8) (Value >> 4);
629 } else {
630 Value = (UINT8) (Line->Buffer[FColumn - 1] & 0xf);
631 }
632
633 ShellPrintEx (
634 (INT32)HBufferImageBackupVar.MousePosition.Column - 1,
635 (INT32)HBufferImageBackupVar.MousePosition.Row - 1,
636 L"%x",
637 Value
638 );
639 }
640
641 if (!HBufferImageIsInSelectedArea (
642 HBufferImage.MousePosition.Row,
643 HBufferImage.MousePosition.Column
644 )) {
645 gST->ConOut->SetAttribute (gST->ConOut, New.Data);
646 } else {
647 gST->ConOut->SetAttribute (gST->ConOut, Orig.Data);
648 }
649 //
650 // clear the old mouse position
651 //
652 FRow = HBufferImage.LowVisibleRow + HBufferImage.MousePosition.Row - 2;
653
654 HighBits = HBufferImageIsAtHighBits (
655 HBufferImage.MousePosition.Column,
656 &FColumn
657 );
658
659 HasCharacter = TRUE;
660 if (FRow > HBufferImage.NumLines || FColumn == 0) {
661 HasCharacter = FALSE;
662 } else {
663 CurrentLine = HBufferImage.CurrentLine;
664 Line = HMoveLine (FRow - HBufferImage.BufferPosition.Row);
665
666 if (Line == NULL || FColumn > Line->Size) {
667 HasCharacter = FALSE;
668 }
669
670 HBufferImage.CurrentLine = CurrentLine;
671 }
672
673 ShellPrintEx (
674 (INT32)HBufferImage.MousePosition.Column - 1,
675 (INT32)HBufferImage.MousePosition.Row - 1,
676 L" "
677 );
678
679 if (HasCharacter) {
680 if (HighBits) {
681 Value = (UINT8) (Line->Buffer[FColumn - 1] & 0xf0);
682 Value = (UINT8) (Value >> 4);
683 } else {
684 Value = (UINT8) (Line->Buffer[FColumn - 1] & 0xf);
685 }
686
687 ShellPrintEx (
688 (INT32)HBufferImage.MousePosition.Column - 1,
689 (INT32)HBufferImage.MousePosition.Row - 1,
690 L"%x",
691 Value
692 );
693 }
694 //
695 // end of HasCharacter
696 //
697 gST->ConOut->SetAttribute (gST->ConOut, Orig.Data);
698 }
699 //
700 // end of MouseNeedRefresh
701 //
702 }
703 //
704 // end of MouseSupported
705 //
706 return EFI_SUCCESS;
707 }
708
709 /**
710 Set cursor position according to HBufferImage.DisplayPosition.
711
712 @retval EFI_SUCCESS The operation was successful.
713 **/
714 EFI_STATUS
715 HBufferImageRestorePosition (
716 VOID
717 )
718 {
719 //
720 // set cursor position
721 //
722 gST->ConOut->SetCursorPosition (
723 gST->ConOut,
724 HBufferImage.DisplayPosition.Column - 1,
725 HBufferImage.DisplayPosition.Row - 1
726 );
727
728 return EFI_SUCCESS;
729 }
730
731 /**
732 Refresh function for HBufferImage.
733
734 @retval EFI_SUCCESS The operation was successful.
735 @retval EFI_LOAD_ERROR A Load error occured.
736
737 **/
738 EFI_STATUS
739 HBufferImageRefresh (
740 VOID
741 )
742 {
743 LIST_ENTRY *Link;
744 HEFI_EDITOR_LINE *Line;
745 UINTN Row;
746 HEFI_EDITOR_COLOR_UNION Orig;
747 HEFI_EDITOR_COLOR_UNION New;
748
749 UINTN StartRow;
750 UINTN EndRow;
751 UINTN FStartRow;
752 UINTN FEndRow;
753 UINTN Tmp;
754
755 Orig = HMainEditor.ColorAttributes;
756 New.Colors.Foreground = Orig.Colors.Background;
757 New.Colors.Background = Orig.Colors.Foreground;
758
759 //
760 // if it's the first time after editor launch, so should refresh
761 //
762 if (HEditorFirst == FALSE) {
763 //
764 // no definite required refresh
765 // and file position displayed on screen has not been changed
766 //
767 if (!HBufferImageNeedRefresh &&
768 !HBufferImageOnlyLineNeedRefresh &&
769 HBufferImageBackupVar.LowVisibleRow == HBufferImage.LowVisibleRow
770 ) {
771 HBufferImageRestoreMousePosition ();
772 HBufferImageRestorePosition ();
773 return EFI_SUCCESS;
774 }
775 }
776
777 gST->ConOut->EnableCursor (gST->ConOut, FALSE);
778
779 //
780 // only need to refresh current line
781 //
782 if (HBufferImageOnlyLineNeedRefresh && HBufferImageBackupVar.LowVisibleRow == HBufferImage.LowVisibleRow) {
783
784 HBufferImagePrintLine (
785 HBufferImage.CurrentLine,
786 HBufferImage.DisplayPosition.Row,
787 HBufferImage.BufferPosition.Row,
788 Orig,
789 New
790 );
791 } else {
792 //
793 // the whole edit area need refresh
794 //
795 if (HEditorMouseAction && HMainEditor.SelectStart != 0 && HMainEditor.SelectEnd != 0) {
796 if (HMainEditor.SelectStart != HMainEditorBackupVar.SelectStart) {
797 if (HMainEditor.SelectStart >= HMainEditorBackupVar.SelectStart && HMainEditorBackupVar.SelectStart != 0) {
798 StartRow = (HMainEditorBackupVar.SelectStart - 1) / 0x10 + 1;
799 } else {
800 StartRow = (HMainEditor.SelectStart - 1) / 0x10 + 1;
801 }
802 } else {
803 StartRow = (HMainEditor.SelectStart - 1) / 0x10 + 1;
804 }
805
806 if (HMainEditor.SelectEnd <= HMainEditorBackupVar.SelectEnd) {
807 EndRow = (HMainEditorBackupVar.SelectEnd - 1) / 0x10 + 1;
808 } else {
809 EndRow = (HMainEditor.SelectEnd - 1) / 0x10 + 1;
810 }
811 //
812 // swap
813 //
814 if (StartRow > EndRow) {
815 Tmp = StartRow;
816 StartRow = EndRow;
817 EndRow = Tmp;
818 }
819
820 FStartRow = StartRow;
821 FEndRow = EndRow;
822
823 StartRow = 2 + StartRow - HBufferImage.LowVisibleRow;
824 EndRow = 2 + EndRow - HBufferImage.LowVisibleRow;
825
826 } else {
827 //
828 // not mouse selection actions
829 //
830 FStartRow = HBufferImage.LowVisibleRow;
831 StartRow = 2;
832 EndRow = (HMainEditor.ScreenSize.Row - 4);
833 }
834 //
835 // no line
836 //
837 if (HBufferImage.Lines == NULL) {
838 HBufferImageRestoreMousePosition ();
839 HBufferImageRestorePosition ();
840 gST->ConOut->EnableCursor (gST->ConOut, TRUE);
841 return EFI_SUCCESS;
842 }
843 //
844 // get the first line that will be displayed
845 //
846 Line = HMoveLine (FStartRow - HBufferImage.BufferPosition.Row);
847 if (Line == NULL) {
848 gST->ConOut->EnableCursor (gST->ConOut, TRUE);
849 return EFI_LOAD_ERROR;
850 }
851
852 Link = &(Line->Link);
853 Row = StartRow;
854 do {
855 Line = CR (Link, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST);
856
857 //
858 // print line at row
859 //
860 HBufferImagePrintLine (
861 Line,
862 Row,
863 HBufferImage.LowVisibleRow + Row - 2,
864 Orig,
865 New
866 );
867
868 Link = Link->ForwardLink;
869 Row++;
870 } while (Link != HBufferImage.ListHead && Row <= EndRow);
871
872 while (Row <= EndRow) {
873 EditorClearLine (Row, HMainEditor.ScreenSize.Column, HMainEditor.ScreenSize.Row);
874 Row++;
875 }
876 //
877 // while not file end and not screen full
878 //
879 }
880
881 HBufferImageRestoreMousePosition ();
882 HBufferImageRestorePosition ();
883
884 HBufferImageNeedRefresh = FALSE;
885 HBufferImageOnlyLineNeedRefresh = FALSE;
886 gST->ConOut->EnableCursor (gST->ConOut, TRUE);
887
888 return EFI_SUCCESS;
889 }
890
891 /**
892 Read an image into a buffer friom a source.
893
894 @param[in] FileName Pointer to the file name. OPTIONAL and ignored if not FileTypeFileBuffer.
895 @param[in] DiskName Pointer to the disk name. OPTIONAL and ignored if not FileTypeDiskBuffer.
896 @param[in] DiskOffset Offset into the disk. OPTIONAL and ignored if not FileTypeDiskBuffer.
897 @param[in] DiskSize Size of the disk buffer. OPTIONAL and ignored if not FileTypeDiskBuffer.
898 @param[in] MemOffset Offset into the Memory. OPTIONAL and ignored if not FileTypeMemBuffer.
899 @param[in] MemSize Size of the Memory buffer. OPTIONAL and ignored if not FileTypeMemBuffer.
900 @param[in] BufferType The type of buffer to save. IGNORED.
901 @param[in] Recover TRUE for recovermode, FALSE otherwise.
902
903 @return EFI_SUCCESS The operation was successful.
904 **/
905 EFI_STATUS
906 EFIAPI
907 HBufferImageRead (
908 IN CONST CHAR16 *FileName,
909 IN CONST CHAR16 *DiskName,
910 IN UINTN DiskOffset,
911 IN UINTN DiskSize,
912 IN UINTN MemOffset,
913 IN UINTN MemSize,
914 IN EDIT_FILE_TYPE BufferType,
915 IN BOOLEAN Recover
916 )
917 {
918 EFI_STATUS Status;
919 EDIT_FILE_TYPE BufferTypeBackup;
920
921 //
922 // variable initialization
923 //
924 Status = EFI_SUCCESS;
925 HBufferImage.BufferType = BufferType;
926
927 //
928 // three types of buffer supported
929 // file buffer
930 // disk buffer
931 // memory buffer
932 //
933 BufferTypeBackup = HBufferImage.BufferType;
934
935 switch (BufferType) {
936 case FileTypeFileBuffer:
937 Status = HFileImageRead (FileName, Recover);
938 break;
939
940 case FileTypeDiskBuffer:
941 Status = HDiskImageRead (DiskName, DiskOffset, DiskSize, Recover);
942 break;
943
944 case FileTypeMemBuffer:
945 Status = HMemImageRead (MemOffset, MemSize, Recover);
946 break;
947 }
948
949 if (EFI_ERROR (Status)) {
950 HBufferImage.BufferType = BufferTypeBackup;
951 }
952
953 return Status;
954 }
955
956 /**
957 Save the current image.
958
959 @param[in] FileName Pointer to the file name. OPTIONAL and ignored if not FileTypeFileBuffer.
960 @param[in] DiskName Pointer to the disk name. OPTIONAL and ignored if not FileTypeDiskBuffer.
961 @param[in] DiskOffset Offset into the disk. OPTIONAL and ignored if not FileTypeDiskBuffer.
962 @param[in] DiskSize Size of the disk buffer. OPTIONAL and ignored if not FileTypeDiskBuffer.
963 @param[in] MemOffset Offset into the Memory. OPTIONAL and ignored if not FileTypeMemBuffer.
964 @param[in] MemSize Size of the Memory buffer. OPTIONAL and ignored if not FileTypeMemBuffer.
965 @param[in] BufferType The type of buffer to save. IGNORED.
966
967 @return EFI_SUCCESS The operation was successful.
968 **/
969 EFI_STATUS
970 HBufferImageSave (
971 IN CHAR16 *FileName,
972 IN CHAR16 *DiskName,
973 IN UINTN DiskOffset,
974 IN UINTN DiskSize,
975 IN UINTN MemOffset,
976 IN UINTN MemSize,
977 IN EDIT_FILE_TYPE BufferType
978 )
979 {
980 EFI_STATUS Status;
981 EDIT_FILE_TYPE BufferTypeBackup;
982
983 //
984 // variable initialization
985 //
986 Status = EFI_SUCCESS;
987 BufferTypeBackup = HBufferImage.BufferType;
988
989 switch (HBufferImage.BufferType) {
990 //
991 // file buffer
992 //
993 case FileTypeFileBuffer:
994 Status = HFileImageSave (FileName);
995 break;
996
997 //
998 // disk buffer
999 //
1000 case FileTypeDiskBuffer:
1001 Status = HDiskImageSave (DiskName, DiskOffset, DiskSize);
1002 break;
1003
1004 //
1005 // memory buffer
1006 //
1007 case FileTypeMemBuffer:
1008 Status = HMemImageSave (MemOffset, MemSize);
1009 break;
1010 }
1011
1012 if (EFI_ERROR (Status)) {
1013 HBufferImage.BufferType = BufferTypeBackup;
1014 }
1015
1016 return Status;
1017 }
1018
1019 /**
1020 Create a new line and append it to the line list.
1021 Fields affected:
1022 NumLines
1023 Lines
1024
1025 @retval NULL create line failed.
1026 @return the line created.
1027
1028 **/
1029 HEFI_EDITOR_LINE *
1030 HBufferImageCreateLine (
1031 VOID
1032 )
1033 {
1034 HEFI_EDITOR_LINE *Line;
1035
1036 //
1037 // allocate for line structure
1038 //
1039 Line = AllocateZeroPool (sizeof (HEFI_EDITOR_LINE));
1040 if (Line == NULL) {
1041 return NULL;
1042 }
1043
1044 Line->Signature = EFI_EDITOR_LINE_LIST;
1045 Line->Size = 0;
1046
1047 HBufferImage.NumLines++;
1048
1049 //
1050 // insert to line list
1051 //
1052 InsertTailList (HBufferImage.ListHead, &Line->Link);
1053
1054 if (HBufferImage.Lines == NULL) {
1055 HBufferImage.Lines = CR (
1056 HBufferImage.ListHead->ForwardLink,
1057 HEFI_EDITOR_LINE,
1058 Link,
1059 EFI_EDITOR_LINE_LIST
1060 );
1061 }
1062
1063 return Line;
1064 }
1065
1066 /**
1067 Free the current image.
1068
1069 @retval EFI_SUCCESS The operation was successful.
1070 **/
1071 EFI_STATUS
1072 HBufferImageFree (
1073 VOID
1074 )
1075 {
1076 //
1077 // free all lines
1078 //
1079 HBufferImageFreeLines ();
1080
1081 return EFI_SUCCESS;
1082 }
1083
1084 /**
1085 change char to int value based on Hex.
1086
1087 @param[in] Char The input char.
1088
1089 @return The character's index value.
1090 @retval -1 The operation failed.
1091 **/
1092 INTN
1093 EFIAPI
1094 HBufferImageCharToHex (
1095 IN CHAR16 Char
1096 )
1097 {
1098 //
1099 // change the character to hex
1100 //
1101 if (Char >= L'0' && Char <= L'9') {
1102 return (INTN) (Char - L'0');
1103 }
1104
1105 if (Char >= L'a' && Char <= L'f') {
1106 return (INTN) (Char - L'a' + 10);
1107 }
1108
1109 if (Char >= L'A' && Char <= L'F') {
1110 return (INTN) (Char - L'A' + 10);
1111 }
1112
1113 return -1;
1114 }
1115
1116 /**
1117 Add character.
1118
1119 @param[in] Char -- input char.
1120
1121 @retval EFI_SUCCESS The operation was successful.
1122 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
1123 **/
1124 EFI_STATUS
1125 EFIAPI
1126 HBufferImageAddChar (
1127 IN CHAR16 Char
1128 )
1129 {
1130 HEFI_EDITOR_LINE *Line;
1131 HEFI_EDITOR_LINE *NewLine;
1132 INTN Value;
1133 UINT8 Old;
1134 UINTN FRow;
1135 UINTN FCol;
1136 BOOLEAN High;
1137
1138 Value = HBufferImageCharToHex (Char);
1139
1140 //
1141 // invalid input
1142 //
1143 if (Value == -1) {
1144 return EFI_SUCCESS;
1145 }
1146
1147 Line = HBufferImage.CurrentLine;
1148 FRow = HBufferImage.BufferPosition.Row;
1149 FCol = HBufferImage.BufferPosition.Column;
1150 High = HBufferImage.HighBits;
1151
1152 //
1153 // only needs to refresh current line
1154 //
1155 HBufferImageOnlyLineNeedRefresh = TRUE;
1156
1157 //
1158 // not a full line and beyond the last character
1159 //
1160 if (FCol > Line->Size) {
1161 //
1162 // cursor always at high 4 bits
1163 // and always put input to the low 4 bits
1164 //
1165 Line->Buffer[Line->Size] = (UINT8) Value;
1166 Line->Size++;
1167 High = FALSE;
1168 } else {
1169
1170 Old = Line->Buffer[FCol - 1];
1171
1172 //
1173 // always put the input to the low 4 bits
1174 //
1175 Old = (UINT8) (Old & 0x0f);
1176 Old = (UINT8) (Old << 4);
1177 Old = (UINT8) (Value + Old);
1178 Line->Buffer[FCol - 1] = Old;
1179
1180 //
1181 // at the low 4 bits of the last character of a full line
1182 // so if no next line, need to create a new line
1183 //
1184 if (!High && FCol == 0x10) {
1185
1186 HBufferImageOnlyLineNeedRefresh = FALSE;
1187 HBufferImageNeedRefresh = TRUE;
1188
1189 if (Line->Link.ForwardLink == HBufferImage.ListHead) {
1190 //
1191 // last line
1192 //
1193 // create a new line
1194 //
1195 NewLine = HBufferImageCreateLine ();
1196 if (NewLine == NULL) {
1197 return EFI_OUT_OF_RESOURCES;
1198 }
1199 //
1200 // end of NULL
1201 //
1202 }
1203 //
1204 // end of == ListHead
1205 //
1206 }
1207 //
1208 // end of == 0x10
1209 //
1210 // if already at end of this line, scroll it to the start of next line
1211 //
1212 if (FCol == 0x10 && !High) {
1213 //
1214 // definitely has next line
1215 //
1216 FRow++;
1217 FCol = 1;
1218 High = TRUE;
1219 } else {
1220 //
1221 // if not at end of this line, just move to next column
1222 //
1223 if (!High) {
1224 FCol++;
1225 }
1226
1227 if (High) {
1228 High = FALSE;
1229 } else {
1230 High = TRUE;
1231 }
1232
1233 }
1234 //
1235 // end of ==FALSE
1236 //
1237 }
1238 //
1239 // move cursor to right
1240 //
1241 HBufferImageMovePosition (FRow, FCol, High);
1242
1243 if (!HBufferImage.Modified) {
1244 HBufferImage.Modified = TRUE;
1245 }
1246
1247 return EFI_SUCCESS;
1248 }
1249
1250 /**
1251 Delete the previous character.
1252
1253 @retval EFI_SUCCESS The operationw as successful.
1254 **/
1255 EFI_STATUS
1256 EFIAPI
1257 HBufferImageDoBackspace (
1258 VOID
1259 )
1260 {
1261 HEFI_EDITOR_LINE *Line;
1262
1263 UINTN FileColumn;
1264 UINTN FPos;
1265 BOOLEAN LastLine;
1266
1267 //
1268 // variable initialization
1269 //
1270 LastLine = FALSE;
1271
1272 //
1273 // already the first character
1274 //
1275 if (HBufferImage.BufferPosition.Row == 1 && HBufferImage.BufferPosition.Column == 1) {
1276 return EFI_SUCCESS;
1277 }
1278
1279 FPos = (HBufferImage.BufferPosition.Row - 1) * 0x10 + HBufferImage.BufferPosition.Column - 1;
1280
1281 FileColumn = HBufferImage.BufferPosition.Column;
1282
1283 Line = HBufferImage.CurrentLine;
1284 LastLine = FALSE;
1285 if (Line->Link.ForwardLink == HBufferImage.ListHead && FileColumn > 1) {
1286 LastLine = TRUE;
1287 }
1288
1289 HBufferImageDeleteCharacterFromBuffer (FPos - 1, 1, NULL);
1290
1291 //
1292 // if is the last line
1293 // then only this line need to be refreshed
1294 //
1295 if (LastLine) {
1296 HBufferImageNeedRefresh = FALSE;
1297 HBufferImageOnlyLineNeedRefresh = TRUE;
1298 } else {
1299 HBufferImageNeedRefresh = TRUE;
1300 HBufferImageOnlyLineNeedRefresh = FALSE;
1301 }
1302
1303 if (!HBufferImage.Modified) {
1304 HBufferImage.Modified = TRUE;
1305 }
1306
1307 return EFI_SUCCESS;
1308 }
1309
1310 /**
1311 ASCII key + Backspace + return.
1312
1313 @param[in] Char The input char.
1314
1315 @retval EFI_SUCCESS The operation was successful.
1316 @retval EFI_LOAD_ERROR A load error occured.
1317 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
1318 **/
1319 EFI_STATUS
1320 EFIAPI
1321 HBufferImageDoCharInput (
1322 IN CHAR16 Char
1323 )
1324 {
1325 EFI_STATUS Status;
1326
1327 Status = EFI_SUCCESS;
1328
1329 switch (Char) {
1330 case 0:
1331 break;
1332
1333 case 0x08:
1334 Status = HBufferImageDoBackspace ();
1335 break;
1336
1337 case 0x09:
1338 case 0x0a:
1339 case 0x0d:
1340 //
1341 // Tabs, Returns are thought as nothing
1342 //
1343 break;
1344
1345 default:
1346 //
1347 // DEAL WITH ASCII CHAR, filter out thing like ctrl+f
1348 //
1349 if (Char > 127 || Char < 32) {
1350 Status = StatusBarSetStatusString (L"Unknown Command");
1351 } else {
1352 Status = HBufferImageAddChar (Char);
1353 }
1354
1355 break;
1356 }
1357
1358 return Status;
1359 }
1360
1361 /**
1362 Check user specified FileRow is above current screen.
1363
1364 @param[in] FileRow Row of file position ( start from 1 ).
1365
1366 @retval TRUE It is above the current screen.
1367 @retval FALSE It is not above the current screen.
1368
1369 **/
1370 BOOLEAN
1371 HAboveCurrentScreen (
1372 IN UINTN FileRow
1373 )
1374 {
1375 if (FileRow < HBufferImage.LowVisibleRow) {
1376 return TRUE;
1377 }
1378
1379 return FALSE;
1380 }
1381
1382 /**
1383 Check user specified FileRow is under current screen.
1384
1385 @param[in] FileRow Row of file position ( start from 1 ).
1386
1387 @retval TRUE It is under the current screen.
1388 @retval FALSE It is not under the current screen.
1389
1390 **/
1391 BOOLEAN
1392 HUnderCurrentScreen (
1393 IN UINTN FileRow
1394 )
1395 {
1396 if (FileRow > HBufferImage.LowVisibleRow + (HMainEditor.ScreenSize.Row - 5) - 1) {
1397 return TRUE;
1398 }
1399
1400 return FALSE;
1401 }
1402
1403 /**
1404 According to cursor's file position, adjust screen display.
1405
1406 @param[in] NewFilePosRow Row of file position ( start from 1 ).
1407 @param[in] NewFilePosCol Column of file position ( start from 1 ).
1408 @param[in] HighBits Cursor will on high4 bits or low4 bits.
1409 **/
1410 VOID
1411 HBufferImageMovePosition (
1412 IN UINTN NewFilePosRow,
1413 IN UINTN NewFilePosCol,
1414 IN BOOLEAN HighBits
1415 )
1416 {
1417 INTN RowGap;
1418 UINTN Abs;
1419 BOOLEAN Above;
1420 BOOLEAN Under;
1421 UINTN NewDisplayCol;
1422
1423 //
1424 // CALCULATE gap between current file position and new file position
1425 //
1426 RowGap = NewFilePosRow - HBufferImage.BufferPosition.Row;
1427
1428 Under = HUnderCurrentScreen (NewFilePosRow);
1429 Above = HAboveCurrentScreen (NewFilePosRow);
1430
1431 HBufferImage.HighBits = HighBits;
1432
1433 //
1434 // if is below current screen
1435 //
1436 if (Under) {
1437 //
1438 // display row will be unchanged
1439 //
1440 HBufferImage.BufferPosition.Row = NewFilePosRow;
1441 } else {
1442 if (Above) {
1443 //
1444 // has enough above line, so display row unchanged
1445 // not has enough above lines, so the first line is
1446 // at the first display line
1447 //
1448 if (NewFilePosRow < (HBufferImage.DisplayPosition.Row - 2 + 1)) {
1449 HBufferImage.DisplayPosition.Row = NewFilePosRow + 2 - 1;
1450 }
1451
1452 HBufferImage.BufferPosition.Row = NewFilePosRow;
1453 } else {
1454 //
1455 // in current screen
1456 //
1457 HBufferImage.BufferPosition.Row = NewFilePosRow;
1458 if (RowGap <= 0) {
1459 Abs = (UINTN)ABS(RowGap);
1460 HBufferImage.DisplayPosition.Row -= Abs;
1461 } else {
1462 HBufferImage.DisplayPosition.Row += RowGap;
1463 }
1464
1465 }
1466 }
1467
1468 HBufferImage.LowVisibleRow = HBufferImage.BufferPosition.Row - (HBufferImage.DisplayPosition.Row - 2);
1469
1470 //
1471 // always in current screen
1472 //
1473 HBufferImage.BufferPosition.Column = NewFilePosCol;
1474
1475 NewDisplayCol = 10 + (NewFilePosCol - 1) * 3;
1476 if (NewFilePosCol > 0x8) {
1477 NewDisplayCol++;
1478 }
1479
1480 if (!HighBits) {
1481 NewDisplayCol++;
1482 }
1483
1484 HBufferImage.DisplayPosition.Column = NewDisplayCol;
1485
1486 //
1487 // let CurrentLine point to correct line;
1488 //
1489 HBufferImage.CurrentLine = HMoveCurrentLine (RowGap);
1490
1491 }
1492
1493 /**
1494 Scroll cursor to right.
1495
1496 @retval EFI_SUCCESS The operation was successful.
1497 **/
1498 EFI_STATUS
1499 HBufferImageScrollRight (
1500 VOID
1501 )
1502 {
1503 HEFI_EDITOR_LINE *Line;
1504 UINTN FRow;
1505 UINTN FCol;
1506
1507 //
1508 // scroll right will always move to the high4 bits of the next character
1509 //
1510 HBufferImageNeedRefresh = FALSE;
1511 HBufferImageOnlyLineNeedRefresh = FALSE;
1512
1513 Line = HBufferImage.CurrentLine;
1514
1515 FRow = HBufferImage.BufferPosition.Row;
1516 FCol = HBufferImage.BufferPosition.Column;
1517
1518 //
1519 // this line is not full and no next line
1520 //
1521 if (FCol > Line->Size) {
1522 return EFI_SUCCESS;
1523 }
1524 //
1525 // if already at end of this line, scroll it to the start of next line
1526 //
1527 if (FCol == 0x10) {
1528 //
1529 // has next line
1530 //
1531 if (Line->Link.ForwardLink != HBufferImage.ListHead) {
1532 FRow++;
1533 FCol = 1;
1534
1535 } else {
1536 return EFI_SUCCESS;
1537 }
1538 } else {
1539 //
1540 // if not at end of this line, just move to next column
1541 //
1542 FCol++;
1543
1544 }
1545
1546 HBufferImageMovePosition (FRow, FCol, TRUE);
1547
1548 return EFI_SUCCESS;
1549 }
1550
1551 /**
1552 Scroll cursor to left.
1553
1554 @retval EFI_SUCCESS The operation was successful.
1555 **/
1556 EFI_STATUS
1557 HBufferImageScrollLeft (
1558 VOID
1559 )
1560 {
1561
1562 HEFI_EDITOR_LINE *Line;
1563 UINTN FRow;
1564 UINTN FCol;
1565
1566 HBufferImageNeedRefresh = FALSE;
1567 HBufferImageOnlyLineNeedRefresh = FALSE;
1568
1569 Line = HBufferImage.CurrentLine;
1570
1571 FRow = HBufferImage.BufferPosition.Row;
1572 FCol = HBufferImage.BufferPosition.Column;
1573
1574 //
1575 // if already at start of this line, so move to the end of previous line
1576 //
1577 if (FCol <= 1) {
1578 //
1579 // has previous line
1580 //
1581 if (Line->Link.BackLink != HBufferImage.ListHead) {
1582 FRow--;
1583 Line = CR (Line->Link.BackLink, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST);
1584 FCol = Line->Size;
1585 } else {
1586 return EFI_SUCCESS;
1587 }
1588 } else {
1589 //
1590 // if not at start of this line, just move to previous column
1591 //
1592 FCol--;
1593 }
1594
1595 HBufferImageMovePosition (FRow, FCol, TRUE);
1596
1597 return EFI_SUCCESS;
1598 }
1599
1600 /**
1601 Scroll cursor to the next line
1602
1603 @retval EFI_SUCCESS The operation was successful.
1604 **/
1605 EFI_STATUS
1606 HBufferImageScrollDown (
1607 VOID
1608 )
1609 {
1610 HEFI_EDITOR_LINE *Line;
1611 UINTN FRow;
1612 UINTN FCol;
1613 BOOLEAN HighBits;
1614
1615 Line = HBufferImage.CurrentLine;
1616
1617 FRow = HBufferImage.BufferPosition.Row;
1618 FCol = HBufferImage.BufferPosition.Column;
1619 HighBits = HBufferImage.HighBits;
1620
1621 //
1622 // has next line
1623 //
1624 if (Line->Link.ForwardLink != HBufferImage.ListHead) {
1625 FRow++;
1626 Line = CR (Line->Link.ForwardLink, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST);
1627
1628 //
1629 // if the next line is not that long, so move to end of next line
1630 //
1631 if (FCol > Line->Size) {
1632 FCol = Line->Size + 1;
1633 HighBits = TRUE;
1634 }
1635
1636 } else {
1637 return EFI_SUCCESS;
1638 }
1639
1640 HBufferImageMovePosition (FRow, FCol, HighBits);
1641
1642 return EFI_SUCCESS;
1643 }
1644
1645 /**
1646 Scroll cursor to previous line
1647
1648 @retval EFI_SUCCESS The operation was successful.
1649 **/
1650 EFI_STATUS
1651 HBufferImageScrollUp (
1652 VOID
1653 )
1654 {
1655 HEFI_EDITOR_LINE *Line;
1656 UINTN FRow;
1657 UINTN FCol;
1658
1659 Line = HBufferImage.CurrentLine;
1660
1661 FRow = HBufferImage.BufferPosition.Row;
1662 FCol = HBufferImage.BufferPosition.Column;
1663
1664 //
1665 // has previous line
1666 //
1667 if (Line->Link.BackLink != HBufferImage.ListHead) {
1668 FRow--;
1669
1670 } else {
1671 return EFI_SUCCESS;
1672 }
1673
1674 HBufferImageMovePosition (FRow, FCol, HBufferImage.HighBits);
1675
1676 return EFI_SUCCESS;
1677 }
1678
1679 /**
1680 Scroll cursor to next page
1681
1682 @retval EFI_SUCCESS The operation was successful.
1683 **/
1684 EFI_STATUS
1685 HBufferImagePageDown (
1686 VOID
1687 )
1688 {
1689 HEFI_EDITOR_LINE *Line;
1690 UINTN FRow;
1691 UINTN FCol;
1692 UINTN Gap;
1693 BOOLEAN HighBits;
1694
1695 Line = HBufferImage.CurrentLine;
1696
1697 FRow = HBufferImage.BufferPosition.Row;
1698 FCol = HBufferImage.BufferPosition.Column;
1699 HighBits = HBufferImage.HighBits;
1700
1701 //
1702 // has next page
1703 //
1704 if (HBufferImage.NumLines >= FRow + (HMainEditor.ScreenSize.Row - 5)) {
1705 Gap = (HMainEditor.ScreenSize.Row - 5);
1706 } else {
1707 //
1708 // MOVE CURSOR TO LAST LINE
1709 //
1710 Gap = HBufferImage.NumLines - FRow;
1711 }
1712 //
1713 // get correct line
1714 //
1715 Line = HMoveLine (Gap);
1716
1717 //
1718 // if that line, is not that long, so move to the end of that line
1719 //
1720 if (Line != NULL && FCol > Line->Size) {
1721 FCol = Line->Size + 1;
1722 HighBits = TRUE;
1723 }
1724
1725 FRow += Gap;
1726
1727 HBufferImageMovePosition (FRow, FCol, HighBits);
1728
1729 return EFI_SUCCESS;
1730 }
1731
1732 /**
1733 Scroll cursor to previous page
1734
1735 @retval EFI_SUCCESS The operation was successful.
1736 **/
1737 EFI_STATUS
1738 HBufferImagePageUp (
1739 VOID
1740 )
1741 {
1742 HEFI_EDITOR_LINE *Line;
1743 UINTN FRow;
1744 UINTN FCol;
1745 UINTN Gap;
1746 INTN Retreat;
1747
1748 Line = HBufferImage.CurrentLine;
1749
1750 FRow = HBufferImage.BufferPosition.Row;
1751 FCol = HBufferImage.BufferPosition.Column;
1752
1753 //
1754 // has previous page
1755 //
1756 if (FRow > (HMainEditor.ScreenSize.Row - 5)) {
1757 Gap = (HMainEditor.ScreenSize.Row - 5);
1758 } else {
1759 //
1760 // the first line of file will displayed on the first line of screen
1761 //
1762 Gap = FRow - 1;
1763 }
1764
1765 Retreat = Gap;
1766 Retreat = -Retreat;
1767
1768 //
1769 // get correct line
1770 //
1771 Line = HMoveLine (Retreat);
1772
1773 FRow -= Gap;
1774
1775 HBufferImageMovePosition (FRow, FCol, HBufferImage.HighBits);
1776
1777 return EFI_SUCCESS;
1778 }
1779
1780 /**
1781 Scroll cursor to start of line
1782
1783 @retval EFI_SUCCESS The operation was successful.
1784 **/
1785 EFI_STATUS
1786 HBufferImageHome (
1787 VOID
1788 )
1789 {
1790 HEFI_EDITOR_LINE *Line;
1791 UINTN FRow;
1792 UINTN FCol;
1793 BOOLEAN HighBits;
1794
1795 Line = HBufferImage.CurrentLine;
1796
1797 //
1798 // curosr will at the high bit
1799 //
1800 FRow = HBufferImage.BufferPosition.Row;
1801 FCol = 1;
1802 HighBits = TRUE;
1803
1804 //
1805 // move cursor position
1806 //
1807 HBufferImageMovePosition (FRow, FCol, HighBits);
1808
1809 return EFI_SUCCESS;
1810 }
1811
1812 /**
1813 Scroll cursor to end of line.
1814
1815 @retval EFI_SUCCESS Teh operation was successful.
1816 **/
1817 EFI_STATUS
1818 HBufferImageEnd (
1819 VOID
1820 )
1821 {
1822 HEFI_EDITOR_LINE *Line;
1823 UINTN FRow;
1824 UINTN FCol;
1825 BOOLEAN HighBits;
1826
1827 //
1828 // need refresh mouse
1829 //
1830 HBufferImageMouseNeedRefresh = TRUE;
1831
1832 Line = HBufferImage.CurrentLine;
1833
1834 FRow = HBufferImage.BufferPosition.Row;
1835
1836 if (Line->Size == 0x10) {
1837 FCol = Line->Size;
1838 HighBits = FALSE;
1839 } else {
1840 FCol = Line->Size + 1;
1841 HighBits = TRUE;
1842 }
1843 //
1844 // move cursor position
1845 //
1846 HBufferImageMovePosition (FRow, FCol, HighBits);
1847
1848 return EFI_SUCCESS;
1849 }
1850
1851 /**
1852 Get the size of the open buffer.
1853
1854 @retval The size in bytes.
1855 **/
1856 UINTN
1857 HBufferImageGetTotalSize (
1858 VOID
1859 )
1860 {
1861 UINTN Size;
1862
1863 HEFI_EDITOR_LINE *Line;
1864
1865 //
1866 // calculate the total size of whole line list's buffer
1867 //
1868 if (HBufferImage.Lines == NULL) {
1869 return 0;
1870 }
1871
1872 Line = CR (
1873 HBufferImage.ListHead->BackLink,
1874 HEFI_EDITOR_LINE,
1875 Link,
1876 EFI_EDITOR_LINE_LIST
1877 );
1878 //
1879 // one line at most 0x10
1880 //
1881 Size = 0x10 * (HBufferImage.NumLines - 1) + Line->Size;
1882
1883 return Size;
1884 }
1885
1886 /**
1887 Delete character from buffer.
1888
1889 @param[in] Pos Position, Pos starting from 0.
1890 @param[in] Count The Count of characters to delete.
1891 @param[out] DeleteBuffer The DeleteBuffer.
1892
1893 @retval EFI_SUCCESS Success
1894 **/
1895 EFI_STATUS
1896 HBufferImageDeleteCharacterFromBuffer (
1897 IN UINTN Pos,
1898 IN UINTN Count,
1899 OUT UINT8 *DeleteBuffer
1900 )
1901 {
1902 UINTN Index;
1903
1904 VOID *Buffer;
1905 UINT8 *BufferPtr;
1906 UINTN Size;
1907
1908 HEFI_EDITOR_LINE *Line;
1909 LIST_ENTRY *Link;
1910 UINTN StartRow;
1911
1912 UINTN OldFCol;
1913 UINTN OldFRow;
1914 UINTN OldPos;
1915
1916 UINTN NewPos;
1917
1918 EFI_STATUS Status;
1919
1920 //
1921 // get the line that start position is at
1922 //
1923 StartRow = Pos / 0x10;
1924
1925 Size = HBufferImageGetTotalSize ();
1926
1927 if (Size < Count) {
1928 return EFI_LOAD_ERROR;
1929 }
1930
1931 if (Size == 0) {
1932 return EFI_SUCCESS;
1933 }
1934
1935 //
1936 // relocate all the HBufferImage fields
1937 //
1938 OldFRow = HBufferImage.BufferPosition.Row;
1939 OldFCol = HBufferImage.BufferPosition.Column;
1940 OldPos = (OldFRow - 1) * 0x10 + OldFCol - 1;
1941
1942 if (Pos > 0) {
1943 //
1944 // has character before it,
1945 // so locate according to block's previous character
1946 //
1947 NewPos = Pos - 1;
1948
1949 } else {
1950 //
1951 // has no character before it,
1952 // so locate according to block's next character
1953 //
1954 NewPos = 0;
1955 }
1956
1957 HBufferImageMovePosition (NewPos / 0x10 + 1, NewPos % 0x10 + 1, TRUE);
1958
1959 Buffer = AllocateZeroPool (Size);
1960 if (Buffer == NULL) {
1961 return EFI_OUT_OF_RESOURCES;
1962 }
1963
1964 HBufferImageListToBuffer (Buffer, Size);
1965
1966 BufferPtr = (UINT8 *) Buffer;
1967
1968 //
1969 // pass deleted buffer out
1970 //
1971 if (DeleteBuffer != NULL) {
1972 for (Index = 0; Index < Count; Index++) {
1973 DeleteBuffer[Index] = BufferPtr[Pos + Index];
1974 }
1975 }
1976 //
1977 // delete the part from Pos
1978 //
1979 for (Index = Pos; Index < Size - Count; Index++) {
1980 BufferPtr[Index] = BufferPtr[Index + Count];
1981 }
1982
1983 Size -= Count;
1984
1985 HBufferImageFreeLines ();
1986
1987 Status = HBufferImageBufferToList (Buffer, Size);
1988 FreePool (Buffer);
1989
1990 if (EFI_ERROR (Status)) {
1991 return Status;
1992 }
1993
1994 Link = HMainEditor.BufferImage->ListHead->ForwardLink;
1995 for (Index = 0; Index < NewPos / 0x10; Index++) {
1996 Link = Link->ForwardLink;
1997 }
1998
1999 Line = CR (Link, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST);
2000 HBufferImage.CurrentLine = Line;
2001
2002 //
2003 // if current cursor position if inside select area
2004 // then move it to the block's NEXT character
2005 //
2006 if (OldPos >= Pos && OldPos < (Pos + Count)) {
2007 NewPos = Pos;
2008 } else {
2009 if (OldPos < Pos) {
2010 NewPos = OldPos;
2011 } else {
2012 NewPos = OldPos - Count;
2013 }
2014 }
2015
2016 HBufferImageMovePosition (NewPos / 0x10 + 1, NewPos % 0x10 + 1, TRUE);
2017
2018 return EFI_SUCCESS;
2019 }
2020
2021 /**
2022 Add character to buffer, add before pos.
2023
2024 @param[in] Pos Position, Pos starting from 0.
2025 @param[in] Count Count of characters to add.
2026 @param[in] AddBuffer Add buffer.
2027
2028 @retval EFI_SUCCESS Success.
2029 **/
2030 EFI_STATUS
2031 HBufferImageAddCharacterToBuffer (
2032 IN UINTN Pos,
2033 IN UINTN Count,
2034 IN UINT8 *AddBuffer
2035 )
2036 {
2037 INTN Index;
2038
2039 VOID *Buffer;
2040 UINT8 *BufferPtr;
2041 UINTN Size;
2042
2043 HEFI_EDITOR_LINE *Line;
2044
2045 LIST_ENTRY *Link;
2046 UINTN StartRow;
2047
2048 UINTN OldFCol;
2049 UINTN OldFRow;
2050 UINTN OldPos;
2051
2052 UINTN NewPos;
2053
2054 //
2055 // get the line that start position is at
2056 //
2057 StartRow = Pos / 0x10;
2058
2059 Size = HBufferImageGetTotalSize ();
2060
2061 //
2062 // relocate all the HBufferImage fields
2063 //
2064 OldFRow = HBufferImage.BufferPosition.Row;
2065 OldFCol = HBufferImage.BufferPosition.Column;
2066 OldPos = (OldFRow - 1) * 0x10 + OldFCol - 1;
2067
2068 //
2069 // move cursor before Pos
2070 //
2071 if (Pos > 0) {
2072 NewPos = Pos - 1;
2073 } else {
2074 NewPos = 0;
2075 }
2076
2077 HBufferImageMovePosition (NewPos / 0x10 + 1, NewPos % 0x10 + 1, TRUE);
2078
2079 Buffer = AllocateZeroPool (Size + Count);
2080 if (Buffer == NULL) {
2081 return EFI_OUT_OF_RESOURCES;
2082 }
2083
2084 HBufferImageListToBuffer (Buffer, Size);
2085
2086 BufferPtr = (UINT8 *) Buffer;
2087
2088 //
2089 // get a place to add
2090 //
2091 for (Index = (INTN) (Size + Count - 1); Index >= (INTN) Pos; Index--) {
2092 BufferPtr[Index] = BufferPtr[Index - Count];
2093 }
2094 //
2095 // add the buffer
2096 //
2097 for (Index = (INTN) 0; Index < (INTN) Count; Index++) {
2098 BufferPtr[Index + Pos] = AddBuffer[Index];
2099 }
2100
2101 Size += Count;
2102
2103 HBufferImageFreeLines ();
2104
2105 HBufferImageBufferToList (Buffer, Size);
2106
2107 FreePool (Buffer);
2108
2109 Link = HMainEditor.BufferImage->ListHead->ForwardLink;
2110 for (Index = 0; Index < (INTN) NewPos / 0x10; Index++) {
2111 Link = Link->ForwardLink;
2112 }
2113
2114 Line = CR (Link, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST);
2115 HBufferImage.CurrentLine = Line;
2116
2117 if (OldPos >= Pos) {
2118 NewPos = OldPos + Count;
2119 } else {
2120 NewPos = OldPos;
2121 }
2122
2123 HBufferImageMovePosition (NewPos / 0x10 + 1, NewPos % 0x10 + 1, TRUE);
2124
2125 return EFI_SUCCESS;
2126 }
2127
2128 /**
2129 Delete current character from line.
2130
2131 @retval EFI_SUCCESS The operationw as successful.
2132 **/
2133 EFI_STATUS
2134 EFIAPI
2135 HBufferImageDoDelete (
2136 VOID
2137 )
2138 {
2139
2140 HEFI_EDITOR_LINE *Line;
2141
2142 BOOLEAN LastLine;
2143 UINTN FileColumn;
2144 UINTN FPos;
2145
2146 FPos = (HBufferImage.BufferPosition.Row - 1) * 0x10 + HBufferImage.BufferPosition.Column - 1;
2147
2148 FileColumn = HBufferImage.BufferPosition.Column;
2149
2150 Line = HBufferImage.CurrentLine;
2151
2152 //
2153 // if beyond the last character
2154 //
2155 if (FileColumn > Line->Size) {
2156 return EFI_SUCCESS;
2157 }
2158
2159 LastLine = FALSE;
2160 if (Line->Link.ForwardLink == HBufferImage.ListHead) {
2161 LastLine = TRUE;
2162 }
2163
2164 HBufferImageDeleteCharacterFromBuffer (FPos, 1, NULL);
2165
2166 //
2167 // if is the last line
2168 // then only this line need to be refreshed
2169 //
2170 if (LastLine) {
2171 HBufferImageNeedRefresh = FALSE;
2172 HBufferImageOnlyLineNeedRefresh = TRUE;
2173 } else {
2174 HBufferImageNeedRefresh = TRUE;
2175 HBufferImageOnlyLineNeedRefresh = FALSE;
2176 }
2177
2178 if (!HBufferImage.Modified) {
2179 HBufferImage.Modified = TRUE;
2180 }
2181
2182 return EFI_SUCCESS;
2183 }
2184
2185 /**
2186 Change the raw buffer to a list of lines for the UI.
2187
2188 @param[in] Buffer The pointer to the buffer to fill.
2189 @param[in] Bytes The size of the buffer in bytes.
2190
2191 @retval EFI_SUCCESS The operation was successful.
2192 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
2193 **/
2194 EFI_STATUS
2195 EFIAPI
2196 HBufferImageBufferToList (
2197 IN VOID *Buffer,
2198 IN UINTN Bytes
2199 )
2200 {
2201 UINTN TempI;
2202 UINTN TempJ;
2203 UINTN Left;
2204 HEFI_EDITOR_LINE *Line;
2205 UINT8 *BufferPtr;
2206
2207 TempI = 0;
2208 Left = 0;
2209 BufferPtr = (UINT8 *) Buffer;
2210
2211 //
2212 // parse file content line by line
2213 //
2214 while (TempI < Bytes) {
2215 if (Bytes - TempI >= 0x10) {
2216 Left = 0x10;
2217 } else {
2218 Left = Bytes - TempI;
2219 }
2220
2221 //
2222 // allocate a new line
2223 //
2224 Line = HBufferImageCreateLine ();
2225 if (Line == NULL) {
2226 return EFI_OUT_OF_RESOURCES;
2227 }
2228
2229 Line->Size = Left;
2230
2231 for (TempJ = 0; TempJ < Left; TempJ++) {
2232 Line->Buffer[TempJ] = BufferPtr[TempI];
2233 TempI++;
2234 }
2235
2236 }
2237
2238 //
2239 // last line is a full line, SO create a new line
2240 //
2241 if (Left == 0x10 || Bytes == 0) {
2242 Line = HBufferImageCreateLine ();
2243 if (Line == NULL) {
2244 return EFI_OUT_OF_RESOURCES;
2245 }
2246 }
2247
2248 return EFI_SUCCESS;
2249 }
2250
2251 /**
2252 Change the list of lines from the UI to a raw buffer.
2253
2254 @param[in] Buffer The pointer to the buffer to fill.
2255 @param[in] Bytes The size of the buffer in bytes.
2256
2257 @retval EFI_SUCCESS The operation was successful.
2258 **/
2259 EFI_STATUS
2260 EFIAPI
2261 HBufferImageListToBuffer (
2262 IN VOID *Buffer,
2263 IN UINTN Bytes
2264 )
2265 {
2266 UINTN Count;
2267 UINTN Index;
2268 HEFI_EDITOR_LINE *Line;
2269 LIST_ENTRY *Link;
2270 UINT8 *BufferPtr;
2271
2272 //
2273 // change the line list to a large buffer
2274 //
2275 if (HBufferImage.Lines == NULL) {
2276 return EFI_SUCCESS;
2277 }
2278
2279 Link = &HBufferImage.Lines->Link;
2280 Count = 0;
2281 BufferPtr = (UINT8 *) Buffer;
2282
2283 //
2284 // deal line by line
2285 //
2286 while (Link != HBufferImage.ListHead) {
2287
2288 Line = CR (Link, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST);
2289
2290 //@todo shouldn't this be an error???
2291 if (Count + Line->Size > Bytes) {
2292 return EFI_SUCCESS;
2293 }
2294
2295 for (Index = 0; Index < Line->Size; Index++) {
2296 BufferPtr[Index] = Line->Buffer[Index];
2297 }
2298
2299 Count += Line->Size;
2300 BufferPtr += Line->Size;
2301
2302 Link = Link->ForwardLink;
2303 }
2304
2305 return EFI_SUCCESS;
2306 }
2307
2308 /**
2309 Move the mouse in the image buffer.
2310
2311 @param[in] TextX The x-coordinate.
2312 @param[in] TextY The y-coordinate.
2313 **/
2314 VOID
2315 EFIAPI
2316 HBufferImageAdjustMousePosition (
2317 IN INT32 TextX,
2318 IN INT32 TextY
2319 )
2320 {
2321 UINTN TempX;
2322 UINTN TempY;
2323 UINTN AbsX;
2324 UINTN AbsY;
2325
2326 //
2327 // TextX and TextY is mouse movement data returned by mouse driver
2328 // This function will change it to MousePosition
2329 //
2330 //
2331 // get absolute TempX value
2332 //
2333 if (TextX >= 0) {
2334 AbsX = TextX;
2335 } else {
2336 AbsX = -TextX;
2337 }
2338 //
2339 // get absolute TempY value
2340 //
2341 if (TextY >= 0) {
2342 AbsY = TextY;
2343 } else {
2344 AbsY = -TextY;
2345 }
2346
2347 TempX = HBufferImage.MousePosition.Column;
2348 TempY = HBufferImage.MousePosition.Row;
2349
2350 if (TextX >= 0) {
2351 TempX += TextX;
2352 } else {
2353 if (TempX >= AbsX) {
2354 TempX -= AbsX;
2355 } else {
2356 TempX = 0;
2357 }
2358 }
2359
2360 if (TextY >= 0) {
2361 TempY += TextY;
2362 } else {
2363 if (TempY >= AbsY) {
2364 TempY -= AbsY;
2365 } else {
2366 TempY = 0;
2367 }
2368 }
2369 //
2370 // check whether new mouse column position is beyond screen
2371 // if not, adjust it
2372 //
2373 if (TempX >= 10 && TempX <= (10 + 0x10 * 3 - 1)) {
2374 HBufferImage.MousePosition.Column = TempX;
2375 } else if (TempX < 10) {
2376 HBufferImage.MousePosition.Column = 10;
2377 } else if (TempX > (10 + 0x10 * 3 - 1)) {
2378 HBufferImage.MousePosition.Column = 10 + 0x10 * 3 - 1;
2379 }
2380 //
2381 // check whether new mouse row position is beyond screen
2382 // if not, adjust it
2383 //
2384 if (TempY >= 2 && TempY <= (HMainEditor.ScreenSize.Row - 4)) {
2385 HBufferImage.MousePosition.Row = TempY;
2386 } else if (TempY < 2) {
2387 HBufferImage.MousePosition.Row = 2;
2388 } else if (TempY > (HMainEditor.ScreenSize.Row - 4)) {
2389 HBufferImage.MousePosition.Row = (HMainEditor.ScreenSize.Row - 4);
2390 }
2391
2392 }
2393
2394 /**
2395 Dispatch input to different handler
2396
2397 @param[in] Key The input key:
2398 the keys can be:
2399 ASCII KEY
2400 Backspace/Delete
2401 Direction key: up/down/left/right/pgup/pgdn
2402 Home/End
2403 INS
2404
2405 @retval EFI_SUCCESS The operation was successful.
2406 @retval EFI_LOAD_ERROR A load error occured.
2407 @retval EFI_OUT_OF_RESOURCES A Memory allocation failed.
2408 **/
2409 EFI_STATUS
2410 HBufferImageHandleInput (
2411 IN EFI_INPUT_KEY *Key
2412 )
2413 {
2414 EFI_STATUS Status;
2415
2416 Status = EFI_SUCCESS;
2417
2418 switch (Key->ScanCode) {
2419 //
2420 // ordinary key
2421 //
2422 case SCAN_NULL:
2423 Status = HBufferImageDoCharInput (Key->UnicodeChar);
2424 break;
2425
2426 //
2427 // up arrow
2428 //
2429 case SCAN_UP:
2430 Status = HBufferImageScrollUp ();
2431 break;
2432
2433 //
2434 // down arrow
2435 //
2436 case SCAN_DOWN:
2437 Status = HBufferImageScrollDown ();
2438 break;
2439
2440 //
2441 // right arrow
2442 //
2443 case SCAN_RIGHT:
2444 Status = HBufferImageScrollRight ();
2445 break;
2446
2447 //
2448 // left arrow
2449 //
2450 case SCAN_LEFT:
2451 Status = HBufferImageScrollLeft ();
2452 break;
2453
2454 //
2455 // page up
2456 //
2457 case SCAN_PAGE_UP:
2458 Status = HBufferImagePageUp ();
2459 break;
2460
2461 //
2462 // page down
2463 //
2464 case SCAN_PAGE_DOWN:
2465 Status = HBufferImagePageDown ();
2466 break;
2467
2468 //
2469 // delete
2470 //
2471 case SCAN_DELETE:
2472 Status = HBufferImageDoDelete ();
2473 break;
2474
2475 //
2476 // home
2477 //
2478 case SCAN_HOME:
2479 Status = HBufferImageHome ();
2480 break;
2481
2482 //
2483 // end
2484 //
2485 case SCAN_END:
2486 Status = HBufferImageEnd ();
2487 break;
2488
2489 default:
2490 Status = StatusBarSetStatusString (L"Unknown Command");
2491 break;
2492 }
2493
2494 return Status;
2495 }
2496