]> git.proxmox.com Git - mirror_edk2.git/blame - ShellPkg/Library/UefiShellDebug1CommandsLib/Edit/MainTextEditor.c
SecurityPkg: Apply uncrustify changes
[mirror_edk2.git] / ShellPkg / Library / UefiShellDebug1CommandsLib / Edit / MainTextEditor.c
CommitLineData
632820d1 1/** @file\r
2 Implements editor interface functions.\r
3\r
5563281f 4 Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved. <BR>\r
56ba3746 5 SPDX-License-Identifier: BSD-2-Clause-Patent\r
632820d1 6\r
7**/\r
8\r
9#include "TextEditor.h"\r
10#include "EditStatusBar.h"\r
11#include "EditInputBar.h"\r
5a2beb74 12#include "EditMenuBar.h"\r
13\r
14//\r
15// the first time editor launch\r
16//\r
17BOOLEAN EditorFirst;\r
18\r
19//\r
20// it's time editor should exit\r
21//\r
22BOOLEAN EditorExit;\r
23\r
24BOOLEAN EditorMouseAction;\r
25\r
26extern EFI_EDITOR_FILE_BUFFER FileBuffer;\r
27\r
28extern BOOLEAN FileBufferNeedRefresh;\r
29\r
30extern BOOLEAN FileBufferOnlyLineNeedRefresh;\r
31\r
32extern BOOLEAN FileBufferMouseNeedRefresh;\r
33\r
34extern EFI_EDITOR_FILE_BUFFER FileBufferBackupVar;\r
35\r
36EFI_EDITOR_GLOBAL_EDITOR MainEditor;\r
37\r
632820d1 38\r
39/**\r
40 Load a file from disk to editor\r
41\r
42 @retval EFI_SUCCESS The operation was successful.\r
a048af3c 43 @retval EFI_LOAD_ERROR A load error occurred.\r
632820d1 44 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.\r
45**/\r
46EFI_STATUS\r
632820d1 47MainCommandOpenFile (\r
48 VOID\r
49 );\r
50\r
51/**\r
52 Switch a file from ASCII to UNICODE or vise-versa.\r
53\r
54 @retval EFI_SUCCESS The switch was ok or a warning was presented.\r
55**/\r
56EFI_STATUS\r
632820d1 57MainCommandSwitchFileType (\r
58 VOID\r
59 );\r
60\r
61/**\r
62 move cursor to specified lines\r
63\r
64 @retval EFI_SUCCESS The operation was successful.\r
65**/\r
66EFI_STATUS\r
632820d1 67MainCommandGotoLine (\r
68 VOID\r
69 );\r
70\r
71/**\r
72 Save current file to disk, you can save to current file name or\r
73 save to another file name.\r
ba0014b9 74\r
632820d1 75 @retval EFI_SUCCESS The file was saved correctly.\r
76 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.\r
a048af3c 77 @retval EFI_LOAD_ERROR A file access error occurred.\r
632820d1 78**/\r
79EFI_STATUS\r
632820d1 80MainCommandSaveFile (\r
81 VOID\r
82 );\r
83\r
5a2beb74 84/**\r
feccc28a 85 Show help information for the editor.\r
5a2beb74 86\r
87 @retval EFI_SUCCESS The operation was successful.\r
88**/\r
89EFI_STATUS\r
90MainCommandDisplayHelp (\r
91 VOID\r
92 );\r
93\r
632820d1 94/**\r
95 exit editor\r
96\r
97 @retval EFI_SUCCESS The operation was successful.\r
98 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.\r
a048af3c 99 @retval EFI_LOAD_ERROR A load error occurred.\r
632820d1 100**/\r
101EFI_STATUS\r
632820d1 102MainCommandExit (\r
103 VOID\r
104 );\r
105\r
106/**\r
107 search string in file buffer\r
108\r
109 @retval EFI_SUCCESS The operation was successful.\r
110 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.\r
a048af3c 111 @retval EFI_LOAD_ERROR A load error occurred.\r
632820d1 112**/\r
113EFI_STATUS\r
632820d1 114MainCommandSearch (\r
115 VOID\r
116 );\r
117\r
ae724571 118/**\r
632820d1 119 search string in file buffer, and replace it with another str\r
120\r
121 @retval EFI_SUCCESS The operation was successful.\r
122 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.\r
a048af3c 123 @retval EFI_LOAD_ERROR A load error occurred.\r
632820d1 124**/\r
125EFI_STATUS\r
632820d1 126MainCommandSearchReplace (\r
127 VOID\r
128 );\r
129\r
130/**\r
131 cut current line to clipboard\r
132\r
133 @retval EFI_SUCCESS The operation was successful.\r
134 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.\r
a048af3c 135 @retval EFI_LOAD_ERROR A load error occurred.\r
632820d1 136**/\r
137EFI_STATUS\r
632820d1 138MainCommandCutLine (\r
139 VOID\r
140 );\r
141\r
142/**\r
143 paste line to file buffer.\r
144\r
145 @retval EFI_SUCCESS The operation was successful.\r
146 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.\r
a048af3c 147 @retval EFI_LOAD_ERROR A load error occurred.\r
632820d1 148**/\r
149EFI_STATUS\r
632820d1 150MainCommandPasteLine (\r
151 VOID\r
152 );\r
153\r
5a2beb74 154/**\r
155 Help info that will be displayed.\r
156**/\r
157EFI_STRING_ID MainMenuHelpInfo[] = {\r
158 STRING_TOKEN(STR_EDIT_HELP_TITLE),\r
159 STRING_TOKEN(STR_EDIT_HELP_BLANK),\r
160 STRING_TOKEN(STR_EDIT_HELP_LIST_TITLE),\r
161 STRING_TOKEN(STR_EDIT_HELP_DIV),\r
162 STRING_TOKEN(STR_EDIT_HELP_GO_TO_LINE),\r
163 STRING_TOKEN(STR_EDIT_HELP_SAVE_FILE),\r
164 STRING_TOKEN(STR_EDIT_HELP_EXIT),\r
165 STRING_TOKEN(STR_EDIT_HELP_SEARCH),\r
166 STRING_TOKEN(STR_EDIT_HELP_SEARCH_REPLACE),\r
167 STRING_TOKEN(STR_EDIT_HELP_CUT_LINE),\r
168 STRING_TOKEN(STR_EDIT_HELP_PASTE_LINE),\r
169 STRING_TOKEN(STR_EDIT_HELP_OPEN_FILE),\r
170 STRING_TOKEN(STR_EDIT_HELP_FILE_TYPE),\r
171 STRING_TOKEN(STR_EDIT_HELP_BLANK),\r
172 STRING_TOKEN(STR_EDIT_HELP_EXIT_HELP),\r
173 STRING_TOKEN(STR_EDIT_HELP_BLANK),\r
174 STRING_TOKEN(STR_EDIT_HELP_BLANK),\r
175 STRING_TOKEN(STR_EDIT_HELP_BLANK),\r
176 STRING_TOKEN(STR_EDIT_HELP_BLANK),\r
177 STRING_TOKEN(STR_EDIT_HELP_BLANK),\r
178 STRING_TOKEN(STR_EDIT_HELP_BLANK),\r
179 STRING_TOKEN(STR_EDIT_HELP_BLANK),\r
180 STRING_TOKEN(STR_EDIT_HELP_DIV),\r
1810\r
182};\r
183\r
184MENU_ITEM_FUNCTION MainControlBasedMenuFunctions[] = {\r
185 NULL,\r
186 NULL, /* Ctrl - A */\r
187 NULL, /* Ctrl - B */\r
188 NULL, /* Ctrl - C */\r
189 NULL, /* Ctrl - D */\r
190 MainCommandDisplayHelp, /* Ctrl - E */\r
191 MainCommandSearch, /* Ctrl - F */\r
192 MainCommandGotoLine, /* Ctrl - G */\r
193 NULL, /* Ctrl - H */\r
194 NULL, /* Ctrl - I */\r
195 NULL, /* Ctrl - J */\r
196 MainCommandCutLine, /* Ctrl - K */\r
197 NULL, /* Ctrl - L */\r
198 NULL, /* Ctrl - M */\r
199 NULL, /* Ctrl - N */\r
200 MainCommandOpenFile, /* Ctrl - O */\r
201 NULL, /* Ctrl - P */\r
202 MainCommandExit, /* Ctrl - Q */\r
203 MainCommandSearchReplace, /* Ctrl - R */\r
204 MainCommandSaveFile, /* Ctrl - S */\r
205 MainCommandSwitchFileType, /* Ctrl - T */\r
206 MainCommandPasteLine, /* Ctrl - U */\r
207 NULL, /* Ctrl - V */\r
208 NULL, /* Ctrl - W */\r
209 NULL, /* Ctrl - X */\r
210 NULL, /* Ctrl - Y */\r
211 NULL, /* Ctrl - Z */\r
212};\r
213\r
632820d1 214EDITOR_MENU_ITEM MainMenuItems[] = {\r
215 {\r
216 STRING_TOKEN(STR_EDIT_LIBMENUBAR_GO_TO_LINE),\r
217 STRING_TOKEN(STR_EDIT_LIBMENUBAR_F1),\r
218 MainCommandGotoLine\r
219 },\r
220 {\r
221 STRING_TOKEN(STR_EDIT_LIBMENUBAR_SAVE_FILE),\r
222 STRING_TOKEN(STR_EDIT_LIBMENUBAR_F2),\r
223 MainCommandSaveFile\r
224 },\r
225 {\r
226 STRING_TOKEN(STR_EDIT_LIBMENUBAR_EXIT),\r
227 STRING_TOKEN(STR_EDIT_LIBMENUBAR_F3),\r
228 MainCommandExit\r
229 },\r
230\r
231 {\r
232 STRING_TOKEN(STR_EDIT_LIBMENUBAR_SEARCH),\r
233 STRING_TOKEN(STR_EDIT_LIBMENUBAR_F4),\r
234 MainCommandSearch\r
235 },\r
236 {\r
237 STRING_TOKEN(STR_EDIT_LIBMENUBAR_SEARCH_REPLACE),\r
238 STRING_TOKEN(STR_EDIT_LIBMENUBAR_F5),\r
239 MainCommandSearchReplace\r
240 },\r
241 {\r
242 STRING_TOKEN(STR_EDIT_LIBMENUBAR_CUT_LINE),\r
243 STRING_TOKEN(STR_EDIT_LIBMENUBAR_F6),\r
244 MainCommandCutLine\r
245 },\r
246 {\r
247 STRING_TOKEN(STR_EDIT_LIBMENUBAR_PASTE_LINE),\r
248 STRING_TOKEN(STR_EDIT_LIBMENUBAR_F7),\r
249 MainCommandPasteLine\r
250 },\r
251\r
252 {\r
253 STRING_TOKEN(STR_EDIT_LIBMENUBAR_OPEN_FILE),\r
254 STRING_TOKEN(STR_EDIT_LIBMENUBAR_F8),\r
255 MainCommandOpenFile\r
256 },\r
257 {\r
258 STRING_TOKEN(STR_EDIT_LIBMENUBAR_FILE_TYPE),\r
259 STRING_TOKEN(STR_EDIT_LIBMENUBAR_F9),\r
260 MainCommandSwitchFileType\r
261 },\r
5a2beb74 262 {\r
263 STRING_TOKEN(STR_EDIT_LIBMENUBAR_FILE_TYPE),\r
264 STRING_TOKEN(STR_EDIT_LIBMENUBAR_F11),\r
265 MainCommandSwitchFileType\r
266 },\r
632820d1 267\r
268 {\r
269 0,\r
270 0,\r
271 NULL\r
272 }\r
273};\r
274\r
275\r
276/**\r
277 Load a file from disk to editor\r
278\r
279 @retval EFI_SUCCESS The operation was successful.\r
a048af3c 280 @retval EFI_LOAD_ERROR A load error occurred.\r
632820d1 281 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.\r
282**/\r
283EFI_STATUS\r
632820d1 284MainCommandOpenFile (\r
285 VOID\r
286 )\r
287{\r
288 BOOLEAN Done;\r
289 EFI_STATUS Status;\r
290\r
291 //\r
292 // This command will open a file from current working directory.\r
293 // Read-only file can also be opened. But it can not be modified.\r
294 // Below is the scenario of Open File command:\r
295 // 1.IF currently opened file has not been modIFied, directly go to step .\r
296 // IF currently opened file has been modified,\r
297 // an Input Bar will be prompted as :\r
298 // "File Modified. Save ( Yes/No/Cancel) ?"\r
299 // IF user press 'y' or 'Y', currently opened file will be saved.\r
300 // IF user press 'n' or 'N', currently opened file will\r
301 // not be saved.\r
302 // IF user press 'c' or 'C' or ESC, Open File command ends and\r
303 // currently opened file is still opened.\r
304 //\r
305 // 2. An Input Bar will be prompted as : "File Name to Open: "\r
306 // IF user press ESC, Open File command ends and\r
307 // currently opened file is still opened.\r
308 // Any other inputs with a Return will\r
309 // cause currently opened file close.\r
310 //\r
311 // 3. IF user input file name is an existing file , this file will be read\r
312 // and opened.\r
313 // IF user input file name is a new file, this file will be created\r
314 // and opened. This file's type ( UNICODE or ASCII ) is the same\r
315 // with the old file.\r
316 // if current file is modified, so you need to choose\r
317 // whether to save it first.\r
318 //\r
319 if (MainEditor.FileBuffer->FileModified) {\r
320\r
321 Status = InputBarSetPrompt (L"File modified. Save (Yes/No/Cancel) ? ");\r
322 if (EFI_ERROR (Status)) {\r
323 return Status;\r
324 }\r
325 //\r
326 // the answer is just one character\r
327 //\r
328 Status = InputBarSetStringSize (1);\r
329 if (EFI_ERROR (Status)) {\r
330 return Status;\r
331 }\r
332 //\r
333 // loop for user's answer\r
334 // valid answer is just 'y' 'Y', 'n' 'N', 'c' 'C'\r
335 //\r
336 Done = FALSE;\r
337 while (!Done) {\r
338 Status = InputBarRefresh (MainEditor.ScreenSize.Row, MainEditor.ScreenSize.Column);\r
339 StatusBarSetRefresh();\r
340\r
341 //\r
342 // ESC pressed\r
343 //\r
344 if (Status == EFI_NOT_READY) {\r
345 return EFI_SUCCESS;\r
346 }\r
347\r
348 switch (InputBarGetString()[0]) {\r
349 case L'y':\r
350 case L'Y':\r
351 //\r
352 // want to save this file first\r
353 //\r
354 Status = FileBufferSave (MainEditor.FileBuffer->FileName);\r
355 if (EFI_ERROR (Status)) {\r
356 return Status;\r
357 }\r
358\r
980d554e 359 MainTitleBarRefresh (MainEditor.FileBuffer->FileName, MainEditor.FileBuffer->FileType, MainEditor.FileBuffer->ReadOnly, MainEditor.FileBuffer->FileModified, MainEditor.ScreenSize.Column, MainEditor.ScreenSize.Row, 0, 0);\r
632820d1 360 FileBufferRestorePosition ();\r
361 Done = TRUE;\r
362 break;\r
363\r
364 case L'n':\r
365 case L'N':\r
366 //\r
367 // the file won't be saved\r
368 //\r
369 Done = TRUE;\r
370 break;\r
371\r
372 case L'c':\r
373 case L'C':\r
374 return EFI_SUCCESS;\r
375 }\r
376 }\r
377 }\r
378 //\r
379 // TO get the open file name\r
380 //\r
381 Status = InputBarSetPrompt (L"File Name to Open: ");\r
382 if (EFI_ERROR (Status)) {\r
383 FileBufferRead (MainEditor.FileBuffer->FileName, TRUE);\r
384 return Status;\r
385 }\r
386\r
387 Status = InputBarSetStringSize (100);\r
388 if (EFI_ERROR (Status)) {\r
389 FileBufferRead (MainEditor.FileBuffer->FileName, TRUE);\r
390 return Status;\r
391 }\r
392\r
393 while (1) {\r
394 Status = InputBarRefresh (MainEditor.ScreenSize.Row, MainEditor.ScreenSize.Column);\r
395 StatusBarSetRefresh();\r
396\r
397 //\r
398 // ESC pressed\r
399 //\r
400 if (Status == EFI_NOT_READY) {\r
401 return EFI_SUCCESS;\r
402 }\r
403 //\r
404 // The input string length should > 0\r
405 //\r
406 if (StrLen (InputBarGetString()) > 0) {\r
407 //\r
408 // CHECK if filename is valid\r
409 //\r
410 if (!IsValidFileName (InputBarGetString())) {\r
411 FileBufferRead (MainEditor.FileBuffer->FileName, TRUE);\r
412 StatusBarSetStatusString (L"Invalid File Name");\r
413 return EFI_SUCCESS;\r
414 }\r
415\r
416 break;\r
417 }\r
418 }\r
419 //\r
420 // read from disk\r
421 //\r
422 Status = FileBufferRead (InputBarGetString(), FALSE);\r
423\r
424 if (EFI_ERROR (Status)) {\r
425 FileBufferRead (MainEditor.FileBuffer->FileName, TRUE);\r
426 return EFI_LOAD_ERROR;\r
427 }\r
428\r
429 return EFI_SUCCESS;\r
430}\r
431\r
432/**\r
433 Switch a file from ASCII to UNICODE or vise-versa.\r
434\r
435 @retval EFI_SUCCESS The switch was ok or a warning was presented.\r
436**/\r
437EFI_STATUS\r
632820d1 438MainCommandSwitchFileType (\r
439 VOID\r
440 )\r
441{\r
442 //\r
443 // Below is the scenario of File Type command:\r
444 // After File Type is executed, file type will be changed to another type\r
445 // if file is read-only, can not be modified\r
446 //\r
447 if (MainEditor.FileBuffer->ReadOnly) {\r
448 StatusBarSetStatusString (L"Read Only File Can Not Be Modified");\r
449 return EFI_SUCCESS;\r
450 }\r
451\r
452 if (MainEditor.FileBuffer->FileType == FileTypeUnicode) {\r
453 MainEditor.FileBuffer->FileType = FileTypeAscii;\r
454 } else {\r
455 MainEditor.FileBuffer->FileType = FileTypeUnicode;\r
456 }\r
457\r
458 MainEditor.FileBuffer->FileModified = TRUE;\r
459\r
460 return EFI_SUCCESS;\r
461}\r
462\r
463/**\r
464 cut current line to clipboard\r
465\r
466 @retval EFI_SUCCESS The operation was successful.\r
467 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.\r
a048af3c 468 @retval EFI_LOAD_ERROR A load error occurred.\r
632820d1 469**/\r
470EFI_STATUS\r
632820d1 471MainCommandCutLine (\r
472 VOID\r
473 )\r
474{\r
475 EFI_STATUS Status;\r
476 EFI_EDITOR_LINE *Line;\r
477\r
478 //\r
479 // This command will cut current line ( where cursor is on ) to clip board.\r
480 // And cursor will move to the beginning of next line.\r
481 // Below is the scenario of Cut Line command:\r
482 // 1. IF cursor is on valid line, current line will be cut to clip board.\r
483 // IF cursor is not on valid line, an Status String will be prompted :\r
484 // "Nothing to Cut".\r
485 //\r
0d807dae 486 Line = NULL;\r
632820d1 487 Status = FileBufferCutLine (&Line);\r
488 if (Status == EFI_NOT_FOUND) {\r
489 return EFI_SUCCESS;\r
490 }\r
491\r
492 if (EFI_ERROR (Status)) {\r
493 return Status;\r
494 }\r
495\r
496 MainEditor.CutLine = Line;\r
497\r
498 return EFI_SUCCESS;\r
499}\r
500\r
501/**\r
502 paste line to file buffer.\r
503\r
504 @retval EFI_SUCCESS The operation was successful.\r
505 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.\r
a048af3c 506 @retval EFI_LOAD_ERROR A load error occurred.\r
632820d1 507**/\r
508EFI_STATUS\r
632820d1 509MainCommandPasteLine (\r
510 VOID\r
511 )\r
512{\r
513 EFI_STATUS Status;\r
514\r
515 //\r
516 // Below is the scenario of Paste Line command:\r
517 // 1. IF nothing is on clipboard, a Status String will be prompted :\r
518 // "No Line to Paste" and Paste Line command ends.\r
519 // IF something is on clipboard, insert it above current line.\r
520 // nothing on clipboard\r
521 //\r
522 if (MainEditor.CutLine == NULL) {\r
523 StatusBarSetStatusString (L"No Line to Paste");\r
524 return EFI_SUCCESS;\r
525 }\r
526\r
527 Status = FileBufferPasteLine ();\r
528\r
529 return Status;\r
530}\r
531\r
532\r
533/**\r
534 search string in file buffer\r
535\r
536 @retval EFI_SUCCESS The operation was successful.\r
537 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.\r
a048af3c 538 @retval EFI_LOAD_ERROR A load error occurred.\r
632820d1 539**/\r
540EFI_STATUS\r
632820d1 541MainCommandSearch (\r
542 VOID\r
543 )\r
544{\r
545 EFI_STATUS Status;\r
546 CHAR16 *Buffer;\r
547 BOOLEAN Done;\r
548 UINTN Offset;\r
549\r
550 //\r
551 // Below is the scenario of Search command:\r
552 // 1. An Input Bar will be prompted : "Enter Search String:".\r
553 // IF user press ESC, Search command ends.\r
554 // IF user just press Enter, Search command ends.\r
555 // IF user inputs the search string, do Step 2.\r
556 //\r
557 // 2. IF input search string is found, cursor will move to the first\r
558 // occurrence and do Step 3.\r
559 // IF input search string is not found, a Status String\r
560 // "Search String Not Found" will be prompted and Search command ends.\r
561 //\r
562 // 3. An Input Bar will be prompted: "Find Next (Yes/No/Cancel ) ?".\r
563 // IF user press ESC, Search command ends.\r
564 // IF user press 'y' or 'Y', do Step 2.\r
565 // IF user press 'n' or 'N', Search command ends.\r
566 // IF user press 'c' or 'C', Search command ends.\r
567 //\r
568 Status = InputBarSetPrompt (L"Enter Search String: ");\r
569 if (EFI_ERROR (Status)) {\r
570 return Status;\r
571 }\r
572\r
573 Status = InputBarSetStringSize (40);\r
574 if (EFI_ERROR (Status)) {\r
575 return Status;\r
576 }\r
577\r
578 Status = InputBarRefresh (MainEditor.ScreenSize.Row, MainEditor.ScreenSize.Column);\r
579 StatusBarSetRefresh();\r
580\r
581 //\r
582 // ESC\r
583 //\r
584 if (Status == EFI_NOT_READY) {\r
585 return EFI_SUCCESS;\r
586 }\r
587 //\r
588 // just enter pressed\r
589 //\r
590 if (StrLen (InputBarGetString()) == 0) {\r
591 return EFI_SUCCESS;\r
592 }\r
593\r
594 Buffer = CatSPrint (NULL, L"%s", InputBarGetString());\r
595 if (Buffer == NULL) {\r
596 return EFI_OUT_OF_RESOURCES;\r
597 }\r
598 //\r
599 // the first time , search from current position\r
600 //\r
601 Offset = 0;\r
602 do {\r
603 //\r
604 // since search may be continued to search multiple times\r
605 // so we need to backup editor each time\r
606 //\r
607 MainEditorBackup ();\r
608\r
609 Status = FileBufferSearch (Buffer, Offset);\r
610\r
611 if (Status == EFI_NOT_FOUND) {\r
612 break;\r
613 }\r
614 //\r
615 // Find next\r
616 //\r
617 Status = InputBarSetPrompt (L"Find Next (Yes/No) ?");\r
618 if (EFI_ERROR (Status)) {\r
619 FreePool (Buffer);\r
620 return Status;\r
621 }\r
622\r
623 Status = InputBarSetStringSize (1);\r
624 if (EFI_ERROR (Status)) {\r
625 FreePool (Buffer);\r
626 return Status;\r
627 }\r
628\r
629 Done = FALSE;\r
630 while (!Done) {\r
631 Status = InputBarRefresh (MainEditor.ScreenSize.Row, MainEditor.ScreenSize.Column);\r
632 StatusBarSetRefresh();\r
633\r
634 //\r
635 // ESC pressed\r
636 //\r
637 if (Status == EFI_NOT_READY) {\r
638 FreePool (Buffer);\r
639 return EFI_SUCCESS;\r
640 }\r
641\r
642 switch (InputBarGetString()[0]) {\r
643 case L'y':\r
644 case L'Y':\r
645 Done = TRUE;\r
646 break;\r
647\r
648 case L'n':\r
649 case L'N':\r
650 FreePool (Buffer);\r
651 return EFI_SUCCESS;\r
652\r
653 }\r
654 //\r
655 // end of which\r
656 //\r
657 }\r
658 //\r
659 // end of while !Done\r
660 // for search second, third time, search from current position + strlen\r
661 //\r
662 Offset = StrLen (Buffer);\r
663\r
664 } while (1);\r
665 //\r
666 // end of do\r
667 //\r
668 FreePool (Buffer);\r
669 StatusBarSetStatusString (L"Search String Not Found");\r
670\r
671 return EFI_SUCCESS;\r
672}\r
673\r
ae724571 674/**\r
675 Search string in file buffer, and replace it with another str.\r
632820d1 676\r
677 @retval EFI_SUCCESS The operation was successful.\r
678 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.\r
a048af3c 679 @retval EFI_LOAD_ERROR A load error occurred.\r
632820d1 680**/\r
681EFI_STATUS\r
632820d1 682MainCommandSearchReplace (\r
683 VOID\r
684 )\r
685{\r
686 EFI_STATUS Status;\r
687 CHAR16 *Search;\r
688 CHAR16 *Replace;\r
689 BOOLEAN Done;\r
690 BOOLEAN First;\r
691 BOOLEAN ReplaceOption;\r
692 UINTN SearchLen;\r
693 UINTN ReplaceLen;\r
694 BOOLEAN ReplaceAll;\r
695\r
696 ReplaceOption = FALSE;\r
697\r
698 //\r
699 // Below is the scenario of Search/Replace command:\r
700 // 1. An Input Bar is prompted : "Enter Search String:".\r
701 // IF user press ESC, Search/Replace command ends.\r
702 // IF user just press Enter, Search/Replace command ends.\r
703 // IF user inputs the search string S, do Step 2.\r
704 //\r
705 // 2. An Input Bar is prompted: "Replace With:".\r
706 // IF user press ESC, Search/Replace command ends.\r
707 // IF user inputs the replace string R, do Step 3.\r
708 //\r
709 // 3. IF input search string is not found, an Status String\r
710 // "Search String Not Found" will be prompted\r
711 // and Search/Replace command ends\r
712 // IF input search string is found, do Step 4.\r
713 //\r
714 // 4. An Input Bar will be prompted: "Replace ( Yes/No/All/Cancel )?"\r
715 // IF user press 'y' or 'Y', S will be replaced with R and do Step 5\r
716 // IF user press 'n' or 'N', S will not be replaced and do Step 5.\r
717 // IF user press 'a' or 'A', all the S from file current position on\r
718 // will be replaced with R and Search/Replace command ends.\r
719 // IF user press 'c' or 'C' or ESC, Search/Replace command ends.\r
720 //\r
721 // 5. An Input Bar will be prompted: "Find Next (Yes/No/Cancel) ?".\r
722 // IF user press ESC, Search/Replace command ends.\r
723 // IF user press 'y' or 'Y', do Step 3.\r
724 // IF user press 'n' or 'N', Search/Replace command ends.\r
725 // IF user press 'c' or 'C', Search/Replace command ends.\r
726 // input search string\r
727 //\r
728 Status = InputBarSetPrompt (L"Enter Search String: ");\r
729 if (EFI_ERROR (Status)) {\r
730 return Status;\r
731 }\r
732\r
733 Status = InputBarSetStringSize (40);\r
734 if (EFI_ERROR (Status)) {\r
735 return Status;\r
736 }\r
737\r
738 Status = InputBarRefresh (MainEditor.ScreenSize.Row, MainEditor.ScreenSize.Column);\r
739 StatusBarSetRefresh();\r
740\r
741 //\r
742 // ESC\r
743 //\r
744 if (Status == EFI_NOT_READY) {\r
745 return EFI_SUCCESS;\r
746 }\r
747 //\r
748 // if just pressed enter\r
749 //\r
750 if (StrLen (InputBarGetString()) == 0) {\r
751 return EFI_SUCCESS;\r
752 }\r
753\r
754 Search = CatSPrint (NULL, L"%s", InputBarGetString());\r
755 if (Search == NULL) {\r
756 return EFI_OUT_OF_RESOURCES;\r
757 }\r
758\r
759 SearchLen = StrLen (Search);\r
760\r
761 //\r
762 // input replace string\r
763 //\r
764 Status = InputBarSetPrompt (L"Replace With: ");\r
765 if (EFI_ERROR (Status)) {\r
766 return Status;\r
767 }\r
768\r
769 Status = InputBarSetStringSize (40);\r
770 if (EFI_ERROR (Status)) {\r
771 return Status;\r
772 }\r
773\r
774 Status = InputBarRefresh (MainEditor.ScreenSize.Row, MainEditor.ScreenSize.Column);\r
775 StatusBarSetRefresh();\r
776\r
777 //\r
778 // ESC\r
779 //\r
780 if (Status == EFI_NOT_READY) {\r
781 return EFI_SUCCESS;\r
782 }\r
783\r
784 Replace = CatSPrint (NULL, L"%s", InputBarGetString());\r
785 if (Replace == NULL) {\r
786 FreePool (Search);\r
787 return EFI_OUT_OF_RESOURCES;\r
788 }\r
789\r
790 ReplaceLen = StrLen (Replace);\r
791\r
792 First = TRUE;\r
793 ReplaceAll = FALSE;\r
794 do {\r
795 //\r
796 // since search may be continued to search multiple times\r
797 // so we need to backup editor each time\r
798 //\r
799 MainEditorBackup ();\r
800\r
801 if (First) {\r
802 Status = FileBufferSearch (Search, 0);\r
803 } else {\r
804 //\r
805 // if just replace, so skip this replace string\r
806 // if replace string is an empty string, so skip to next character\r
807 //\r
808 if (ReplaceOption) {\r
809 Status = FileBufferSearch (Search, (ReplaceLen == 0) ? 1 : ReplaceLen);\r
810 } else {\r
811 Status = FileBufferSearch (Search, SearchLen);\r
812 }\r
813 }\r
814\r
815 if (Status == EFI_NOT_FOUND) {\r
816 break;\r
817 }\r
818 //\r
819 // replace or not?\r
820 //\r
821 Status = InputBarSetPrompt (L"Replace (Yes/No/All/Cancel) ?");\r
822\r
823 if (EFI_ERROR (Status)) {\r
824 FreePool (Search);\r
825 FreePool (Replace);\r
826 return Status;\r
827 }\r
828\r
829 Status = InputBarSetStringSize (1);\r
830 if (EFI_ERROR (Status)) {\r
831 FreePool (Search);\r
832 FreePool (Replace);\r
833 return Status;\r
834 }\r
835\r
836 Done = FALSE;\r
837 while (!Done) {\r
838 Status = InputBarRefresh (MainEditor.ScreenSize.Row, MainEditor.ScreenSize.Column);\r
839 StatusBarSetRefresh();\r
840\r
841 //\r
842 // ESC pressed\r
843 //\r
844 if (Status == EFI_NOT_READY) {\r
845 FreePool (Search);\r
846 FreePool (Replace);\r
847 return EFI_SUCCESS;\r
848 }\r
849\r
850 switch (InputBarGetString()[0]) {\r
851 case L'y':\r
852 case L'Y':\r
853 Done = TRUE;\r
854 ReplaceOption = TRUE;\r
855 break;\r
856\r
857 case L'n':\r
858 case L'N':\r
859 Done = TRUE;\r
860 ReplaceOption = FALSE;\r
861 break;\r
862\r
863 case L'a':\r
864 case L'A':\r
865 Done = TRUE;\r
866 ReplaceOption = TRUE;\r
867 ReplaceAll = TRUE;\r
868 break;\r
869\r
870 case L'c':\r
871 case L'C':\r
872 FreePool (Search);\r
873 FreePool (Replace);\r
874 return EFI_SUCCESS;\r
875\r
876 }\r
877 //\r
878 // end of which\r
879 //\r
880 }\r
881 //\r
882 // end of while !Done\r
883 // Decide to Replace\r
884 //\r
885 if (ReplaceOption) {\r
886 //\r
887 // file is read-only\r
888 //\r
889 if (MainEditor.FileBuffer->ReadOnly) {\r
890 StatusBarSetStatusString (L"Read Only File Can Not Be Modified");\r
891 return EFI_SUCCESS;\r
892 }\r
893 //\r
894 // replace all\r
895 //\r
896 if (ReplaceAll) {\r
897 Status = FileBufferReplaceAll (Search, Replace, 0);\r
898 FreePool (Search);\r
899 FreePool (Replace);\r
900 return Status;\r
901 }\r
902 //\r
903 // replace\r
904 //\r
905 Status = FileBufferReplace (Replace, SearchLen);\r
906 if (EFI_ERROR (Status)) {\r
907 FreePool (Search);\r
908 FreePool (Replace);\r
909 return Status;\r
910 }\r
911 }\r
912 //\r
913 // Find next\r
914 //\r
915 Status = InputBarSetPrompt (L"Find Next (Yes/No) ?");\r
916 if (EFI_ERROR (Status)) {\r
917 FreePool (Search);\r
918 FreePool (Replace);\r
919 return Status;\r
920 }\r
921\r
922 Status = InputBarSetStringSize (1);\r
923 if (EFI_ERROR (Status)) {\r
924 FreePool (Search);\r
925 FreePool (Replace);\r
926 return Status;\r
927 }\r
928\r
929 Done = FALSE;\r
930 while (!Done) {\r
931 Status = InputBarRefresh (MainEditor.ScreenSize.Row, MainEditor.ScreenSize.Column);\r
932 StatusBarSetRefresh();\r
933\r
934 //\r
935 // ESC pressed\r
936 //\r
937 if (Status == EFI_NOT_READY) {\r
938 FreePool (Search);\r
939 FreePool (Replace);\r
940 return EFI_SUCCESS;\r
941 }\r
942\r
943 switch (InputBarGetString()[0]) {\r
944 case L'y':\r
945 case L'Y':\r
946 Done = TRUE;\r
947 break;\r
948\r
949 case L'n':\r
950 case L'N':\r
951 FreePool (Search);\r
952 FreePool (Replace);\r
953 return EFI_SUCCESS;\r
954\r
955 }\r
956 //\r
957 // end of which\r
958 //\r
959 }\r
960 //\r
961 // end of while !Done\r
962 //\r
963 First = FALSE;\r
964\r
965 } while (1);\r
966 //\r
967 // end of do\r
968 //\r
969 FreePool (Search);\r
970 FreePool (Replace);\r
971\r
972 StatusBarSetStatusString (L"Search String Not Found");\r
973\r
974 return EFI_SUCCESS;\r
975}\r
976\r
977/**\r
978 exit editor\r
979\r
980 @retval EFI_SUCCESS The operation was successful.\r
981 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.\r
a048af3c 982 @retval EFI_LOAD_ERROR A load error occurred.\r
632820d1 983**/\r
984EFI_STATUS\r
632820d1 985MainCommandExit (\r
986 VOID\r
987 )\r
988{\r
989 EFI_STATUS Status;\r
990\r
991 //\r
992 // Below is the scenario of Exit command:\r
993 // 1. IF currently opened file is not modified, exit the editor and\r
994 // Exit command ends.\r
995 // IF currently opened file is modified, do Step 2\r
996 //\r
997 // 2. An Input Bar will be prompted:\r
998 // "File modified. Save ( Yes/No/Cancel )?"\r
999 // IF user press 'y' or 'Y', currently opened file will be saved\r
1000 // and Editor exits\r
1001 // IF user press 'n' or 'N', currently opened file will not be saved\r
1002 // and Editor exits.\r
1003 // IF user press 'c' or 'C' or ESC, Exit command ends.\r
1004 // if file has been modified, so will prompt user whether to save the changes\r
1005 //\r
1006 if (MainEditor.FileBuffer->FileModified) {\r
1007\r
1008 Status = InputBarSetPrompt (L"File modified. Save (Yes/No/Cancel) ? ");\r
1009 if (EFI_ERROR (Status)) {\r
1010 return Status;\r
1011 }\r
1012\r
1013 Status = InputBarSetStringSize (1);\r
1014 if (EFI_ERROR (Status)) {\r
1015 return Status;\r
1016 }\r
1017\r
1018 while (1) {\r
1019 Status = InputBarRefresh (MainEditor.ScreenSize.Row, MainEditor.ScreenSize.Column);\r
1020 StatusBarSetRefresh();\r
1021\r
1022 //\r
1023 // ESC pressed\r
1024 //\r
1025 if (Status == EFI_NOT_READY) {\r
1026 return EFI_SUCCESS;\r
1027 }\r
1028\r
1029 switch (InputBarGetString()[0]) {\r
1030 case L'y':\r
1031 case L'Y':\r
1032 //\r
1033 // write file back to disk\r
1034 //\r
1035 Status = FileBufferSave (MainEditor.FileBuffer->FileName);\r
1036 if (!EFI_ERROR (Status)) {\r
1037 EditorExit = TRUE;\r
1038 }\r
1039\r
1040 return Status;\r
1041\r
1042 case L'n':\r
1043 case L'N':\r
1044 EditorExit = TRUE;\r
1045 return EFI_SUCCESS;\r
1046\r
1047 case L'c':\r
1048 case L'C':\r
1049 return EFI_SUCCESS;\r
1050\r
1051 }\r
1052 }\r
1053 }\r
1054\r
1055 EditorExit = TRUE;\r
1056 return EFI_SUCCESS;\r
1057\r
1058}\r
1059\r
1060/**\r
1061 move cursor to specified lines\r
1062\r
1063 @retval EFI_SUCCESS The operation was successful.\r
1064**/\r
1065EFI_STATUS\r
632820d1 1066MainCommandGotoLine (\r
1067 VOID\r
1068 )\r
1069{\r
1070 EFI_STATUS Status;\r
1071 UINTN Row;\r
1072\r
1073 //\r
1074 // Below is the scenario of Go To Line command:\r
1075 // 1. An Input Bar will be prompted : "Go To Line:".\r
1076 // IF user press ESC, Go To Line command ends.\r
1077 // IF user just press Enter, cursor remains unchanged.\r
1078 // IF user inputs line number, do Step 2.\r
1079 //\r
1080 // 2. IF input line number is valid, move cursor to the beginning\r
1081 // of specified line and Go To Line command ends.\r
1082 // IF input line number is invalid, a Status String will be prompted:\r
1083 // "No Such Line" and Go To Line command ends.\r
1084 //\r
1085 Status = InputBarSetPrompt (L"Go To Line: ");\r
1086 if (EFI_ERROR (Status)) {\r
1087 return Status;\r
1088 }\r
1089 //\r
1090 // line number's digit <= 6\r
1091 //\r
1092 Status = InputBarSetStringSize (6);\r
1093 if (EFI_ERROR (Status)) {\r
1094 return Status;\r
1095 }\r
1096\r
1097 Status = InputBarRefresh (MainEditor.ScreenSize.Row, MainEditor.ScreenSize.Column);\r
1098 StatusBarSetRefresh();\r
1099\r
1100 //\r
1101 // press ESC\r
1102 //\r
1103 if (Status == EFI_NOT_READY) {\r
1104 return EFI_SUCCESS;\r
1105 }\r
1106 //\r
1107 // if JUST press enter\r
1108 //\r
1109 if (StrLen (InputBarGetString()) == 0) {\r
1110 return EFI_SUCCESS;\r
1111 }\r
1112\r
1113 Row = ShellStrToUintn (InputBarGetString());\r
1114\r
1115 //\r
1116 // invalid line number\r
1117 //\r
1118 if (Row > MainEditor.FileBuffer->NumLines || Row <= 0) {\r
1119 StatusBarSetStatusString (L"No Such Line");\r
1120 return EFI_SUCCESS;\r
1121 }\r
1122 //\r
1123 // move cursor to that line's start\r
1124 //\r
1125 FileBufferMovePosition (Row, 1);\r
1126\r
1127 return EFI_SUCCESS;\r
1128}\r
1129\r
1130/**\r
1131 Save current file to disk, you can save to current file name or\r
1132 save to another file name.\r
ba0014b9 1133\r
632820d1 1134 @retval EFI_SUCCESS The file was saved correctly.\r
1135 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.\r
a048af3c 1136 @retval EFI_LOAD_ERROR A file access error occurred.\r
632820d1 1137**/\r
1138EFI_STATUS\r
632820d1 1139MainCommandSaveFile (\r
1140 VOID\r
1141 )\r
1142{\r
1143 EFI_STATUS Status;\r
1144 CHAR16 *FileName;\r
1145 BOOLEAN OldFile;\r
1146 CHAR16 *Str;\r
ba0014b9 1147 SHELL_FILE_HANDLE FileHandle;\r
632820d1 1148 EFI_FILE_INFO *Info;\r
1149\r
1150 //\r
1151 // This command will save currently opened file to disk.\r
1152 // You can choose save to another file name or just save to\r
1153 // current file name.\r
1154 // Below is the scenario of Save File command:\r
1155 // ( Suppose the old file name is A )\r
1156 // 1. An Input Bar will be prompted: "File To Save: [ old file name]"\r
1157 // IF user press ESC, Save File command ends .\r
1158 // IF user press Enter, input file name will be A.\r
1159 // IF user inputs a new file name B, input file name will be B.\r
1160 //\r
1161 // 2. IF input file name is A, go to do Step 3.\r
1162 // IF input file name is B, go to do Step 4.\r
1163 //\r
1164 // 3. IF A is read only, Status Bar will show "Access Denied" and\r
1165 // Save File commands ends.\r
1166 // IF A is not read only, save file buffer to disk and remove modified\r
1167 // flag in Title Bar , then Save File command ends.\r
1168 //\r
1169 // 4. IF B does not exist, create this file and save file buffer to it.\r
1170 // Go to do Step 7.\r
1171 // IF B exits, do Step 5.\r
1172 //\r
1173 // 5.An Input Bar will be prompted:\r
1174 // "File Exists. Overwrite ( Yes/No/Cancel )?"\r
1175 // IF user press 'y' or 'Y', do Step 6.\r
1176 // IF user press 'n' or 'N', Save File commands ends.\r
1177 // IF user press 'c' or 'C' or ESC, Save File commands ends.\r
1178 //\r
1179 // 6. IF B is a read-only file, Status Bar will show "Access Denied" and\r
1180 // Save File commands ends.\r
1181 // IF B can be read and write, save file buffer to B.\r
1182 //\r
1183 // 7. Update File Name field in Title Bar to B and remove the modified\r
1184 // flag in Title Bar.\r
1185 //\r
1186 Str = CatSPrint (NULL, L"File to Save: [%s]", MainEditor.FileBuffer->FileName);\r
1187 if (Str == NULL) {\r
1188 return EFI_OUT_OF_RESOURCES;\r
1189 }\r
1190\r
1191 if (StrLen (Str) >= 50) {\r
1192 //\r
1193 // replace the long file name with "..."\r
1194 //\r
1195 Str[46] = L'.';\r
1196 Str[47] = L'.';\r
1197 Str[48] = L'.';\r
1198 Str[49] = L']';\r
1199 Str[50] = CHAR_NULL;\r
1200 }\r
1201\r
1202 Status = InputBarSetPrompt (Str);\r
1203 FreePool(Str);\r
1204\r
1205 if (EFI_ERROR (Status)) {\r
1206 return Status;\r
1207 }\r
1208\r
1209\r
1210 Status = InputBarSetStringSize (100);\r
1211 if (EFI_ERROR (Status)) {\r
1212 return Status;\r
1213 }\r
1214 //\r
1215 // get new file name\r
1216 //\r
1217 Status = InputBarRefresh (MainEditor.ScreenSize.Row, MainEditor.ScreenSize.Column);\r
1218 StatusBarSetRefresh();\r
1219\r
1220 //\r
1221 // if user pressed ESC\r
1222 //\r
1223 if (Status == EFI_NOT_READY) {\r
1224 return EFI_SUCCESS;\r
1225 }\r
1226\r
1227 //\r
1228 // if just enter pressed, so think save to current file name\r
1229 //\r
1230 if (StrLen (InputBarGetString()) == 0) {\r
1231 FileName = CatSPrint (NULL, L"%s", MainEditor.FileBuffer->FileName);\r
1232 } else {\r
1233 FileName = CatSPrint (NULL, L"%s", InputBarGetString());\r
1234 }\r
1235\r
1236 if (FileName == NULL) {\r
1237 return EFI_OUT_OF_RESOURCES;\r
1238 }\r
1239\r
1240 if (!IsValidFileName (FileName)) {\r
1241 StatusBarSetStatusString (L"Invalid File Name");\r
1242 FreePool (FileName);\r
1243 return EFI_SUCCESS;\r
1244 }\r
1245\r
1246 OldFile = FALSE;\r
1247\r
1248 //\r
1249 // save to the old file\r
1250 //\r
1251 if (StringNoCaseCompare (&FileName, &MainEditor.FileBuffer->FileName) == 0) {\r
1252 OldFile = TRUE;\r
1253 }\r
1254\r
1255 if (OldFile) {\r
1256 //\r
1257 // if the file is read only, so can not write back to it.\r
1258 //\r
1259 if (MainEditor.FileBuffer->ReadOnly == TRUE) {\r
1260 StatusBarSetStatusString (L"Access Denied");\r
1261 FreePool (FileName);\r
1262 return EFI_SUCCESS;\r
1263 }\r
1264 } else {\r
1265 //\r
1266 // if the file exists\r
1267 //\r
1268 if (ShellFileExists(FileName) != EFI_NOT_FOUND) {\r
1269 //\r
1270 // check for read only\r
1271 //\r
1272 Status = ShellOpenFileByName(FileName, &FileHandle, EFI_FILE_MODE_READ, 0);\r
1273 if (EFI_ERROR(Status)) {\r
1274 StatusBarSetStatusString (L"Open Failed");\r
1275 FreePool (FileName);\r
1276 return EFI_SUCCESS;\r
ba0014b9 1277 }\r
632820d1 1278\r
1279 Info = ShellGetFileInfo(FileHandle);\r
1280 if (Info == NULL) {\r
1281 StatusBarSetStatusString (L"Access Denied");\r
1282 FreePool (FileName);\r
1283 return (EFI_SUCCESS);\r
ba0014b9
LG
1284 }\r
1285\r
632820d1 1286 if (Info->Attribute & EFI_FILE_READ_ONLY) {\r
1287 StatusBarSetStatusString (L"Access Denied - Read Only");\r
1288 FreePool (Info);\r
1289 FreePool (FileName);\r
1290 return (EFI_SUCCESS);\r
1291 }\r
1292 FreePool (Info);\r
1293\r
1294 //\r
1295 // ask user whether to overwrite this file\r
1296 //\r
1297 Status = InputBarSetPrompt (L"File exists. Overwrite (Yes/No/Cancel) ? ");\r
1298 if (EFI_ERROR (Status)) {\r
1299 SHELL_FREE_NON_NULL (FileName);\r
1300 return Status;\r
1301 }\r
1302\r
1303 Status = InputBarSetStringSize (1);\r
1304 if (EFI_ERROR (Status)) {\r
1305 SHELL_FREE_NON_NULL (FileName);\r
1306 return Status;\r
1307 }\r
1308\r
1309 while (TRUE) {\r
1310 Status = InputBarRefresh (MainEditor.ScreenSize.Row, MainEditor.ScreenSize.Column);\r
1311 StatusBarSetRefresh();\r
1312\r
1313 //\r
1314 // ESC pressed\r
1315 //\r
1316 if (Status == EFI_NOT_READY) {\r
1317 SHELL_FREE_NON_NULL (FileName);\r
1318 return EFI_SUCCESS;\r
1319 }\r
1320\r
1321 switch (InputBarGetString()[0]) {\r
1322 case L'y':\r
1323 case L'Y':\r
1324 break;\r
1325\r
1326 case L'n':\r
1327 case L'N':\r
1328 case L'c':\r
1329 case L'C':\r
1330 SHELL_FREE_NON_NULL (FileName);\r
1331 return EFI_SUCCESS;\r
1332 } // end switch\r
1333 } // while (!done)\r
1334 } // file does exist\r
1335 } // if old file name same\r
1336\r
1337 //\r
1338 // save file to disk with specified name\r
1339 //\r
1340 FileBufferSetModified();\r
1341 Status = FileBufferSave (FileName);\r
1342 SHELL_FREE_NON_NULL (FileName);\r
1343\r
1344 return Status;\r
1345}\r
1346\r
5a2beb74 1347/**\r
feccc28a 1348 Show help information for the editor.\r
632820d1 1349\r
5a2beb74 1350 @retval EFI_SUCCESS The operation was successful.\r
1351**/\r
1352EFI_STATUS\r
1353MainCommandDisplayHelp (\r
1354 VOID\r
1355 )\r
1356{\r
feccc28a 1357 INT32 CurrentLine;\r
1358 CHAR16 *InfoString;\r
5563281f
RN
1359 EFI_KEY_DATA KeyData;\r
1360 EFI_STATUS Status;\r
1361 UINTN EventIndex;\r
ba0014b9 1362\r
feccc28a 1363 //\r
ba0014b9 1364 // print helpInfo\r
feccc28a 1365 //\r
5a2beb74 1366 for (CurrentLine = 0; 0 != MainMenuHelpInfo[CurrentLine]; CurrentLine++) {\r
1367 InfoString = HiiGetString(gShellDebug1HiiHandle, MainMenuHelpInfo[CurrentLine], NULL);\r
ba0014b9 1368 ShellPrintEx (0, CurrentLine+1, L"%E%s%N", InfoString);\r
5a2beb74 1369 }\r
5563281f 1370\r
feccc28a 1371 //\r
5a2beb74 1372 // scan for ctrl+w\r
feccc28a 1373 //\r
5563281f
RN
1374 while (TRUE) {\r
1375 Status = gBS->WaitForEvent (1, &MainEditor.TextInputEx->WaitForKeyEx, &EventIndex);\r
1376 if (EFI_ERROR (Status) || (EventIndex != 0)) {\r
1377 continue;\r
1378 }\r
1379 Status = MainEditor.TextInputEx->ReadKeyStrokeEx (MainEditor.TextInputEx, &KeyData);\r
1380 if (EFI_ERROR (Status)) {\r
1381 continue;\r
1382 }\r
632820d1 1383\r
7cb03133
RN
1384 if (((KeyData.KeyState.KeyShiftState & EFI_SHIFT_STATE_VALID) == 0) ||\r
1385 (KeyData.KeyState.KeyShiftState == EFI_SHIFT_STATE_VALID)) {\r
5563281f 1386 //\r
7cb03133 1387 // For consoles that don't support/report shift state,\r
5563281f
RN
1388 // CTRL+W is translated to L'W' - L'A' + 1.\r
1389 //\r
1390 if (KeyData.Key.UnicodeChar == L'W' - L'A' + 1) {\r
1391 break;\r
1392 }\r
7cb03133
RN
1393 } else if (((KeyData.KeyState.KeyShiftState & EFI_SHIFT_STATE_VALID) != 0) &&\r
1394 ((KeyData.KeyState.KeyShiftState & (EFI_LEFT_CONTROL_PRESSED | EFI_RIGHT_CONTROL_PRESSED)) != 0) &&\r
5563281f
RN
1395 ((KeyData.KeyState.KeyShiftState & ~(EFI_SHIFT_STATE_VALID | EFI_LEFT_CONTROL_PRESSED | EFI_RIGHT_CONTROL_PRESSED)) == 0)) {\r
1396 //\r
7cb03133 1397 // For consoles that supports/reports shift state,\r
5563281f
RN
1398 // make sure that only CONTROL shift key is pressed.\r
1399 //\r
1400 if ((KeyData.Key.UnicodeChar == 'w') || (KeyData.Key.UnicodeChar == 'W')) {\r
1401 break;\r
1402 }\r
1403 }\r
1404 }\r
feccc28a 1405 //\r
5a2beb74 1406 // update screen with file buffer's info\r
feccc28a 1407 //\r
5a2beb74 1408 FileBufferRestorePosition ();\r
1409 FileBufferNeedRefresh = TRUE;\r
1410 FileBufferOnlyLineNeedRefresh = FALSE;\r
ba0014b9 1411 FileBufferRefresh ();\r
632820d1 1412\r
5a2beb74 1413 return EFI_SUCCESS;\r
1414}\r
632820d1 1415\r
5a2beb74 1416EFI_EDITOR_COLOR_ATTRIBUTES OriginalColors;\r
1417INTN OriginalMode;\r
632820d1 1418\r
632820d1 1419\r
1420//\r
1421// basic initialization for MainEditor\r
1422//\r
1423EFI_EDITOR_GLOBAL_EDITOR MainEditorConst = {\r
1424 &FileBuffer,\r
1425 {\r
ce68d3bc 1426 {0, 0}\r
632820d1 1427 },\r
1428 {\r
1429 0,\r
1430 0\r
1431 },\r
1432 NULL,\r
5563281f 1433 NULL,\r
632820d1 1434 FALSE,\r
1435 NULL\r
1436};\r
1437\r
1438/**\r
1439 The initialization function for MainEditor.\r
1440\r
1441 @retval EFI_SUCCESS The operation was successful.\r
a048af3c 1442 @retval EFI_LOAD_ERROR A load error occurred.\r
632820d1 1443**/\r
1444EFI_STATUS\r
632820d1 1445MainEditorInit (\r
1446 VOID\r
1447 )\r
1448{\r
1449 EFI_STATUS Status;\r
1450 EFI_HANDLE *HandleBuffer;\r
1451 UINTN HandleCount;\r
1452 UINTN Index;\r
1453\r
1454 //\r
1455 // basic initialization\r
1456 //\r
1457 CopyMem (&MainEditor, &MainEditorConst, sizeof (MainEditor));\r
1458\r
1459 //\r
1460 // set screen attributes\r
1461 //\r
1462 MainEditor.ColorAttributes.Colors.Foreground = gST->ConOut->Mode->Attribute & 0x000000ff;\r
1463\r
1464 MainEditor.ColorAttributes.Colors.Background = (UINT8) (gST->ConOut->Mode->Attribute >> 4);\r
1465 OriginalColors = MainEditor.ColorAttributes.Colors;\r
1466\r
1467 OriginalMode = gST->ConOut->Mode->Mode;\r
1468\r
1469 //\r
1470 // query screen size\r
1471 //\r
1472 gST->ConOut->QueryMode (\r
1473 gST->ConOut,\r
1474 gST->ConOut->Mode->Mode,\r
1475 &(MainEditor.ScreenSize.Column),\r
1476 &(MainEditor.ScreenSize.Row)\r
1477 );\r
1478\r
5563281f
RN
1479 //\r
1480 // Find TextInEx in System Table ConsoleInHandle\r
1481 // Per UEFI Spec, TextInEx is required for a console capable platform.\r
1482 //\r
1483 Status = gBS->HandleProtocol (\r
1484 gST->ConsoleInHandle,\r
1485 &gEfiSimpleTextInputExProtocolGuid,\r
1486 (VOID**)&MainEditor.TextInputEx\r
1487 );\r
1488 if (EFI_ERROR (Status)) {\r
1489 return Status;\r
1490 }\r
1491\r
632820d1 1492 //\r
1493 // Find mouse in System Table ConsoleInHandle\r
1494 //\r
1495 Status = gBS->HandleProtocol (\r
f110b773 1496 gST->ConsoleInHandle,\r
632820d1 1497 &gEfiSimplePointerProtocolGuid,\r
1498 (VOID**)&MainEditor.MouseInterface\r
1499 );\r
1500 if (EFI_ERROR (Status)) {\r
1501 //\r
1502 // If there is no Simple Pointer Protocol on System Table\r
1503 //\r
1504 HandleBuffer = NULL;\r
1505 MainEditor.MouseInterface = NULL;\r
1506 Status = gBS->LocateHandleBuffer (\r
1507 ByProtocol,\r
1508 &gEfiSimplePointerProtocolGuid,\r
1509 NULL,\r
1510 &HandleCount,\r
1511 &HandleBuffer\r
1512 );\r
1513 if (!EFI_ERROR (Status) && HandleCount > 0) {\r
1514 //\r
1515 // Try to find the first available mouse device\r
1516 //\r
1517 for (Index = 0; Index < HandleCount; Index++) {\r
1518 Status = gBS->HandleProtocol (\r
1519 HandleBuffer[Index],\r
1520 &gEfiSimplePointerProtocolGuid,\r
1521 (VOID**)&MainEditor.MouseInterface\r
1522 );\r
1523 if (!EFI_ERROR (Status)) {\r
1524 break;\r
1525 }\r
1526 }\r
1527 }\r
1528 if (HandleBuffer != NULL) {\r
1529 FreePool (HandleBuffer);\r
1530 }\r
1531 }\r
1532\r
1533 if (!EFI_ERROR (Status) && MainEditor.MouseInterface != NULL) {\r
1534 MainEditor.MouseAccumulatorX = 0;\r
1535 MainEditor.MouseAccumulatorY = 0;\r
1536 MainEditor.MouseSupported = TRUE;\r
1537 }\r
1538\r
1539 //\r
1540 // below will call the five components' init function\r
1541 //\r
caa6c0cc 1542 Status = MainTitleBarInit (L"UEFI EDIT");\r
632820d1 1543 if (EFI_ERROR (Status)) {\r
1544 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN(STR_EDIT_LIBEDITOR_TITLEBAR), gShellDebug1HiiHandle);\r
1545 return EFI_LOAD_ERROR;\r
1546 }\r
1547\r
5a2beb74 1548 Status = ControlHotKeyInit (MainControlBasedMenuFunctions);\r
632820d1 1549 Status = MenuBarInit (MainMenuItems);\r
1550 if (EFI_ERROR (Status)) {\r
1551 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN(STR_EDIT_LIBEDITOR_MAINMENU), gShellDebug1HiiHandle);\r
1552 return EFI_LOAD_ERROR;\r
1553 }\r
1554\r
1555 Status = StatusBarInit ();\r
1556 if (EFI_ERROR (Status)) {\r
1557 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN(STR_EDIT_LIBEDITOR_STATUSBAR), gShellDebug1HiiHandle);\r
1558 return EFI_LOAD_ERROR;\r
1559 }\r
1560\r
5563281f 1561 InputBarInit (MainEditor.TextInputEx);\r
632820d1 1562\r
1563 Status = FileBufferInit ();\r
1564 if (EFI_ERROR (Status)) {\r
1565 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN(STR_EDIT_LIBEDITOR_FILEBUFFER), gShellDebug1HiiHandle);\r
1566 return EFI_LOAD_ERROR;\r
1567 }\r
1568 //\r
1569 // clear whole screen and enable cursor\r
1570 //\r
1571 gST->ConOut->ClearScreen (gST->ConOut);\r
1572 gST->ConOut->EnableCursor (gST->ConOut, TRUE);\r
1573\r
1574 //\r
1575 // initialize EditorFirst and EditorExit\r
1576 //\r
1577 EditorFirst = TRUE;\r
1578 EditorExit = FALSE;\r
1579 EditorMouseAction = FALSE;\r
1580\r
1581 return EFI_SUCCESS;\r
1582}\r
1583\r
1584/**\r
1585 The cleanup function for MainEditor.\r
1586\r
1587 @retval EFI_SUCCESS The operation was successful.\r
a048af3c 1588 @retval EFI_LOAD_ERROR A load error occurred.\r
632820d1 1589**/\r
1590EFI_STATUS\r
632820d1 1591MainEditorCleanup (\r
1592 VOID\r
1593 )\r
1594{\r
1595 EFI_STATUS Status;\r
1596\r
1597 //\r
1598 // call the five components' cleanup function\r
1599 // if error, do not exit\r
1600 // just print some warning\r
1601 //\r
1602 MainTitleBarCleanup();\r
1603 StatusBarCleanup();\r
1604 InputBarCleanup();\r
1605 MenuBarCleanup ();\r
1606\r
1607 Status = FileBufferCleanup ();\r
1608 if (EFI_ERROR (Status)) {\r
1609 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN(STR_EDIT_LIBEDITOR_FILEBUFFER_CLEANUP), gShellDebug1HiiHandle);\r
1610 }\r
1611 //\r
1612 // restore old mode\r
1613 //\r
1614 if (OriginalMode != gST->ConOut->Mode->Mode) {\r
1615 gST->ConOut->SetMode (gST->ConOut, OriginalMode);\r
1616 }\r
1617 //\r
1618 // restore old screen color\r
1619 //\r
1620 gST->ConOut->SetAttribute (\r
1621 gST->ConOut,\r
1622 EFI_TEXT_ATTR (OriginalColors.Foreground, OriginalColors.Background)\r
1623 );\r
1624\r
1625 gST->ConOut->ClearScreen (gST->ConOut);\r
1626\r
1627 return EFI_SUCCESS;\r
1628}\r
1629\r
1630/**\r
1631 Refresh the main editor component.\r
1632**/\r
1633VOID\r
632820d1 1634MainEditorRefresh (\r
1635 VOID\r
1636 )\r
1637{\r
1638 //\r
1639 // The Stall value is from experience. NOT from spec. avoids 'flicker'\r
1640 //\r
1641 gBS->Stall (50);\r
1642\r
1643 //\r
1644 // call the components refresh function\r
1645 //\r
ba0014b9
LG
1646 if (EditorFirst\r
1647 || StrCmp (FileBufferBackupVar.FileName, FileBuffer.FileName) != 0\r
1648 || FileBufferBackupVar.FileType != FileBuffer.FileType\r
1649 || FileBufferBackupVar.FileModified != FileBuffer.FileModified\r
632820d1 1650 || FileBufferBackupVar.ReadOnly != FileBuffer.ReadOnly) {\r
1651\r
980d554e 1652 MainTitleBarRefresh (MainEditor.FileBuffer->FileName, MainEditor.FileBuffer->FileType, MainEditor.FileBuffer->ReadOnly, MainEditor.FileBuffer->FileModified, MainEditor.ScreenSize.Column, MainEditor.ScreenSize.Row, 0, 0);\r
632820d1 1653 FileBufferRestorePosition ();\r
632820d1 1654 }\r
fb9dd832 1655\r
632820d1 1656 if (EditorFirst\r
ba0014b9
LG
1657 || FileBufferBackupVar.FilePosition.Row != FileBuffer.FilePosition.Row\r
1658 || FileBufferBackupVar.FilePosition.Column != FileBuffer.FilePosition.Column\r
632820d1 1659 || FileBufferBackupVar.ModeInsert != FileBuffer.ModeInsert\r
1660 || StatusBarGetRefresh()) {\r
1661\r
1662 StatusBarRefresh (EditorFirst, MainEditor.ScreenSize.Row, MainEditor.ScreenSize.Column, MainEditor.FileBuffer->FilePosition.Row, MainEditor.FileBuffer->FilePosition.Column, MainEditor.FileBuffer->ModeInsert);\r
1663 FileBufferRestorePosition ();\r
632820d1 1664 }\r
1665\r
1666 if (EditorFirst) {\r
632820d1 1667 FileBufferRestorePosition ();\r
1668 }\r
1669\r
fb9dd832
QS
1670 FileBufferRefresh ();\r
1671\r
632820d1 1672 //\r
1673 // EditorFirst is now set to FALSE\r
1674 //\r
1675 EditorFirst = FALSE;\r
1676}\r
1677\r
1678/**\r
1679 Get's the resultant location of the cursor based on the relative movement of the Mouse.\r
1680\r
1681 @param[in] GuidX The relative mouse movement.\r
1682\r
1683 @return The X location of the mouse.\r
1684**/\r
1685INT32\r
632820d1 1686GetTextX (\r
1687 IN INT32 GuidX\r
1688 )\r
1689{\r
1690 INT32 Gap;\r
1691\r
1692 MainEditor.MouseAccumulatorX += GuidX;\r
1693 Gap = (MainEditor.MouseAccumulatorX * (INT32) MainEditor.ScreenSize.Column) / (INT32) (50 * (INT32) MainEditor.MouseInterface->Mode->ResolutionX);\r
1694 MainEditor.MouseAccumulatorX = (MainEditor.MouseAccumulatorX * (INT32) MainEditor.ScreenSize.Column) % (INT32) (50 * (INT32) MainEditor.MouseInterface->Mode->ResolutionX);\r
1695 MainEditor.MouseAccumulatorX = MainEditor.MouseAccumulatorX / (INT32) MainEditor.ScreenSize.Column;\r
1696 return Gap;\r
1697}\r
1698\r
1699/**\r
1700 Get's the resultant location of the cursor based on the relative movement of the Mouse.\r
1701\r
1702 @param[in] GuidY The relative mouse movement.\r
1703\r
1704 @return The Y location of the mouse.\r
1705**/\r
1706INT32\r
632820d1 1707GetTextY (\r
1708 IN INT32 GuidY\r
1709 )\r
1710{\r
1711 INT32 Gap;\r
1712\r
1713 MainEditor.MouseAccumulatorY += GuidY;\r
1714 Gap = (MainEditor.MouseAccumulatorY * (INT32) MainEditor.ScreenSize.Row) / (INT32) (50 * (INT32) MainEditor.MouseInterface->Mode->ResolutionY);\r
1715 MainEditor.MouseAccumulatorY = (MainEditor.MouseAccumulatorY * (INT32) MainEditor.ScreenSize.Row) % (INT32) (50 * (INT32) MainEditor.MouseInterface->Mode->ResolutionY);\r
1716 MainEditor.MouseAccumulatorY = MainEditor.MouseAccumulatorY / (INT32) MainEditor.ScreenSize.Row;\r
1717\r
1718 return Gap;\r
1719}\r
1720\r
1721/**\r
1722 Support mouse movement. Move the cursor.\r
1723\r
664fd587 1724 @param[in] MouseState The current mouse state.\r
632820d1 1725\r
1726 @retval EFI_SUCCESS The operation was successful.\r
1727 @retval EFI_NOT_FOUND There was no mouse support found.\r
1728**/\r
632820d1 1729EFI_STATUS\r
632820d1 1730MainEditorHandleMouseInput (\r
664fd587 1731 IN EFI_SIMPLE_POINTER_STATE MouseState\r
632820d1 1732 )\r
1733{\r
1734\r
1735 INT32 TextX;\r
1736 INT32 TextY;\r
1737 UINTN FRow;\r
1738 UINTN FCol;\r
664fd587
RN
1739\r
1740 LIST_ENTRY *Link;\r
632820d1 1741 EFI_EDITOR_LINE *Line;\r
664fd587 1742\r
632820d1 1743 UINTN Index;\r
1744 BOOLEAN Action;\r
1745\r
1746 //\r
1747 // mouse action means:\r
1748 // mouse movement\r
1749 // mouse left button\r
1750 //\r
1751 Action = FALSE;\r
1752\r
1753 //\r
1754 // have mouse movement\r
1755 //\r
1756 if (MouseState.RelativeMovementX || MouseState.RelativeMovementY) {\r
1757 //\r
1758 // handle\r
1759 //\r
1760 TextX = GetTextX (MouseState.RelativeMovementX);\r
1761 TextY = GetTextY (MouseState.RelativeMovementY);\r
1762\r
1763 FileBufferAdjustMousePosition (TextX, TextY);\r
1764\r
1765 Action = TRUE;\r
1766\r
1767 }\r
1768\r
1769 //\r
1770 // if left button pushed down\r
1771 //\r
1772 if (MouseState.LeftButton) {\r
1773\r
1774 FCol = MainEditor.FileBuffer->MousePosition.Column - 1 + 1;\r
1775\r
1776 FRow = MainEditor.FileBuffer->FilePosition.Row +\r
1777 MainEditor.FileBuffer->MousePosition.Row -\r
1778 MainEditor.FileBuffer->DisplayPosition.Row;\r
1779\r
1780 //\r
1781 // beyond the file line length\r
1782 //\r
1783 if (MainEditor.FileBuffer->NumLines < FRow) {\r
1784 FRow = MainEditor.FileBuffer->NumLines;\r
1785 }\r
1786\r
1787 Link = MainEditor.FileBuffer->ListHead->ForwardLink;\r
1788 for (Index = 0; Index < FRow - 1; Index++) {\r
1789 Link = Link->ForwardLink;\r
1790 }\r
1791\r
1792 Line = CR (Link, EFI_EDITOR_LINE, Link, LINE_LIST_SIGNATURE);\r
1793\r
1794 //\r
1795 // beyond the line's column length\r
1796 //\r
664fd587
RN
1797 if (FCol > Line->Size + 1) {\r
1798 FCol = Line->Size + 1;\r
632820d1 1799 }\r
1800\r
1801 FileBufferMovePosition (FRow, FCol);\r
1802\r
1803 MainEditor.FileBuffer->MousePosition.Row = MainEditor.FileBuffer->DisplayPosition.Row;\r
1804\r
1805 MainEditor.FileBuffer->MousePosition.Column = MainEditor.FileBuffer->DisplayPosition.Column;\r
1806\r
1807 Action = TRUE;\r
1808 }\r
1809 //\r
1810 // mouse has action\r
1811 //\r
1812 if (Action) {\r
1813 return EFI_SUCCESS;\r
1814 }\r
1815\r
1816 //\r
1817 // no mouse action\r
1818 //\r
1819 return EFI_NOT_FOUND;\r
1820}\r
1821\r
1822/**\r
1823 Handle user key input. This routes to other functions for the actions.\r
1824\r
1825 @retval EFI_SUCCESS The operation was successful.\r
a048af3c 1826 @retval EFI_LOAD_ERROR A load error occurred.\r
632820d1 1827 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.\r
1828**/\r
1829EFI_STATUS\r
632820d1 1830MainEditorKeyInput (\r
1831 VOID\r
1832 )\r
1833{\r
5563281f 1834 EFI_KEY_DATA KeyData;\r
632820d1 1835 EFI_STATUS Status;\r
1836 EFI_SIMPLE_POINTER_STATE MouseState;\r
5563281f 1837 BOOLEAN NoShiftState;\r
632820d1 1838\r
1839 do {\r
1840\r
1841 Status = EFI_SUCCESS;\r
1842 EditorMouseAction = FALSE;\r
1843\r
1844 //\r
1845 // backup some key elements, so that can aVOID some refresh work\r
1846 //\r
1847 MainEditorBackup ();\r
1848\r
1849 //\r
1850 // change priority of checking mouse/keyboard activity dynamically\r
1851 // so prevent starvation of keyboard.\r
1852 // if last time, mouse moves then this time check keyboard\r
1853 //\r
1854 if (MainEditor.MouseSupported) {\r
1855 Status = MainEditor.MouseInterface->GetState (\r
1856 MainEditor.MouseInterface,\r
1857 &MouseState\r
1858 );\r
1859 if (!EFI_ERROR (Status)) {\r
1860\r
664fd587 1861 Status = MainEditorHandleMouseInput (MouseState);\r
632820d1 1862\r
1863 if (!EFI_ERROR (Status)) {\r
1864 EditorMouseAction = TRUE;\r
1865 FileBufferMouseNeedRefresh = TRUE;\r
1866 } else if (Status == EFI_LOAD_ERROR) {\r
1867 StatusBarSetStatusString (L"Invalid Mouse Movement ");\r
1868 }\r
1869 }\r
1870 }\r
1871\r
58793b88
RN
1872 //\r
1873 // CheckEvent() returns Success when non-partial key is pressed.\r
1874 //\r
1875 Status = gBS->CheckEvent (MainEditor.TextInputEx->WaitForKeyEx);\r
1876 if (!EFI_ERROR (Status)) {\r
5563281f
RN
1877 Status = MainEditor.TextInputEx->ReadKeyStrokeEx (MainEditor.TextInputEx, &KeyData);\r
1878 if (!EFI_ERROR (Status)) {\r
1879 //\r
1880 // dispatch to different components' key handling function\r
1881 // so not everywhere has to set this variable\r
1882 //\r
1883 FileBufferMouseNeedRefresh = TRUE;\r
632820d1 1884 //\r
5563281f 1885 // clear previous status string\r
632820d1 1886 //\r
5563281f
RN
1887 StatusBarSetRefresh();\r
1888 //\r
1889 // NoShiftState: TRUE when no shift key is pressed.\r
1890 //\r
1891 NoShiftState = ((KeyData.KeyState.KeyShiftState & EFI_SHIFT_STATE_VALID) == 0) || (KeyData.KeyState.KeyShiftState == EFI_SHIFT_STATE_VALID);\r
1892 //\r
1893 // dispatch to different components' key handling function\r
1894 //\r
1895 if (EFI_NOT_FOUND != MenuBarDispatchControlHotKey(&KeyData)) {\r
1896 Status = EFI_SUCCESS;\r
1897 } else if (NoShiftState && ((KeyData.Key.ScanCode == SCAN_NULL) || ((KeyData.Key.ScanCode >= SCAN_UP) && (KeyData.Key.ScanCode <= SCAN_PAGE_DOWN)))) {\r
1898 Status = FileBufferHandleInput (&KeyData.Key);\r
1899 } else if (NoShiftState && (KeyData.Key.ScanCode >= SCAN_F1) && (KeyData.Key.ScanCode <= SCAN_F12)) {\r
1900 Status = MenuBarDispatchFunctionKey (&KeyData.Key);\r
1901 } else {\r
1902 StatusBarSetStatusString (L"Unknown Command");\r
ba0014b9 1903 FileBufferMouseNeedRefresh = FALSE;\r
5563281f 1904 }\r
ba0014b9 1905\r
5563281f
RN
1906 if (Status != EFI_SUCCESS && Status != EFI_OUT_OF_RESOURCES) {\r
1907 //\r
1908 // not already has some error status\r
1909 //\r
1910 if (StatusBarGetString() != NULL && StrCmp (L"", StatusBarGetString()) == 0) {\r
1911 StatusBarSetStatusString (L"Disk Error. Try Again");\r
1912 }\r
632820d1 1913 }\r
632820d1 1914\r
5563281f 1915 }\r
632820d1 1916 }\r
58793b88
RN
1917 //\r
1918 // after handling, refresh editor\r
1919 //\r
1920 MainEditorRefresh ();\r
632820d1 1921\r
1922 } while (Status != EFI_OUT_OF_RESOURCES && !EditorExit);\r
1923\r
1924 return Status;\r
1925}\r
1926\r
1927/**\r
1928 Set clipboard\r
1929\r
1930 @param[in] Line A pointer to the line to be set to clipboard\r
1931\r
1932 @retval EFI_SUCCESS The operation was successful.\r
1933 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.\r
1934**/\r
1935EFI_STATUS\r
632820d1 1936MainEditorSetCutLine (\r
1937 EFI_EDITOR_LINE *Line\r
1938 )\r
1939{\r
1940 if (Line == NULL) {\r
1941 return EFI_SUCCESS;\r
1942 }\r
1943\r
1944 if (MainEditor.CutLine != NULL) {\r
1945 //\r
1946 // free the old clipboard\r
1947 //\r
1948 LineFree (MainEditor.CutLine);\r
1949 }\r
1950 //\r
1951 // duplicate the line to clipboard\r
1952 //\r
1953 MainEditor.CutLine = LineDup (Line);\r
1954 if (MainEditor.CutLine == NULL) {\r
1955 return EFI_OUT_OF_RESOURCES;\r
1956 }\r
1957\r
1958 return EFI_SUCCESS;\r
1959}\r
1960\r
1961/**\r
1962 Backup function for MainEditor\r
1963\r
1964 @retval EFI_SUCCESS The operation was successful.\r
1965**/\r
1966EFI_STATUS\r
632820d1 1967MainEditorBackup (\r
1968 VOID\r
1969 )\r
1970{\r
1971 FileBufferBackup ();\r
ba0014b9 1972\r
632820d1 1973 return EFI_SUCCESS;\r
1974}\r