]> git.proxmox.com Git - mirror_edk2.git/blame - ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/BufferImage.c
ShellPkg: Fixed build error 'variable set but not used'
[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
632820d1 755 UINTN Tmp;\r
756\r
757 Orig = HMainEditor.ColorAttributes;\r
758 New.Colors.Foreground = Orig.Colors.Background;\r
759 New.Colors.Background = Orig.Colors.Foreground;\r
760\r
761 //\r
762 // if it's the first time after editor launch, so should refresh\r
763 //\r
764 if (HEditorFirst == FALSE) {\r
765 //\r
766 // no definite required refresh\r
767 // and file position displayed on screen has not been changed\r
768 //\r
ae724571 769 if (!HBufferImageNeedRefresh &&\r
770 !HBufferImageOnlyLineNeedRefresh &&\r
632820d1 771 HBufferImageBackupVar.LowVisibleRow == HBufferImage.LowVisibleRow\r
772 ) {\r
773 HBufferImageRestoreMousePosition ();\r
774 HBufferImageRestorePosition ();\r
775 return EFI_SUCCESS;\r
776 }\r
777 }\r
778\r
779 gST->ConOut->EnableCursor (gST->ConOut, FALSE);\r
780\r
781 //\r
782 // only need to refresh current line\r
783 //\r
ae724571 784 if (HBufferImageOnlyLineNeedRefresh && HBufferImageBackupVar.LowVisibleRow == HBufferImage.LowVisibleRow) {\r
632820d1 785\r
786 HBufferImagePrintLine (\r
787 HBufferImage.CurrentLine,\r
788 HBufferImage.DisplayPosition.Row,\r
789 HBufferImage.BufferPosition.Row,\r
790 Orig,\r
791 New\r
792 );\r
793 } else {\r
794 //\r
795 // the whole edit area need refresh\r
796 //\r
797 if (HEditorMouseAction && HMainEditor.SelectStart != 0 && HMainEditor.SelectEnd != 0) {\r
798 if (HMainEditor.SelectStart != HMainEditorBackupVar.SelectStart) {\r
799 if (HMainEditor.SelectStart >= HMainEditorBackupVar.SelectStart && HMainEditorBackupVar.SelectStart != 0) {\r
800 StartRow = (HMainEditorBackupVar.SelectStart - 1) / 0x10 + 1;\r
801 } else {\r
802 StartRow = (HMainEditor.SelectStart - 1) / 0x10 + 1;\r
803 }\r
804 } else {\r
805 StartRow = (HMainEditor.SelectStart - 1) / 0x10 + 1;\r
806 }\r
807\r
808 if (HMainEditor.SelectEnd <= HMainEditorBackupVar.SelectEnd) {\r
809 EndRow = (HMainEditorBackupVar.SelectEnd - 1) / 0x10 + 1;\r
810 } else {\r
811 EndRow = (HMainEditor.SelectEnd - 1) / 0x10 + 1;\r
812 }\r
813 //\r
814 // swap\r
815 //\r
816 if (StartRow > EndRow) {\r
817 Tmp = StartRow;\r
818 StartRow = EndRow;\r
819 EndRow = Tmp;\r
820 }\r
821\r
822 FStartRow = StartRow;\r
632820d1 823\r
824 StartRow = 2 + StartRow - HBufferImage.LowVisibleRow;\r
825 EndRow = 2 + EndRow - HBufferImage.LowVisibleRow;\r
826\r
827 } else {\r
828 //\r
829 // not mouse selection actions\r
830 //\r
831 FStartRow = HBufferImage.LowVisibleRow;\r
832 StartRow = 2;\r
5a2beb74 833 EndRow = (HMainEditor.ScreenSize.Row - 1);\r
632820d1 834 }\r
835 //\r
836 // no line\r
837 //\r
838 if (HBufferImage.Lines == NULL) {\r
839 HBufferImageRestoreMousePosition ();\r
840 HBufferImageRestorePosition ();\r
841 gST->ConOut->EnableCursor (gST->ConOut, TRUE);\r
842 return EFI_SUCCESS;\r
843 }\r
844 //\r
845 // get the first line that will be displayed\r
846 //\r
847 Line = HMoveLine (FStartRow - HBufferImage.BufferPosition.Row);\r
848 if (Line == NULL) {\r
849 gST->ConOut->EnableCursor (gST->ConOut, TRUE);\r
850 return EFI_LOAD_ERROR;\r
851 }\r
852\r
853 Link = &(Line->Link);\r
854 Row = StartRow;\r
855 do {\r
856 Line = CR (Link, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST);\r
857\r
858 //\r
859 // print line at row\r
860 //\r
861 HBufferImagePrintLine (\r
862 Line,\r
863 Row,\r
864 HBufferImage.LowVisibleRow + Row - 2,\r
865 Orig,\r
866 New\r
867 );\r
868\r
869 Link = Link->ForwardLink;\r
870 Row++;\r
871 } while (Link != HBufferImage.ListHead && Row <= EndRow);\r
872\r
873 while (Row <= EndRow) {\r
a1d4bfcc 874 EditorClearLine (Row, HMainEditor.ScreenSize.Column, HMainEditor.ScreenSize.Row);\r
632820d1 875 Row++;\r
876 }\r
877 //\r
878 // while not file end and not screen full\r
879 //\r
880 }\r
881\r
882 HBufferImageRestoreMousePosition ();\r
883 HBufferImageRestorePosition ();\r
884\r
885 HBufferImageNeedRefresh = FALSE;\r
886 HBufferImageOnlyLineNeedRefresh = FALSE;\r
887 gST->ConOut->EnableCursor (gST->ConOut, TRUE);\r
888\r
889 return EFI_SUCCESS;\r
890}\r
891\r
ae724571 892/**\r
893 Read an image into a buffer friom a source.\r
894\r
895 @param[in] FileName Pointer to the file name. OPTIONAL and ignored if not FileTypeFileBuffer.\r
896 @param[in] DiskName Pointer to the disk name. OPTIONAL and ignored if not FileTypeDiskBuffer.\r
897 @param[in] DiskOffset Offset into the disk. OPTIONAL and ignored if not FileTypeDiskBuffer.\r
898 @param[in] DiskSize Size of the disk buffer. OPTIONAL and ignored if not FileTypeDiskBuffer.\r
a1d4bfcc 899 @param[in] MemOffset Offset into the Memory. OPTIONAL and ignored if not FileTypeMemBuffer.\r
900 @param[in] MemSize Size of the Memory buffer. OPTIONAL and ignored if not FileTypeMemBuffer.\r
ae724571 901 @param[in] BufferType The type of buffer to save. IGNORED.\r
902 @param[in] Recover TRUE for recovermode, FALSE otherwise.\r
903\r
904 @return EFI_SUCCESS The operation was successful.\r
905**/\r
632820d1 906EFI_STATUS\r
ae724571 907EFIAPI\r
632820d1 908HBufferImageRead (\r
909 IN CONST CHAR16 *FileName,\r
910 IN CONST CHAR16 *DiskName,\r
911 IN UINTN DiskOffset,\r
912 IN UINTN DiskSize,\r
913 IN UINTN MemOffset,\r
914 IN UINTN MemSize,\r
915 IN EDIT_FILE_TYPE BufferType,\r
916 IN BOOLEAN Recover\r
917 )\r
918{\r
919 EFI_STATUS Status;\r
920 EDIT_FILE_TYPE BufferTypeBackup;\r
921\r
922 //\r
923 // variable initialization\r
924 //\r
925 Status = EFI_SUCCESS;\r
980d554e 926 HBufferImage.BufferType = BufferType;\r
632820d1 927\r
928 //\r
929 // three types of buffer supported\r
930 // file buffer\r
931 // disk buffer\r
932 // memory buffer\r
933 //\r
934 BufferTypeBackup = HBufferImage.BufferType;\r
935\r
936 switch (BufferType) {\r
937 case FileTypeFileBuffer:\r
938 Status = HFileImageRead (FileName, Recover);\r
939 break;\r
940\r
941 case FileTypeDiskBuffer:\r
942 Status = HDiskImageRead (DiskName, DiskOffset, DiskSize, Recover);\r
943 break;\r
944\r
945 case FileTypeMemBuffer:\r
946 Status = HMemImageRead (MemOffset, MemSize, Recover);\r
947 break;\r
e0c2cc6f 948 \r
949 default:\r
950 Status = EFI_NOT_FOUND;\r
951 break;\r
632820d1 952 }\r
953\r
954 if (EFI_ERROR (Status)) {\r
955 HBufferImage.BufferType = BufferTypeBackup;\r
956 }\r
957\r
958 return Status;\r
959}\r
960\r
ae724571 961/**\r
962 Save the current image.\r
963\r
964 @param[in] FileName Pointer to the file name. OPTIONAL and ignored if not FileTypeFileBuffer.\r
965 @param[in] DiskName Pointer to the disk name. OPTIONAL and ignored if not FileTypeDiskBuffer.\r
966 @param[in] DiskOffset Offset into the disk. OPTIONAL and ignored if not FileTypeDiskBuffer.\r
967 @param[in] DiskSize Size of the disk buffer. OPTIONAL and ignored if not FileTypeDiskBuffer.\r
a1d4bfcc 968 @param[in] MemOffset Offset into the Memory. OPTIONAL and ignored if not FileTypeMemBuffer.\r
969 @param[in] MemSize Size of the Memory buffer. OPTIONAL and ignored if not FileTypeMemBuffer.\r
ae724571 970 @param[in] BufferType The type of buffer to save. IGNORED.\r
971\r
972 @return EFI_SUCCESS The operation was successful.\r
973**/\r
632820d1 974EFI_STATUS\r
975HBufferImageSave (\r
976 IN CHAR16 *FileName,\r
977 IN CHAR16 *DiskName,\r
978 IN UINTN DiskOffset,\r
979 IN UINTN DiskSize,\r
980 IN UINTN MemOffset,\r
981 IN UINTN MemSize,\r
982 IN EDIT_FILE_TYPE BufferType\r
983 )\r
984{\r
985 EFI_STATUS Status;\r
986 EDIT_FILE_TYPE BufferTypeBackup;\r
987\r
988 //\r
989 // variable initialization\r
990 //\r
991 Status = EFI_SUCCESS;\r
992 BufferTypeBackup = HBufferImage.BufferType;\r
993\r
994 switch (HBufferImage.BufferType) {\r
995 //\r
996 // file buffer\r
997 //\r
998 case FileTypeFileBuffer:\r
999 Status = HFileImageSave (FileName);\r
1000 break;\r
1001\r
1002 //\r
1003 // disk buffer\r
1004 //\r
1005 case FileTypeDiskBuffer:\r
1006 Status = HDiskImageSave (DiskName, DiskOffset, DiskSize);\r
1007 break;\r
1008\r
1009 //\r
1010 // memory buffer\r
1011 //\r
1012 case FileTypeMemBuffer:\r
1013 Status = HMemImageSave (MemOffset, MemSize);\r
1014 break;\r
e0c2cc6f 1015 \r
1016 default:\r
1017 Status = EFI_NOT_FOUND;\r
1018 break;\r
632820d1 1019 }\r
1020\r
1021 if (EFI_ERROR (Status)) {\r
1022 HBufferImage.BufferType = BufferTypeBackup;\r
1023 }\r
1024\r
1025 return Status;\r
1026}\r
1027\r
e0c2cc6f 1028/**
ae724571 1029 Create a new line and append it to the line list.\r
632820d1 1030 Fields affected:\r
1031 NumLines\r
1032 Lines \r
1033\r
ae724571 1034 @retval NULL create line failed.\r
1035 @return the line created.\r
632820d1 1036\r
ae724571 1037**/\r
1038HEFI_EDITOR_LINE *\r
1039HBufferImageCreateLine (\r
1040 VOID\r
1041 )\r
632820d1 1042{\r
1043 HEFI_EDITOR_LINE *Line;\r
1044\r
1045 //\r
1046 // allocate for line structure\r
1047 //\r
1048 Line = AllocateZeroPool (sizeof (HEFI_EDITOR_LINE));\r
1049 if (Line == NULL) {\r
1050 return NULL;\r
1051 }\r
1052\r
1053 Line->Signature = EFI_EDITOR_LINE_LIST;\r
1054 Line->Size = 0;\r
1055\r
1056 HBufferImage.NumLines++;\r
1057\r
1058 //\r
1059 // insert to line list\r
1060 //\r
1061 InsertTailList (HBufferImage.ListHead, &Line->Link);\r
1062\r
1063 if (HBufferImage.Lines == NULL) {\r
1064 HBufferImage.Lines = CR (\r
1065 HBufferImage.ListHead->ForwardLink,\r
1066 HEFI_EDITOR_LINE,\r
1067 Link,\r
1068 EFI_EDITOR_LINE_LIST\r
1069 );\r
1070 }\r
1071\r
1072 return Line;\r
1073}\r
1074\r
e0c2cc6f 1075/**
ae724571 1076 Free the current image.\r
1077\r
1078 @retval EFI_SUCCESS The operation was successful.\r
1079**/\r
632820d1 1080EFI_STATUS\r
1081HBufferImageFree (\r
1082 VOID\r
1083 )\r
632820d1 1084{\r
1085 //\r
1086 // free all lines\r
1087 //\r
1088 HBufferImageFreeLines ();\r
1089\r
1090 return EFI_SUCCESS;\r
1091}\r
1092\r
e0c2cc6f 1093/**
ae724571 1094 change char to int value based on Hex.\r
1095\r
1096 @param[in] Char The input char.\r
1097\r
1098 @return The character's index value.\r
1099 @retval -1 The operation failed.\r
1100**/\r
632820d1 1101INTN\r
ae724571 1102EFIAPI\r
632820d1 1103HBufferImageCharToHex (\r
1104 IN CHAR16 Char\r
1105 )\r
632820d1 1106{\r
1107 //\r
1108 // change the character to hex\r
1109 //\r
1110 if (Char >= L'0' && Char <= L'9') {\r
1111 return (INTN) (Char - L'0');\r
1112 }\r
1113\r
1114 if (Char >= L'a' && Char <= L'f') {\r
1115 return (INTN) (Char - L'a' + 10);\r
1116 }\r
1117\r
1118 if (Char >= L'A' && Char <= L'F') {\r
1119 return (INTN) (Char - L'A' + 10);\r
1120 }\r
1121\r
1122 return -1;\r
1123}\r
1124\r
ae724571 1125/**\r
1126 Add character.\r
1127\r
1128 @param[in] Char -- input char.\r
1129\r
1130 @retval EFI_SUCCESS The operation was successful.\r
1131 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.\r
1132**/\r
632820d1 1133EFI_STATUS\r
ae724571 1134EFIAPI\r
632820d1 1135HBufferImageAddChar (\r
1136 IN CHAR16 Char\r
1137 )\r
632820d1 1138{\r
1139 HEFI_EDITOR_LINE *Line;\r
1140 HEFI_EDITOR_LINE *NewLine;\r
1141 INTN Value;\r
1142 UINT8 Old;\r
1143 UINTN FRow;\r
1144 UINTN FCol;\r
1145 BOOLEAN High;\r
1146\r
1147 Value = HBufferImageCharToHex (Char);\r
1148\r
1149 //\r
1150 // invalid input\r
1151 //\r
1152 if (Value == -1) {\r
1153 return EFI_SUCCESS;\r
1154 }\r
1155\r
1156 Line = HBufferImage.CurrentLine;\r
1157 FRow = HBufferImage.BufferPosition.Row;\r
1158 FCol = HBufferImage.BufferPosition.Column;\r
1159 High = HBufferImage.HighBits;\r
1160\r
1161 //\r
1162 // only needs to refresh current line\r
1163 //\r
1164 HBufferImageOnlyLineNeedRefresh = TRUE;\r
1165\r
1166 //\r
1167 // not a full line and beyond the last character\r
1168 //\r
1169 if (FCol > Line->Size) {\r
1170 //\r
1171 // cursor always at high 4 bits\r
1172 // and always put input to the low 4 bits\r
1173 //\r
1174 Line->Buffer[Line->Size] = (UINT8) Value;\r
1175 Line->Size++;\r
1176 High = FALSE;\r
1177 } else {\r
1178\r
1179 Old = Line->Buffer[FCol - 1];\r
1180\r
1181 //\r
1182 // always put the input to the low 4 bits\r
1183 //\r
1184 Old = (UINT8) (Old & 0x0f);\r
1185 Old = (UINT8) (Old << 4);\r
1186 Old = (UINT8) (Value + Old);\r
1187 Line->Buffer[FCol - 1] = Old;\r
1188\r
1189 //\r
1190 // at the low 4 bits of the last character of a full line\r
1191 // so if no next line, need to create a new line\r
1192 //\r
ae724571 1193 if (!High && FCol == 0x10) {\r
632820d1 1194\r
1195 HBufferImageOnlyLineNeedRefresh = FALSE;\r
1196 HBufferImageNeedRefresh = TRUE;\r
1197\r
1198 if (Line->Link.ForwardLink == HBufferImage.ListHead) {\r
1199 //\r
1200 // last line\r
1201 //\r
1202 // create a new line\r
1203 //\r
1204 NewLine = HBufferImageCreateLine ();\r
1205 if (NewLine == NULL) {\r
1206 return EFI_OUT_OF_RESOURCES;\r
1207 }\r
1208 //\r
1209 // end of NULL\r
1210 //\r
1211 }\r
1212 //\r
1213 // end of == ListHead\r
1214 //\r
1215 }\r
1216 //\r
1217 // end of == 0x10\r
1218 //\r
1219 // if already at end of this line, scroll it to the start of next line\r
1220 //\r
ae724571 1221 if (FCol == 0x10 && !High) {\r
632820d1 1222 //\r
1223 // definitely has next line\r
1224 //\r
1225 FRow++;\r
1226 FCol = 1;\r
1227 High = TRUE;\r
1228 } else {\r
1229 //\r
1230 // if not at end of this line, just move to next column\r
1231 //\r
1232 if (!High) {\r
1233 FCol++;\r
1234 }\r
1235\r
1236 if (High) {\r
1237 High = FALSE;\r
1238 } else {\r
1239 High = TRUE;\r
1240 }\r
1241\r
1242 }\r
1243 //\r
1244 // end of ==FALSE\r
1245 //\r
1246 }\r
1247 //\r
1248 // move cursor to right\r
1249 //\r
1250 HBufferImageMovePosition (FRow, FCol, High);\r
1251\r
1252 if (!HBufferImage.Modified) {\r
1253 HBufferImage.Modified = TRUE;\r
1254 }\r
1255\r
1256 return EFI_SUCCESS;\r
1257}\r
1258\r
ae724571 1259/**\r
a1d4bfcc 1260 Delete the previous character.\r
ae724571 1261\r
a1d4bfcc 1262 @retval EFI_SUCCESS The operationw as successful.\r
ae724571 1263**/\r
a1d4bfcc 1264EFI_STATUS\r
1265EFIAPI\r
1266HBufferImageDoBackspace (\r
1267 VOID\r
632820d1 1268 )\r
632820d1 1269{\r
a1d4bfcc 1270 HEFI_EDITOR_LINE *Line;\r
632820d1 1271\r
a1d4bfcc 1272 UINTN FileColumn;\r
1273 UINTN FPos;\r
1274 BOOLEAN LastLine;\r
1275\r
1276 //\r
1277 // variable initialization\r
1278 //\r
1279 LastLine = FALSE;\r
1280\r
1281 //\r
1282 // already the first character\r
1283 //\r
1284 if (HBufferImage.BufferPosition.Row == 1 && HBufferImage.BufferPosition.Column == 1) {\r
1285 return EFI_SUCCESS;\r
1286 }\r
1287\r
1288 FPos = (HBufferImage.BufferPosition.Row - 1) * 0x10 + HBufferImage.BufferPosition.Column - 1;\r
1289\r
1290 FileColumn = HBufferImage.BufferPosition.Column;\r
1291\r
1292 Line = HBufferImage.CurrentLine;\r
1293 LastLine = FALSE;\r
1294 if (Line->Link.ForwardLink == HBufferImage.ListHead && FileColumn > 1) {\r
1295 LastLine = TRUE;\r
1296 }\r
1297\r
1298 HBufferImageDeleteCharacterFromBuffer (FPos - 1, 1, NULL);\r
1299\r
1300 //\r
1301 // if is the last line\r
1302 // then only this line need to be refreshed\r
1303 //\r
1304 if (LastLine) {\r
1305 HBufferImageNeedRefresh = FALSE;\r
1306 HBufferImageOnlyLineNeedRefresh = TRUE;\r
1307 } else {\r
1308 HBufferImageNeedRefresh = TRUE;\r
1309 HBufferImageOnlyLineNeedRefresh = FALSE;\r
1310 }\r
1311\r
1312 if (!HBufferImage.Modified) {\r
1313 HBufferImage.Modified = TRUE;\r
1314 }\r
1315\r
1316 return EFI_SUCCESS;\r
1317}\r
1318\r
1319/**\r
1320 ASCII key + Backspace + return.\r
1321\r
1322 @param[in] Char The input char.\r
1323\r
1324 @retval EFI_SUCCESS The operation was successful.\r
1325 @retval EFI_LOAD_ERROR A load error occured.\r
1326 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.\r
1327**/\r
1328EFI_STATUS\r
1329EFIAPI\r
1330HBufferImageDoCharInput (\r
1331 IN CHAR16 Char\r
1332 )\r
1333{\r
1334 EFI_STATUS Status;\r
1335\r
1336 Status = EFI_SUCCESS;\r
1337\r
1338 switch (Char) {\r
1339 case 0:\r
1340 break;\r
1341\r
1342 case 0x08:\r
1343 Status = HBufferImageDoBackspace ();\r
1344 break;\r
1345\r
1346 case 0x09:\r
1347 case 0x0a:\r
1348 case 0x0d:\r
1349 //\r
1350 // Tabs, Returns are thought as nothing\r
1351 //\r
1352 break;\r
1353\r
1354 default:\r
1355 //\r
1356 // DEAL WITH ASCII CHAR, filter out thing like ctrl+f\r
1357 //\r
1358 if (Char > 127 || Char < 32) {\r
1359 Status = StatusBarSetStatusString (L"Unknown Command");\r
1360 } else {\r
1361 Status = HBufferImageAddChar (Char);\r
1362 }\r
1363\r
1364 break;\r
1365 }\r
1366\r
1367 return Status;\r
632820d1 1368}\r
1369\r
ae724571 1370/**\r
1371 Check user specified FileRow is above current screen.\r
1372\r
1373 @param[in] FileRow Row of file position ( start from 1 ).\r
1374 \r
1375 @retval TRUE It is above the current screen.\r
1376 @retval FALSE It is not above the current screen.\r
1377\r
1378**/\r
632820d1 1379BOOLEAN\r
1380HAboveCurrentScreen (\r
1381 IN UINTN FileRow\r
1382 )\r
632820d1 1383{\r
1384 if (FileRow < HBufferImage.LowVisibleRow) {\r
1385 return TRUE;\r
1386 }\r
1387\r
1388 return FALSE;\r
1389}\r
1390\r
ae724571 1391/**\r
1392 Check user specified FileRow is under current screen.\r
1393\r
1394 @param[in] FileRow Row of file position ( start from 1 ).\r
1395\r
1396 @retval TRUE It is under the current screen.\r
1397 @retval FALSE It is not under the current screen.\r
1398\r
1399**/\r
632820d1 1400BOOLEAN\r
1401HUnderCurrentScreen (\r
1402 IN UINTN FileRow\r
1403 )\r
632820d1 1404{\r
5a2beb74 1405 if (FileRow > HBufferImage.LowVisibleRow + (HMainEditor.ScreenSize.Row - 2) - 1) {\r
632820d1 1406 return TRUE;\r
1407 }\r
1408\r
1409 return FALSE;\r
1410}\r
1411\r
ae724571 1412/**\r
1413 According to cursor's file position, adjust screen display.\r
1414\r
1415 @param[in] NewFilePosRow Row of file position ( start from 1 ).\r
1416 @param[in] NewFilePosCol Column of file position ( start from 1 ).\r
1417 @param[in] HighBits Cursor will on high4 bits or low4 bits.\r
1418**/\r
632820d1 1419VOID\r
1420HBufferImageMovePosition (\r
1421 IN UINTN NewFilePosRow,\r
1422 IN UINTN NewFilePosCol,\r
1423 IN BOOLEAN HighBits\r
1424 )\r
632820d1 1425{\r
1426 INTN RowGap;\r
1427 UINTN Abs;\r
1428 BOOLEAN Above;\r
1429 BOOLEAN Under;\r
1430 UINTN NewDisplayCol;\r
1431\r
1432 //\r
1433 // CALCULATE gap between current file position and new file position\r
1434 //\r
1435 RowGap = NewFilePosRow - HBufferImage.BufferPosition.Row;\r
1436\r
1437 Under = HUnderCurrentScreen (NewFilePosRow);\r
1438 Above = HAboveCurrentScreen (NewFilePosRow);\r
1439\r
1440 HBufferImage.HighBits = HighBits;\r
1441\r
1442 //\r
1443 // if is below current screen\r
1444 //\r
1445 if (Under) {\r
1446 //\r
1447 // display row will be unchanged\r
1448 //\r
1449 HBufferImage.BufferPosition.Row = NewFilePosRow;\r
1450 } else {\r
1451 if (Above) {\r
1452 //\r
1453 // has enough above line, so display row unchanged\r
1454 // not has enough above lines, so the first line is\r
1455 // at the first display line\r
1456 //\r
1457 if (NewFilePosRow < (HBufferImage.DisplayPosition.Row - 2 + 1)) {\r
1458 HBufferImage.DisplayPosition.Row = NewFilePosRow + 2 - 1;\r
1459 }\r
1460\r
1461 HBufferImage.BufferPosition.Row = NewFilePosRow;\r
1462 } else {\r
1463 //\r
1464 // in current screen\r
1465 //\r
1466 HBufferImage.BufferPosition.Row = NewFilePosRow;\r
1467 if (RowGap <= 0) {\r
33c031ee 1468 Abs = (UINTN)ABS(RowGap);\r
632820d1 1469 HBufferImage.DisplayPosition.Row -= Abs;\r
1470 } else {\r
1471 HBufferImage.DisplayPosition.Row += RowGap;\r
1472 }\r
1473\r
1474 }\r
1475 }\r
1476\r
1477 HBufferImage.LowVisibleRow = HBufferImage.BufferPosition.Row - (HBufferImage.DisplayPosition.Row - 2);\r
1478\r
1479 //\r
1480 // always in current screen\r
1481 //\r
1482 HBufferImage.BufferPosition.Column = NewFilePosCol;\r
1483\r
1484 NewDisplayCol = 10 + (NewFilePosCol - 1) * 3;\r
1485 if (NewFilePosCol > 0x8) {\r
1486 NewDisplayCol++;\r
1487 }\r
1488\r
ae724571 1489 if (!HighBits) {\r
632820d1 1490 NewDisplayCol++;\r
1491 }\r
1492\r
1493 HBufferImage.DisplayPosition.Column = NewDisplayCol;\r
1494\r
1495 //\r
1496 // let CurrentLine point to correct line;\r
1497 //\r
1498 HBufferImage.CurrentLine = HMoveCurrentLine (RowGap);\r
1499\r
1500}\r
1501\r
ae724571 1502/**\r
1503 Scroll cursor to right.\r
1504\r
1505 @retval EFI_SUCCESS The operation was successful.\r
1506**/\r
632820d1 1507EFI_STATUS\r
1508HBufferImageScrollRight (\r
1509 VOID\r
1510 )\r
632820d1 1511{\r
1512 HEFI_EDITOR_LINE *Line;\r
1513 UINTN FRow;\r
1514 UINTN FCol;\r
1515\r
1516 //\r
1517 // scroll right will always move to the high4 bits of the next character\r
1518 //\r
1519 HBufferImageNeedRefresh = FALSE;\r
1520 HBufferImageOnlyLineNeedRefresh = FALSE;\r
1521\r
1522 Line = HBufferImage.CurrentLine;\r
1523\r
1524 FRow = HBufferImage.BufferPosition.Row;\r
1525 FCol = HBufferImage.BufferPosition.Column;\r
1526\r
1527 //\r
1528 // this line is not full and no next line\r
1529 //\r
1530 if (FCol > Line->Size) {\r
1531 return EFI_SUCCESS;\r
1532 }\r
1533 //\r
1534 // if already at end of this line, scroll it to the start of next line\r
1535 //\r
1536 if (FCol == 0x10) {\r
1537 //\r
1538 // has next line\r
1539 //\r
1540 if (Line->Link.ForwardLink != HBufferImage.ListHead) {\r
1541 FRow++;\r
1542 FCol = 1;\r
1543\r
1544 } else {\r
1545 return EFI_SUCCESS;\r
1546 }\r
1547 } else {\r
1548 //\r
1549 // if not at end of this line, just move to next column\r
1550 //\r
1551 FCol++;\r
1552\r
1553 }\r
1554\r
1555 HBufferImageMovePosition (FRow, FCol, TRUE);\r
1556\r
1557 return EFI_SUCCESS;\r
1558}\r
1559\r
ae724571 1560/**\r
1561 Scroll cursor to left.\r
1562\r
1563 @retval EFI_SUCCESS The operation was successful.\r
1564**/\r
632820d1 1565EFI_STATUS\r
1566HBufferImageScrollLeft (\r
1567 VOID\r
1568 )\r
632820d1 1569{\r
1570\r
1571 HEFI_EDITOR_LINE *Line;\r
1572 UINTN FRow;\r
1573 UINTN FCol;\r
1574\r
1575 HBufferImageNeedRefresh = FALSE;\r
1576 HBufferImageOnlyLineNeedRefresh = FALSE;\r
1577\r
1578 Line = HBufferImage.CurrentLine;\r
1579\r
1580 FRow = HBufferImage.BufferPosition.Row;\r
1581 FCol = HBufferImage.BufferPosition.Column;\r
1582\r
1583 //\r
1584 // if already at start of this line, so move to the end of previous line\r
1585 //\r
1586 if (FCol <= 1) {\r
1587 //\r
1588 // has previous line\r
1589 //\r
1590 if (Line->Link.BackLink != HBufferImage.ListHead) {\r
1591 FRow--;\r
1592 Line = CR (Line->Link.BackLink, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST);\r
1593 FCol = Line->Size;\r
1594 } else {\r
1595 return EFI_SUCCESS;\r
1596 }\r
1597 } else {\r
1598 //\r
1599 // if not at start of this line, just move to previous column\r
1600 //\r
1601 FCol--;\r
1602 }\r
1603\r
1604 HBufferImageMovePosition (FRow, FCol, TRUE);\r
1605\r
1606 return EFI_SUCCESS;\r
1607}\r
1608\r
ae724571 1609/**\r
1610 Scroll cursor to the next line\r
1611\r
1612 @retval EFI_SUCCESS The operation was successful.\r
1613**/\r
632820d1 1614EFI_STATUS\r
1615HBufferImageScrollDown (\r
1616 VOID\r
1617 )\r
632820d1 1618{\r
1619 HEFI_EDITOR_LINE *Line;\r
1620 UINTN FRow;\r
1621 UINTN FCol;\r
1622 BOOLEAN HighBits;\r
1623\r
1624 Line = HBufferImage.CurrentLine;\r
1625\r
1626 FRow = HBufferImage.BufferPosition.Row;\r
1627 FCol = HBufferImage.BufferPosition.Column;\r
1628 HighBits = HBufferImage.HighBits;\r
1629\r
1630 //\r
1631 // has next line\r
1632 //\r
1633 if (Line->Link.ForwardLink != HBufferImage.ListHead) {\r
1634 FRow++;\r
1635 Line = CR (Line->Link.ForwardLink, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST);\r
1636\r
1637 //\r
1638 // if the next line is not that long, so move to end of next line\r
1639 //\r
1640 if (FCol > Line->Size) {\r
1641 FCol = Line->Size + 1;\r
1642 HighBits = TRUE;\r
1643 }\r
1644\r
1645 } else {\r
1646 return EFI_SUCCESS;\r
1647 }\r
1648\r
1649 HBufferImageMovePosition (FRow, FCol, HighBits);\r
1650\r
1651 return EFI_SUCCESS;\r
1652}\r
1653\r
ae724571 1654/**\r
1655 Scroll cursor to previous line\r
1656\r
1657 @retval EFI_SUCCESS The operation was successful.\r
1658**/\r
632820d1 1659EFI_STATUS\r
1660HBufferImageScrollUp (\r
1661 VOID\r
1662 )\r
632820d1 1663{\r
1664 HEFI_EDITOR_LINE *Line;\r
1665 UINTN FRow;\r
1666 UINTN FCol;\r
1667\r
1668 Line = HBufferImage.CurrentLine;\r
1669\r
1670 FRow = HBufferImage.BufferPosition.Row;\r
1671 FCol = HBufferImage.BufferPosition.Column;\r
1672\r
1673 //\r
1674 // has previous line\r
1675 //\r
1676 if (Line->Link.BackLink != HBufferImage.ListHead) {\r
1677 FRow--;\r
1678\r
1679 } else {\r
1680 return EFI_SUCCESS;\r
1681 }\r
1682\r
1683 HBufferImageMovePosition (FRow, FCol, HBufferImage.HighBits);\r
1684\r
1685 return EFI_SUCCESS;\r
1686}\r
1687\r
ae724571 1688/**\r
1689 Scroll cursor to next page\r
1690\r
1691 @retval EFI_SUCCESS The operation was successful.\r
1692**/\r
632820d1 1693EFI_STATUS\r
1694HBufferImagePageDown (\r
1695 VOID\r
1696 )\r
632820d1 1697{\r
1698 HEFI_EDITOR_LINE *Line;\r
1699 UINTN FRow;\r
1700 UINTN FCol;\r
1701 UINTN Gap;\r
1702 BOOLEAN HighBits;\r
1703\r
1704 Line = HBufferImage.CurrentLine;\r
1705\r
1706 FRow = HBufferImage.BufferPosition.Row;\r
1707 FCol = HBufferImage.BufferPosition.Column;\r
1708 HighBits = HBufferImage.HighBits;\r
1709\r
1710 //\r
1711 // has next page\r
1712 //\r
5a2beb74 1713 if (HBufferImage.NumLines >= FRow + (HMainEditor.ScreenSize.Row - 2)) {\r
1714 Gap = (HMainEditor.ScreenSize.Row - 2);\r
632820d1 1715 } else {\r
1716 //\r
1717 // MOVE CURSOR TO LAST LINE\r
1718 //\r
1719 Gap = HBufferImage.NumLines - FRow;\r
1720 }\r
1721 //\r
1722 // get correct line\r
1723 //\r
1724 Line = HMoveLine (Gap);\r
1725\r
1726 //\r
1727 // if that line, is not that long, so move to the end of that line\r
1728 //\r
33c031ee 1729 if (Line != NULL && FCol > Line->Size) {\r
632820d1 1730 FCol = Line->Size + 1;\r
1731 HighBits = TRUE;\r
1732 }\r
1733\r
1734 FRow += Gap;\r
1735\r
1736 HBufferImageMovePosition (FRow, FCol, HighBits);\r
1737\r
1738 return EFI_SUCCESS;\r
1739}\r
1740\r
ae724571 1741/**\r
1742 Scroll cursor to previous page\r
1743\r
1744 @retval EFI_SUCCESS The operation was successful.\r
1745**/\r
632820d1 1746EFI_STATUS\r
1747HBufferImagePageUp (\r
1748 VOID\r
1749 )\r
632820d1 1750{\r
632820d1 1751 UINTN FRow;\r
1752 UINTN FCol;\r
1753 UINTN Gap;\r
1754 INTN Retreat;\r
1755\r
632820d1 1756 FRow = HBufferImage.BufferPosition.Row;\r
1757 FCol = HBufferImage.BufferPosition.Column;\r
1758\r
1759 //\r
1760 // has previous page\r
1761 //\r
5a2beb74 1762 if (FRow > (HMainEditor.ScreenSize.Row - 2)) {\r
1763 Gap = (HMainEditor.ScreenSize.Row - 2);\r
632820d1 1764 } else {\r
1765 //\r
1766 // the first line of file will displayed on the first line of screen\r
1767 //\r
1768 Gap = FRow - 1;\r
1769 }\r
1770\r
1771 Retreat = Gap;\r
1772 Retreat = -Retreat;\r
1773\r
632820d1 1774 FRow -= Gap;\r
1775\r
1776 HBufferImageMovePosition (FRow, FCol, HBufferImage.HighBits);\r
1777\r
1778 return EFI_SUCCESS;\r
1779}\r
1780\r
ae724571 1781/**\r
1782 Scroll cursor to start of line\r
1783\r
1784 @retval EFI_SUCCESS The operation was successful.\r
1785**/\r
632820d1 1786EFI_STATUS\r
1787HBufferImageHome (\r
1788 VOID\r
1789 )\r
632820d1 1790{\r
632820d1 1791 UINTN FRow;\r
1792 UINTN FCol;\r
1793 BOOLEAN HighBits;\r
1794\r
632820d1 1795 //\r
1796 // curosr will at the high bit\r
1797 //\r
1798 FRow = HBufferImage.BufferPosition.Row;\r
1799 FCol = 1;\r
1800 HighBits = TRUE;\r
1801\r
1802 //\r
1803 // move cursor position\r
1804 //\r
1805 HBufferImageMovePosition (FRow, FCol, HighBits);\r
1806\r
1807 return EFI_SUCCESS;\r
1808}\r
1809\r
ae724571 1810/**\r
1811 Scroll cursor to end of line.\r
1812\r
1813 @retval EFI_SUCCESS Teh operation was successful.\r
1814**/\r
632820d1 1815EFI_STATUS\r
1816HBufferImageEnd (\r
1817 VOID\r
1818 )\r
632820d1 1819{\r
1820 HEFI_EDITOR_LINE *Line;\r
1821 UINTN FRow;\r
1822 UINTN FCol;\r
1823 BOOLEAN HighBits;\r
1824\r
1825 //\r
1826 // need refresh mouse\r
1827 //\r
1828 HBufferImageMouseNeedRefresh = TRUE;\r
1829\r
1830 Line = HBufferImage.CurrentLine;\r
1831\r
1832 FRow = HBufferImage.BufferPosition.Row;\r
1833\r
1834 if (Line->Size == 0x10) {\r
1835 FCol = Line->Size;\r
1836 HighBits = FALSE;\r
1837 } else {\r
1838 FCol = Line->Size + 1;\r
1839 HighBits = TRUE;\r
1840 }\r
1841 //\r
1842 // move cursor position\r
1843 //\r
1844 HBufferImageMovePosition (FRow, FCol, HighBits);\r
1845\r
1846 return EFI_SUCCESS;\r
1847}\r
1848\r
ae724571 1849/**\r
1850 Get the size of the open buffer.\r
1851\r
1852 @retval The size in bytes.\r
1853**/\r
632820d1 1854UINTN\r
1855HBufferImageGetTotalSize (\r
1856 VOID\r
1857 )\r
1858{\r
1859 UINTN Size;\r
1860\r
1861 HEFI_EDITOR_LINE *Line;\r
1862\r
1863 //\r
1864 // calculate the total size of whole line list's buffer\r
1865 //\r
1866 if (HBufferImage.Lines == NULL) {\r
1867 return 0;\r
1868 }\r
1869\r
1870 Line = CR (\r
1871 HBufferImage.ListHead->BackLink,\r
1872 HEFI_EDITOR_LINE,\r
1873 Link,\r
1874 EFI_EDITOR_LINE_LIST\r
1875 );\r
1876 //\r
1877 // one line at most 0x10\r
1878 //\r
1879 Size = 0x10 * (HBufferImage.NumLines - 1) + Line->Size;\r
1880\r
1881 return Size;\r
1882}\r
1883\r
ae724571 1884/**\r
1885 Delete character from buffer.\r
1886 \r
1887 @param[in] Pos Position, Pos starting from 0.\r
1888 @param[in] Count The Count of characters to delete.\r
a1d4bfcc 1889 @param[out] DeleteBuffer The DeleteBuffer.\r
ae724571 1890\r
1891 @retval EFI_SUCCESS Success \r
1892**/\r
632820d1 1893EFI_STATUS\r
1894HBufferImageDeleteCharacterFromBuffer (\r
1895 IN UINTN Pos,\r
1896 IN UINTN Count,\r
1897 OUT UINT8 *DeleteBuffer\r
1898 )\r
632820d1 1899{\r
1900 UINTN Index;\r
1901\r
1902 VOID *Buffer;\r
1903 UINT8 *BufferPtr;\r
1904 UINTN Size;\r
1905\r
1906 HEFI_EDITOR_LINE *Line;\r
1907 LIST_ENTRY *Link;\r
632820d1 1908\r
1909 UINTN OldFCol;\r
1910 UINTN OldFRow;\r
1911 UINTN OldPos;\r
1912\r
1913 UINTN NewPos;\r
1914\r
1915 EFI_STATUS Status;\r
1916\r
632820d1 1917 Size = HBufferImageGetTotalSize ();\r
1918\r
1919 if (Size < Count) {\r
1920 return EFI_LOAD_ERROR;\r
1921 }\r
1922\r
1923 if (Size == 0) {\r
1924 return EFI_SUCCESS;\r
1925 }\r
1926\r
1927 //\r
1928 // relocate all the HBufferImage fields\r
1929 //\r
1930 OldFRow = HBufferImage.BufferPosition.Row;\r
1931 OldFCol = HBufferImage.BufferPosition.Column;\r
1932 OldPos = (OldFRow - 1) * 0x10 + OldFCol - 1;\r
1933\r
1934 if (Pos > 0) {\r
1935 //\r
1936 // has character before it,\r
1937 // so locate according to block's previous character\r
1938 //\r
1939 NewPos = Pos - 1;\r
1940\r
1941 } else {\r
1942 //\r
1943 // has no character before it,\r
1944 // so locate according to block's next character\r
1945 //\r
1946 NewPos = 0;\r
1947 }\r
1948\r
1949 HBufferImageMovePosition (NewPos / 0x10 + 1, NewPos % 0x10 + 1, TRUE);\r
1950\r
1951 Buffer = AllocateZeroPool (Size);\r
1952 if (Buffer == NULL) {\r
1953 return EFI_OUT_OF_RESOURCES;\r
1954 }\r
1955\r
1956 HBufferImageListToBuffer (Buffer, Size);\r
1957\r
1958 BufferPtr = (UINT8 *) Buffer;\r
1959\r
1960 //\r
1961 // pass deleted buffer out\r
1962 //\r
1963 if (DeleteBuffer != NULL) {\r
1964 for (Index = 0; Index < Count; Index++) {\r
1965 DeleteBuffer[Index] = BufferPtr[Pos + Index];\r
1966 }\r
1967 }\r
1968 //\r
1969 // delete the part from Pos\r
1970 //\r
1971 for (Index = Pos; Index < Size - Count; Index++) {\r
1972 BufferPtr[Index] = BufferPtr[Index + Count];\r
1973 }\r
1974\r
1975 Size -= Count;\r
1976\r
1977 HBufferImageFreeLines ();\r
1978\r
1979 Status = HBufferImageBufferToList (Buffer, Size);\r
1980 FreePool (Buffer);\r
1981\r
1982 if (EFI_ERROR (Status)) {\r
1983 return Status;\r
1984 }\r
1985\r
1986 Link = HMainEditor.BufferImage->ListHead->ForwardLink;\r
1987 for (Index = 0; Index < NewPos / 0x10; Index++) {\r
1988 Link = Link->ForwardLink;\r
1989 }\r
1990\r
1991 Line = CR (Link, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST);\r
1992 HBufferImage.CurrentLine = Line;\r
1993\r
1994 //\r
1995 // if current cursor position if inside select area\r
1996 // then move it to the block's NEXT character\r
1997 //\r
1998 if (OldPos >= Pos && OldPos < (Pos + Count)) {\r
1999 NewPos = Pos;\r
2000 } else {\r
2001 if (OldPos < Pos) {\r
2002 NewPos = OldPos;\r
2003 } else {\r
2004 NewPos = OldPos - Count;\r
2005 }\r
2006 }\r
2007\r
2008 HBufferImageMovePosition (NewPos / 0x10 + 1, NewPos % 0x10 + 1, TRUE);\r
2009\r
2010 return EFI_SUCCESS;\r
2011}\r
2012\r
ae724571 2013/**\r
2014 Add character to buffer, add before pos.\r
2015\r
2016 @param[in] Pos Position, Pos starting from 0.\r
2017 @param[in] Count Count of characters to add.\r
2018 @param[in] AddBuffer Add buffer.\r
2019\r
2020 @retval EFI_SUCCESS Success. \r
2021**/\r
632820d1 2022EFI_STATUS\r
2023HBufferImageAddCharacterToBuffer (\r
2024 IN UINTN Pos,\r
2025 IN UINTN Count,\r
2026 IN UINT8 *AddBuffer\r
2027 )\r
632820d1 2028{\r
2029 INTN Index;\r
2030\r
2031 VOID *Buffer;\r
2032 UINT8 *BufferPtr;\r
2033 UINTN Size;\r
2034\r
2035 HEFI_EDITOR_LINE *Line;\r
2036\r
2037 LIST_ENTRY *Link;\r
632820d1 2038\r
2039 UINTN OldFCol;\r
2040 UINTN OldFRow;\r
2041 UINTN OldPos;\r
2042\r
2043 UINTN NewPos;\r
2044\r
632820d1 2045 Size = HBufferImageGetTotalSize ();\r
2046\r
2047 //\r
2048 // relocate all the HBufferImage fields\r
2049 //\r
2050 OldFRow = HBufferImage.BufferPosition.Row;\r
2051 OldFCol = HBufferImage.BufferPosition.Column;\r
2052 OldPos = (OldFRow - 1) * 0x10 + OldFCol - 1;\r
2053\r
2054 //\r
2055 // move cursor before Pos\r
2056 //\r
2057 if (Pos > 0) {\r
2058 NewPos = Pos - 1;\r
2059 } else {\r
2060 NewPos = 0;\r
2061 }\r
2062\r
2063 HBufferImageMovePosition (NewPos / 0x10 + 1, NewPos % 0x10 + 1, TRUE);\r
2064\r
2065 Buffer = AllocateZeroPool (Size + Count);\r
2066 if (Buffer == NULL) {\r
2067 return EFI_OUT_OF_RESOURCES;\r
2068 }\r
2069\r
2070 HBufferImageListToBuffer (Buffer, Size);\r
2071\r
2072 BufferPtr = (UINT8 *) Buffer;\r
2073\r
2074 //\r
2075 // get a place to add\r
2076 //\r
2077 for (Index = (INTN) (Size + Count - 1); Index >= (INTN) Pos; Index--) {\r
2078 BufferPtr[Index] = BufferPtr[Index - Count];\r
2079 }\r
2080 //\r
2081 // add the buffer\r
2082 //\r
2083 for (Index = (INTN) 0; Index < (INTN) Count; Index++) {\r
2084 BufferPtr[Index + Pos] = AddBuffer[Index];\r
2085 }\r
2086\r
2087 Size += Count;\r
2088\r
2089 HBufferImageFreeLines ();\r
2090\r
2091 HBufferImageBufferToList (Buffer, Size);\r
2092\r
2093 FreePool (Buffer);\r
2094\r
2095 Link = HMainEditor.BufferImage->ListHead->ForwardLink;\r
2096 for (Index = 0; Index < (INTN) NewPos / 0x10; Index++) {\r
2097 Link = Link->ForwardLink;\r
2098 }\r
2099\r
2100 Line = CR (Link, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST);\r
2101 HBufferImage.CurrentLine = Line;\r
2102\r
2103 if (OldPos >= Pos) {\r
2104 NewPos = OldPos + Count;\r
2105 } else {\r
2106 NewPos = OldPos;\r
2107 }\r
2108\r
2109 HBufferImageMovePosition (NewPos / 0x10 + 1, NewPos % 0x10 + 1, TRUE);\r
2110\r
2111 return EFI_SUCCESS;\r
2112}\r
2113\r
ae724571 2114/**\r
2115 Delete current character from line.\r
2116\r
2117 @retval EFI_SUCCESS The operationw as successful.\r
2118**/\r
632820d1 2119EFI_STATUS\r
ae724571 2120EFIAPI\r
632820d1 2121HBufferImageDoDelete (\r
2122 VOID\r
2123 )\r
632820d1 2124{\r
2125\r
2126 HEFI_EDITOR_LINE *Line;\r
2127\r
2128 BOOLEAN LastLine;\r
2129 UINTN FileColumn;\r
2130 UINTN FPos;\r
2131\r
2132 FPos = (HBufferImage.BufferPosition.Row - 1) * 0x10 + HBufferImage.BufferPosition.Column - 1;\r
2133\r
2134 FileColumn = HBufferImage.BufferPosition.Column;\r
2135\r
2136 Line = HBufferImage.CurrentLine;\r
2137\r
2138 //\r
2139 // if beyond the last character\r
2140 //\r
2141 if (FileColumn > Line->Size) {\r
2142 return EFI_SUCCESS;\r
2143 }\r
2144\r
2145 LastLine = FALSE;\r
2146 if (Line->Link.ForwardLink == HBufferImage.ListHead) {\r
2147 LastLine = TRUE;\r
2148 }\r
2149\r
2150 HBufferImageDeleteCharacterFromBuffer (FPos, 1, NULL);\r
2151\r
2152 //\r
2153 // if is the last line\r
2154 // then only this line need to be refreshed\r
2155 //\r
2156 if (LastLine) {\r
2157 HBufferImageNeedRefresh = FALSE;\r
2158 HBufferImageOnlyLineNeedRefresh = TRUE;\r
2159 } else {\r
2160 HBufferImageNeedRefresh = TRUE;\r
2161 HBufferImageOnlyLineNeedRefresh = FALSE;\r
2162 }\r
2163\r
2164 if (!HBufferImage.Modified) {\r
2165 HBufferImage.Modified = TRUE;\r
2166 }\r
2167\r
2168 return EFI_SUCCESS;\r
2169}\r
2170\r
ae724571 2171/**\r
2172 Change the raw buffer to a list of lines for the UI.\r
2173 \r
2174 @param[in] Buffer The pointer to the buffer to fill.\r
2175 @param[in] Bytes The size of the buffer in bytes.\r
2176\r
2177 @retval EFI_SUCCESS The operation was successful.\r
2178 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.\r
2179**/\r
632820d1 2180EFI_STATUS\r
ae724571 2181EFIAPI\r
632820d1 2182HBufferImageBufferToList (\r
2183 IN VOID *Buffer,\r
2184 IN UINTN Bytes\r
2185 )\r
2186{\r
ae724571 2187 UINTN TempI;\r
2188 UINTN TempJ;\r
632820d1 2189 UINTN Left;\r
2190 HEFI_EDITOR_LINE *Line;\r
2191 UINT8 *BufferPtr;\r
2192\r
ae724571 2193 TempI = 0;\r
632820d1 2194 Left = 0;\r
2195 BufferPtr = (UINT8 *) Buffer;\r
2196\r
2197 //\r
2198 // parse file content line by line\r
2199 //\r
ae724571 2200 while (TempI < Bytes) {\r
2201 if (Bytes - TempI >= 0x10) {\r
632820d1 2202 Left = 0x10;\r
2203 } else {\r
ae724571 2204 Left = Bytes - TempI;\r
632820d1 2205 }\r
2206\r
2207 //\r
2208 // allocate a new line\r
2209 //\r
2210 Line = HBufferImageCreateLine ();\r
2211 if (Line == NULL) {\r
2212 return EFI_OUT_OF_RESOURCES;\r
2213 }\r
2214\r
2215 Line->Size = Left;\r
2216\r
ae724571 2217 for (TempJ = 0; TempJ < Left; TempJ++) {\r
2218 Line->Buffer[TempJ] = BufferPtr[TempI];\r
2219 TempI++;\r
632820d1 2220 }\r
2221\r
2222 }\r
2223\r
2224 //\r
2225 // last line is a full line, SO create a new line\r
2226 //\r
2227 if (Left == 0x10 || Bytes == 0) {\r
2228 Line = HBufferImageCreateLine ();\r
2229 if (Line == NULL) {\r
2230 return EFI_OUT_OF_RESOURCES;\r
2231 }\r
2232 }\r
2233\r
2234 return EFI_SUCCESS;\r
2235}\r
2236\r
ae724571 2237/**\r
2238 Change the list of lines from the UI to a raw buffer.\r
2239 \r
2240 @param[in] Buffer The pointer to the buffer to fill.\r
2241 @param[in] Bytes The size of the buffer in bytes.\r
2242\r
2243 @retval EFI_SUCCESS The operation was successful.\r
2244**/\r
632820d1 2245EFI_STATUS\r
ae724571 2246EFIAPI\r
632820d1 2247HBufferImageListToBuffer (\r
2248 IN VOID *Buffer,\r
2249 IN UINTN Bytes\r
2250 )\r
2251{\r
2252 UINTN Count;\r
2253 UINTN Index;\r
2254 HEFI_EDITOR_LINE *Line;\r
2255 LIST_ENTRY *Link;\r
2256 UINT8 *BufferPtr;\r
2257\r
2258 //\r
2259 // change the line list to a large buffer\r
2260 //\r
2261 if (HBufferImage.Lines == NULL) {\r
2262 return EFI_SUCCESS;\r
2263 }\r
2264\r
2265 Link = &HBufferImage.Lines->Link;\r
2266 Count = 0;\r
2267 BufferPtr = (UINT8 *) Buffer;\r
2268\r
2269 //\r
2270 // deal line by line\r
2271 //\r
2272 while (Link != HBufferImage.ListHead) {\r
2273\r
2274 Line = CR (Link, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST);\r
2275\r
ae724571 2276 //@todo shouldn't this be an error???\r
632820d1 2277 if (Count + Line->Size > Bytes) {\r
2278 return EFI_SUCCESS;\r
2279 }\r
2280\r
2281 for (Index = 0; Index < Line->Size; Index++) {\r
2282 BufferPtr[Index] = Line->Buffer[Index];\r
2283 }\r
2284\r
2285 Count += Line->Size;\r
2286 BufferPtr += Line->Size;\r
2287\r
2288 Link = Link->ForwardLink;\r
2289 }\r
2290\r
2291 return EFI_SUCCESS;\r
2292}\r
2293\r
ae724571 2294/**\r
2295 Move the mouse in the image buffer.\r
2296\r
2297 @param[in] TextX The x-coordinate.\r
2298 @param[in] TextY The y-coordinate.\r
2299**/\r
632820d1 2300VOID\r
ae724571 2301EFIAPI\r
632820d1 2302HBufferImageAdjustMousePosition (\r
2303 IN INT32 TextX,\r
2304 IN INT32 TextY\r
2305 )\r
2306{\r
ae724571 2307 UINTN TempX;\r
2308 UINTN TempY;\r
632820d1 2309 UINTN AbsX;\r
2310 UINTN AbsY;\r
2311\r
2312 //\r
2313 // TextX and TextY is mouse movement data returned by mouse driver\r
2314 // This function will change it to MousePosition\r
2315 //\r
2316 //\r
ae724571 2317 // get absolute TempX value\r
632820d1 2318 //\r
2319 if (TextX >= 0) {\r
2320 AbsX = TextX;\r
2321 } else {\r
2322 AbsX = -TextX;\r
2323 }\r
2324 //\r
ae724571 2325 // get absolute TempY value\r
632820d1 2326 //\r
2327 if (TextY >= 0) {\r
2328 AbsY = TextY;\r
2329 } else {\r
2330 AbsY = -TextY;\r
2331 }\r
2332\r
ae724571 2333 TempX = HBufferImage.MousePosition.Column;\r
2334 TempY = HBufferImage.MousePosition.Row;\r
632820d1 2335\r
2336 if (TextX >= 0) {\r
ae724571 2337 TempX += TextX;\r
632820d1 2338 } else {\r
ae724571 2339 if (TempX >= AbsX) {\r
2340 TempX -= AbsX;\r
632820d1 2341 } else {\r
ae724571 2342 TempX = 0;\r
632820d1 2343 }\r
2344 }\r
2345\r
2346 if (TextY >= 0) {\r
ae724571 2347 TempY += TextY;\r
632820d1 2348 } else {\r
ae724571 2349 if (TempY >= AbsY) {\r
2350 TempY -= AbsY;\r
632820d1 2351 } else {\r
ae724571 2352 TempY = 0;\r
632820d1 2353 }\r
2354 }\r
2355 //\r
2356 // check whether new mouse column position is beyond screen\r
2357 // if not, adjust it\r
2358 //\r
ae724571 2359 if (TempX >= 10 && TempX <= (10 + 0x10 * 3 - 1)) {\r
2360 HBufferImage.MousePosition.Column = TempX;\r
2361 } else if (TempX < 10) {\r
632820d1 2362 HBufferImage.MousePosition.Column = 10;\r
ae724571 2363 } else if (TempX > (10 + 0x10 * 3 - 1)) {\r
632820d1 2364 HBufferImage.MousePosition.Column = 10 + 0x10 * 3 - 1;\r
2365 }\r
2366 //\r
2367 // check whether new mouse row position is beyond screen\r
2368 // if not, adjust it\r
2369 //\r
5a2beb74 2370 if (TempY >= 2 && TempY <= (HMainEditor.ScreenSize.Row - 1)) {\r
ae724571 2371 HBufferImage.MousePosition.Row = TempY;\r
2372 } else if (TempY < 2) {\r
632820d1 2373 HBufferImage.MousePosition.Row = 2;\r
5a2beb74 2374 } else if (TempY > (HMainEditor.ScreenSize.Row - 1)) {\r
2375 HBufferImage.MousePosition.Row = (HMainEditor.ScreenSize.Row - 1);\r
632820d1 2376 }\r
2377\r
2378}\r
a1d4bfcc 2379\r
2380/**\r
2381 Dispatch input to different handler\r
2382\r
2383 @param[in] Key The input key:\r
2384 the keys can be:\r
2385 ASCII KEY\r
2386 Backspace/Delete\r
2387 Direction key: up/down/left/right/pgup/pgdn\r
2388 Home/End\r
2389 INS\r
2390\r
2391 @retval EFI_SUCCESS The operation was successful.\r
2392 @retval EFI_LOAD_ERROR A load error occured.\r
2393 @retval EFI_OUT_OF_RESOURCES A Memory allocation failed.\r
2394**/\r
2395EFI_STATUS\r
2396HBufferImageHandleInput (\r
2397 IN EFI_INPUT_KEY *Key\r
2398 )\r
2399{\r
2400 EFI_STATUS Status;\r
2401\r
2402 Status = EFI_SUCCESS;\r
2403\r
2404 switch (Key->ScanCode) {\r
2405 //\r
2406 // ordinary key\r
2407 //\r
2408 case SCAN_NULL:\r
2409 Status = HBufferImageDoCharInput (Key->UnicodeChar);\r
2410 break;\r
2411\r
2412 //\r
2413 // up arrow\r
2414 //\r
2415 case SCAN_UP:\r
2416 Status = HBufferImageScrollUp ();\r
2417 break;\r
2418\r
2419 //\r
2420 // down arrow\r
2421 //\r
2422 case SCAN_DOWN:\r
2423 Status = HBufferImageScrollDown ();\r
2424 break;\r
2425\r
2426 //\r
2427 // right arrow\r
2428 //\r
2429 case SCAN_RIGHT:\r
2430 Status = HBufferImageScrollRight ();\r
2431 break;\r
2432\r
2433 //\r
2434 // left arrow\r
2435 //\r
2436 case SCAN_LEFT:\r
2437 Status = HBufferImageScrollLeft ();\r
2438 break;\r
2439\r
2440 //\r
2441 // page up\r
2442 //\r
2443 case SCAN_PAGE_UP:\r
2444 Status = HBufferImagePageUp ();\r
2445 break;\r
2446\r
2447 //\r
2448 // page down\r
2449 //\r
2450 case SCAN_PAGE_DOWN:\r
2451 Status = HBufferImagePageDown ();\r
2452 break;\r
2453\r
2454 //\r
2455 // delete\r
2456 //\r
2457 case SCAN_DELETE:\r
2458 Status = HBufferImageDoDelete ();\r
2459 break;\r
2460\r
2461 //\r
2462 // home\r
2463 //\r
2464 case SCAN_HOME:\r
2465 Status = HBufferImageHome ();\r
2466 break;\r
2467\r
2468 //\r
2469 // end\r
2470 //\r
2471 case SCAN_END:\r
2472 Status = HBufferImageEnd ();\r
2473 break;\r
2474\r
2475 default:\r
2476 Status = StatusBarSetStatusString (L"Unknown Command");\r
2477 break;\r
2478 }\r
2479\r
2480 return Status;\r
2481}\r
2482\r