]> git.proxmox.com Git - mirror_edk2.git/blame - ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/BufferImage.c
pointer verification (not NULL) and buffer overrun fixes.
[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
33c031ee 640 if (Line == NULL || FColumn > Line->Size) {\r
632820d1 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
980d554e 957 HBufferImage.BufferType = BufferType;\r
632820d1 958\r
959 //\r
960 // three types of buffer supported\r
961 // file buffer\r
962 // disk buffer\r
963 // memory buffer\r
964 //\r
965 BufferTypeBackup = HBufferImage.BufferType;\r
966\r
967 switch (BufferType) {\r
968 case FileTypeFileBuffer:\r
969 Status = HFileImageRead (FileName, Recover);\r
970 break;\r
971\r
972 case FileTypeDiskBuffer:\r
973 Status = HDiskImageRead (DiskName, DiskOffset, DiskSize, Recover);\r
974 break;\r
975\r
976 case FileTypeMemBuffer:\r
977 Status = HMemImageRead (MemOffset, MemSize, Recover);\r
978 break;\r
979 }\r
980\r
981 if (EFI_ERROR (Status)) {\r
982 HBufferImage.BufferType = BufferTypeBackup;\r
983 }\r
984\r
985 return Status;\r
986}\r
987\r
988EFI_STATUS\r
989HBufferImageSave (\r
990 IN CHAR16 *FileName,\r
991 IN CHAR16 *DiskName,\r
992 IN UINTN DiskOffset,\r
993 IN UINTN DiskSize,\r
994 IN UINTN MemOffset,\r
995 IN UINTN MemSize,\r
996 IN EDIT_FILE_TYPE BufferType\r
997 )\r
998{\r
999 EFI_STATUS Status;\r
1000 EDIT_FILE_TYPE BufferTypeBackup;\r
1001\r
1002 //\r
1003 // variable initialization\r
1004 //\r
1005 Status = EFI_SUCCESS;\r
1006 BufferTypeBackup = HBufferImage.BufferType;\r
1007\r
1008 switch (HBufferImage.BufferType) {\r
1009 //\r
1010 // file buffer\r
1011 //\r
1012 case FileTypeFileBuffer:\r
1013 Status = HFileImageSave (FileName);\r
1014 break;\r
1015\r
1016 //\r
1017 // disk buffer\r
1018 //\r
1019 case FileTypeDiskBuffer:\r
1020 Status = HDiskImageSave (DiskName, DiskOffset, DiskSize);\r
1021 break;\r
1022\r
1023 //\r
1024 // memory buffer\r
1025 //\r
1026 case FileTypeMemBuffer:\r
1027 Status = HMemImageSave (MemOffset, MemSize);\r
1028 break;\r
1029 }\r
1030\r
1031 if (EFI_ERROR (Status)) {\r
1032 HBufferImage.BufferType = BufferTypeBackup;\r
1033 }\r
1034\r
1035 return Status;\r
1036}\r
1037\r
1038HEFI_EDITOR_LINE *\r
1039HBufferImageCreateLine (\r
1040 VOID\r
1041 )\r
1042/*++\r
1043\r
1044Routine Description: \r
1045\r
1046 Create a new line and append it to the line list\r
1047 Fields affected:\r
1048 NumLines\r
1049 Lines \r
1050\r
1051Arguments: \r
1052\r
1053 None\r
1054\r
1055Returns: \r
1056\r
1057 NULL -- create line failed\r
1058 Not NULL -- the line created\r
1059\r
1060--*/\r
1061{\r
1062 HEFI_EDITOR_LINE *Line;\r
1063\r
1064 //\r
1065 // allocate for line structure\r
1066 //\r
1067 Line = AllocateZeroPool (sizeof (HEFI_EDITOR_LINE));\r
1068 if (Line == NULL) {\r
1069 return NULL;\r
1070 }\r
1071\r
1072 Line->Signature = EFI_EDITOR_LINE_LIST;\r
1073 Line->Size = 0;\r
1074\r
1075 HBufferImage.NumLines++;\r
1076\r
1077 //\r
1078 // insert to line list\r
1079 //\r
1080 InsertTailList (HBufferImage.ListHead, &Line->Link);\r
1081\r
1082 if (HBufferImage.Lines == NULL) {\r
1083 HBufferImage.Lines = CR (\r
1084 HBufferImage.ListHead->ForwardLink,\r
1085 HEFI_EDITOR_LINE,\r
1086 Link,\r
1087 EFI_EDITOR_LINE_LIST\r
1088 );\r
1089 }\r
1090\r
1091 return Line;\r
1092}\r
1093\r
1094EFI_STATUS\r
1095HBufferImageFree (\r
1096 VOID\r
1097 )\r
1098/*++\r
1099\r
1100Routine Description: \r
1101\r
1102 Function called when load a new file in. It will free all the old lines\r
1103 and set FileModified field to FALSE\r
1104\r
1105Arguments: \r
1106\r
1107 None\r
1108\r
1109Returns: \r
1110\r
1111 EFI_SUCCESS\r
1112\r
1113--*/\r
1114{\r
1115 //\r
1116 // free all lines\r
1117 //\r
1118 HBufferImageFreeLines ();\r
1119\r
1120 return EFI_SUCCESS;\r
1121}\r
1122\r
1123EFI_STATUS\r
1124HBufferImageHandleInput (\r
1125 IN EFI_INPUT_KEY *Key\r
1126 )\r
1127/*++\r
1128\r
1129Routine Description: \r
1130\r
1131 Dispatch input to different handler\r
1132\r
1133Arguments: \r
1134\r
1135 Key -- input key\r
1136 the keys can be:\r
1137 ASCII KEY\r
1138 Backspace/Delete\r
1139 Direction key: up/down/left/right/pgup/pgdn\r
1140 Home/End\r
1141 INS\r
1142\r
1143Returns: \r
1144\r
1145 EFI_SUCCESS\r
1146 EFI_LOAD_ERROR\r
1147 EFI_OUT_OF_RESOURCES\r
1148\r
1149--*/\r
1150{\r
1151 EFI_STATUS Status;\r
1152\r
1153 Status = EFI_SUCCESS;\r
1154\r
1155 switch (Key->ScanCode) {\r
1156 //\r
1157 // ordinary key\r
1158 //\r
1159 case SCAN_NULL:\r
1160 Status = HBufferImageDoCharInput (Key->UnicodeChar);\r
1161 break;\r
1162\r
1163 //\r
1164 // up arrow\r
1165 //\r
1166 case SCAN_UP:\r
1167 Status = HBufferImageScrollUp ();\r
1168 break;\r
1169\r
1170 //\r
1171 // down arrow\r
1172 //\r
1173 case SCAN_DOWN:\r
1174 Status = HBufferImageScrollDown ();\r
1175 break;\r
1176\r
1177 //\r
1178 // right arrow\r
1179 //\r
1180 case SCAN_RIGHT:\r
1181 Status = HBufferImageScrollRight ();\r
1182 break;\r
1183\r
1184 //\r
1185 // left arrow\r
1186 //\r
1187 case SCAN_LEFT:\r
1188 Status = HBufferImageScrollLeft ();\r
1189 break;\r
1190\r
1191 //\r
1192 // page up\r
1193 //\r
1194 case SCAN_PAGE_UP:\r
1195 Status = HBufferImagePageUp ();\r
1196 break;\r
1197\r
1198 //\r
1199 // page down\r
1200 //\r
1201 case SCAN_PAGE_DOWN:\r
1202 Status = HBufferImagePageDown ();\r
1203 break;\r
1204\r
1205 //\r
1206 // delete\r
1207 //\r
1208 case SCAN_DELETE:\r
1209 Status = HBufferImageDoDelete ();\r
1210 break;\r
1211\r
1212 //\r
1213 // home\r
1214 //\r
1215 case SCAN_HOME:\r
1216 Status = HBufferImageHome ();\r
1217 break;\r
1218\r
1219 //\r
1220 // end\r
1221 //\r
1222 case SCAN_END:\r
1223 Status = HBufferImageEnd ();\r
1224 break;\r
1225\r
1226 default:\r
1227 Status = StatusBarSetStatusString (L"Unknown Command");\r
1228 break;\r
1229 }\r
1230\r
1231 return Status;\r
1232}\r
1233\r
1234EFI_STATUS\r
1235HBufferImageDoCharInput (\r
1236 IN CHAR16 Char\r
1237 )\r
1238/*++\r
1239\r
1240Routine Description: \r
1241\r
1242 ASCII key + Backspace + return\r
1243\r
1244Arguments: \r
1245\r
1246 Char -- input char\r
1247\r
1248Returns: \r
1249\r
1250 EFI_SUCCESS\r
1251 EFI_LOAD_ERROR\r
1252 EFI_OUT_OF_RESOURCES\r
1253\r
1254--*/\r
1255{\r
1256 EFI_STATUS Status;\r
1257\r
1258 Status = EFI_SUCCESS;\r
1259\r
1260 switch (Char) {\r
1261 case 0:\r
1262 break;\r
1263\r
1264 case 0x08:\r
1265 Status = HBufferImageDoBackspace ();\r
1266 break;\r
1267\r
1268 case 0x09:\r
1269 case 0x0a:\r
1270 case 0x0d:\r
1271 //\r
1272 // Tabs, Returns are thought as nothing\r
1273 //\r
1274 break;\r
1275\r
1276 default:\r
1277 //\r
1278 // DEAL WITH ASCII CHAR, filter out thing like ctrl+f\r
1279 //\r
1280 if (Char > 127 || Char < 32) {\r
1281 Status = StatusBarSetStatusString (L"Unknown Command");\r
1282 } else {\r
1283 Status = HBufferImageAddChar (Char);\r
1284 }\r
1285\r
1286 break;\r
1287 }\r
1288\r
1289 return Status;\r
1290}\r
1291\r
1292INTN\r
1293HBufferImageCharToHex (\r
1294 IN CHAR16 Char\r
1295 )\r
1296/*++\r
1297\r
1298Routine Description: \r
1299\r
1300 change char to int value based on Hex\r
1301\r
1302Arguments: \r
1303\r
1304 Char -- input char\r
1305\r
1306Returns: \r
1307\r
1308 int value;\r
1309\r
1310\r
1311--*/\r
1312{\r
1313 //\r
1314 // change the character to hex\r
1315 //\r
1316 if (Char >= L'0' && Char <= L'9') {\r
1317 return (INTN) (Char - L'0');\r
1318 }\r
1319\r
1320 if (Char >= L'a' && Char <= L'f') {\r
1321 return (INTN) (Char - L'a' + 10);\r
1322 }\r
1323\r
1324 if (Char >= L'A' && Char <= L'F') {\r
1325 return (INTN) (Char - L'A' + 10);\r
1326 }\r
1327\r
1328 return -1;\r
1329}\r
1330\r
1331EFI_STATUS\r
1332HBufferImageAddChar (\r
1333 IN CHAR16 Char\r
1334 )\r
1335/*++\r
1336\r
1337Routine Description: \r
1338\r
1339 Add character\r
1340\r
1341Arguments: \r
1342\r
1343 Char -- input char\r
1344\r
1345Returns: \r
1346\r
1347 EFI_SUCCESS\r
1348 EFI_OUT_OF_RESOURCES\r
1349\r
1350--*/\r
1351{\r
1352 HEFI_EDITOR_LINE *Line;\r
1353 HEFI_EDITOR_LINE *NewLine;\r
1354 INTN Value;\r
1355 UINT8 Old;\r
1356 UINTN FRow;\r
1357 UINTN FCol;\r
1358 BOOLEAN High;\r
1359\r
1360 Value = HBufferImageCharToHex (Char);\r
1361\r
1362 //\r
1363 // invalid input\r
1364 //\r
1365 if (Value == -1) {\r
1366 return EFI_SUCCESS;\r
1367 }\r
1368\r
1369 Line = HBufferImage.CurrentLine;\r
1370 FRow = HBufferImage.BufferPosition.Row;\r
1371 FCol = HBufferImage.BufferPosition.Column;\r
1372 High = HBufferImage.HighBits;\r
1373\r
1374 //\r
1375 // only needs to refresh current line\r
1376 //\r
1377 HBufferImageOnlyLineNeedRefresh = TRUE;\r
1378\r
1379 //\r
1380 // not a full line and beyond the last character\r
1381 //\r
1382 if (FCol > Line->Size) {\r
1383 //\r
1384 // cursor always at high 4 bits\r
1385 // and always put input to the low 4 bits\r
1386 //\r
1387 Line->Buffer[Line->Size] = (UINT8) Value;\r
1388 Line->Size++;\r
1389 High = FALSE;\r
1390 } else {\r
1391\r
1392 Old = Line->Buffer[FCol - 1];\r
1393\r
1394 //\r
1395 // always put the input to the low 4 bits\r
1396 //\r
1397 Old = (UINT8) (Old & 0x0f);\r
1398 Old = (UINT8) (Old << 4);\r
1399 Old = (UINT8) (Value + Old);\r
1400 Line->Buffer[FCol - 1] = Old;\r
1401\r
1402 //\r
1403 // at the low 4 bits of the last character of a full line\r
1404 // so if no next line, need to create a new line\r
1405 //\r
1406 if (High == FALSE && FCol == 0x10) {\r
1407\r
1408 HBufferImageOnlyLineNeedRefresh = FALSE;\r
1409 HBufferImageNeedRefresh = TRUE;\r
1410\r
1411 if (Line->Link.ForwardLink == HBufferImage.ListHead) {\r
1412 //\r
1413 // last line\r
1414 //\r
1415 // create a new line\r
1416 //\r
1417 NewLine = HBufferImageCreateLine ();\r
1418 if (NewLine == NULL) {\r
1419 return EFI_OUT_OF_RESOURCES;\r
1420 }\r
1421 //\r
1422 // end of NULL\r
1423 //\r
1424 }\r
1425 //\r
1426 // end of == ListHead\r
1427 //\r
1428 }\r
1429 //\r
1430 // end of == 0x10\r
1431 //\r
1432 // if already at end of this line, scroll it to the start of next line\r
1433 //\r
1434 if (FCol == 0x10 && High == FALSE) {\r
1435 //\r
1436 // definitely has next line\r
1437 //\r
1438 FRow++;\r
1439 FCol = 1;\r
1440 High = TRUE;\r
1441 } else {\r
1442 //\r
1443 // if not at end of this line, just move to next column\r
1444 //\r
1445 if (!High) {\r
1446 FCol++;\r
1447 }\r
1448\r
1449 if (High) {\r
1450 High = FALSE;\r
1451 } else {\r
1452 High = TRUE;\r
1453 }\r
1454\r
1455 }\r
1456 //\r
1457 // end of ==FALSE\r
1458 //\r
1459 }\r
1460 //\r
1461 // move cursor to right\r
1462 //\r
1463 HBufferImageMovePosition (FRow, FCol, High);\r
1464\r
1465 if (!HBufferImage.Modified) {\r
1466 HBufferImage.Modified = TRUE;\r
1467 }\r
1468\r
1469 return EFI_SUCCESS;\r
1470}\r
1471\r
1472BOOLEAN\r
1473HInCurrentScreen (\r
1474 IN UINTN FileRow\r
1475 )\r
1476/*++\r
1477\r
1478Routine Description: \r
1479\r
1480 Check user specified FileRow and FileCol is in current screen\r
1481\r
1482Arguments: \r
1483\r
1484 FileRow -- Row of file position ( start from 1 )\r
1485\r
1486\r
1487Returns: \r
1488\r
1489 TRUE\r
1490 FALSE\r
1491\r
1492--*/\r
1493{\r
1494 if (FileRow >= HBufferImage.LowVisibleRow && FileRow <= HBufferImage.LowVisibleRow + (HMainEditor.ScreenSize.Row - 5) - 1) {\r
1495 return TRUE;\r
1496 }\r
1497\r
1498 return FALSE;\r
1499}\r
1500\r
1501BOOLEAN\r
1502HAboveCurrentScreen (\r
1503 IN UINTN FileRow\r
1504 )\r
1505/*++\r
1506\r
1507Routine Description: \r
1508\r
1509 Check user specified FileRow is above current screen\r
1510\r
1511Arguments: \r
1512\r
1513 FileRow -- Row of file position ( start from 1 )\r
1514 \r
1515Returns: \r
1516\r
1517 TRUE\r
1518 FALSE\r
1519\r
1520--*/\r
1521{\r
1522 if (FileRow < HBufferImage.LowVisibleRow) {\r
1523 return TRUE;\r
1524 }\r
1525\r
1526 return FALSE;\r
1527}\r
1528\r
1529BOOLEAN\r
1530HUnderCurrentScreen (\r
1531 IN UINTN FileRow\r
1532 )\r
1533/*++\r
1534\r
1535Routine Description: \r
1536\r
1537 Check user specified FileRow is under current screen\r
1538\r
1539Arguments: \r
1540\r
1541 FileRow -- Row of file position ( start from 1 )\r
1542\r
1543Returns: \r
1544\r
1545 TRUE\r
1546 FALSE\r
1547\r
1548--*/\r
1549{\r
1550 if (FileRow > HBufferImage.LowVisibleRow + (HMainEditor.ScreenSize.Row - 5) - 1) {\r
1551 return TRUE;\r
1552 }\r
1553\r
1554 return FALSE;\r
1555}\r
1556\r
1557VOID\r
1558HBufferImageMovePosition (\r
1559 IN UINTN NewFilePosRow,\r
1560 IN UINTN NewFilePosCol,\r
1561 IN BOOLEAN HighBits\r
1562 )\r
1563/*++\r
1564\r
1565Routine Description: \r
1566\r
1567 According to cursor's file position, adjust screen display\r
1568\r
1569Arguments: \r
1570\r
1571 NewFilePosRow -- Row of file position ( start from 1 )\r
1572 NewFilePosCol -- Column of file position ( start from 1 ) \r
1573 HighBits -- cursor will on high4 bits or low4 bits\r
1574\r
1575Returns: \r
1576\r
1577 None\r
1578\r
1579--*/\r
1580{\r
1581 INTN RowGap;\r
1582 UINTN Abs;\r
1583 BOOLEAN Above;\r
1584 BOOLEAN Under;\r
1585 UINTN NewDisplayCol;\r
1586\r
1587 //\r
1588 // CALCULATE gap between current file position and new file position\r
1589 //\r
1590 RowGap = NewFilePosRow - HBufferImage.BufferPosition.Row;\r
1591\r
1592 Under = HUnderCurrentScreen (NewFilePosRow);\r
1593 Above = HAboveCurrentScreen (NewFilePosRow);\r
1594\r
1595 HBufferImage.HighBits = HighBits;\r
1596\r
1597 //\r
1598 // if is below current screen\r
1599 //\r
1600 if (Under) {\r
1601 //\r
1602 // display row will be unchanged\r
1603 //\r
1604 HBufferImage.BufferPosition.Row = NewFilePosRow;\r
1605 } else {\r
1606 if (Above) {\r
1607 //\r
1608 // has enough above line, so display row unchanged\r
1609 // not has enough above lines, so the first line is\r
1610 // at the first display line\r
1611 //\r
1612 if (NewFilePosRow < (HBufferImage.DisplayPosition.Row - 2 + 1)) {\r
1613 HBufferImage.DisplayPosition.Row = NewFilePosRow + 2 - 1;\r
1614 }\r
1615\r
1616 HBufferImage.BufferPosition.Row = NewFilePosRow;\r
1617 } else {\r
1618 //\r
1619 // in current screen\r
1620 //\r
1621 HBufferImage.BufferPosition.Row = NewFilePosRow;\r
1622 if (RowGap <= 0) {\r
33c031ee 1623 Abs = (UINTN)ABS(RowGap);\r
632820d1 1624 HBufferImage.DisplayPosition.Row -= Abs;\r
1625 } else {\r
1626 HBufferImage.DisplayPosition.Row += RowGap;\r
1627 }\r
1628\r
1629 }\r
1630 }\r
1631\r
1632 HBufferImage.LowVisibleRow = HBufferImage.BufferPosition.Row - (HBufferImage.DisplayPosition.Row - 2);\r
1633\r
1634 //\r
1635 // always in current screen\r
1636 //\r
1637 HBufferImage.BufferPosition.Column = NewFilePosCol;\r
1638\r
1639 NewDisplayCol = 10 + (NewFilePosCol - 1) * 3;\r
1640 if (NewFilePosCol > 0x8) {\r
1641 NewDisplayCol++;\r
1642 }\r
1643\r
1644 if (HighBits == FALSE) {\r
1645 NewDisplayCol++;\r
1646 }\r
1647\r
1648 HBufferImage.DisplayPosition.Column = NewDisplayCol;\r
1649\r
1650 //\r
1651 // let CurrentLine point to correct line;\r
1652 //\r
1653 HBufferImage.CurrentLine = HMoveCurrentLine (RowGap);\r
1654\r
1655}\r
1656\r
1657EFI_STATUS\r
1658HBufferImageScrollRight (\r
1659 VOID\r
1660 )\r
1661/*++\r
1662\r
1663Routine Description: \r
1664\r
1665 Scroll cursor to right\r
1666\r
1667Arguments: \r
1668\r
1669 None\r
1670\r
1671Returns: \r
1672\r
1673 EFI_SUCCESS\r
1674\r
1675--*/\r
1676{\r
1677 HEFI_EDITOR_LINE *Line;\r
1678 UINTN FRow;\r
1679 UINTN FCol;\r
1680\r
1681 //\r
1682 // scroll right will always move to the high4 bits of the next character\r
1683 //\r
1684 HBufferImageNeedRefresh = FALSE;\r
1685 HBufferImageOnlyLineNeedRefresh = FALSE;\r
1686\r
1687 Line = HBufferImage.CurrentLine;\r
1688\r
1689 FRow = HBufferImage.BufferPosition.Row;\r
1690 FCol = HBufferImage.BufferPosition.Column;\r
1691\r
1692 //\r
1693 // this line is not full and no next line\r
1694 //\r
1695 if (FCol > Line->Size) {\r
1696 return EFI_SUCCESS;\r
1697 }\r
1698 //\r
1699 // if already at end of this line, scroll it to the start of next line\r
1700 //\r
1701 if (FCol == 0x10) {\r
1702 //\r
1703 // has next line\r
1704 //\r
1705 if (Line->Link.ForwardLink != HBufferImage.ListHead) {\r
1706 FRow++;\r
1707 FCol = 1;\r
1708\r
1709 } else {\r
1710 return EFI_SUCCESS;\r
1711 }\r
1712 } else {\r
1713 //\r
1714 // if not at end of this line, just move to next column\r
1715 //\r
1716 FCol++;\r
1717\r
1718 }\r
1719\r
1720 HBufferImageMovePosition (FRow, FCol, TRUE);\r
1721\r
1722 return EFI_SUCCESS;\r
1723}\r
1724\r
1725EFI_STATUS\r
1726HBufferImageScrollLeft (\r
1727 VOID\r
1728 )\r
1729/*++\r
1730\r
1731Routine Description: \r
1732\r
1733 Scroll cursor to left\r
1734\r
1735Arguments: \r
1736\r
1737 None\r
1738\r
1739Returns: \r
1740\r
1741 EFI_SUCCESS\r
1742\r
1743--*/\r
1744{\r
1745\r
1746 HEFI_EDITOR_LINE *Line;\r
1747 UINTN FRow;\r
1748 UINTN FCol;\r
1749\r
1750 HBufferImageNeedRefresh = FALSE;\r
1751 HBufferImageOnlyLineNeedRefresh = FALSE;\r
1752\r
1753 Line = HBufferImage.CurrentLine;\r
1754\r
1755 FRow = HBufferImage.BufferPosition.Row;\r
1756 FCol = HBufferImage.BufferPosition.Column;\r
1757\r
1758 //\r
1759 // if already at start of this line, so move to the end of previous line\r
1760 //\r
1761 if (FCol <= 1) {\r
1762 //\r
1763 // has previous line\r
1764 //\r
1765 if (Line->Link.BackLink != HBufferImage.ListHead) {\r
1766 FRow--;\r
1767 Line = CR (Line->Link.BackLink, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST);\r
1768 FCol = Line->Size;\r
1769 } else {\r
1770 return EFI_SUCCESS;\r
1771 }\r
1772 } else {\r
1773 //\r
1774 // if not at start of this line, just move to previous column\r
1775 //\r
1776 FCol--;\r
1777 }\r
1778\r
1779 HBufferImageMovePosition (FRow, FCol, TRUE);\r
1780\r
1781 return EFI_SUCCESS;\r
1782}\r
1783\r
1784EFI_STATUS\r
1785HBufferImageScrollDown (\r
1786 VOID\r
1787 )\r
1788/*++\r
1789\r
1790Routine Description: \r
1791\r
1792 Scroll cursor to the next line\r
1793\r
1794Arguments: \r
1795\r
1796 None\r
1797\r
1798Returns: \r
1799\r
1800 EFI_SUCCESS\r
1801\r
1802--*/\r
1803{\r
1804 HEFI_EDITOR_LINE *Line;\r
1805 UINTN FRow;\r
1806 UINTN FCol;\r
1807 BOOLEAN HighBits;\r
1808\r
1809 Line = HBufferImage.CurrentLine;\r
1810\r
1811 FRow = HBufferImage.BufferPosition.Row;\r
1812 FCol = HBufferImage.BufferPosition.Column;\r
1813 HighBits = HBufferImage.HighBits;\r
1814\r
1815 //\r
1816 // has next line\r
1817 //\r
1818 if (Line->Link.ForwardLink != HBufferImage.ListHead) {\r
1819 FRow++;\r
1820 Line = CR (Line->Link.ForwardLink, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST);\r
1821\r
1822 //\r
1823 // if the next line is not that long, so move to end of next line\r
1824 //\r
1825 if (FCol > Line->Size) {\r
1826 FCol = Line->Size + 1;\r
1827 HighBits = TRUE;\r
1828 }\r
1829\r
1830 } else {\r
1831 return EFI_SUCCESS;\r
1832 }\r
1833\r
1834 HBufferImageMovePosition (FRow, FCol, HighBits);\r
1835\r
1836 return EFI_SUCCESS;\r
1837}\r
1838\r
1839EFI_STATUS\r
1840HBufferImageScrollUp (\r
1841 VOID\r
1842 )\r
1843/*++\r
1844\r
1845Routine Description: \r
1846\r
1847 Scroll cursor to previous line\r
1848\r
1849Arguments: \r
1850\r
1851 None\r
1852\r
1853Returns: \r
1854\r
1855 EFI_SUCCESS\r
1856\r
1857--*/\r
1858{\r
1859 HEFI_EDITOR_LINE *Line;\r
1860 UINTN FRow;\r
1861 UINTN FCol;\r
1862\r
1863 Line = HBufferImage.CurrentLine;\r
1864\r
1865 FRow = HBufferImage.BufferPosition.Row;\r
1866 FCol = HBufferImage.BufferPosition.Column;\r
1867\r
1868 //\r
1869 // has previous line\r
1870 //\r
1871 if (Line->Link.BackLink != HBufferImage.ListHead) {\r
1872 FRow--;\r
1873\r
1874 } else {\r
1875 return EFI_SUCCESS;\r
1876 }\r
1877\r
1878 HBufferImageMovePosition (FRow, FCol, HBufferImage.HighBits);\r
1879\r
1880 return EFI_SUCCESS;\r
1881}\r
1882\r
1883EFI_STATUS\r
1884HBufferImagePageDown (\r
1885 VOID\r
1886 )\r
1887/*++\r
1888\r
1889Routine Description: \r
1890\r
1891 Scroll cursor to next page\r
1892\r
1893Arguments: \r
1894\r
1895 None\r
1896\r
1897Returns: \r
1898\r
1899 EFI_SUCCESS\r
1900\r
1901--*/\r
1902{\r
1903 HEFI_EDITOR_LINE *Line;\r
1904 UINTN FRow;\r
1905 UINTN FCol;\r
1906 UINTN Gap;\r
1907 BOOLEAN HighBits;\r
1908\r
1909 Line = HBufferImage.CurrentLine;\r
1910\r
1911 FRow = HBufferImage.BufferPosition.Row;\r
1912 FCol = HBufferImage.BufferPosition.Column;\r
1913 HighBits = HBufferImage.HighBits;\r
1914\r
1915 //\r
1916 // has next page\r
1917 //\r
1918 if (HBufferImage.NumLines >= FRow + (HMainEditor.ScreenSize.Row - 5)) {\r
1919 Gap = (HMainEditor.ScreenSize.Row - 5);\r
1920 } else {\r
1921 //\r
1922 // MOVE CURSOR TO LAST LINE\r
1923 //\r
1924 Gap = HBufferImage.NumLines - FRow;\r
1925 }\r
1926 //\r
1927 // get correct line\r
1928 //\r
1929 Line = HMoveLine (Gap);\r
1930\r
1931 //\r
1932 // if that line, is not that long, so move to the end of that line\r
1933 //\r
33c031ee 1934 if (Line != NULL && FCol > Line->Size) {\r
632820d1 1935 FCol = Line->Size + 1;\r
1936 HighBits = TRUE;\r
1937 }\r
1938\r
1939 FRow += Gap;\r
1940\r
1941 HBufferImageMovePosition (FRow, FCol, HighBits);\r
1942\r
1943 return EFI_SUCCESS;\r
1944}\r
1945\r
1946EFI_STATUS\r
1947HBufferImagePageUp (\r
1948 VOID\r
1949 )\r
1950/*++\r
1951\r
1952Routine Description: \r
1953\r
1954 Scroll cursor to previous page\r
1955\r
1956Arguments: \r
1957\r
1958 None\r
1959\r
1960Returns: \r
1961\r
1962 EFI_SUCCESS\r
1963\r
1964--*/\r
1965{\r
1966 HEFI_EDITOR_LINE *Line;\r
1967 UINTN FRow;\r
1968 UINTN FCol;\r
1969 UINTN Gap;\r
1970 INTN Retreat;\r
1971\r
1972 Line = HBufferImage.CurrentLine;\r
1973\r
1974 FRow = HBufferImage.BufferPosition.Row;\r
1975 FCol = HBufferImage.BufferPosition.Column;\r
1976\r
1977 //\r
1978 // has previous page\r
1979 //\r
1980 if (FRow > (HMainEditor.ScreenSize.Row - 5)) {\r
1981 Gap = (HMainEditor.ScreenSize.Row - 5);\r
1982 } else {\r
1983 //\r
1984 // the first line of file will displayed on the first line of screen\r
1985 //\r
1986 Gap = FRow - 1;\r
1987 }\r
1988\r
1989 Retreat = Gap;\r
1990 Retreat = -Retreat;\r
1991\r
1992 //\r
1993 // get correct line\r
1994 //\r
1995 Line = HMoveLine (Retreat);\r
1996\r
1997 FRow -= Gap;\r
1998\r
1999 HBufferImageMovePosition (FRow, FCol, HBufferImage.HighBits);\r
2000\r
2001 return EFI_SUCCESS;\r
2002}\r
2003\r
2004EFI_STATUS\r
2005HBufferImageHome (\r
2006 VOID\r
2007 )\r
2008/*++\r
2009\r
2010Routine Description: \r
2011\r
2012 Scroll cursor to start of line\r
2013\r
2014Arguments: \r
2015\r
2016 None\r
2017\r
2018Returns: \r
2019\r
2020 EFI_SUCCESS\r
2021\r
2022--*/\r
2023{\r
2024 HEFI_EDITOR_LINE *Line;\r
2025 UINTN FRow;\r
2026 UINTN FCol;\r
2027 BOOLEAN HighBits;\r
2028\r
2029 Line = HBufferImage.CurrentLine;\r
2030\r
2031 //\r
2032 // curosr will at the high bit\r
2033 //\r
2034 FRow = HBufferImage.BufferPosition.Row;\r
2035 FCol = 1;\r
2036 HighBits = TRUE;\r
2037\r
2038 //\r
2039 // move cursor position\r
2040 //\r
2041 HBufferImageMovePosition (FRow, FCol, HighBits);\r
2042\r
2043 return EFI_SUCCESS;\r
2044}\r
2045\r
2046EFI_STATUS\r
2047HBufferImageEnd (\r
2048 VOID\r
2049 )\r
2050/*++\r
2051\r
2052Routine Description: \r
2053\r
2054 Scroll cursor to end of line\r
2055\r
2056Arguments: \r
2057\r
2058 None\r
2059\r
2060Returns: \r
2061\r
2062 EFI_SUCCESS\r
2063\r
2064--*/\r
2065{\r
2066 HEFI_EDITOR_LINE *Line;\r
2067 UINTN FRow;\r
2068 UINTN FCol;\r
2069 BOOLEAN HighBits;\r
2070\r
2071 //\r
2072 // need refresh mouse\r
2073 //\r
2074 HBufferImageMouseNeedRefresh = TRUE;\r
2075\r
2076 Line = HBufferImage.CurrentLine;\r
2077\r
2078 FRow = HBufferImage.BufferPosition.Row;\r
2079\r
2080 if (Line->Size == 0x10) {\r
2081 FCol = Line->Size;\r
2082 HighBits = FALSE;\r
2083 } else {\r
2084 FCol = Line->Size + 1;\r
2085 HighBits = TRUE;\r
2086 }\r
2087 //\r
2088 // move cursor position\r
2089 //\r
2090 HBufferImageMovePosition (FRow, FCol, HighBits);\r
2091\r
2092 return EFI_SUCCESS;\r
2093}\r
2094\r
2095UINTN\r
2096HBufferImageGetTotalSize (\r
2097 VOID\r
2098 )\r
2099{\r
2100 UINTN Size;\r
2101\r
2102 HEFI_EDITOR_LINE *Line;\r
2103\r
2104 //\r
2105 // calculate the total size of whole line list's buffer\r
2106 //\r
2107 if (HBufferImage.Lines == NULL) {\r
2108 return 0;\r
2109 }\r
2110\r
2111 Line = CR (\r
2112 HBufferImage.ListHead->BackLink,\r
2113 HEFI_EDITOR_LINE,\r
2114 Link,\r
2115 EFI_EDITOR_LINE_LIST\r
2116 );\r
2117 //\r
2118 // one line at most 0x10\r
2119 //\r
2120 Size = 0x10 * (HBufferImage.NumLines - 1) + Line->Size;\r
2121\r
2122 return Size;\r
2123}\r
2124\r
2125EFI_STATUS\r
2126HBufferImageDeleteCharacterFromBuffer (\r
2127 IN UINTN Pos,\r
2128 IN UINTN Count,\r
2129 OUT UINT8 *DeleteBuffer\r
2130 )\r
2131/*++\r
2132Routine Description:\r
2133\r
2134 Delete character from buffer\r
2135 \r
2136Arguments:\r
2137\r
2138 Pos - Position, Pos starting from 0\r
2139 Count - Count\r
2140 DeleteBuffer - DeleteBuffer\r
2141\r
2142Returns:\r
2143\r
2144 EFI_SUCCESS Success\r
2145 \r
2146--*/\r
2147{\r
2148 UINTN Index;\r
2149\r
2150 VOID *Buffer;\r
2151 UINT8 *BufferPtr;\r
2152 UINTN Size;\r
2153\r
2154 HEFI_EDITOR_LINE *Line;\r
2155 LIST_ENTRY *Link;\r
2156 UINTN StartRow;\r
2157\r
2158 UINTN OldFCol;\r
2159 UINTN OldFRow;\r
2160 UINTN OldPos;\r
2161\r
2162 UINTN NewPos;\r
2163\r
2164 EFI_STATUS Status;\r
2165\r
2166 //\r
2167 // get the line that start position is at\r
2168 //\r
2169 StartRow = Pos / 0x10;\r
2170\r
2171 Size = HBufferImageGetTotalSize ();\r
2172\r
2173 if (Size < Count) {\r
2174 return EFI_LOAD_ERROR;\r
2175 }\r
2176\r
2177 if (Size == 0) {\r
2178 return EFI_SUCCESS;\r
2179 }\r
2180\r
2181 //\r
2182 // relocate all the HBufferImage fields\r
2183 //\r
2184 OldFRow = HBufferImage.BufferPosition.Row;\r
2185 OldFCol = HBufferImage.BufferPosition.Column;\r
2186 OldPos = (OldFRow - 1) * 0x10 + OldFCol - 1;\r
2187\r
2188 if (Pos > 0) {\r
2189 //\r
2190 // has character before it,\r
2191 // so locate according to block's previous character\r
2192 //\r
2193 NewPos = Pos - 1;\r
2194\r
2195 } else {\r
2196 //\r
2197 // has no character before it,\r
2198 // so locate according to block's next character\r
2199 //\r
2200 NewPos = 0;\r
2201 }\r
2202\r
2203 HBufferImageMovePosition (NewPos / 0x10 + 1, NewPos % 0x10 + 1, TRUE);\r
2204\r
2205 Buffer = AllocateZeroPool (Size);\r
2206 if (Buffer == NULL) {\r
2207 return EFI_OUT_OF_RESOURCES;\r
2208 }\r
2209\r
2210 HBufferImageListToBuffer (Buffer, Size);\r
2211\r
2212 BufferPtr = (UINT8 *) Buffer;\r
2213\r
2214 //\r
2215 // pass deleted buffer out\r
2216 //\r
2217 if (DeleteBuffer != NULL) {\r
2218 for (Index = 0; Index < Count; Index++) {\r
2219 DeleteBuffer[Index] = BufferPtr[Pos + Index];\r
2220 }\r
2221 }\r
2222 //\r
2223 // delete the part from Pos\r
2224 //\r
2225 for (Index = Pos; Index < Size - Count; Index++) {\r
2226 BufferPtr[Index] = BufferPtr[Index + Count];\r
2227 }\r
2228\r
2229 Size -= Count;\r
2230\r
2231 HBufferImageFreeLines ();\r
2232\r
2233 Status = HBufferImageBufferToList (Buffer, Size);\r
2234 FreePool (Buffer);\r
2235\r
2236 if (EFI_ERROR (Status)) {\r
2237 return Status;\r
2238 }\r
2239\r
2240 Link = HMainEditor.BufferImage->ListHead->ForwardLink;\r
2241 for (Index = 0; Index < NewPos / 0x10; Index++) {\r
2242 Link = Link->ForwardLink;\r
2243 }\r
2244\r
2245 Line = CR (Link, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST);\r
2246 HBufferImage.CurrentLine = Line;\r
2247\r
2248 //\r
2249 // if current cursor position if inside select area\r
2250 // then move it to the block's NEXT character\r
2251 //\r
2252 if (OldPos >= Pos && OldPos < (Pos + Count)) {\r
2253 NewPos = Pos;\r
2254 } else {\r
2255 if (OldPos < Pos) {\r
2256 NewPos = OldPos;\r
2257 } else {\r
2258 NewPos = OldPos - Count;\r
2259 }\r
2260 }\r
2261\r
2262 HBufferImageMovePosition (NewPos / 0x10 + 1, NewPos % 0x10 + 1, TRUE);\r
2263\r
2264 return EFI_SUCCESS;\r
2265}\r
2266\r
2267EFI_STATUS\r
2268HBufferImageAddCharacterToBuffer (\r
2269 IN UINTN Pos,\r
2270 IN UINTN Count,\r
2271 IN UINT8 *AddBuffer\r
2272 )\r
2273/*++'\r
2274Routine Description:\r
2275\r
2276 Add character to buffer, add before pos\r
2277\r
2278Arguments:\r
2279\r
2280 Pos - Position, Pos starting from 0\r
2281 Count - Count\r
2282 AddBuffer - Add buffer\r
2283\r
2284Returns:\r
2285\r
2286 EFI_SUCCESS Success\r
2287 \r
2288--*/\r
2289{\r
2290 INTN Index;\r
2291\r
2292 VOID *Buffer;\r
2293 UINT8 *BufferPtr;\r
2294 UINTN Size;\r
2295\r
2296 HEFI_EDITOR_LINE *Line;\r
2297\r
2298 LIST_ENTRY *Link;\r
2299 UINTN StartRow;\r
2300\r
2301 UINTN OldFCol;\r
2302 UINTN OldFRow;\r
2303 UINTN OldPos;\r
2304\r
2305 UINTN NewPos;\r
2306\r
2307 //\r
2308 // get the line that start position is at\r
2309 //\r
2310 StartRow = Pos / 0x10;\r
2311\r
2312 Size = HBufferImageGetTotalSize ();\r
2313\r
2314 //\r
2315 // relocate all the HBufferImage fields\r
2316 //\r
2317 OldFRow = HBufferImage.BufferPosition.Row;\r
2318 OldFCol = HBufferImage.BufferPosition.Column;\r
2319 OldPos = (OldFRow - 1) * 0x10 + OldFCol - 1;\r
2320\r
2321 //\r
2322 // move cursor before Pos\r
2323 //\r
2324 if (Pos > 0) {\r
2325 NewPos = Pos - 1;\r
2326 } else {\r
2327 NewPos = 0;\r
2328 }\r
2329\r
2330 HBufferImageMovePosition (NewPos / 0x10 + 1, NewPos % 0x10 + 1, TRUE);\r
2331\r
2332 Buffer = AllocateZeroPool (Size + Count);\r
2333 if (Buffer == NULL) {\r
2334 return EFI_OUT_OF_RESOURCES;\r
2335 }\r
2336\r
2337 HBufferImageListToBuffer (Buffer, Size);\r
2338\r
2339 BufferPtr = (UINT8 *) Buffer;\r
2340\r
2341 //\r
2342 // get a place to add\r
2343 //\r
2344 for (Index = (INTN) (Size + Count - 1); Index >= (INTN) Pos; Index--) {\r
2345 BufferPtr[Index] = BufferPtr[Index - Count];\r
2346 }\r
2347 //\r
2348 // add the buffer\r
2349 //\r
2350 for (Index = (INTN) 0; Index < (INTN) Count; Index++) {\r
2351 BufferPtr[Index + Pos] = AddBuffer[Index];\r
2352 }\r
2353\r
2354 Size += Count;\r
2355\r
2356 HBufferImageFreeLines ();\r
2357\r
2358 HBufferImageBufferToList (Buffer, Size);\r
2359\r
2360 FreePool (Buffer);\r
2361\r
2362 Link = HMainEditor.BufferImage->ListHead->ForwardLink;\r
2363 for (Index = 0; Index < (INTN) NewPos / 0x10; Index++) {\r
2364 Link = Link->ForwardLink;\r
2365 }\r
2366\r
2367 Line = CR (Link, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST);\r
2368 HBufferImage.CurrentLine = Line;\r
2369\r
2370 if (OldPos >= Pos) {\r
2371 NewPos = OldPos + Count;\r
2372 } else {\r
2373 NewPos = OldPos;\r
2374 }\r
2375\r
2376 HBufferImageMovePosition (NewPos / 0x10 + 1, NewPos % 0x10 + 1, TRUE);\r
2377\r
2378 return EFI_SUCCESS;\r
2379}\r
2380\r
2381EFI_STATUS\r
2382HBufferImageDoBackspace (\r
2383 VOID\r
2384 )\r
2385/*++\r
2386\r
2387Routine Description: \r
2388\r
2389 delete the previous character\r
2390\r
2391Arguments: \r
2392\r
2393 None\r
2394\r
2395Returns: \r
2396\r
2397 EFI_SUCCESS\r
2398\r
2399--*/\r
2400{\r
2401 HEFI_EDITOR_LINE *Line;\r
2402\r
2403 UINTN FileColumn;\r
2404 UINTN FPos;\r
2405 BOOLEAN LastLine;\r
2406\r
2407 //\r
2408 // variable initialization\r
2409 //\r
2410 LastLine = FALSE;\r
2411\r
2412 //\r
2413 // already the first character\r
2414 //\r
2415 if (HBufferImage.BufferPosition.Row == 1 && HBufferImage.BufferPosition.Column == 1) {\r
2416 return EFI_SUCCESS;\r
2417 }\r
2418\r
2419 FPos = (HBufferImage.BufferPosition.Row - 1) * 0x10 + HBufferImage.BufferPosition.Column - 1;\r
2420\r
2421 FileColumn = HBufferImage.BufferPosition.Column;\r
2422\r
2423 Line = HBufferImage.CurrentLine;\r
2424 LastLine = FALSE;\r
2425 if (Line->Link.ForwardLink == HBufferImage.ListHead && FileColumn > 1) {\r
2426 LastLine = TRUE;\r
2427 }\r
2428\r
2429 HBufferImageDeleteCharacterFromBuffer (FPos - 1, 1, NULL);\r
2430\r
2431 //\r
2432 // if is the last line\r
2433 // then only this line need to be refreshed\r
2434 //\r
2435 if (LastLine) {\r
2436 HBufferImageNeedRefresh = FALSE;\r
2437 HBufferImageOnlyLineNeedRefresh = TRUE;\r
2438 } else {\r
2439 HBufferImageNeedRefresh = TRUE;\r
2440 HBufferImageOnlyLineNeedRefresh = FALSE;\r
2441 }\r
2442\r
2443 if (!HBufferImage.Modified) {\r
2444 HBufferImage.Modified = TRUE;\r
2445 }\r
2446\r
2447 return EFI_SUCCESS;\r
2448}\r
2449\r
2450EFI_STATUS\r
2451HBufferImageDoDelete (\r
2452 VOID\r
2453 )\r
2454/*++\r
2455\r
2456Routine Description: \r
2457\r
2458 Delete current character from line\r
2459\r
2460Arguments: \r
2461\r
2462 None\r
2463\r
2464Returns: \r
2465\r
2466 EFI_SUCCESS\r
2467\r
2468--*/\r
2469{\r
2470\r
2471 HEFI_EDITOR_LINE *Line;\r
2472\r
2473 BOOLEAN LastLine;\r
2474 UINTN FileColumn;\r
2475 UINTN FPos;\r
2476\r
2477 FPos = (HBufferImage.BufferPosition.Row - 1) * 0x10 + HBufferImage.BufferPosition.Column - 1;\r
2478\r
2479 FileColumn = HBufferImage.BufferPosition.Column;\r
2480\r
2481 Line = HBufferImage.CurrentLine;\r
2482\r
2483 //\r
2484 // if beyond the last character\r
2485 //\r
2486 if (FileColumn > Line->Size) {\r
2487 return EFI_SUCCESS;\r
2488 }\r
2489\r
2490 LastLine = FALSE;\r
2491 if (Line->Link.ForwardLink == HBufferImage.ListHead) {\r
2492 LastLine = TRUE;\r
2493 }\r
2494\r
2495 HBufferImageDeleteCharacterFromBuffer (FPos, 1, NULL);\r
2496\r
2497 //\r
2498 // if is the last line\r
2499 // then only this line need to be refreshed\r
2500 //\r
2501 if (LastLine) {\r
2502 HBufferImageNeedRefresh = FALSE;\r
2503 HBufferImageOnlyLineNeedRefresh = TRUE;\r
2504 } else {\r
2505 HBufferImageNeedRefresh = TRUE;\r
2506 HBufferImageOnlyLineNeedRefresh = FALSE;\r
2507 }\r
2508\r
2509 if (!HBufferImage.Modified) {\r
2510 HBufferImage.Modified = TRUE;\r
2511 }\r
2512\r
2513 return EFI_SUCCESS;\r
2514}\r
2515\r
2516EFI_STATUS\r
2517HBufferImageBufferToList (\r
2518 IN VOID *Buffer,\r
2519 IN UINTN Bytes\r
2520 )\r
2521{\r
2522 UINTN i;\r
2523 UINTN j;\r
2524 UINTN Left;\r
2525 HEFI_EDITOR_LINE *Line;\r
2526 UINT8 *BufferPtr;\r
2527\r
2528 i = 0;\r
2529 Left = 0;\r
2530 BufferPtr = (UINT8 *) Buffer;\r
2531\r
2532 //\r
2533 // parse file content line by line\r
2534 //\r
2535 while (i < Bytes) {\r
2536 if (Bytes - i >= 0x10) {\r
2537 Left = 0x10;\r
2538 } else {\r
2539 Left = Bytes - i;\r
2540 }\r
2541\r
2542 //\r
2543 // allocate a new line\r
2544 //\r
2545 Line = HBufferImageCreateLine ();\r
2546 if (Line == NULL) {\r
2547 return EFI_OUT_OF_RESOURCES;\r
2548 }\r
2549\r
2550 Line->Size = Left;\r
2551\r
2552 for (j = 0; j < Left; j++) {\r
2553 Line->Buffer[j] = BufferPtr[i];\r
2554 i++;\r
2555 }\r
2556\r
2557 }\r
2558\r
2559 //\r
2560 // last line is a full line, SO create a new line\r
2561 //\r
2562 if (Left == 0x10 || Bytes == 0) {\r
2563 Line = HBufferImageCreateLine ();\r
2564 if (Line == NULL) {\r
2565 return EFI_OUT_OF_RESOURCES;\r
2566 }\r
2567 }\r
2568\r
2569 return EFI_SUCCESS;\r
2570}\r
2571\r
2572EFI_STATUS\r
2573HBufferImageListToBuffer (\r
2574 IN VOID *Buffer,\r
2575 IN UINTN Bytes\r
2576 )\r
2577{\r
2578 UINTN Count;\r
2579 UINTN Index;\r
2580 HEFI_EDITOR_LINE *Line;\r
2581 LIST_ENTRY *Link;\r
2582 UINT8 *BufferPtr;\r
2583\r
2584 //\r
2585 // change the line list to a large buffer\r
2586 //\r
2587 if (HBufferImage.Lines == NULL) {\r
2588 return EFI_SUCCESS;\r
2589 }\r
2590\r
2591 Link = &HBufferImage.Lines->Link;\r
2592 Count = 0;\r
2593 BufferPtr = (UINT8 *) Buffer;\r
2594\r
2595 //\r
2596 // deal line by line\r
2597 //\r
2598 while (Link != HBufferImage.ListHead) {\r
2599\r
2600 Line = CR (Link, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST);\r
2601\r
2602 if (Count + Line->Size > Bytes) {\r
2603 return EFI_SUCCESS;\r
2604 }\r
2605\r
2606 for (Index = 0; Index < Line->Size; Index++) {\r
2607 BufferPtr[Index] = Line->Buffer[Index];\r
2608 }\r
2609\r
2610 Count += Line->Size;\r
2611 BufferPtr += Line->Size;\r
2612\r
2613 Link = Link->ForwardLink;\r
2614 }\r
2615\r
2616 return EFI_SUCCESS;\r
2617}\r
2618\r
2619VOID\r
2620HBufferImageAdjustMousePosition (\r
2621 IN INT32 TextX,\r
2622 IN INT32 TextY\r
2623 )\r
2624{\r
2625 UINTN X;\r
2626 UINTN Y;\r
2627 UINTN AbsX;\r
2628 UINTN AbsY;\r
2629\r
2630 //\r
2631 // TextX and TextY is mouse movement data returned by mouse driver\r
2632 // This function will change it to MousePosition\r
2633 //\r
2634 //\r
2635 // get absolute X value\r
2636 //\r
2637 if (TextX >= 0) {\r
2638 AbsX = TextX;\r
2639 } else {\r
2640 AbsX = -TextX;\r
2641 }\r
2642 //\r
2643 // get absolute Y value\r
2644 //\r
2645 if (TextY >= 0) {\r
2646 AbsY = TextY;\r
2647 } else {\r
2648 AbsY = -TextY;\r
2649 }\r
2650\r
2651 X = HBufferImage.MousePosition.Column;\r
2652 Y = HBufferImage.MousePosition.Row;\r
2653\r
2654 if (TextX >= 0) {\r
2655 X += TextX;\r
2656 } else {\r
2657 if (X >= AbsX) {\r
2658 X -= AbsX;\r
2659 } else {\r
2660 X = 0;\r
2661 }\r
2662 }\r
2663\r
2664 if (TextY >= 0) {\r
2665 Y += TextY;\r
2666 } else {\r
2667 if (Y >= AbsY) {\r
2668 Y -= AbsY;\r
2669 } else {\r
2670 Y = 0;\r
2671 }\r
2672 }\r
2673 //\r
2674 // check whether new mouse column position is beyond screen\r
2675 // if not, adjust it\r
2676 //\r
2677 if (X >= 10 && X <= (10 + 0x10 * 3 - 1)) {\r
2678 HBufferImage.MousePosition.Column = X;\r
2679 } else if (X < 10) {\r
2680 HBufferImage.MousePosition.Column = 10;\r
2681 } else if (X > (10 + 0x10 * 3 - 1)) {\r
2682 HBufferImage.MousePosition.Column = 10 + 0x10 * 3 - 1;\r
2683 }\r
2684 //\r
2685 // check whether new mouse row position is beyond screen\r
2686 // if not, adjust it\r
2687 //\r
2688 if (Y >= 2 && Y <= (HMainEditor.ScreenSize.Row - 4)) {\r
2689 HBufferImage.MousePosition.Row = Y;\r
2690 } else if (Y < 2) {\r
2691 HBufferImage.MousePosition.Row = 2;\r
2692 } else if (Y > (HMainEditor.ScreenSize.Row - 4)) {\r
2693 HBufferImage.MousePosition.Row = (HMainEditor.ScreenSize.Row - 4);\r
2694 }\r
2695\r
2696}\r