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