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