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