162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci#include <dlfcn.h>
362306a36Sopenharmony_ci#include <signal.h>
462306a36Sopenharmony_ci#include <unistd.h>
562306a36Sopenharmony_ci
662306a36Sopenharmony_ci#include <subcmd/pager.h>
762306a36Sopenharmony_ci#include "../util/debug.h"
862306a36Sopenharmony_ci#include "../util/hist.h"
962306a36Sopenharmony_ci#include "ui.h"
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_cistruct mutex ui__lock;
1262306a36Sopenharmony_civoid *perf_gtk_handle;
1362306a36Sopenharmony_ciint use_browser = -1;
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_ci#define PERF_GTK_DSO "libperf-gtk.so"
1662306a36Sopenharmony_ci
1762306a36Sopenharmony_ci#ifdef HAVE_GTK2_SUPPORT
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_cistatic int setup_gtk_browser(void)
2062306a36Sopenharmony_ci{
2162306a36Sopenharmony_ci	int (*perf_ui_init)(void);
2262306a36Sopenharmony_ci
2362306a36Sopenharmony_ci	if (perf_gtk_handle)
2462306a36Sopenharmony_ci		return 0;
2562306a36Sopenharmony_ci
2662306a36Sopenharmony_ci	perf_gtk_handle = dlopen(PERF_GTK_DSO, RTLD_LAZY);
2762306a36Sopenharmony_ci	if (perf_gtk_handle == NULL) {
2862306a36Sopenharmony_ci		char buf[PATH_MAX];
2962306a36Sopenharmony_ci		scnprintf(buf, sizeof(buf), "%s/%s", LIBDIR, PERF_GTK_DSO);
3062306a36Sopenharmony_ci		perf_gtk_handle = dlopen(buf, RTLD_LAZY);
3162306a36Sopenharmony_ci	}
3262306a36Sopenharmony_ci	if (perf_gtk_handle == NULL)
3362306a36Sopenharmony_ci		return -1;
3462306a36Sopenharmony_ci
3562306a36Sopenharmony_ci	perf_ui_init = dlsym(perf_gtk_handle, "perf_gtk__init");
3662306a36Sopenharmony_ci	if (perf_ui_init == NULL)
3762306a36Sopenharmony_ci		goto out_close;
3862306a36Sopenharmony_ci
3962306a36Sopenharmony_ci	if (perf_ui_init() == 0)
4062306a36Sopenharmony_ci		return 0;
4162306a36Sopenharmony_ci
4262306a36Sopenharmony_ciout_close:
4362306a36Sopenharmony_ci	dlclose(perf_gtk_handle);
4462306a36Sopenharmony_ci	return -1;
4562306a36Sopenharmony_ci}
4662306a36Sopenharmony_ci
4762306a36Sopenharmony_cistatic void exit_gtk_browser(bool wait_for_ok)
4862306a36Sopenharmony_ci{
4962306a36Sopenharmony_ci	void (*perf_ui_exit)(bool);
5062306a36Sopenharmony_ci
5162306a36Sopenharmony_ci	if (perf_gtk_handle == NULL)
5262306a36Sopenharmony_ci		return;
5362306a36Sopenharmony_ci
5462306a36Sopenharmony_ci	perf_ui_exit = dlsym(perf_gtk_handle, "perf_gtk__exit");
5562306a36Sopenharmony_ci	if (perf_ui_exit == NULL)
5662306a36Sopenharmony_ci		goto out_close;
5762306a36Sopenharmony_ci
5862306a36Sopenharmony_ci	perf_ui_exit(wait_for_ok);
5962306a36Sopenharmony_ci
6062306a36Sopenharmony_ciout_close:
6162306a36Sopenharmony_ci	dlclose(perf_gtk_handle);
6262306a36Sopenharmony_ci
6362306a36Sopenharmony_ci	perf_gtk_handle = NULL;
6462306a36Sopenharmony_ci}
6562306a36Sopenharmony_ci#else
6662306a36Sopenharmony_cistatic inline int setup_gtk_browser(void) { return -1; }
6762306a36Sopenharmony_cistatic inline void exit_gtk_browser(bool wait_for_ok __maybe_unused) {}
6862306a36Sopenharmony_ci#endif
6962306a36Sopenharmony_ci
7062306a36Sopenharmony_ciint stdio__config_color(const struct option *opt __maybe_unused,
7162306a36Sopenharmony_ci			const char *mode, int unset __maybe_unused)
7262306a36Sopenharmony_ci{
7362306a36Sopenharmony_ci	perf_use_color_default = perf_config_colorbool("color.ui", mode, -1);
7462306a36Sopenharmony_ci	return 0;
7562306a36Sopenharmony_ci}
7662306a36Sopenharmony_ci
7762306a36Sopenharmony_civoid setup_browser(bool fallback_to_pager)
7862306a36Sopenharmony_ci{
7962306a36Sopenharmony_ci	mutex_init(&ui__lock);
8062306a36Sopenharmony_ci	if (use_browser < 2 && (!isatty(1) || dump_trace))
8162306a36Sopenharmony_ci		use_browser = 0;
8262306a36Sopenharmony_ci
8362306a36Sopenharmony_ci	/* default to TUI */
8462306a36Sopenharmony_ci	if (use_browser < 0)
8562306a36Sopenharmony_ci		use_browser = 1;
8662306a36Sopenharmony_ci
8762306a36Sopenharmony_ci	switch (use_browser) {
8862306a36Sopenharmony_ci	case 2:
8962306a36Sopenharmony_ci		if (setup_gtk_browser() == 0)
9062306a36Sopenharmony_ci			break;
9162306a36Sopenharmony_ci		printf("GTK browser requested but could not find %s\n",
9262306a36Sopenharmony_ci		       PERF_GTK_DSO);
9362306a36Sopenharmony_ci		sleep(1);
9462306a36Sopenharmony_ci		use_browser = 1;
9562306a36Sopenharmony_ci		/* fall through */
9662306a36Sopenharmony_ci	case 1:
9762306a36Sopenharmony_ci		if (ui__init() == 0)
9862306a36Sopenharmony_ci			break;
9962306a36Sopenharmony_ci		/* fall through */
10062306a36Sopenharmony_ci	default:
10162306a36Sopenharmony_ci		use_browser = 0;
10262306a36Sopenharmony_ci		if (fallback_to_pager)
10362306a36Sopenharmony_ci			setup_pager();
10462306a36Sopenharmony_ci		break;
10562306a36Sopenharmony_ci	}
10662306a36Sopenharmony_ci}
10762306a36Sopenharmony_ci
10862306a36Sopenharmony_civoid exit_browser(bool wait_for_ok)
10962306a36Sopenharmony_ci{
11062306a36Sopenharmony_ci	switch (use_browser) {
11162306a36Sopenharmony_ci	case 2:
11262306a36Sopenharmony_ci		exit_gtk_browser(wait_for_ok);
11362306a36Sopenharmony_ci		break;
11462306a36Sopenharmony_ci
11562306a36Sopenharmony_ci	case 1:
11662306a36Sopenharmony_ci		ui__exit(wait_for_ok);
11762306a36Sopenharmony_ci		break;
11862306a36Sopenharmony_ci
11962306a36Sopenharmony_ci	default:
12062306a36Sopenharmony_ci		break;
12162306a36Sopenharmony_ci	}
12262306a36Sopenharmony_ci	mutex_destroy(&ui__lock);
12362306a36Sopenharmony_ci}
12462306a36Sopenharmony_ci
12562306a36Sopenharmony_civoid pthread__block_sigwinch(void)
12662306a36Sopenharmony_ci{
12762306a36Sopenharmony_ci	sigset_t set;
12862306a36Sopenharmony_ci
12962306a36Sopenharmony_ci	sigemptyset(&set);
13062306a36Sopenharmony_ci	sigaddset(&set, SIGWINCH);
13162306a36Sopenharmony_ci	pthread_sigmask(SIG_BLOCK, &set, NULL);
13262306a36Sopenharmony_ci}
13362306a36Sopenharmony_ci
13462306a36Sopenharmony_civoid pthread__unblock_sigwinch(void)
13562306a36Sopenharmony_ci{
13662306a36Sopenharmony_ci	sigset_t set;
13762306a36Sopenharmony_ci
13862306a36Sopenharmony_ci	sigemptyset(&set);
13962306a36Sopenharmony_ci	sigaddset(&set, SIGWINCH);
14062306a36Sopenharmony_ci	pthread_sigmask(SIG_UNBLOCK, &set, NULL);
14162306a36Sopenharmony_ci}
142