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