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