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