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