mirror of
				https://xff.cz/git/u-boot/
				synced 2025-10-31 02:15:45 +01:00 
			
		
		
		
	bootmenu: factor out the user input handling
This commit moves the user input handling from cmd/bootmenu.c to common/menu.c to reuse it from other modules. Signed-off-by: Masahisa Kojima <masahisa.kojima@linaro.org> Reviewed-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
This commit is contained in:
		
				
					committed by
					
						 Heinrich Schuchardt
						Heinrich Schuchardt
					
				
			
			
				
	
			
			
			
						parent
						
							6ae494831d
						
					
				
				
					commit
					3ae6cf5400
				
			
							
								
								
									
										141
									
								
								cmd/bootmenu.c
									
									
									
									
									
								
							
							
						
						
									
										141
									
								
								cmd/bootmenu.c
									
									
									
									
									
								
							| @@ -51,21 +51,6 @@ struct bootmenu_entry { | |||||||
| 	struct bootmenu_entry *next;	/* next menu entry (num+1) */ | 	struct bootmenu_entry *next;	/* next menu entry (num+1) */ | ||||||
| }; | }; | ||||||
|  |  | ||||||
| struct bootmenu_data { |  | ||||||
| 	int delay;			/* delay for autoboot */ |  | ||||||
| 	int active;			/* active menu entry */ |  | ||||||
| 	int count;			/* total count of menu entries */ |  | ||||||
| 	struct bootmenu_entry *first;	/* first menu entry */ |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| enum bootmenu_key { |  | ||||||
| 	KEY_NONE = 0, |  | ||||||
| 	KEY_UP, |  | ||||||
| 	KEY_DOWN, |  | ||||||
| 	KEY_SELECT, |  | ||||||
| 	KEY_QUIT, |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| static char *bootmenu_getoption(unsigned short int n) | static char *bootmenu_getoption(unsigned short int n) | ||||||
| { | { | ||||||
| 	char name[MAX_ENV_SIZE]; | 	char name[MAX_ENV_SIZE]; | ||||||
| @@ -97,132 +82,6 @@ static void bootmenu_print_entry(void *data) | |||||||
| 		puts(ANSI_COLOR_RESET); | 		puts(ANSI_COLOR_RESET); | ||||||
| } | } | ||||||
|  |  | ||||||
| static void bootmenu_autoboot_loop(struct bootmenu_data *menu, |  | ||||||
| 				enum bootmenu_key *key, int *esc) |  | ||||||
| { |  | ||||||
| 	int i, c; |  | ||||||
|  |  | ||||||
| 	while (menu->delay > 0) { |  | ||||||
| 		printf(ANSI_CURSOR_POSITION, menu->count + 5, 3); |  | ||||||
| 		printf("Hit any key to stop autoboot: %d ", menu->delay); |  | ||||||
| 		for (i = 0; i < 100; ++i) { |  | ||||||
| 			if (!tstc()) { |  | ||||||
| 				WATCHDOG_RESET(); |  | ||||||
| 				mdelay(10); |  | ||||||
| 				continue; |  | ||||||
| 			} |  | ||||||
|  |  | ||||||
| 			menu->delay = -1; |  | ||||||
| 			c = getchar(); |  | ||||||
|  |  | ||||||
| 			switch (c) { |  | ||||||
| 			case '\e': |  | ||||||
| 				*esc = 1; |  | ||||||
| 				*key = KEY_NONE; |  | ||||||
| 				break; |  | ||||||
| 			case '\r': |  | ||||||
| 				*key = KEY_SELECT; |  | ||||||
| 				break; |  | ||||||
| 			case 0x3: /* ^C */ |  | ||||||
| 				*key = KEY_QUIT; |  | ||||||
| 				break; |  | ||||||
| 			default: |  | ||||||
| 				*key = KEY_NONE; |  | ||||||
| 				break; |  | ||||||
| 			} |  | ||||||
|  |  | ||||||
| 			break; |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		if (menu->delay < 0) |  | ||||||
| 			break; |  | ||||||
|  |  | ||||||
| 		--menu->delay; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	printf(ANSI_CURSOR_POSITION, menu->count + 5, 1); |  | ||||||
| 	puts(ANSI_CLEAR_LINE); |  | ||||||
|  |  | ||||||
| 	if (menu->delay == 0) |  | ||||||
| 		*key = KEY_SELECT; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static void bootmenu_loop(struct bootmenu_data *menu, |  | ||||||
| 		enum bootmenu_key *key, int *esc) |  | ||||||
| { |  | ||||||
| 	int c; |  | ||||||
|  |  | ||||||
| 	if (*esc == 1) { |  | ||||||
| 		if (tstc()) { |  | ||||||
| 			c = getchar(); |  | ||||||
| 		} else { |  | ||||||
| 			WATCHDOG_RESET(); |  | ||||||
| 			mdelay(10); |  | ||||||
| 			if (tstc()) |  | ||||||
| 				c = getchar(); |  | ||||||
| 			else |  | ||||||
| 				c = '\e'; |  | ||||||
| 		} |  | ||||||
| 	} else { |  | ||||||
| 		while (!tstc()) { |  | ||||||
| 			WATCHDOG_RESET(); |  | ||||||
| 			mdelay(10); |  | ||||||
| 		} |  | ||||||
| 		c = getchar(); |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	switch (*esc) { |  | ||||||
| 	case 0: |  | ||||||
| 		/* First char of ANSI escape sequence '\e' */ |  | ||||||
| 		if (c == '\e') { |  | ||||||
| 			*esc = 1; |  | ||||||
| 			*key = KEY_NONE; |  | ||||||
| 		} |  | ||||||
| 		break; |  | ||||||
| 	case 1: |  | ||||||
| 		/* Second char of ANSI '[' */ |  | ||||||
| 		if (c == '[') { |  | ||||||
| 			*esc = 2; |  | ||||||
| 			*key = KEY_NONE; |  | ||||||
| 		} else { |  | ||||||
| 		/* Alone ESC key was pressed */ |  | ||||||
| 			*key = KEY_QUIT; |  | ||||||
| 			*esc = (c == '\e') ? 1 : 0; |  | ||||||
| 		} |  | ||||||
| 		break; |  | ||||||
| 	case 2: |  | ||||||
| 	case 3: |  | ||||||
| 		/* Third char of ANSI (number '1') - optional */ |  | ||||||
| 		if (*esc == 2 && c == '1') { |  | ||||||
| 			*esc = 3; |  | ||||||
| 			*key = KEY_NONE; |  | ||||||
| 			break; |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		*esc = 0; |  | ||||||
|  |  | ||||||
| 		/* ANSI 'A' - key up was pressed */ |  | ||||||
| 		if (c == 'A') |  | ||||||
| 			*key = KEY_UP; |  | ||||||
| 		/* ANSI 'B' - key down was pressed */ |  | ||||||
| 		else if (c == 'B') |  | ||||||
| 			*key = KEY_DOWN; |  | ||||||
| 		/* other key was pressed */ |  | ||||||
| 		else |  | ||||||
| 			*key = KEY_NONE; |  | ||||||
|  |  | ||||||
| 		break; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	/* enter key was pressed */ |  | ||||||
| 	if (c == '\r') |  | ||||||
| 		*key = KEY_SELECT; |  | ||||||
|  |  | ||||||
| 	/* ^C was pressed */ |  | ||||||
| 	if (c == 0x3) |  | ||||||
| 		*key = KEY_QUIT; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static char *bootmenu_choice_entry(void *data) | static char *bootmenu_choice_entry(void *data) | ||||||
| { | { | ||||||
| 	struct bootmenu_data *menu = data; | 	struct bootmenu_data *menu = data; | ||||||
|   | |||||||
							
								
								
									
										128
									
								
								common/menu.c
									
									
									
									
									
								
							
							
						
						
									
										128
									
								
								common/menu.c
									
									
									
									
									
								
							| @@ -4,11 +4,14 @@ | |||||||
|  * Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved. |  * Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved. | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
|  | #include <ansi.h> | ||||||
| #include <common.h> | #include <common.h> | ||||||
| #include <cli.h> | #include <cli.h> | ||||||
| #include <malloc.h> | #include <malloc.h> | ||||||
| #include <errno.h> | #include <errno.h> | ||||||
|  | #include <linux/delay.h> | ||||||
| #include <linux/list.h> | #include <linux/list.h> | ||||||
|  | #include <watchdog.h> | ||||||
|  |  | ||||||
| #include "menu.h" | #include "menu.h" | ||||||
|  |  | ||||||
| @@ -421,3 +424,128 @@ int menu_destroy(struct menu *m) | |||||||
|  |  | ||||||
| 	return 1; | 	return 1; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | void bootmenu_autoboot_loop(struct bootmenu_data *menu, | ||||||
|  | 			    enum bootmenu_key *key, int *esc) | ||||||
|  | { | ||||||
|  | 	int i, c; | ||||||
|  |  | ||||||
|  | 	while (menu->delay > 0) { | ||||||
|  | 		printf(ANSI_CURSOR_POSITION, menu->count + 5, 3); | ||||||
|  | 		printf("Hit any key to stop autoboot: %d ", menu->delay); | ||||||
|  | 		for (i = 0; i < 100; ++i) { | ||||||
|  | 			if (!tstc()) { | ||||||
|  | 				WATCHDOG_RESET(); | ||||||
|  | 				mdelay(10); | ||||||
|  | 				continue; | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			menu->delay = -1; | ||||||
|  | 			c = getchar(); | ||||||
|  |  | ||||||
|  | 			switch (c) { | ||||||
|  | 			case '\e': | ||||||
|  | 				*esc = 1; | ||||||
|  | 				*key = KEY_NONE; | ||||||
|  | 				break; | ||||||
|  | 			case '\r': | ||||||
|  | 				*key = KEY_SELECT; | ||||||
|  | 				break; | ||||||
|  | 			case 0x3: /* ^C */ | ||||||
|  | 				*key = KEY_QUIT; | ||||||
|  | 				break; | ||||||
|  | 			default: | ||||||
|  | 				*key = KEY_NONE; | ||||||
|  | 				break; | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		if (menu->delay < 0) | ||||||
|  | 			break; | ||||||
|  |  | ||||||
|  | 		--menu->delay; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	printf(ANSI_CURSOR_POSITION ANSI_CLEAR_LINE, menu->count + 5, 1); | ||||||
|  |  | ||||||
|  | 	if (menu->delay == 0) | ||||||
|  | 		*key = KEY_SELECT; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void bootmenu_loop(struct bootmenu_data *menu, | ||||||
|  | 		   enum bootmenu_key *key, int *esc) | ||||||
|  | { | ||||||
|  | 	int c; | ||||||
|  |  | ||||||
|  | 	if (*esc == 1) { | ||||||
|  | 		if (tstc()) { | ||||||
|  | 			c = getchar(); | ||||||
|  | 		} else { | ||||||
|  | 			WATCHDOG_RESET(); | ||||||
|  | 			mdelay(10); | ||||||
|  | 			if (tstc()) | ||||||
|  | 				c = getchar(); | ||||||
|  | 			else | ||||||
|  | 				c = '\e'; | ||||||
|  | 		} | ||||||
|  | 	} else { | ||||||
|  | 		while (!tstc()) { | ||||||
|  | 			WATCHDOG_RESET(); | ||||||
|  | 			mdelay(10); | ||||||
|  | 		} | ||||||
|  | 		c = getchar(); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	switch (*esc) { | ||||||
|  | 	case 0: | ||||||
|  | 		/* First char of ANSI escape sequence '\e' */ | ||||||
|  | 		if (c == '\e') { | ||||||
|  | 			*esc = 1; | ||||||
|  | 			*key = KEY_NONE; | ||||||
|  | 		} | ||||||
|  | 		break; | ||||||
|  | 	case 1: | ||||||
|  | 		/* Second char of ANSI '[' */ | ||||||
|  | 		if (c == '[') { | ||||||
|  | 			*esc = 2; | ||||||
|  | 			*key = KEY_NONE; | ||||||
|  | 		} else { | ||||||
|  | 		/* Alone ESC key was pressed */ | ||||||
|  | 			*key = KEY_QUIT; | ||||||
|  | 			*esc = (c == '\e') ? 1 : 0; | ||||||
|  | 		} | ||||||
|  | 		break; | ||||||
|  | 	case 2: | ||||||
|  | 	case 3: | ||||||
|  | 		/* Third char of ANSI (number '1') - optional */ | ||||||
|  | 		if (*esc == 2 && c == '1') { | ||||||
|  | 			*esc = 3; | ||||||
|  | 			*key = KEY_NONE; | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		*esc = 0; | ||||||
|  |  | ||||||
|  | 		/* ANSI 'A' - key up was pressed */ | ||||||
|  | 		if (c == 'A') | ||||||
|  | 			*key = KEY_UP; | ||||||
|  | 		/* ANSI 'B' - key down was pressed */ | ||||||
|  | 		else if (c == 'B') | ||||||
|  | 			*key = KEY_DOWN; | ||||||
|  | 		/* other key was pressed */ | ||||||
|  | 		else | ||||||
|  | 			*key = KEY_NONE; | ||||||
|  |  | ||||||
|  | 		break; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	/* enter key was pressed */ | ||||||
|  | 	if (c == '\r') | ||||||
|  | 		*key = KEY_SELECT; | ||||||
|  |  | ||||||
|  | 	/* ^C was pressed */ | ||||||
|  | 	if (c == 0x3) | ||||||
|  | 		*key = KEY_QUIT; | ||||||
|  | } | ||||||
|   | |||||||
| @@ -35,4 +35,24 @@ int menu_default_choice(struct menu *m, void **choice); | |||||||
|  */ |  */ | ||||||
| int menu_show(int bootdelay); | int menu_show(int bootdelay); | ||||||
|  |  | ||||||
|  | struct bootmenu_data { | ||||||
|  | 	int delay;			/* delay for autoboot */ | ||||||
|  | 	int active;			/* active menu entry */ | ||||||
|  | 	int count;			/* total count of menu entries */ | ||||||
|  | 	struct bootmenu_entry *first;	/* first menu entry */ | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | enum bootmenu_key { | ||||||
|  | 	KEY_NONE = 0, | ||||||
|  | 	KEY_UP, | ||||||
|  | 	KEY_DOWN, | ||||||
|  | 	KEY_SELECT, | ||||||
|  | 	KEY_QUIT, | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | void bootmenu_autoboot_loop(struct bootmenu_data *menu, | ||||||
|  | 			    enum bootmenu_key *key, int *esc); | ||||||
|  | void bootmenu_loop(struct bootmenu_data *menu, | ||||||
|  | 		   enum bootmenu_key *key, int *esc); | ||||||
|  |  | ||||||
| #endif /* __MENU_H__ */ | #endif /* __MENU_H__ */ | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user