Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ba47a142 authored by Namhyung Kim's avatar Namhyung Kim Committed by Arnaldo Carvalho de Melo
Browse files

perf ui: Introduce struct perf_error_ops



The struct perf_error_ops is for flexible error logging.

We can register appropriate functions based on front-end.

Signed-off-by: default avatarNamhyung Kim <namhyung.kim@lge.com>
Acked-by: default avatarPekka Enberg <penberg@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Pekka Enberg <penberg@kernel.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/r/1338265382-6872-4-git-send-email-namhyung@gmail.com


Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent 409a8be6
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -503,6 +503,7 @@ else
		LIB_OBJS += $(OUTPUT)ui/progress.o
		LIB_OBJS += $(OUTPUT)ui/util.o
		LIB_OBJS += $(OUTPUT)ui/tui/setup.o
		LIB_OBJS += $(OUTPUT)ui/tui/util.o
		LIB_H += ui/browser.h
		LIB_H += ui/browsers/map.h
		LIB_H += ui/helpline.h
@@ -526,9 +527,11 @@ else
		EXTLIBS += $(shell pkg-config --libs gtk+-2.0)
		LIB_OBJS += $(OUTPUT)ui/gtk/browser.o
		LIB_OBJS += $(OUTPUT)ui/gtk/setup.o
		LIB_OBJS += $(OUTPUT)ui/gtk/util.o
		# Make sure that it'd be included only once.
		ifneq ($(findstring -DNO_NEWT_SUPPORT,$(BASIC_CFLAGS)),)
			LIB_OBJS += $(OUTPUT)ui/setup.o
			LIB_OBJS += $(OUTPUT)ui/util.o
		endif
	endif
endif
+20 −0
Original line number Diff line number Diff line
#include "../util.h"
#include "../../util/debug.h"
#include "gtk.h"


/*
 * FIXME: Functions below should be implemented properly.
 *        For now, just add stubs for NO_NEWT=1 build.
 */
#ifdef NO_NEWT_SUPPORT
int ui_helpline__show_help(const char *format __used, va_list ap __used)
{
	return 0;
}

void ui_progress__update(u64 curr __used, u64 total __used,
			 const char *title __used)
{
}
#endif
+6 −0
Original line number Diff line number Diff line
@@ -15,6 +15,8 @@ pthread_mutex_t ui__lock = PTHREAD_MUTEX_INITIALIZER;

static volatile int ui__need_resize;

extern struct perf_error_ops perf_tui_eops;

void ui__refresh_dimensions(bool force)
{
	if (force || ui__need_resize) {
@@ -122,6 +124,8 @@ int ui__init(void)
	signal(SIGINT, ui__signal);
	signal(SIGQUIT, ui__signal);
	signal(SIGTERM, ui__signal);

	perf_error__register(&perf_tui_eops);
out:
	return err;
}
@@ -137,4 +141,6 @@ void ui__exit(bool wait_for_ok)
	SLsmg_refresh();
	SLsmg_reset_smg();
	SLang_reset_tty();

	perf_error__unregister(&perf_tui_eops);
}
+243 −0
Original line number Diff line number Diff line
#include "../../util/util.h"
#include <signal.h>
#include <stdbool.h>
#include <string.h>
#include <sys/ttydefaults.h>

#include "../../util/cache.h"
#include "../../util/debug.h"
#include "../browser.h"
#include "../keysyms.h"
#include "../helpline.h"
#include "../ui.h"
#include "../util.h"
#include "../libslang.h"

static void ui_browser__argv_write(struct ui_browser *browser,
				   void *entry, int row)
{
	char **arg = entry;
	bool current_entry = ui_browser__is_current_entry(browser, row);

	ui_browser__set_color(browser, current_entry ? HE_COLORSET_SELECTED :
						       HE_COLORSET_NORMAL);
	slsmg_write_nstring(*arg, browser->width);
}

static int popup_menu__run(struct ui_browser *menu)
{
	int key;

	if (ui_browser__show(menu, " ", "ESC: exit, ENTER|->: Select option") < 0)
		return -1;

	while (1) {
		key = ui_browser__run(menu, 0);

		switch (key) {
		case K_RIGHT:
		case K_ENTER:
			key = menu->index;
			break;
		case K_LEFT:
		case K_ESC:
		case 'q':
		case CTRL('c'):
			key = -1;
			break;
		default:
			continue;
		}

		break;
	}

	ui_browser__hide(menu);
	return key;
}

