49 &gUsbKeyboardDriverBinding,
51 &gUsbKeyboardComponentName,
52 &gUsbKeyboardComponentName2
84 Status =
gBS->OpenProtocol (
86 &gEfiUsbIoProtocolGuid,
88 This->DriverBindingHandle,
90 EFI_OPEN_PROTOCOL_BY_DRIVER
92 if (EFI_ERROR (Status)) {
103 Status = EFI_UNSUPPORTED;
108 &gEfiUsbIoProtocolGuid,
109 This->DriverBindingHandle,
144 UINT8 EndpointNumber;
148 UINT8 PollingInterval;
153 OldTpl =
gBS->RaiseTPL (TPL_CALLBACK);
157 Status =
gBS->OpenProtocol (
159 &gEfiUsbIoProtocolGuid,
161 This->DriverBindingHandle,
163 EFI_OPEN_PROTOCOL_BY_DRIVER
165 if (EFI_ERROR (Status)) {
170 ASSERT (UsbKeyboardDevice !=
NULL);
175 Status =
gBS->OpenProtocol (
177 &gEfiDevicePathProtocolGuid,
178 (VOID **)&UsbKeyboardDevice->DevicePath,
179 This->DriverBindingHandle,
181 EFI_OPEN_PROTOCOL_GET_PROTOCOL
184 if (EFI_ERROR (Status)) {
193 (EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_ENABLE),
194 UsbKeyboardDevice->DevicePath
202 (EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_PRESENCE_DETECT),
203 UsbKeyboardDevice->DevicePath
206 UsbKeyboardDevice->UsbIo = UsbIo;
211 UsbIo->UsbGetInterfaceDescriptor (
213 &UsbKeyboardDevice->InterfaceDescriptor
216 EndpointNumber = UsbKeyboardDevice->InterfaceDescriptor.NumEndpoints;
222 for (Index = 0; Index < EndpointNumber; Index++) {
223 UsbIo->UsbGetEndpointDescriptor (
229 if (((EndpointDescriptor.Attributes & (BIT0 | BIT1)) == USB_ENDPOINT_INTERRUPT) &&
230 ((EndpointDescriptor.EndpointAddress & USB_ENDPOINT_DIR_IN) != 0))
235 CopyMem (&UsbKeyboardDevice->IntEndpointDescriptor, &EndpointDescriptor, sizeof (EndpointDescriptor));
247 (EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_NOT_DETECTED)
252 Status = EFI_UNSUPPORTED;
258 (EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_DETECTED),
259 UsbKeyboardDevice->DevicePath
262 UsbKeyboardDevice->Signature = USB_KB_DEV_SIGNATURE;
274 Status =
gBS->CreateEvent (
275 EVT_TIMER | EVT_NOTIFY_SIGNAL,
279 &UsbKeyboardDevice->TimerEvent
281 if (!EFI_ERROR (Status)) {
282 Status =
gBS->SetTimer (UsbKeyboardDevice->TimerEvent,
TimerPeriodic, KEYBOARD_TIMER_INTERVAL);
285 if (EFI_ERROR (Status)) {
289 Status =
gBS->CreateEvent (
297 if (EFI_ERROR (Status)) {
301 Status =
gBS->CreateEvent (
308 if (EFI_ERROR (Status)) {
312 Status =
gBS->CreateEvent (
317 &UsbKeyboardDevice->KeyNotifyProcessEvent
319 if (EFI_ERROR (Status)) {
330 Status =
gBS->InstallMultipleProtocolInterfaces (
332 &gEfiSimpleTextInProtocolGuid,
333 &UsbKeyboardDevice->SimpleInput,
334 &gEfiSimpleTextInputExProtocolGuid,
335 &UsbKeyboardDevice->SimpleInputEx,
338 if (EFI_ERROR (Status)) {
342 UsbKeyboardDevice->ControllerHandle = Controller;
344 if (EFI_ERROR (Status)) {
345 gBS->UninstallMultipleProtocolInterfaces (
347 &gEfiSimpleTextInProtocolGuid,
348 &UsbKeyboardDevice->SimpleInput,
349 &gEfiSimpleTextInputExProtocolGuid,
350 &UsbKeyboardDevice->SimpleInputEx,
359 Status = UsbKeyboardDevice->SimpleInputEx.Reset (
360 &UsbKeyboardDevice->SimpleInputEx,
363 if (EFI_ERROR (Status)) {
364 gBS->UninstallMultipleProtocolInterfaces (
366 &gEfiSimpleTextInProtocolGuid,
367 &UsbKeyboardDevice->SimpleInput,
368 &gEfiSimpleTextInputExProtocolGuid,
369 &UsbKeyboardDevice->SimpleInputEx,
378 EndpointAddr = UsbKeyboardDevice->IntEndpointDescriptor.EndpointAddress;
379 PollingInterval = UsbKeyboardDevice->IntEndpointDescriptor.Interval;
380 PacketSize = (UINT8)(UsbKeyboardDevice->IntEndpointDescriptor.MaxPacketSize);
382 Status = UsbIo->UsbAsyncInterruptTransfer (
392 if (EFI_ERROR (Status)) {
393 gBS->UninstallMultipleProtocolInterfaces (
395 &gEfiSimpleTextInProtocolGuid,
396 &UsbKeyboardDevice->SimpleInput,
397 &gEfiSimpleTextInputExProtocolGuid,
398 &UsbKeyboardDevice->SimpleInputEx,
404 UsbKeyboardDevice->ControllerNameTable =
NULL;
408 &UsbKeyboardDevice->ControllerNameTable,
409 L
"Generic Usb Keyboard",
415 &UsbKeyboardDevice->ControllerNameTable,
416 L
"Generic Usb Keyboard",
420 gBS->RestoreTPL (OldTpl);
427 if (UsbKeyboardDevice !=
NULL) {
428 if (UsbKeyboardDevice->TimerEvent !=
NULL) {
429 gBS->CloseEvent (UsbKeyboardDevice->TimerEvent);
440 if (UsbKeyboardDevice->KeyNotifyProcessEvent !=
NULL) {
441 gBS->CloseEvent (UsbKeyboardDevice->KeyNotifyProcessEvent);
444 if (UsbKeyboardDevice->KeyboardLayoutEvent !=
NULL) {
446 gBS->CloseEvent (UsbKeyboardDevice->KeyboardLayoutEvent);
450 UsbKeyboardDevice =
NULL;
455 &gEfiUsbIoProtocolGuid,
456 This->DriverBindingHandle,
461 gBS->RestoreTPL (OldTpl);
494 Status =
gBS->OpenProtocol (
496 &gEfiSimpleTextInProtocolGuid,
497 (VOID **)&SimpleInput,
498 This->DriverBindingHandle,
500 EFI_OPEN_PROTOCOL_GET_PROTOCOL
502 if (EFI_ERROR (Status)) {
503 return EFI_UNSUPPORTED;
506 Status =
gBS->OpenProtocol (
508 &gEfiSimpleTextInputExProtocolGuid,
510 This->DriverBindingHandle,
512 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
514 if (EFI_ERROR (Status)) {
515 return EFI_UNSUPPORTED;
518 UsbKeyboardDevice = USB_KB_DEV_FROM_THIS (SimpleInput);
525 (EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_DISABLE),
526 UsbKeyboardDevice->DevicePath
532 UsbKeyboardDevice->UsbIo->UsbAsyncInterruptTransfer (
533 UsbKeyboardDevice->UsbIo,
534 UsbKeyboardDevice->IntEndpointDescriptor.EndpointAddress,
536 UsbKeyboardDevice->IntEndpointDescriptor.Interval,
544 &gEfiUsbIoProtocolGuid,
545 This->DriverBindingHandle,
549 Status =
gBS->UninstallMultipleProtocolInterfaces (
551 &gEfiSimpleTextInProtocolGuid,
552 &UsbKeyboardDevice->SimpleInput,
553 &gEfiSimpleTextInputExProtocolGuid,
554 &UsbKeyboardDevice->SimpleInputEx,
560 gBS->CloseEvent (UsbKeyboardDevice->TimerEvent);
561 gBS->CloseEvent (UsbKeyboardDevice->RepeatTimer);
562 gBS->CloseEvent (UsbKeyboardDevice->DelayedRecoveryEvent);
565 gBS->CloseEvent (UsbKeyboardDevice->KeyNotifyProcessEvent);
569 gBS->CloseEvent (UsbKeyboardDevice->KeyboardLayoutEvent);
571 if (UsbKeyboardDevice->ControllerNameTable !=
NULL) {
577 DestroyQueue (&UsbKeyboardDevice->EfiKeyQueueForNotify);
605 if (KeyData ==
NULL) {
606 return EFI_INVALID_PARAMETER;
610 ZeroMem (&KeyData->Key, sizeof (KeyData->Key));
612 return EFI_NOT_READY;
615 Dequeue (&UsbKeyboardDevice->EfiKeyQueue, KeyData, sizeof (*KeyData));
639 IN BOOLEAN ExtendedVerification
645 UsbKeyboardDevice = USB_KB_DEV_FROM_THIS (This);
649 (EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_RESET),
650 UsbKeyboardDevice->DevicePath
657 if (!ExtendedVerification) {
661 UsbKeyboardDevice->DevicePath
677 if (EFI_ERROR (Status)) {
678 return EFI_DEVICE_ERROR;
709 UsbKeyboardDevice = USB_KB_DEV_FROM_THIS (This);
718 if (EFI_ERROR (Status)) {
725 if ((KeyData.
Key.ScanCode == CHAR_NULL) && (KeyData.
Key.UnicodeChar == SCAN_NULL)) {
733 if ((KeyData.
KeyState.
KeyShiftState & (EFI_LEFT_CONTROL_PRESSED | EFI_RIGHT_CONTROL_PRESSED)) != 0) {
734 if ((KeyData.
Key.UnicodeChar >= L
'a') && (KeyData.
Key.UnicodeChar <= L
'z')) {
735 KeyData.
Key.UnicodeChar = (CHAR16)(KeyData.
Key.UnicodeChar - L
'a' + 1);
736 }
else if ((KeyData.
Key.UnicodeChar >= L
'A') && (KeyData.
Key.UnicodeChar <= L
'Z')) {
737 KeyData.
Key.UnicodeChar = (CHAR16)(KeyData.
Key.UnicodeChar - L
'A' + 1);
770 OldTpl =
gBS->RaiseTPL (TPL_NOTIFY);
778 while (!
IsQueueEmpty (&UsbKeyboardDevice->EfiKeyQueue)) {
784 UsbKeyboardDevice->EfiKeyQueue.Buffer[UsbKeyboardDevice->EfiKeyQueue.Head],
787 if ((KeyData.
Key.ScanCode == SCAN_NULL) && (KeyData.
Key.UnicodeChar == CHAR_NULL)) {
792 gBS->SignalEvent (Event);
799 gBS->RestoreTPL (OldTpl);
826 Status =
USBParseKey (UsbKeyboardDevice, &KeyCode);
827 if (EFI_ERROR (Status)) {
835 if (EFI_ERROR (Status)) {
842 Enqueue (&UsbKeyboardDevice->EfiKeyQueue, &KeyData, sizeof (KeyData));
862 if (NotifyList ==
NULL) {
863 return EFI_INVALID_PARAMETER;
892 ASSERT (RegsiteredData !=
NULL && InputData !=
NULL);
894 if ((RegsiteredData->Key.ScanCode != InputData->Key.ScanCode) ||
895 (RegsiteredData->Key.UnicodeChar != InputData->Key.UnicodeChar))
903 if ((RegsiteredData->KeyState.KeyShiftState != 0) &&
904 (RegsiteredData->KeyState.KeyShiftState != InputData->KeyState.KeyShiftState))
909 if ((RegsiteredData->KeyState.KeyToggleState != 0) &&
910 (RegsiteredData->KeyState.KeyToggleState != InputData->KeyState.KeyToggleState))
948 IN BOOLEAN ExtendedVerification
954 UsbKeyboardDevice = TEXT_INPUT_EX_USB_KB_DEV_FROM_THIS (This);
956 Status = UsbKeyboardDevice->SimpleInput.Reset (&UsbKeyboardDevice->SimpleInput, ExtendedVerification);
957 if (EFI_ERROR (Status)) {
958 return EFI_DEVICE_ERROR;
961 UsbKeyboardDevice->KeyState.
KeyShiftState = EFI_SHIFT_STATE_VALID;
962 UsbKeyboardDevice->KeyState.
KeyToggleState = EFI_TOGGLE_STATE_VALID;
991 if (KeyData ==
NULL) {
992 return EFI_INVALID_PARAMETER;
995 UsbKeyboardDevice = TEXT_INPUT_EX_USB_KB_DEV_FROM_THIS (This);
1023 if (KeyToggleState ==
NULL) {
1024 return EFI_INVALID_PARAMETER;
1027 UsbKeyboardDevice = TEXT_INPUT_EX_USB_KB_DEV_FROM_THIS (This);
1029 if (((UsbKeyboardDevice->KeyState.
KeyToggleState & EFI_TOGGLE_STATE_VALID) != EFI_TOGGLE_STATE_VALID) ||
1030 ((*KeyToggleState & EFI_TOGGLE_STATE_VALID) != EFI_TOGGLE_STATE_VALID))
1032 return EFI_UNSUPPORTED;
1039 UsbKeyboardDevice->ScrollOn =
FALSE;
1040 UsbKeyboardDevice->NumLockOn =
FALSE;
1041 UsbKeyboardDevice->CapsOn =
FALSE;
1042 UsbKeyboardDevice->IsSupportPartialKey =
FALSE;
1044 if ((*KeyToggleState & EFI_SCROLL_LOCK_ACTIVE) == EFI_SCROLL_LOCK_ACTIVE) {
1045 UsbKeyboardDevice->ScrollOn =
TRUE;
1048 if ((*KeyToggleState & EFI_NUM_LOCK_ACTIVE) == EFI_NUM_LOCK_ACTIVE) {
1049 UsbKeyboardDevice->NumLockOn =
TRUE;
1052 if ((*KeyToggleState & EFI_CAPS_LOCK_ACTIVE) == EFI_CAPS_LOCK_ACTIVE) {
1053 UsbKeyboardDevice->CapsOn =
TRUE;
1056 if ((*KeyToggleState & EFI_KEY_STATE_EXPOSED) == EFI_KEY_STATE_EXPOSED) {
1057 UsbKeyboardDevice->IsSupportPartialKey =
TRUE;
1092 OUT VOID **NotifyHandle
1101 if ((KeyData ==
NULL) || (NotifyHandle ==
NULL) || (KeyNotificationFunction ==
NULL)) {
1102 return EFI_INVALID_PARAMETER;
1105 UsbKeyboardDevice = TEXT_INPUT_EX_USB_KB_DEV_FROM_THIS (This);
1110 NotifyList = &UsbKeyboardDevice->NotifyList;
1113 !
IsNull (NotifyList, Link);
1116 CurrentNotify =
CR (
1120 USB_KB_CONSOLE_IN_EX_NOTIFY_SIGNATURE
1123 if (CurrentNotify->KeyNotificationFn == KeyNotificationFunction) {
1124 *NotifyHandle = CurrentNotify;
1134 if (NewNotify ==
NULL) {
1135 return EFI_OUT_OF_RESOURCES;
1138 NewNotify->Signature = USB_KB_CONSOLE_IN_EX_NOTIFY_SIGNATURE;
1139 NewNotify->KeyNotificationFn = KeyNotificationFunction;
1141 InsertTailList (&UsbKeyboardDevice->NotifyList, &NewNotify->NotifyEntry);
1143 *NotifyHandle = NewNotify;
1162 IN VOID *NotificationHandle
1170 if (NotificationHandle ==
NULL) {
1171 return EFI_INVALID_PARAMETER;
1174 UsbKeyboardDevice = TEXT_INPUT_EX_USB_KB_DEV_FROM_THIS (This);
1179 NotifyList = &UsbKeyboardDevice->NotifyList;
1181 !
IsNull (NotifyList, Link);
1184 CurrentNotify =
CR (
1188 USB_KB_CONSOLE_IN_EX_NOTIFY_SIGNATURE
1190 if (CurrentNotify == NotificationHandle) {
1204 return EFI_INVALID_PARAMETER;
1233 NotifyList = &UsbKeyboardDevice->NotifyList;
1238 OldTpl =
gBS->RaiseTPL (TPL_NOTIFY);
1239 Status =
Dequeue (&UsbKeyboardDevice->EfiKeyQueueForNotify, &KeyData, sizeof (KeyData));
1243 gBS->RestoreTPL (OldTpl);
1244 if (EFI_ERROR (Status)) {
1251 CurrentNotify->KeyNotificationFn (&KeyData);
BOOLEAN EFIAPI IsNull(IN CONST LIST_ENTRY *List, IN CONST LIST_ENTRY *Node)
BOOLEAN EFIAPI IsListEmpty(IN CONST LIST_ENTRY *ListHead)
LIST_ENTRY *EFIAPI GetNextNode(IN CONST LIST_ENTRY *List, IN CONST LIST_ENTRY *Node)
LIST_ENTRY *EFIAPI GetFirstNode(IN CONST LIST_ENTRY *List)
LIST_ENTRY *EFIAPI RemoveEntryList(IN CONST LIST_ENTRY *Entry)
LIST_ENTRY *EFIAPI InitializeListHead(IN OUT LIST_ENTRY *ListHead)
LIST_ENTRY *EFIAPI InsertTailList(IN OUT LIST_ENTRY *ListHead, IN OUT LIST_ENTRY *Entry)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
EFI_STATUS USBKeyboardReadKeyStrokeWorker(IN OUT USB_KB_DEV *UsbKeyboardDevice, OUT EFI_KEY_DATA *KeyData)
EFI_STATUS EFIAPI USBKeyboardDriverBindingSupported(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE Controller, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath)
VOID EFIAPI KeyNotifyProcessHandler(IN EFI_EVENT Event, IN VOID *Context)
EFI_STATUS EFIAPI USBKeyboardUnregisterKeyNotify(IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, IN VOID *NotificationHandle)
EFI_STATUS EFIAPI USBKeyboardResetEx(IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, IN BOOLEAN ExtendedVerification)
EFI_STATUS EFIAPI USBKeyboardRegisterKeyNotify(IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, IN EFI_KEY_DATA *KeyData, IN EFI_KEY_NOTIFY_FUNCTION KeyNotificationFunction, OUT VOID **NotifyHandle)
EFI_STATUS EFIAPI USBKeyboardDriverBindingStop(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE Controller, IN UINTN NumberOfChildren, IN EFI_HANDLE *ChildHandleBuffer)
EFI_STATUS EFIAPI USBKeyboardDriverBindingEntryPoint(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
VOID EFIAPI USBKeyboardWaitForKey(IN EFI_EVENT Event, IN VOID *Context)
EFI_STATUS EFIAPI USBKeyboardSetState(IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, IN EFI_KEY_TOGGLE_STATE *KeyToggleState)
VOID EFIAPI USBKeyboardTimerHandler(IN EFI_EVENT Event, IN VOID *Context)
EFI_STATUS EFIAPI USBKeyboardDriverBindingStart(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE Controller, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath)
EFI_STATUS KbdFreeNotifyList(IN OUT LIST_ENTRY *NotifyList)
EFI_STATUS EFIAPI USBKeyboardReset(IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This, IN BOOLEAN ExtendedVerification)
EFI_STATUS EFIAPI USBKeyboardReadKeyStrokeEx(IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, OUT EFI_KEY_DATA *KeyData)
EFI_STATUS EFIAPI USBKeyboardReadKeyStroke(IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This, OUT EFI_INPUT_KEY *Key)
BOOLEAN IsKeyRegistered(IN EFI_KEY_DATA *RegsiteredData, IN EFI_KEY_DATA *InputData)
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
EFI_STATUS EFIAPI KeyboardHandler(IN VOID *Data, IN UINTN DataLength, IN VOID *Context, IN UINT32 Result)
VOID SetKeyLED(IN USB_KB_DEV *UsbKeyboardDevice)
VOID DestroyQueue(IN OUT USB_SIMPLE_QUEUE *Queue)
EFI_STATUS InitUSBKeyboard(IN OUT USB_KB_DEV *UsbKeyboardDevice)
VOID ReleaseKeyboardLayoutResources(IN OUT USB_KB_DEV *UsbKeyboardDevice)
EFI_STATUS USBParseKey(IN OUT USB_KB_DEV *UsbKeyboardDevice, OUT UINT8 *KeyCode)
VOID InitQueue(IN OUT USB_SIMPLE_QUEUE *Queue, IN UINTN ItemSize)
BOOLEAN IsUSBKeyboard(IN EFI_USB_IO_PROTOCOL *UsbIo)
EFI_STATUS UsbKeyCodeToEfiInputKey(IN USB_KB_DEV *UsbKeyboardDevice, IN UINT8 KeyCode, OUT EFI_KEY_DATA *KeyData)
EFI_STATUS InitKeyboardLayout(OUT USB_KB_DEV *UsbKeyboardDevice)
BOOLEAN IsQueueEmpty(IN USB_SIMPLE_QUEUE *Queue)
#define ASSERT_EFI_ERROR(StatusParameter)
#define CR(Record, TYPE, Field, TestSignature)
#define REPORT_STATUS_CODE(Type, Value)
#define REPORT_STATUS_CODE_WITH_DEVICE_PATH(Type, Value, DevicePathParameter)
#define EFI_PROGRESS_CODE
#define EFI_P_KEYBOARD_PC_CLEAR_BUFFER
UINT8 EFI_KEY_TOGGLE_STATE
EFI_STATUS(EFIAPI * EFI_KEY_NOTIFY_FUNCTION)(IN EFI_KEY_DATA *KeyData)
EFI_STATUS EFIAPI AddUnicodeString2(IN CONST CHAR8 *Language, IN CONST CHAR8 *SupportedLanguages, IN OUT EFI_UNICODE_STRING_TABLE **UnicodeStringTable, IN CONST CHAR16 *UnicodeString, IN BOOLEAN Iso639Language)
EFI_STATUS EFIAPI EfiLibInstallDriverBindingComponentName2(IN CONST EFI_HANDLE ImageHandle, IN CONST EFI_SYSTEM_TABLE *SystemTable, IN EFI_DRIVER_BINDING_PROTOCOL *DriverBinding, IN EFI_HANDLE DriverBindingHandle, IN CONST EFI_COMPONENT_NAME_PROTOCOL *ComponentName OPTIONAL, IN CONST EFI_COMPONENT_NAME2_PROTOCOL *ComponentName2 OPTIONAL)
EFI_STATUS EFIAPI FreeUnicodeStringTable(IN EFI_UNICODE_STRING_TABLE *UnicodeStringTable)
EFI_STATUS Dequeue(IN SIMPLE_QUEUE *Queue, IN EFI_KEY_DATA *KeyData)
EFI_STATUS Enqueue(IN SIMPLE_QUEUE *Queue, IN EFI_KEY_DATA *KeyData)
CHAR8 * SupportedLanguages
CHAR8 * SupportedLanguages
EFI_KEY_TOGGLE_STATE KeyToggleState