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