xref: /netbsd-src/sys/stand/efiboot/console.c (revision 9765cbf3ad15b65980fbe88a1971a85ba76737c0)
1 /* $NetBSD: console.c,v 1.2 2018/09/15 16:44:15 jmcneill Exp $ */
2 
3 /*-
4  * Copyright (c) 2018 Jared McNeill <jmcneill@invisible.ca>
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  */
28 
29 #include "efiboot.h"
30 
31 static EFI_INPUT_KEY key_cur;
32 static int key_pending;
33 
34 int
getchar(void)35 getchar(void)
36 {
37 	EFI_STATUS status;
38 	EFI_INPUT_KEY key;
39 
40 	if (key_pending) {
41 		key = key_cur;
42 		key_pending = 0;
43 	} else {
44 		status = uefi_call_wrapper(ST->ConIn->ReadKeyStroke, 2, ST->ConIn, &key);
45 		while (status == EFI_NOT_READY) {
46 			if (ST->ConIn->WaitForKey != NULL)
47 				WaitForSingleEvent(ST->ConIn->WaitForKey, 0);
48 			status = uefi_call_wrapper(ST->ConIn->ReadKeyStroke, 2, ST->ConIn, &key);
49 		}
50 	}
51 
52 	return key.UnicodeChar;
53 }
54 
55 void
putchar(int c)56 putchar(int c)
57 {
58 	CHAR16 buf[2] = { c, '\0' };
59 	if (c == '\n')
60 		putchar('\r');
61 	uefi_call_wrapper(ST->ConOut->OutputString, 2, ST->ConOut, buf);
62 }
63 
64 int
ischar(void)65 ischar(void)
66 {
67 	EFI_INPUT_KEY key;
68 	EFI_STATUS status;
69 
70 	if (ST->ConIn->WaitForKey == NULL) {
71 		if (key_pending)
72 			return 1;
73 		status = uefi_call_wrapper(ST->ConIn->ReadKeyStroke, 2, ST->ConIn, &key);
74 		if (status == EFI_SUCCESS) {
75 			key_cur = key;
76 			key_pending = 1;
77 		}
78 		return key_pending;
79 	} else {
80 		status = uefi_call_wrapper(BS->CheckEvent, 1, ST->ConIn->WaitForKey);
81 		return status == EFI_SUCCESS;
82 	}
83 }
84