OpenCore  1.0.4
OpenCore Bootloader
Loading...
Searching...
No Matches
AIKSource.c
Go to the documentation of this file.
1
15#include "AIKSource.h"
16#include "AIKShim.h"
17
18#include <Library/BaseMemoryLib.h>
19#include <Library/DebugLib.h>
20#include <Library/OcInputLib.h>
21#include <Library/UefiBootServicesTableLib.h>
22
23EFI_STATUS
25 AIK_SOURCE *Source,
26 AMI_EFI_KEY_DATA *KeyData,
27 BOOLEAN KeyFiltering
28 )
29{
30 EFI_STATUS Status;
31 EFI_EVENT Event;
32
33 ZeroMem (KeyData, sizeof (*KeyData));
34
35 if ((Source->AmiKeycode != NULL) && Source->AmiReadEfikey) {
36 Status = Source->AmiReadEfikey (Source->AmiKeycode, KeyData);
37 Event = Source->AmiKeycode->WaitForKeyEx;
38 } else if ((Source->TextInputEx != NULL) && Source->TextReadKeyStrokeEx) {
39 Status = Source->TextReadKeyStrokeEx (Source->TextInputEx, (EFI_KEY_DATA *)KeyData);
40 Event = Source->TextInputEx->WaitForKeyEx;
41 } else if ((Source->TextInput != NULL) && Source->TextReadKeyStroke) {
42 Status = Source->TextReadKeyStroke (Source->TextInput, &KeyData->Key);
43 Event = Source->TextInput->WaitForKey;
44 } else {
45 //
46 // Should never happen.
47 //
48 Status = EFI_NOT_FOUND;
49 Event = NULL;
50 }
51
52 if (EFI_ERROR (Status)) {
53 return Status;
54 }
55
56 //
57 // Some boards like GA Z77P-D3 may return uninitialised data in EFI_INPUT_KEY.
58 // Try to reduce the effects by discarding definitely invalid symbols.
59 // See: tables 107 and 108 in UEFI spec describing EFI Scan Codes.
60 //
61 if (KeyFiltering) {
62 if ((KeyData->Key.UnicodeChar & ~0xFFU) != 0) {
63 return EFI_UNSUPPORTED;
64 }
65
66 switch (KeyData->Key.ScanCode) {
67 case SCAN_NULL:
68 case SCAN_UP:
69 case SCAN_DOWN:
70 case SCAN_RIGHT:
71 case SCAN_LEFT:
72 case SCAN_HOME:
73 case SCAN_END:
74 case SCAN_INSERT:
75 case SCAN_DELETE:
76 case SCAN_PAGE_UP:
77 case SCAN_PAGE_DOWN:
78 case SCAN_F1:
79 case SCAN_F2:
80 case SCAN_F3:
81 case SCAN_F4:
82 case SCAN_F5:
83 case SCAN_F6:
84 case SCAN_F7:
85 case SCAN_F8:
86 case SCAN_F9:
87 case SCAN_F10:
88 case SCAN_ESC:
89 case SCAN_F11:
90 case SCAN_F12:
91 case SCAN_PAUSE:
92 case SCAN_F13:
93 case SCAN_F14:
94 case SCAN_F15:
95 case SCAN_F16:
96 case SCAN_F17:
97 case SCAN_F18:
98 case SCAN_F19:
99 case SCAN_F20:
100 case SCAN_F21:
101 case SCAN_F22:
102 case SCAN_F23:
103 case SCAN_F24:
104 case SCAN_MUTE:
105 case SCAN_VOLUME_UP:
106 case SCAN_VOLUME_DOWN:
107 case SCAN_BRIGHTNESS_UP:
108 case SCAN_BRIGHTNESS_DOWN:
109 case SCAN_SUSPEND:
110 case SCAN_HIBERNATE:
111 case SCAN_TOGGLE_DISPLAY:
112 case SCAN_RECOVERY:
113 case SCAN_EJECT:
114 break;
115 default:
116 return EFI_UNSUPPORTED;
117 }
118 }
119
120 if (Event != NULL) {
121 gBS->SignalEvent (Event);
122 }
123
124 return EFI_SUCCESS;
125}
126
127EFI_STATUS
129 AIK_SOURCE *Source,
131 )
132{
133 EFI_STATUS Status;
134
135 if ((Source->AmiKeycode != NULL) || (Source->TextInput != NULL) || (Source->TextInputEx != NULL)) {
136 return EFI_SUCCESS;
137 }
138
139 Source->ConSplitHandler = gST->ConsoleInHandle;
140
141 if ((Mode == OcInputKeyModeAuto) || (Mode == OcInputKeyModeAmi)) {
142 Status = gBS->HandleProtocol (
143 Source->ConSplitHandler,
145 (VOID **)&Source->AmiKeycode
146 );
147 if (EFI_ERROR (Status)) {
148 DEBUG ((DEBUG_INFO, "OCII: AmiEfiKeycodeProtocol is unavailable on gST->ConsoleHandle - %r\n", Status));
149 }
150 }
151
152 if ((Mode == OcInputKeyModeAuto) || (Mode == OcInputKeyModeV1)) {
153 Status = gBS->HandleProtocol (
154 Source->ConSplitHandler,
155 &gEfiSimpleTextInProtocolGuid,
156 (VOID **)&Source->TextInput
157 );
158 if (EFI_ERROR (Status)) {
159 DEBUG ((DEBUG_INFO, "OCII: EfiSimpleTextInProtocol is unavailable on gST->ConsoleHandle - %r\n", Status));
160 }
161 }
162
163 if ((Mode == OcInputKeyModeAuto) || (Mode == OcInputKeyModeV2)) {
164 Status = gBS->HandleProtocol (
165 Source->ConSplitHandler,
166 &gEfiSimpleTextInputExProtocolGuid,
167 (VOID **)&Source->TextInputEx
168 );
169 if (EFI_ERROR (Status)) {
170 DEBUG ((DEBUG_INFO, "OCII: EfiSimpleTextInputExProtocol is unavailable on gST->ConsoleHandle - %r\n", Status));
171 }
172 }
173
174 if ((Source->AmiKeycode == NULL) && (Source->TextInput == NULL) && (Source->TextInputEx == NULL)) {
175 DEBUG ((DEBUG_INFO, "OCII: No ConSplitter input protocol is unavailable\n"));
176 return EFI_NOT_FOUND;
177 }
178
179 DEBUG ((DEBUG_INFO, "OCII: gST->ConIn %p vs found %p\n", gST->ConIn, Source->TextInput));
180
181 if (Source->AmiKeycode) {
182 Source->AmiReadEfikey = Source->AmiKeycode->ReadEfikey;
183 Source->AmiWait = Source->AmiKeycode->WaitForKeyEx;
185 Status = gBS->CreateEvent (
186 EVT_NOTIFY_WAIT,
187 TPL_NOTIFY,
189 NULL,
190 &Source->AmiKeycode->WaitForKeyEx
191 );
192 if (EFI_ERROR (Status)) {
193 DEBUG ((DEBUG_INFO, "OCII: AmiEfiKeycodeProtocol WaitForKey replace failed - %r\n", Status));
194 Source->AmiKeycode->WaitForKeyEx = Source->AmiWait;
195 Source->AmiWait = NULL;
196 }
197 }
198
199 if (Source->TextInput) {
200 Source->TextReadKeyStroke = Source->TextInput->ReadKeyStroke;
201 Source->TextWait = Source->TextInput->WaitForKey;
202 Source->TextInput->ReadKeyStroke = AIKShimTextInputReadKeyStroke;
203 Status = gBS->CreateEvent (
204 EVT_NOTIFY_WAIT,
205 TPL_NOTIFY,
207 NULL,
208 &Source->TextInput->WaitForKey
209 );
210 if (EFI_ERROR (Status)) {
211 DEBUG ((DEBUG_INFO, "OCII: EfiSimpleTextInProtocol WaitForKey replace failed - %r\n", Status));
212 Source->TextInput->WaitForKey = Source->TextWait;
213 Source->TextWait = NULL;
214 }
215 }
216
217 if (Source->TextInputEx) {
218 Source->TextWaitEx = Source->TextInputEx->WaitForKeyEx;
219 Source->TextReadKeyStrokeEx = Source->TextInputEx->ReadKeyStrokeEx;
220 Source->TextInputEx->ReadKeyStrokeEx = AIKShimTextInputReadKeyStrokeEx;
221 Status = gBS->CreateEvent (
222 EVT_NOTIFY_WAIT,
223 TPL_NOTIFY,
225 NULL,
226 &Source->TextInputEx->WaitForKeyEx
227 );
228 if (EFI_ERROR (Status)) {
229 DEBUG ((DEBUG_INFO, "OCII: EfiSimpleTextInputExProtocol WaitForKey replace failed - %r\n", Status));
230 Source->TextInputEx->WaitForKeyEx = Source->TextWaitEx;
231 Source->TextWaitEx = NULL;
232 }
233 }
234
235 return EFI_SUCCESS;
236}
237
238VOID
240 AIK_SOURCE *Source
241 )
242{
243 if (Source->AmiKeycode) {
244 Source->AmiKeycode->ReadEfikey = Source->AmiReadEfikey;
245 if ((Source->AmiWait != NULL) && (Source->AmiWait != Source->AmiKeycode->WaitForKeyEx)) {
246 gBS->CloseEvent (Source->AmiKeycode->WaitForKeyEx);
247 Source->AmiKeycode->WaitForKeyEx = Source->AmiWait;
248 }
249
250 Source->AmiReadEfikey = NULL;
251 Source->AmiWait = NULL;
252 Source->AmiKeycode = NULL;
253 }
254
255 if (Source->TextInput) {
256 Source->TextInput->ReadKeyStroke = Source->TextReadKeyStroke;
257 if ((Source->TextWait != NULL) && (Source->TextWait != Source->TextInput->WaitForKey)) {
258 gBS->CloseEvent (Source->TextInput->WaitForKey);
259 Source->TextInput->WaitForKey = Source->TextWait;
260 }
261
262 Source->TextInput = NULL;
263 Source->TextWait = NULL;
264 Source->TextReadKeyStroke = NULL;
265 }
266
267 if (Source->TextInputEx) {
268 Source->TextInputEx->ReadKeyStrokeEx = Source->TextReadKeyStrokeEx;
269 if ((Source->TextWaitEx != NULL) && (Source->TextWaitEx != Source->TextInputEx->WaitForKeyEx)) {
270 gBS->CloseEvent (Source->TextInputEx->WaitForKeyEx);
271 Source->TextInputEx->WaitForKeyEx = Source->TextWaitEx;
272 }
273
274 Source->TextInputEx = NULL;
275 Source->TextWaitEx = NULL;
276 Source->TextReadKeyStrokeEx = NULL;
277 }
278
279 if (Source->ConSplitHandler != NULL) {
280 gBS->DisconnectController (Source->ConSplitHandler, NULL, NULL);
281 Source->ConSplitHandler = NULL;
282 }
283}
VOID EFIAPI AIKShimWaitForKeyHandler(IN EFI_EVENT Event, IN VOID *Context)
Definition AIKShim.c:140
EFI_STATUS EFIAPI AIKShimTextInputReadKeyStroke(IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This, OUT EFI_INPUT_KEY *Key)
Definition AIKShim.c:54
EFI_STATUS EFIAPI AIKShimAmiKeycodeReadEfikey(IN AMI_EFIKEYCODE_PROTOCOL *This, OUT AMI_EFI_KEY_DATA *KeyData)
Definition AIKShim.c:24
EFI_STATUS EFIAPI AIKShimTextInputReadKeyStrokeEx(IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, OUT EFI_KEY_DATA *KeyData)
Definition AIKShim.c:101
EFI_STATUS AIKSourceInstall(AIK_SOURCE *Source, OC_INPUT_KEY_MODE Mode)
Definition AIKSource.c:128
EFI_STATUS AIKSourceGrabEfiKey(AIK_SOURCE *Source, AMI_EFI_KEY_DATA *KeyData, BOOLEAN KeyFiltering)
Definition AIKSource.c:24
VOID AIKSourceUninstall(AIK_SOURCE *Source)
Definition AIKSource.c:239
EFI_GUID gAmiEfiKeycodeProtocolGuid
EFI_SYSTEM_TABLE * gST
EFI_BOOT_SERVICES * gBS
OC_INPUT_KEY_MODE
Definition OcInputLib.h:23
@ OcInputKeyModeV1
Definition OcInputLib.h:25
@ OcInputKeyModeV2
Definition OcInputLib.h:26
@ OcInputKeyModeAuto
Definition OcInputLib.h:24
@ OcInputKeyModeAmi
Definition OcInputLib.h:27
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
AMI_READ_EFI_KEY ReadEfikey
Definition AmiKeycode.h:53
EFI_HANDLE ConSplitHandler
Definition AIKSource.h:28
EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL * TextInputEx
Definition AIKSource.h:38
EFI_EVENT TextWait
Definition AIKSource.h:45
EFI_SIMPLE_TEXT_INPUT_PROTOCOL * TextInput
Definition AIKSource.h:37
EFI_INPUT_READ_KEY TextReadKeyStroke
Definition AIKSource.h:46
EFI_EVENT AmiWait
Definition AIKSource.h:44
EFI_EVENT TextWaitEx
Definition AIKSource.h:48
EFI_INPUT_READ_KEY_EX TextReadKeyStrokeEx
Definition AIKSource.h:47
AMI_EFIKEYCODE_PROTOCOL * AmiKeycode
Definition AIKSource.h:36
AMI_READ_EFI_KEY AmiReadEfikey
Definition AIKSource.h:43
EFI_INPUT_KEY Key
Definition AmiKeycode.h:31