X-Git-Url: https://git.dogcows.com/gitweb?p=chaz%2Fopenbox;a=blobdiff_plain;f=openbox%2Fdebug.c;h=ad083b1712088d9c5a9c10fc430edc9808301ee6;hp=af22c69f2cf8626fadf31293dcb1bff9a1a4e6af;hb=HEAD;hpb=3f2d342de80d819f5a40b6af1e4cc5478429e6be diff --git a/openbox/debug.c b/openbox/debug.c index af22c69f..ad083b17 100644 --- a/openbox/debug.c +++ b/openbox/debug.c @@ -17,47 +17,185 @@ */ #include "debug.h" +#include "prompt.h" +#include "openbox.h" +#include "gettext.h" +#include "obt/paths.h" #include #include #include #include +#include -static gboolean show; +#ifdef HAVE_UNISTD_H +# include +#endif -void ob_debug_show_output(gboolean enable) +static gboolean enabled_types[OB_DEBUG_TYPE_NUM] = {FALSE}; +static FILE *log_file = NULL; +static guint rr_handler_id = 0; +static guint obt_handler_id = 0; +static guint ob_handler_id = 0; +static guint ob_handler_prompt_id = 0; +static GList *prompt_queue = NULL; +static gboolean allow_prompts = TRUE; + +static void log_handler(const gchar *log_domain, GLogLevelFlags log_level, + const gchar *message, gpointer user_data); +static void prompt_handler(const gchar *log_domain, GLogLevelFlags log_level, + const gchar *message, gpointer user_data); + +void ob_debug_startup(void) { - show = enable; + ObtPaths *p = obt_paths_new(); + gchar *dir = g_build_filename(obt_paths_cache_home(p), + "openbox", NULL); + + /* log messages to a log file! fancy, no? */ + if (!obt_paths_mkdir_path(dir, 0777)) + g_message(_("Unable to make directory '%s': %s"), + dir, g_strerror(errno)); + else { + gchar *name = g_build_filename(obt_paths_cache_home(p), + "openbox", "openbox.log", NULL); + /* unlink it before opening to remove competition */ + unlink(name); + log_file = fopen(name, "w"); + g_free(name); + } + + rr_handler_id = + g_log_set_handler("ObRender", G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | + G_LOG_FLAG_RECURSION, log_handler, NULL); + obt_handler_id = + g_log_set_handler("Obt", G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | + G_LOG_FLAG_RECURSION, log_handler, NULL); + ob_handler_id = + g_log_set_handler("Openbox", G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | + G_LOG_FLAG_RECURSION, log_handler, NULL); + ob_handler_prompt_id = + g_log_set_handler("Openbox", G_LOG_LEVEL_MASK & ~G_LOG_LEVEL_DEBUG, + prompt_handler, NULL); + + obt_paths_unref(p); + g_free(dir); } -void ob_debug(const gchar *a, ...) +void ob_debug_shutdown(void) { - va_list vl; + g_log_remove_handler("ObRender", rr_handler_id); + g_log_remove_handler("Obt", obt_handler_id); + g_log_remove_handler("Openbox", ob_handler_id); + g_log_remove_handler("Openbox", ob_handler_prompt_id); - if (show) { - va_start(vl, a); - vfprintf(stderr, a, vl); - va_end(vl); + if (log_file) { + fclose(log_file); + log_file = NULL; } } -static gboolean enabled_types[OB_DEBUG_TYPE_NUM] = {FALSE}; - void ob_debug_enable(ObDebugType type, gboolean enable) { g_assert(type < OB_DEBUG_TYPE_NUM); enabled_types[type] = enable; } +static inline void log_print(FILE *out, const gchar* log_domain, + const gchar *level, const gchar *message) +{ + fprintf(out, "%s", log_domain); + fprintf(out, "-"); + fprintf(out, "%s", level); + fprintf(out, ": "); + fprintf(out, "%s", message); + fprintf(out, "\n"); + fflush(out); +} + +static void log_handler(const gchar *log_domain, GLogLevelFlags log_level, + const gchar *message, gpointer data) +{ + FILE *out; + const gchar *level; + + switch (log_level & G_LOG_LEVEL_MASK) { + case G_LOG_LEVEL_DEBUG: level = "Debug"; out = stdout; break; + case G_LOG_LEVEL_INFO: level = "Info"; out = stdout; break; + case G_LOG_LEVEL_MESSAGE: level = "Message"; out = stdout; break; + case G_LOG_LEVEL_WARNING: level = "Warning"; out = stderr; break; + case G_LOG_LEVEL_CRITICAL: level = "Critical"; out = stderr; break; + case G_LOG_LEVEL_ERROR: level = "Error"; out = stderr; break; + default: g_assert_not_reached(); /* invalid level.. */ + } + + log_print(out, log_domain, level, message); + if (log_file) log_print(log_file, log_domain, level, message); +} + +static void prompt_handler(const gchar *log_domain, GLogLevelFlags log_level, + const gchar *message, gpointer data) +{ + if (ob_state() == OB_STATE_RUNNING && allow_prompts) + prompt_queue = g_list_prepend(prompt_queue, g_strdup(message)); + else + log_handler(log_domain, log_level, message, data); +} + +static inline void log_argv(ObDebugType type, + const gchar *format, va_list args) +{ + const gchar *prefix; + gchar *message; + + g_assert(type < OB_DEBUG_TYPE_NUM); + if (!enabled_types[type]) return; + + switch (type) { + case OB_DEBUG_FOCUS: prefix = "(FOCUS) "; break; + case OB_DEBUG_APP_BUGS: prefix = "(APPLICATION BUG) "; break; + case OB_DEBUG_SM: prefix = "(SESSION) "; break; + default: prefix = NULL; break; + } + + message = g_strdup_vprintf(format, args); + if (prefix) { + gchar *a = message; + message = g_strconcat(prefix, message, NULL); + g_free(a); + } + + g_debug("%s", message); + g_free(message); +} + +void ob_debug(const gchar *a, ...) +{ + va_list vl; + + va_start(vl, a); + log_argv(OB_DEBUG_NORMAL, a, vl); + va_end(vl); +} + void ob_debug_type(ObDebugType type, const gchar *a, ...) { va_list vl; - g_assert(type < OB_DEBUG_TYPE_NUM); + va_start(vl, a); + log_argv(type, a, vl); + va_end(vl); +} - if (show && enabled_types[type]) { - va_start(vl, a); - vfprintf(stderr, a, vl); - va_end(vl); +void ob_debug_show_prompts(void) +{ + if (prompt_queue) { + allow_prompts = FALSE; /* avoid recursive prompts */ + while (prompt_queue) { + prompt_show_message(prompt_queue->data, "Openbox", _("Close")); + g_free(prompt_queue->data); + prompt_queue = g_list_delete_link(prompt_queue, prompt_queue); + } + allow_prompts = TRUE; } }