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