int ui__popup_menu(int argc, char * const argv[])
{
	struct ui_browser menu = {
		.entries    = (void *)argv,
		.refresh    = ui_browser__argv_refresh,
		.seek	    = ui_browser__argv_seek,
		.write	    = ui_browser__argv_write,
		.nr_entries = argc,
	};

	return popup_menu__run(&menu);
}

int ui_browser__input_window(const char *title, const char *text, char *input,
			     const char *exit_msg, int delay_secs)
{
	int x, y, len, key;
	int max_len = 60, nr_lines = 0;
	static char buf[50];
	const char *t;

	t = text;
	while (1) {
		const char *sep = strchr(t, '\n');

		if (sep == NULL)
			sep = strchr(t, '\0');
		len = sep - t;
		if (max_len < len)
			max_len = len;
		++nr_lines;
		if (*sep == '\0')
			break;
		t = sep + 1;
	}

	max_len += 2;
	nr_lines += 8;
	y = SLtt_Screen_Rows / 2 - nr_lines / 2;
	x = SLtt_Screen_Cols / 2 - max_len / 2;

	SLsmg_set_color(0);
	SLsmg_draw_box(y, x++, nr_lines, max_len);
	if (title) {
		SLsmg_gotorc(y, x + 1);
		SLsmg_write_string((char *)title);
	}
	SLsmg_gotorc(++y, x);
	nr_lines -= 7;
	max_len -= 2;
	SLsmg_write_wrapped_string((unsigned char *)text, y, x,
				   nr_lines, max_len, 1);
	y += nr_lines;
	len = 5;
	while (len--) {
		SLsmg_gotorc(y + len - 1, x);
		SLsmg_write_nstring((char *)" ", max_len);
	}
	SLsmg_draw_box(y++, x + 1, 3, max_len - 2);

	SLsmg_gotorc(y + 3, x);
	SLsmg_write_nstring((char *)exit_msg, max_len);
	SLsmg_refresh();

	x += 2;
	len = 0;
	key = ui__getch(delay_secs);
	while (key != K_TIMER && key != K_ENTER && key != K_ESC) {
		if (key == K_BKSPC) {
			if (len == 0)
				goto next_key;
			SLsmg_gotorc(y, x + --len);
			SLsmg_write_char(' ');
		} else {
			buf[len] = key;
			SLsmg_gotorc(y, x + len++);
			SLsmg_write_char(key);
		}
		SLsmg_refresh();

		/* XXX more graceful overflow handling needed */
		if (len == sizeof(buf) - 1) {
			ui_helpline__push("maximum size of symbol name reached!");
			key = K_ENTER;
			break;
		}
next_key:
		key = ui__getch(delay_secs);
	}

	buf[len] = '\0';
	strncpy(input, buf, len+1);
	return key;
}

int ui__question_window(const char *title, const char *text,
			const char *exit_msg, int delay_secs)
{
	int x, y;
	int max_len = 0, nr_lines = 0;
	const char *t;

	t = text;
	while (1) {
		const char *sep = strchr(t, '\n');
		int len;

		if (sep == NULL)
			sep = strchr(t, '\0');
		len = sep - t;
		if (max_len < len)
			max_len = len;
		++nr_lines;
		if (*sep == '\0')
			break;
		t = sep + 1;
	}

	max_len += 2;
	nr_lines += 4;
	y = SLtt_Screen_Rows / 2 - nr_lines / 2,
	x = SLtt_Screen_Cols / 2 - max_len / 2;

	SLsmg_set_color(0);
	SLsmg_draw_box(y, x++, nr_lines, max_len);
	if (title) {
		SLsmg_gotorc(y, x + 1);
		SLsmg_write_string((char *)title);
	}
	SLsmg_gotorc(++y, x);
	nr_lines -= 2;
	max_len -= 2;
	SLsmg_write_wrapped_string((unsigned char *)text, y, x,
				   nr_lines, max_len, 1);
	SLsmg_gotorc(y + nr_lines - 2, x);
	SLsmg_write_nstring((char *)" ", max_len);
	SLsmg_gotorc(y + nr_lines - 1, x);
	SLsmg_write_nstring((char *)exit_msg, max_len);
	SLsmg_refresh();
	return ui__getch(delay_secs);
}

int ui__help_window(const char *text)
{
	return ui__question_window("Help", text, "Press any key...", 0);
}

int ui__dialog_yesno(const char *msg)
{
	return ui__question_window(NULL, msg, "Enter: Yes, ESC: No", 0);
}

