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