^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) #include <pthread.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) #include <dlfcn.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) #include <unistd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <subcmd/pager.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include "../util/debug.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include "../util/hist.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include "ui.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) pthread_mutex_t ui__lock = PTHREAD_MUTEX_INITIALIZER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) void *perf_gtk_handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) int use_browser = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #define PERF_GTK_DSO "libperf-gtk.so"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #ifdef HAVE_GTK2_SUPPORT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) static int setup_gtk_browser(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) int (*perf_ui_init)(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) if (perf_gtk_handle)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) perf_gtk_handle = dlopen(PERF_GTK_DSO, RTLD_LAZY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) if (perf_gtk_handle == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) char buf[PATH_MAX];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) scnprintf(buf, sizeof(buf), "%s/%s", LIBDIR, PERF_GTK_DSO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) perf_gtk_handle = dlopen(buf, RTLD_LAZY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) if (perf_gtk_handle == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) perf_ui_init = dlsym(perf_gtk_handle, "perf_gtk__init");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) if (perf_ui_init == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) goto out_close;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) if (perf_ui_init() == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) out_close:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) dlclose(perf_gtk_handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) static void exit_gtk_browser(bool wait_for_ok)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) void (*perf_ui_exit)(bool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) if (perf_gtk_handle == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) perf_ui_exit = dlsym(perf_gtk_handle, "perf_gtk__exit");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) if (perf_ui_exit == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) goto out_close;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) perf_ui_exit(wait_for_ok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) out_close:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) dlclose(perf_gtk_handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) perf_gtk_handle = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) static inline int setup_gtk_browser(void) { return -1; }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) static inline void exit_gtk_browser(bool wait_for_ok __maybe_unused) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) int stdio__config_color(const struct option *opt __maybe_unused,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) const char *mode, int unset __maybe_unused)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) perf_use_color_default = perf_config_colorbool("color.ui", mode, -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) void setup_browser(bool fallback_to_pager)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) if (use_browser < 2 && (!isatty(1) || dump_trace))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) use_browser = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) /* default to TUI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) if (use_browser < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) use_browser = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) switch (use_browser) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) if (setup_gtk_browser() == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) printf("GTK browser requested but could not find %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) PERF_GTK_DSO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) sleep(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) use_browser = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) /* fall through */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) if (ui__init() == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) /* fall through */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) use_browser = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) if (fallback_to_pager)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) setup_pager();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) void exit_browser(bool wait_for_ok)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) switch (use_browser) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) exit_gtk_browser(wait_for_ok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) ui__exit(wait_for_ok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) }