static int __ui__warning(const char *title, const char *format, va_list args)
{
	char *s;

	if (vasprintf(&s, format, args) > 0) {
		int key;

		pthread_mutex_lock(&ui__lock);
		key = ui__question_window(title, s, "Press any key...", 0);
		pthread_mutex_unlock(&ui__lock);
		free(s);
		return key;
	}

	fprintf(stderr, "%s\n", title);
	vfprintf(stderr, format, args);
	return K_ESC;
}

static int perf_tui__error(const char *format, va_list args)
{
	return __ui__warning("Error:", format, args);
}

static int perf_tui__warning(const char *format, va_list args)
{
	return __ui__warning("Warning:", format, args);
}

struct perf_error_ops perf_tui_eops = {
	.error		= perf_tui__error,
	.warning	= perf_tui__warning,
};
+56 −221
Original line number Diff line number Diff line
#include "../util.h"
#include <signal.h>
#include <stdbool.h>
#include <string.h>
#include <sys/ttydefaults.h>

#include "../cache.h"
#include "../debug.h"
#include "browser.h"
#include "keysyms.h"
#include "helpline.h"
#include "ui.h"
#include "util.h"
#include "libslang.h"

static void ui_browser__argv_write(struct ui_browser *browser,
				   void *entry, int row)
{
	char **arg = entry;
	bool current_entry = ui_browser__is_current_entry(browser, row);
#include "../debug.h"

	ui_browser__set_color(browser, current_entry ? HE_COLORSET_SELECTED :
						       HE_COLORSET_NORMAL);
	slsmg_write_nstring(*arg, browser->width);
}

static int popup_menu__run(struct ui_browser *menu)
/*
 * Default error logging functions
 */
static int perf_stdio__error(const char *format, va_list args)
{
	int key;

	if (ui_browser__show(menu, " ", "ESC: exit, ENTER|->: Select option") < 0)
		return -1;

	while (1) {
		key = ui_browser__run(menu, 0);

		switch (key) {
		case K_RIGHT:
		case K_ENTER:
			key = menu->index;
			break;
		case K_LEFT:
		case K_ESC:
		case 'q':
		case CTRL('c'):
			key = -1;
			break;
		default:
			continue;
		}

		break;
	}

	ui_browser__hide(menu);
	return key;
	fprintf(stderr, "Error:\n");
	vfprintf(stderr, format, args);
	return 0;
}

int ui__popup_menu(int argc, char * const argv[])
static int perf_stdio__warning(const char *format, va_list args)
{
	struct ui_browser menu = {
		.entries    = (void *)argv,
		.refresh    = ui_browser__argv_refresh,
		.seek	    = ui_browser__argv_seek,
		.write	    = ui_browser__argv_write,
		.nr_entries = argc,
	};

	return popup_menu__run(&menu);
	fprintf(stderr, "Warning:\n");
	vfprintf(stderr, format, args);
	return 0;
}

int ui_browser__input_window(const char *title, const char *text, char *input,
			     const char *exit_msg, int delay_secs)
static struct perf_error_ops default_eops =
{
	int x, y, len, key;
	int max_len = 60, nr_lines = 0;
	static char buf[50];
	const char *t;

	t = text;
	while (1) {
		const char *sep = strchr(t, '\n');

		if (sep == NULL)
			sep = strchr(t, '\0');
		len = sep - t;
		if (max_len < len)
			max_len = len;
		++nr_lines;
		if (*sep == '\0')
			break;
		t = sep + 1;
	}

	max_len += 2;
	nr_lines += 8;
	y = SLtt_Screen_Rows / 2 - nr_lines / 2;
	x = SLtt_Screen_Cols / 2 - max_len / 2;

	SLsmg_set_color(0);
	SLsmg_draw_box(y, x++, nr_lines, max_len);
	if (title) {
		SLsmg_gotorc(y, x + 1);
		SLsmg_write_string((char *)title);
	}
	SLsmg_gotorc(++y, x);
	nr_lines -= 7;
	max_len -= 2;
	SLsmg_write_wrapped_string((unsigned char *)text, y, x,
				   nr_lines, max_len, 1);
	y += nr_lines;
	len = 5;
	while (len--) {
		SLsmg_gotorc(y + len - 1, x);
		SLsmg_write_nstring((char *)" ", max_len);
	}
	SLsmg_draw_box(y++, x + 1, 3, max_len - 2);

	SLsmg_gotorc(y + 3, x);
	SLsmg_write_nstring((char *)exit_msg, max_len);
	SLsmg_refresh();

