]> git.proxmox.com Git - mirror_edk2.git/blame - ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/BufferImage.c
MdePkg: Update CpuSleep to use ARMv7 instruction.
[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
583 New.Colors.Foreground = Orig.Colors.Background;\r
584 New.Colors.Background = Orig.Colors.Foreground;\r
585\r
586 //\r
587 // if in selected area,\r
588 // so do not need to refresh mouse\r
589 //\r
590 if (!HBufferImageIsInSelectedArea (\r
591 HBufferImageBackupVar.MousePosition.Row,\r
592 HBufferImageBackupVar.MousePosition.Column\r
593 )) {\r
594 gST->ConOut->SetAttribute (gST->ConOut, Orig.Data);\r
595 } else {\r
596 gST->ConOut->SetAttribute (gST->ConOut, New.Data);\r
597 }\r
598 //\r
599 // clear the old mouse position\r
600 //\r
601 FRow = HBufferImage.LowVisibleRow + HBufferImageBackupVar.MousePosition.Row - 2;\r
602\r
603 HighBits = HBufferImageIsAtHighBits (\r
604 HBufferImageBackupVar.MousePosition.Column,\r
605 &FColumn\r
606 );\r
607\r
608 HasCharacter = TRUE;\r
609 if (FRow > HBufferImage.NumLines || FColumn == 0) {\r
610 HasCharacter = FALSE;\r
611 } else {\r
612 CurrentLine = HBufferImage.CurrentLine;\r
613 Line = HMoveLine (FRow - HBufferImage.BufferPosition.Row);\r
614\r
33c031ee 615 if (Line == NULL || FColumn > Line->Size) {\r
632820d1 616 HasCharacter = FALSE;\r
617 }\r
618\r
619 HBufferImage.CurrentLine = CurrentLine;\r
620 }\r
621\r
622 ShellPrintEx (\r
623 (INT32)HBufferImageBackupVar.MousePosition.Column - 1,\r
624 (INT32)HBufferImageBackupVar.MousePosition.Row - 1,\r
625 L" "\r
626 );\r
627\r
628 if (HasCharacter) {\r
629 if (HighBits) {\r
630 Value = (UINT8) (Line->Buffer[FColumn - 1] & 0xf0);\r
631 Value = (UINT8) (Value >> 4);\r
632 } else {\r
633 Value = (UINT8) (Line->Buffer[FColumn - 1] & 0xf);\r
634 }\r
635\r
636 ShellPrintEx (\r
637 (INT32)HBufferImageBackupVar.MousePosition.Column - 1,\r
638 (INT32)HBufferImageBackupVar.MousePosition.Row - 1,\r
639 L"%x",\r
640 Value\r
641 );\r
642 }\r
643\r
644 if (!HBufferImageIsInSelectedArea (\r
645 HBufferImage.MousePosition.Row,\r
646 HBufferImage.MousePosition.Column\r
647 )) {\r
648 gST->ConOut->SetAttribute (gST->ConOut, New.Data);\r
649 } else {\r
650 gST->ConOut->SetAttribute (gST->ConOut, Orig.Data);\r
651 }\r
652 //\r
653 // clear the old mouse position\r
654 //\r
655 FRow = HBufferImage.LowVisibleRow + HBufferImage.MousePosition.Row - 2;\r
656\r
657 HighBits = HBufferImageIsAtHighBits (\r
658 HBufferImage.MousePosition.Column,\r
659 &FColumn\r
660 );\r
661\r
662 HasCharacter = TRUE;\r
663 if (FRow > HBufferImage.NumLines || FColumn == 0) {\r
664 HasCharacter = FALSE;\r
665 } else {\r
666 CurrentLine = HBufferImage.CurrentLine;\r
667 Line = HMoveLine (FRow - HBufferImage.BufferPosition.Row);\r
668\r
ae724571 669 if (Line == NULL || FColumn > Line->Size) {\r
632820d1 670 HasCharacter = FALSE;\r
671 }\r
672\r
673 HBufferImage.CurrentLine = CurrentLine;\r
674 }\r
675\r
676 ShellPrintEx (\r
677 (INT32)HBufferImage.MousePosition.Column - 1,\r
678 (INT32)HBufferImage.MousePosition.Row - 1,\r
679 L" "\r
680 );\r
681\r
682 if (HasCharacter) {\r
683 if (HighBits) {\r
684 Value = (UINT8) (Line->Buffer[FColumn - 1] & 0xf0);\r
685 Value = (UINT8) (Value >> 4);\r
686 } else {\r
687 Value = (UINT8) (Line->Buffer[FColumn - 1] & 0xf);\r
688 }\r
689\r
690 ShellPrintEx (\r
691 (INT32)HBufferImage.MousePosition.Column - 1,\r
692 (INT32)HBufferImage.MousePosition.Row - 1,\r
693 L"%x",\r
694 Value\r
695 );\r
696 }\r
697 //\r
698 // end of HasCharacter\r
699 //\r
700 gST->ConOut->SetAttribute (gST->ConOut, Orig.Data);\r
701 }\r
702 //\r
703 // end of MouseNeedRefresh\r
704 //\r
705 }\r
706 //\r
707 // end of MouseSupported\r
708 //\r
709 return EFI_SUCCESS;\r
710}\r
711\r
a1d4bfcc 712/**\r
713 Set cursor position according to HBufferImage.DisplayPosition.\r
714\r
715 @retval EFI_SUCCESS The operation was successful.\r
716**/\r
632820d1 717EFI_STATUS\r
718HBufferImageRestorePosition (\r
719 VOID\r
720 )\r
632820d1 721{\r
722 //\r
723 // set cursor position\r
724 //\r
725 gST->ConOut->SetCursorPosition (\r
726 gST->ConOut,\r
727 HBufferImage.DisplayPosition.Column - 1,\r
728 HBufferImage.DisplayPosition.Row - 1\r
729 );\r
730\r
731 return EFI_SUCCESS;\r
732}\r
733\r
e0c2cc6f 734/**
ae724571 735 Refresh function for HBufferImage.\r
736\r
737 @retval EFI_SUCCESS The operation was successful.\r
738 @retval EFI_LOAD_ERROR A Load error occured.\r
739\r
740**/\r
632820d1 741EFI_STATUS\r
742HBufferImageRefresh (\r
743 VOID\r
744 )\r
632820d1 745{\r
746 LIST_ENTRY *Link;\r
747 HEFI_EDITOR_LINE *Line;\r
748 UINTN Row;\r
749 HEFI_EDITOR_COLOR_UNION Orig;\r
750 HEFI_EDITOR_COLOR_UNION New;\r
751\r
752 UINTN StartRow;\r
753 UINTN EndRow;\r
754 UINTN FStartRow;\r
755 UINTN FEndRow;\r
756 UINTN Tmp;\r
757\r
758 Orig = HMainEditor.ColorAttributes;\r
759 New.Colors.Foreground = Orig.Colors.Background;\r
760 New.Colors.Background = Orig.Colors.Foreground;\r
761\r
762 //\r
763 // if it's the first time after editor launch, so should refresh\r
764 //\r
765 if (HEditorFirst == FALSE) {\r
766 //\r
767 // no definite required refresh\r
768 // and file position displayed on screen has not been changed\r
769 //\r
ae724571 770 if (!HBufferImageNeedRefresh &&\r
771 !HBufferImageOnlyLineNeedRefresh &&\r
632820d1 772 HBufferImageBackupVar.LowVisibleRow == HBufferImage.LowVisibleRow\r
773 ) {\r
774 HBufferImageRestoreMousePosition ();\r
775 HBufferImageRestorePosition ();\r
776 return EFI_SUCCESS;\r
777 }\r
778 }\r
779\r
780 gST->ConOut->EnableCursor (gST->ConOut, FALSE);\r
781\r
782 //\r
783 // only need to refresh current line\r
784 //\r
ae724571 785 if (HBufferImageOnlyLineNeedRefresh && HBufferImageBackupVar.LowVisibleRow == HBufferImage.LowVisibleRow) {\r
632820d1 786\r
787 HBufferImagePrintLine (\r
788 HBufferImage.CurrentLine,\r
789 HBufferImage.DisplayPosition.Row,\r
790 HBufferImage.BufferPosition.Row,\r
791 Orig,\r
792 New\r
793 );\r
794 } else {\r
795 //\r
796 // the whole edit area need refresh\r
797 //\r
798 if (HEditorMouseAction && HMainEditor.SelectStart != 0 && HMainEditor.SelectEnd != 0) {\r
799 if (HMainEditor.SelectStart != HMainEditorBackupVar.SelectStart) {\r
800 if (HMainEditor.SelectStart >= HMainEditorBackupVar.SelectStart && HMainEditorBackupVar.SelectStart != 0) {\r
801 StartRow = (HMainEditorBackupVar.SelectStart - 1) / 0x10 + 1;\r
802 } else {\r
803 StartRow = (HMainEditor.SelectStart - 1) / 0x10 + 1;\r
804 }\r
805 } else {\r
806 StartRow = (HMainEditor.SelectStart - 1) / 0x10 + 1;\r
807 }\r
808\r
809 if (HMainEditor.SelectEnd <= HMainEditorBackupVar.SelectEnd) {\r
810 EndRow = (HMainEditorBackupVar.SelectEnd - 1) / 0x10 + 1;\r
811 } else {\r
812 EndRow = (HMainEditor.SelectEnd - 1) / 0x10 + 1;\r
813 }\r
814 //\r
815 // swap\r
816 //\r
817 if (StartRow > EndRow) {\r
818 Tmp = StartRow;\r
819 StartRow = EndRow;\r
820 EndRow = Tmp;\r
821 }\r
822\r
823 FStartRow = StartRow;\r
824 FEndRow = EndRow;\r
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
835 EndRow = (HMainEditor.ScreenSize.Row - 4);\r
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
1407 if (FileRow > HBufferImage.LowVisibleRow + (HMainEditor.ScreenSize.Row - 5) - 1) {\r
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
1715 if (HBufferImage.NumLines >= FRow + (HMainEditor.ScreenSize.Row - 5)) {\r
1716 Gap = (HMainEditor.ScreenSize.Row - 5);\r
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
1753 HEFI_EDITOR_LINE *Line;\r
1754 UINTN FRow;\r
1755 UINTN FCol;\r
1756 UINTN Gap;\r
1757 INTN Retreat;\r
1758\r
1759 Line = HBufferImage.CurrentLine;\r
1760\r
1761 FRow = HBufferImage.BufferPosition.Row;\r
1762 FCol = HBufferImage.BufferPosition.Column;\r
1763\r
1764 //\r
1765 // has previous page\r
1766 //\r
1767 if (FRow > (HMainEditor.ScreenSize.Row - 5)) {\r
1768 Gap = (HMainEditor.ScreenSize.Row - 5);\r
1769 } else {\r
1770 //\r
1771 // the first line of file will displayed on the first line of screen\r
1772 //\r
1773 Gap = FRow - 1;\r
1774 }\r
1775\r
1776 Retreat = Gap;\r
1777 Retreat = -Retreat;\r
1778\r
1779 //\r
1780 // get correct line\r
1781 //\r
1782 Line = HMoveLine (Retreat);\r
1783\r
1784 FRow -= Gap;\r
1785\r
1786 HBufferImageMovePosition (FRow, FCol, HBufferImage.HighBits);\r
1787\r
1788 return EFI_SUCCESS;\r
1789}\r
1790\r
ae724571 1791/**\r
1792 Scroll cursor to start of line\r
1793\r
1794 @retval EFI_SUCCESS The operation was successful.\r
1795**/\r
632820d1 1796EFI_STATUS\r
1797HBufferImageHome (\r
1798 VOID\r
1799 )\r
632820d1 1800{\r
1801 HEFI_EDITOR_LINE *Line;\r
1802 UINTN FRow;\r
1803 UINTN FCol;\r
1804 BOOLEAN HighBits;\r
1805\r
1806 Line = HBufferImage.CurrentLine;\r
1807\r
1808 //\r
1809 // curosr will at the high bit\r
1810 //\r
1811 FRow = HBufferImage.BufferPosition.Row;\r
1812 FCol = 1;\r
1813 HighBits = TRUE;\r
1814\r
1815 //\r
1816 // move cursor position\r
1817 //\r
1818 HBufferImageMovePosition (FRow, FCol, HighBits);\r
1819\r
1820 return EFI_SUCCESS;\r
1821}\r
1822\r
ae724571 1823/**\r
1824 Scroll cursor to end of line.\r
1825\r
1826 @retval EFI_SUCCESS Teh operation was successful.\r
1827**/\r
632820d1 1828EFI_STATUS\r
1829HBufferImageEnd (\r
1830 VOID\r
1831 )\r
632820d1 1832{\r
1833 HEFI_EDITOR_LINE *Line;\r
1834 UINTN FRow;\r
1835 UINTN FCol;\r
1836 BOOLEAN HighBits;\r
1837\r
1838 //\r
1839 // need refresh mouse\r
1840 //\r
1841 HBufferImageMouseNeedRefresh = TRUE;\r
1842\r
1843 Line = HBufferImage.CurrentLine;\r
1844\r
1845 FRow = HBufferImage.BufferPosition.Row;\r
1846\r
1847 if (Line->Size == 0x10) {\r
1848 FCol = Line->Size;\r
1849 HighBits = FALSE;\r
1850 } else {\r
1851 FCol = Line->Size + 1;\r
1852 HighBits = TRUE;\r
1853 }\r
1854 //\r
1855 // move cursor position\r
1856 //\r
1857 HBufferImageMovePosition (FRow, FCol, HighBits);\r
1858\r
1859 return EFI_SUCCESS;\r
1860}\r
1861\r
ae724571 1862/**\r
1863 Get the size of the open buffer.\r
1864\r
1865 @retval The size in bytes.\r
1866**/\r
632820d1 1867UINTN\r
1868HBufferImageGetTotalSize (\r
1869 VOID\r
1870 )\r
1871{\r
1872 UINTN Size;\r
1873\r
1874 HEFI_EDITOR_LINE *Line;\r
1875\r
1876 //\r
1877 // calculate the total size of whole line list's buffer\r
1878 //\r
1879 if (HBufferImage.Lines == NULL) {\r
1880 return 0;\r
1881 }\r
1882\r
1883 Line = CR (\r
1884 HBufferImage.ListHead->BackLink,\r
1885 HEFI_EDITOR_LINE,\r
1886 Link,\r
1887 EFI_EDITOR_LINE_LIST\r
1888 );\r
1889 //\r
1890 // one line at most 0x10\r
1891 //\r
1892 Size = 0x10 * (HBufferImage.NumLines - 1) + Line->Size;\r
1893\r
1894 return Size;\r
1895}\r
1896\r
ae724571 1897/**\r
1898 Delete character from buffer.\r
1899 \r
1900 @param[in] Pos Position, Pos starting from 0.\r
1901 @param[in] Count The Count of characters to delete.\r
a1d4bfcc 1902 @param[out] DeleteBuffer The DeleteBuffer.\r
ae724571 1903\r
1904 @retval EFI_SUCCESS Success \r
1905**/\r
632820d1 1906EFI_STATUS\r
1907HBufferImageDeleteCharacterFromBuffer (\r
1908 IN UINTN Pos,\r
1909 IN UINTN Count,\r
1910 OUT UINT8 *DeleteBuffer\r
1911 )\r
632820d1 1912{\r
1913 UINTN Index;\r
1914\r
1915 VOID *Buffer;\r
1916 UINT8 *BufferPtr;\r
1917 UINTN Size;\r
1918\r
1919 HEFI_EDITOR_LINE *Line;\r
1920 LIST_ENTRY *Link;\r
1921 UINTN StartRow;\r
1922\r
1923 UINTN OldFCol;\r
1924 UINTN OldFRow;\r
1925 UINTN OldPos;\r
1926\r
1927 UINTN NewPos;\r
1928\r
1929 EFI_STATUS Status;\r
1930\r
1931 //\r
1932 // get the line that start position is at\r
1933 //\r
1934 StartRow = Pos / 0x10;\r
1935\r
1936 Size = HBufferImageGetTotalSize ();\r
1937\r
1938 if (Size < Count) {\r
1939 return EFI_LOAD_ERROR;\r
1940 }\r
1941\r
1942 if (Size == 0) {\r
1943 return EFI_SUCCESS;\r
1944 }\r
1945\r
1946 //\r
1947 // relocate all the HBufferImage fields\r
1948 //\r
1949 OldFRow = HBufferImage.BufferPosition.Row;\r
1950 OldFCol = HBufferImage.BufferPosition.Column;\r
1951 OldPos = (OldFRow - 1) * 0x10 + OldFCol - 1;\r
1952\r
1953 if (Pos > 0) {\r
1954 //\r
1955 // has character before it,\r
1956 // so locate according to block's previous character\r
1957 //\r
1958 NewPos = Pos - 1;\r
1959\r
1960 } else {\r
1961 //\r
1962 // has no character before it,\r
1963 // so locate according to block's next character\r
1964 //\r
1965 NewPos = 0;\r
1966 }\r
1967\r
1968 HBufferImageMovePosition (NewPos / 0x10 + 1, NewPos % 0x10 + 1, TRUE);\r
1969\r
1970 Buffer = AllocateZeroPool (Size);\r
1971 if (Buffer == NULL) {\r
1972 return EFI_OUT_OF_RESOURCES;\r
1973 }\r
1974\r
1975 HBufferImageListToBuffer (Buffer, Size);\r
1976\r
1977 BufferPtr = (UINT8 *) Buffer;\r
1978\r
1979 //\r
1980 // pass deleted buffer out\r
1981 //\r
1982 if (DeleteBuffer != NULL) {\r
1983 for (Index = 0; Index < Count; Index++) {\r
1984 DeleteBuffer[Index] = BufferPtr[Pos + Index];\r
1985 }\r
1986 }\r
1987 //\r
1988 // delete the part from Pos\r
1989 //\r
1990 for (Index = Pos; Index < Size - Count; Index++) {\r
1991 BufferPtr[Index] = BufferPtr[Index + Count];\r
1992 }\r
1993\r
1994 Size -= Count;\r
1995\r
1996 HBufferImageFreeLines ();\r
1997\r
1998 Status = HBufferImageBufferToList (Buffer, Size);\r
1999 FreePool (Buffer);\r
2000\r
2001 if (EFI_ERROR (Status)) {\r
2002 return Status;\r
2003 }\r
2004\r
2005 Link = HMainEditor.BufferImage->ListHead->ForwardLink;\r
2006 for (Index = 0; Index < NewPos / 0x10; Index++) {\r
2007 Link = Link->ForwardLink;\r
2008 }\r
2009\r
2010 Line = CR (Link, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST);\r
2011 HBufferImage.CurrentLine = Line;\r
2012\r
2013 //\r
2014 // if current cursor position if inside select area\r
2015 // then move it to the block's NEXT character\r
2016 //\r
2017 if (OldPos >= Pos && OldPos < (Pos + Count)) {\r
2018 NewPos = Pos;\r
2019 } else {\r
2020 if (OldPos < Pos) {\r
2021 NewPos = OldPos;\r
2022 } else {\r
2023 NewPos = OldPos - Count;\r
2024 }\r
2025 }\r
2026\r
2027 HBufferImageMovePosition (NewPos / 0x10 + 1, NewPos % 0x10 + 1, TRUE);\r
2028\r
2029 return EFI_SUCCESS;\r
2030}\r
2031\r
ae724571 2032/**\r
2033 Add character to buffer, add before pos.\r
2034\r
2035 @param[in] Pos Position, Pos starting from 0.\r
2036 @param[in] Count Count of characters to add.\r
2037 @param[in] AddBuffer Add buffer.\r
2038\r
2039 @retval EFI_SUCCESS Success. \r
2040**/\r
632820d1 2041EFI_STATUS\r
2042HBufferImageAddCharacterToBuffer (\r
2043 IN UINTN Pos,\r
2044 IN UINTN Count,\r
2045 IN UINT8 *AddBuffer\r
2046 )\r
632820d1 2047{\r
2048 INTN Index;\r
2049\r
2050 VOID *Buffer;\r
2051 UINT8 *BufferPtr;\r
2052 UINTN Size;\r
2053\r
2054 HEFI_EDITOR_LINE *Line;\r
2055\r
2056 LIST_ENTRY *Link;\r
2057 UINTN StartRow;\r
2058\r
2059 UINTN OldFCol;\r
2060 UINTN OldFRow;\r
2061 UINTN OldPos;\r
2062\r
2063 UINTN NewPos;\r
2064\r
2065 //\r
2066 // get the line that start position is at\r
2067 //\r
2068 StartRow = Pos / 0x10;\r
2069\r
2070 Size = HBufferImageGetTotalSize ();\r
2071\r
2072 //\r
2073 // relocate all the HBufferImage fields\r
2074 //\r
2075 OldFRow = HBufferImage.BufferPosition.Row;\r
2076 OldFCol = HBufferImage.BufferPosition.Column;\r
2077 OldPos = (OldFRow - 1) * 0x10 + OldFCol - 1;\r
2078\r
2079 //\r
2080 // move cursor before Pos\r
2081 //\r
2082 if (Pos > 0) {\r
2083 NewPos = Pos - 1;\r
2084 } else {\r
2085 NewPos = 0;\r
2086 }\r
2087\r
2088 HBufferImageMovePosition (NewPos / 0x10 + 1, NewPos % 0x10 + 1, TRUE);\r
2089\r
2090 Buffer = AllocateZeroPool (Size + Count);\r
2091 if (Buffer == NULL) {\r
2092 return EFI_OUT_OF_RESOURCES;\r
2093 }\r
2094\r
2095 HBufferImageListToBuffer (Buffer, Size);\r
2096\r
2097 BufferPtr = (UINT8 *) Buffer;\r
2098\r
2099 //\r
2100 // get a place to add\r
2101 //\r
2102 for (Index = (INTN) (Size + Count - 1); Index >= (INTN) Pos; Index--) {\r
2103 BufferPtr[Index] = BufferPtr[Index - Count];\r
2104 }\r
2105 //\r
2106 // add the buffer\r
2107 //\r
2108 for (Index = (INTN) 0; Index < (INTN) Count; Index++) {\r
2109 BufferPtr[Index + Pos] = AddBuffer[Index];\r
2110 }\r
2111\r
2112 Size += Count;\r
2113\r
2114 HBufferImageFreeLines ();\r
2115\r
2116 HBufferImageBufferToList (Buffer, Size);\r
2117\r
2118 FreePool (Buffer);\r
2119\r
2120 Link = HMainEditor.BufferImage->ListHead->ForwardLink;\r
2121 for (Index = 0; Index < (INTN) NewPos / 0x10; Index++) {\r
2122 Link = Link->ForwardLink;\r
2123 }\r
2124\r
2125 Line = CR (Link, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST);\r
2126 HBufferImage.CurrentLine = Line;\r
2127\r
2128 if (OldPos >= Pos) {\r
2129 NewPos = OldPos + Count;\r
2130 } else {\r
2131 NewPos = OldPos;\r
2132 }\r
2133\r
2134 HBufferImageMovePosition (NewPos / 0x10 + 1, NewPos % 0x10 + 1, TRUE);\r
2135\r
2136 return EFI_SUCCESS;\r
2137}\r
2138\r
ae724571 2139/**\r
2140 Delete current character from line.\r
2141\r
2142 @retval EFI_SUCCESS The operationw as successful.\r
2143**/\r
632820d1 2144EFI_STATUS\r
ae724571 2145EFIAPI\r
632820d1 2146HBufferImageDoDelete (\r
2147 VOID\r
2148 )\r
632820d1 2149{\r
2150\r
2151 HEFI_EDITOR_LINE *Line;\r
2152\r
2153 BOOLEAN LastLine;\r
2154 UINTN FileColumn;\r
2155 UINTN FPos;\r
2156\r
2157 FPos = (HBufferImage.BufferPosition.Row - 1) * 0x10 + HBufferImage.BufferPosition.Column - 1;\r
2158\r
2159 FileColumn = HBufferImage.BufferPosition.Column;\r
2160\r
2161 Line = HBufferImage.CurrentLine;\r
2162\r
2163 //\r
2164 // if beyond the last character\r
2165 //\r
2166 if (FileColumn > Line->Size) {\r
2167 return EFI_SUCCESS;\r
2168 }\r
2169\r
2170 LastLine = FALSE;\r
2171 if (Line->Link.ForwardLink == HBufferImage.ListHead) {\r
2172 LastLine = TRUE;\r
2173 }\r
2174\r
2175 HBufferImageDeleteCharacterFromBuffer (FPos, 1, NULL);\r
2176\r
2177 //\r
2178 // if is the last line\r
2179 // then only this line need to be refreshed\r
2180 //\r
2181 if (LastLine) {\r
2182 HBufferImageNeedRefresh = FALSE;\r
2183 HBufferImageOnlyLineNeedRefresh = TRUE;\r
2184 } else {\r
2185 HBufferImageNeedRefresh = TRUE;\r
2186 HBufferImageOnlyLineNeedRefresh = FALSE;\r
2187 }\r
2188\r
2189 if (!HBufferImage.Modified) {\r
2190 HBufferImage.Modified = TRUE;\r
2191 }\r
2192\r
2193 return EFI_SUCCESS;\r
2194}\r
2195\r
ae724571 2196/**\r
2197 Change the raw buffer to a list of lines for the UI.\r
2198 \r
2199 @param[in] Buffer The pointer to the buffer to fill.\r
2200 @param[in] Bytes The size of the buffer in bytes.\r
2201\r
2202 @retval EFI_SUCCESS The operation was successful.\r
2203 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.\r
2204**/\r
632820d1 2205EFI_STATUS\r
ae724571 2206EFIAPI\r
632820d1 2207HBufferImageBufferToList (\r
2208 IN VOID *Buffer,\r
2209 IN UINTN Bytes\r
2210 )\r
2211{\r
ae724571 2212 UINTN TempI;\r
2213 UINTN TempJ;\r
632820d1 2214 UINTN Left;\r
2215 HEFI_EDITOR_LINE *Line;\r
2216 UINT8 *BufferPtr;\r
2217\r
ae724571 2218 TempI = 0;\r
632820d1 2219 Left = 0;\r
2220 BufferPtr = (UINT8 *) Buffer;\r
2221\r
2222 //\r
2223 // parse file content line by line\r
2224 //\r
ae724571 2225 while (TempI < Bytes) {\r
2226 if (Bytes - TempI >= 0x10) {\r
632820d1 2227 Left = 0x10;\r
2228 } else {\r
ae724571 2229 Left = Bytes - TempI;\r
632820d1 2230 }\r
2231\r
2232 //\r
2233 // allocate a new line\r
2234 //\r
2235 Line = HBufferImageCreateLine ();\r
2236 if (Line == NULL) {\r
2237 return EFI_OUT_OF_RESOURCES;\r
2238 }\r
2239\r
2240 Line->Size = Left;\r
2241\r
ae724571 2242 for (TempJ = 0; TempJ < Left; TempJ++) {\r
2243 Line->Buffer[TempJ] = BufferPtr[TempI];\r
2244 TempI++;\r
632820d1 2245 }\r
2246\r
2247 }\r
2248\r
2249 //\r
2250 // last line is a full line, SO create a new line\r
2251 //\r
2252 if (Left == 0x10 || Bytes == 0) {\r
2253 Line = HBufferImageCreateLine ();\r
2254 if (Line == NULL) {\r
2255 return EFI_OUT_OF_RESOURCES;\r
2256 }\r
2257 }\r
2258\r
2259 return EFI_SUCCESS;\r
2260}\r
2261\r
ae724571 2262/**\r
2263 Change the list of lines from the UI to a raw buffer.\r
2264 \r
2265 @param[in] Buffer The pointer to the buffer to fill.\r
2266 @param[in] Bytes The size of the buffer in bytes.\r
2267\r
2268 @retval EFI_SUCCESS The operation was successful.\r
2269**/\r
632820d1 2270EFI_STATUS\r
ae724571 2271EFIAPI\r
632820d1 2272HBufferImageListToBuffer (\r
2273 IN VOID *Buffer,\r
2274 IN UINTN Bytes\r
2275 )\r
2276{\r
2277 UINTN Count;\r
2278 UINTN Index;\r
2279 HEFI_EDITOR_LINE *Line;\r
2280 LIST_ENTRY *Link;\r
2281 UINT8 *BufferPtr;\r
2282\r
2283 //\r
2284 // change the line list to a large buffer\r
2285 //\r
2286 if (HBufferImage.Lines == NULL) {\r
2287 return EFI_SUCCESS;\r
2288 }\r
2289\r
2290 Link = &HBufferImage.Lines->Link;\r
2291 Count = 0;\r
2292 BufferPtr = (UINT8 *) Buffer;\r
2293\r
2294 //\r
2295 // deal line by line\r
2296 //\r
2297 while (Link != HBufferImage.ListHead) {\r
2298\r
2299 Line = CR (Link, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST);\r
2300\r
ae724571 2301 //@todo shouldn't this be an error???\r
632820d1 2302 if (Count + Line->Size > Bytes) {\r
2303 return EFI_SUCCESS;\r
2304 }\r
2305\r
2306 for (Index = 0; Index < Line->Size; Index++) {\r
2307 BufferPtr[Index] = Line->Buffer[Index];\r
2308 }\r
2309\r
2310 Count += Line->Size;\r
2311 BufferPtr += Line->Size;\r
2312\r
2313 Link = Link->ForwardLink;\r
2314 }\r
2315\r
2316 return EFI_SUCCESS;\r
2317}\r
2318\r
ae724571 2319/**\r
2320 Move the mouse in the image buffer.\r
2321\r
2322 @param[in] TextX The x-coordinate.\r
2323 @param[in] TextY The y-coordinate.\r
2324**/\r
632820d1 2325VOID\r
ae724571 2326EFIAPI\r
632820d1 2327HBufferImageAdjustMousePosition (\r
2328 IN INT32 TextX,\r
2329 IN INT32 TextY\r
2330 )\r
2331{\r
ae724571 2332 UINTN TempX;\r
2333 UINTN TempY;\r
632820d1 2334 UINTN AbsX;\r
2335 UINTN AbsY;\r
2336\r
2337 //\r
2338 // TextX and TextY is mouse movement data returned by mouse driver\r
2339 // This function will change it to MousePosition\r
2340 //\r
2341 //\r
ae724571 2342 // get absolute TempX value\r
632820d1 2343 //\r
2344 if (TextX >= 0) {\r
2345 AbsX = TextX;\r
2346 } else {\r
2347 AbsX = -TextX;\r
2348 }\r
2349 //\r
ae724571 2350 // get absolute TempY value\r
632820d1 2351 //\r
2352 if (TextY >= 0) {\r
2353 AbsY = TextY;\r
2354 } else {\r
2355 AbsY = -TextY;\r
2356 }\r
2357\r
ae724571 2358 TempX = HBufferImage.MousePosition.Column;\r
2359 TempY = HBufferImage.MousePosition.Row;\r
632820d1 2360\r
2361 if (TextX >= 0) {\r
ae724571 2362 TempX += TextX;\r
632820d1 2363 } else {\r
ae724571 2364 if (TempX >= AbsX) {\r
2365 TempX -= AbsX;\r
632820d1 2366 } else {\r
ae724571 2367 TempX = 0;\r
632820d1 2368 }\r
2369 }\r
2370\r
2371 if (TextY >= 0) {\r
ae724571 2372 TempY += TextY;\r
632820d1 2373 } else {\r
ae724571 2374 if (TempY >= AbsY) {\r
2375 TempY -= AbsY;\r
632820d1 2376 } else {\r
ae724571 2377 TempY = 0;\r
632820d1 2378 }\r
2379 }\r
2380 //\r
2381 // check whether new mouse column position is beyond screen\r
2382 // if not, adjust it\r
2383 //\r
ae724571 2384 if (TempX >= 10 && TempX <= (10 + 0x10 * 3 - 1)) {\r
2385 HBufferImage.MousePosition.Column = TempX;\r
2386 } else if (TempX < 10) {\r
632820d1 2387 HBufferImage.MousePosition.Column = 10;\r
ae724571 2388 } else if (TempX > (10 + 0x10 * 3 - 1)) {\r
632820d1 2389 HBufferImage.MousePosition.Column = 10 + 0x10 * 3 - 1;\r
2390 }\r
2391 //\r
2392 // check whether new mouse row position is beyond screen\r
2393 // if not, adjust it\r
2394 //\r
ae724571 2395 if (TempY >= 2 && TempY <= (HMainEditor.ScreenSize.Row - 4)) {\r
2396 HBufferImage.MousePosition.Row = TempY;\r
2397 } else if (TempY < 2) {\r
632820d1 2398 HBufferImage.MousePosition.Row = 2;\r
ae724571 2399 } else if (TempY > (HMainEditor.ScreenSize.Row - 4)) {\r
632820d1 2400 HBufferImage.MousePosition.Row = (HMainEditor.ScreenSize.Row - 4);\r
2401 }\r
2402\r
2403}\r
a1d4bfcc 2404\r
2405/**\r
2406 Dispatch input to different handler\r
2407\r
2408 @param[in] Key The input key:\r
2409 the keys can be:\r
2410 ASCII KEY\r
2411 Backspace/Delete\r
2412 Direction key: up/down/left/right/pgup/pgdn\r
2413 Home/End\r
2414 INS\r
2415\r
2416 @retval EFI_SUCCESS The operation was successful.\r
2417 @retval EFI_LOAD_ERROR A load error occured.\r
2418 @retval EFI_OUT_OF_RESOURCES A Memory allocation failed.\r
2419**/\r
2420EFI_STATUS\r
2421HBufferImageHandleInput (\r
2422 IN EFI_INPUT_KEY *Key\r
2423 )\r
2424{\r
2425 EFI_STATUS Status;\r
2426\r
2427 Status = EFI_SUCCESS;\r
2428\r
2429 switch (Key->ScanCode) {\r
2430 //\r
2431 // ordinary key\r
2432 //\r
2433 case SCAN_NULL:\r
2434 Status = HBufferImageDoCharInput (Key->UnicodeChar);\r
2435 break;\r
2436\r
2437 //\r
2438 // up arrow\r
2439 //\r
2440 case SCAN_UP:\r
2441 Status = HBufferImageScrollUp ();\r
2442 break;\r
2443\r
2444 //\r
2445 // down arrow\r
2446 //\r
2447 case SCAN_DOWN:\r
2448 Status = HBufferImageScrollDown ();\r
2449 break;\r
2450\r
2451 //\r
2452 // right arrow\r
2453 //\r
2454 case SCAN_RIGHT:\r
2455 Status = HBufferImageScrollRight ();\r
2456 break;\r
2457\r
2458 //\r
2459 // left arrow\r
2460 //\r
2461 case SCAN_LEFT:\r
2462 Status = HBufferImageScrollLeft ();\r
2463 break;\r
2464\r
2465 //\r
2466 // page up\r
2467 //\r
2468 case SCAN_PAGE_UP:\r
2469 Status = HBufferImagePageUp ();\r
2470 break;\r
2471\r
2472 //\r
2473 // page down\r
2474 //\r
2475 case SCAN_PAGE_DOWN:\r
2476 Status = HBufferImagePageDown ();\r
2477 break;\r
2478\r
2479 //\r
2480 // delete\r
2481 //\r
2482 case SCAN_DELETE:\r
2483 Status = HBufferImageDoDelete ();\r
2484 break;\r
2485\r
2486 //\r
2487 // home\r
2488 //\r
2489 case SCAN_HOME:\r
2490 Status = HBufferImageHome ();\r
2491 break;\r
2492\r
2493 //\r
2494 // end\r
2495 //\r
2496 case SCAN_END:\r
2497 Status = HBufferImageEnd ();\r
2498 break;\r
2499\r
2500 default:\r
2501 Status = StatusBarSetStatusString (L"Unknown Command");\r
2502 break;\r
2503 }\r
2504\r
2505 return Status;\r
2506}\r
2507\r