	x += 2;
	len = 0;
	key = ui__getch(delay_secs);
	while (key != K_TIMER && key != K_ENTER && key != K_ESC) {
		if (key == K_BKSPC) {
			if (len == 0)
				goto next_key;
			SLsmg_gotorc(y, x + --len);
			SLsmg_write_char(' ');
		} else {
			buf[len] = key;
			SLsmg_gotorc(y, x + len++);
			SLsmg_write_char(key);
		}
		SLsmg_refresh();
	.error		= perf_stdio__error,
	.warning	= perf_stdio__warning,
};

		/* XXX more graceful overflow handling needed */
		if (len == sizeof(buf) - 1) {
			ui_helpline__push("maximum size of symbol name reached!");
			key = K_ENTER;
			break;
		}
next_key:
		key = ui__getch(delay_secs);
	}
static struct perf_error_ops *perf_eops = &default_eops;

	buf[len] = '\0';
	strncpy(input, buf, len+1);
	return key;
}

int ui__question_window(const char *title, const char *text,
			const char *exit_msg, int delay_secs)
int ui__error(const char *format, ...)
{
	int x, y;
	int max_len = 0, nr_lines = 0;
	const char *t;

	t = text;
	while (1) {
		const char *sep = strchr(t, '\n');
		int len;

		if (sep == NULL)
			sep = strchr(t, '\0');
		len = sep - t;
		if (max_len < len)
			max_len = len;
		++nr_lines;
		if (*sep == '\0')
			break;
		t = sep + 1;
	}

	max_len += 2;
	nr_lines += 4;
	y = SLtt_Screen_Rows / 2 - nr_lines / 2,
	x = SLtt_Screen_Cols / 2 - max_len / 2;

	SLsmg_set_color(0);
	SLsmg_draw_box(y, x++, nr_lines, max_len);
	if (title) {
		SLsmg_gotorc(y, x + 1);
		SLsmg_write_string((char *)title);
	}
	SLsmg_gotorc(++y, x);
	nr_lines -= 2;
	max_len -= 2;
	SLsmg_write_wrapped_string((unsigned char *)text, y, x,
				   nr_lines, max_len, 1);
	SLsmg_gotorc(y + nr_lines - 2, x);
	SLsmg_write_nstring((char *)" ", max_len);
	SLsmg_gotorc(y + nr_lines - 1, x);
	SLsmg_write_nstring((char *)exit_msg, max_len);
	SLsmg_refresh();
	return ui__getch(delay_secs);
}
	int ret;
	va_list args;

int ui__help_window(const char *text)
{
	return ui__question_window("Help", text, "Press any key...", 0);
}
	va_start(args, format);
	ret = perf_eops->error(format, args);
	va_end(args);

int ui__dialog_yesno(const char *msg)
{
	return ui__question_window(NULL, msg, "Enter: Yes, ESC: No", 0);
	return ret;
}

int __ui__warning(const char *title, const char *format, va_list args)
int ui__warning(const char *format, ...)
{
	char *s;
	int ret;
	va_list args;

	if (use_browser > 0 && vasprintf(&s, format, args) > 0) {
		int key;
	va_start(args, format);
	ret = perf_eops->warning(format, args);
	va_end(args);

		pthread_mutex_lock(&ui__lock);
		key = ui__question_window(title, s, "Press any key...", 0);
		pthread_mutex_unlock(&ui__lock);
		free(s);
		return key;
	return ret;
}

	fprintf(stderr, "%s:\n", title);
	vfprintf(stderr, format, args);
	return K_ESC;
}

int ui__warning(const char *format, ...)
/**
 * perf_error__register - Register error logging functions
 * @eops: The pointer to error logging function struct
 *
 * Register UI-specific error logging functions. Before calling this,
 * other logging functions should be unregistered, if any.
 */
int perf_error__register(struct perf_error_ops *eops)
{
	int key;
	va_list args;
	if (perf_eops != &default_eops)
		return -1;

	va_start(args, format);
	key = __ui__warning("Warning", format, args);
	va_end(args);
	return key;
	perf_eops = eops;
	return 0;
}

int ui__error(const char *format, ...)
/**
 * perf_error__unregister - Unregister error logging functions
 * @eops: The pointer to error logging function struct
 *
 * Unregister already registered error logging functions.
 */
int perf_error__unregister(struct perf_error_ops *eops)
{
	int key;
	va_list args;
	if (perf_eops != eops)
		return -1;

	va_start(args, format);
	key = __ui__warning("Error", format, args);
	va_end(args);
	return key;
	perf_eops = &default_eops;
	return 0;
}
Loading