2001-05-30 11:36:31 -04:00
|
|
|
/* Metacity utilities */
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Copyright (C) 2001 Havoc Pennington
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License as
|
|
|
|
* published by the Free Software Foundation; either version 2 of the
|
|
|
|
* License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful, but
|
|
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
|
|
|
* 02111-1307, USA.
|
|
|
|
*/
|
|
|
|
|
2002-03-04 21:43:22 -05:00
|
|
|
#include <config.h>
|
2001-05-30 11:36:31 -04:00
|
|
|
#include "util.h"
|
|
|
|
#include "main.h"
|
|
|
|
|
|
|
|
#include <stdio.h>
|
2001-05-30 23:30:58 -04:00
|
|
|
#include <stdlib.h>
|
2001-09-10 23:54:54 -04:00
|
|
|
#include <unistd.h>
|
2002-03-04 21:43:22 -05:00
|
|
|
#include <errno.h>
|
|
|
|
#include <string.h>
|
2001-05-30 11:36:31 -04:00
|
|
|
|
2002-07-23 15:12:02 -04:00
|
|
|
#ifdef HAVE_BACKTRACE
|
|
|
|
#include <execinfo.h>
|
|
|
|
static void
|
|
|
|
print_backtrace (void)
|
|
|
|
{
|
|
|
|
void *bt[500];
|
|
|
|
int bt_size;
|
|
|
|
int i;
|
|
|
|
char **syms;
|
|
|
|
|
|
|
|
bt_size = backtrace (bt, 500);
|
|
|
|
|
|
|
|
syms = backtrace_symbols (bt, bt_size);
|
|
|
|
|
|
|
|
i = 0;
|
|
|
|
while (i < bt_size)
|
|
|
|
{
|
|
|
|
meta_verbose (" %s\n", syms[i]);
|
|
|
|
++i;
|
|
|
|
}
|
|
|
|
|
|
|
|
free (syms);
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
static void
|
|
|
|
print_backtrace (void)
|
|
|
|
{
|
|
|
|
meta_verbose ("Not compiled with backtrace support\n");
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2001-05-31 02:42:58 -04:00
|
|
|
static gboolean is_verbose = FALSE;
|
|
|
|
static gboolean is_debugging = FALSE;
|
2002-06-08 19:55:27 -04:00
|
|
|
static gboolean replace_current = FALSE;
|
2001-06-10 15:23:28 -04:00
|
|
|
static int no_prefix = 0;
|
2001-06-11 01:47:51 -04:00
|
|
|
static FILE* logfile = NULL;
|
|
|
|
|
|
|
|
static void
|
|
|
|
ensure_logfile (void)
|
|
|
|
{
|
2002-03-06 17:27:24 -05:00
|
|
|
if (logfile == NULL && g_getenv ("METACITY_USE_LOGFILE"))
|
2001-06-11 01:47:51 -04:00
|
|
|
{
|
2002-03-04 21:43:22 -05:00
|
|
|
char *filename = NULL;
|
|
|
|
char *tmpl;
|
|
|
|
int fd;
|
|
|
|
GError *err;
|
2001-06-11 01:47:51 -04:00
|
|
|
|
2002-03-04 21:43:22 -05:00
|
|
|
tmpl = g_strdup_printf ("metacity-%d-debug-log-XXXXXX",
|
|
|
|
(int) getpid ());
|
2001-09-10 22:57:05 -04:00
|
|
|
|
2002-03-04 21:43:22 -05:00
|
|
|
err = NULL;
|
|
|
|
fd = g_file_open_tmp (tmpl,
|
|
|
|
&filename,
|
|
|
|
&err);
|
2001-06-11 01:47:51 -04:00
|
|
|
|
2002-03-04 21:43:22 -05:00
|
|
|
g_free (tmpl);
|
|
|
|
|
|
|
|
if (err != NULL)
|
|
|
|
{
|
|
|
|
meta_warning (_("Failed to open debug log: %s\n"),
|
|
|
|
err->message);
|
|
|
|
g_error_free (err);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
logfile = fdopen (fd, "w");
|
|
|
|
|
2001-06-11 01:47:51 -04:00
|
|
|
if (logfile == NULL)
|
2002-03-04 21:43:22 -05:00
|
|
|
{
|
|
|
|
meta_warning (_("Failed to fdopen() log file %s: %s\n"),
|
|
|
|
filename, strerror (errno));
|
|
|
|
close (fd);
|
|
|
|
}
|
2001-06-11 01:47:51 -04:00
|
|
|
else
|
2002-03-04 21:43:22 -05:00
|
|
|
{
|
|
|
|
g_print (_("Opened log file %s\n"), filename);
|
|
|
|
}
|
2001-06-11 01:47:51 -04:00
|
|
|
|
2002-03-04 21:43:22 -05:00
|
|
|
g_free (filename);
|
2001-06-11 01:47:51 -04:00
|
|
|
}
|
|
|
|
}
|
2001-05-30 11:36:31 -04:00
|
|
|
|
|
|
|
gboolean
|
|
|
|
meta_is_verbose (void)
|
|
|
|
{
|
|
|
|
return is_verbose;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
meta_set_verbose (gboolean setting)
|
|
|
|
{
|
2001-06-11 01:47:51 -04:00
|
|
|
if (setting)
|
|
|
|
ensure_logfile ();
|
|
|
|
|
2001-05-30 11:36:31 -04:00
|
|
|
is_verbose = setting;
|
|
|
|
}
|
|
|
|
|
2001-05-31 02:42:58 -04:00
|
|
|
gboolean
|
|
|
|
meta_is_debugging (void)
|
|
|
|
{
|
|
|
|
return is_debugging;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
meta_set_debugging (gboolean setting)
|
|
|
|
{
|
2001-06-11 01:47:51 -04:00
|
|
|
if (setting)
|
|
|
|
ensure_logfile ();
|
|
|
|
|
2001-05-31 02:42:58 -04:00
|
|
|
is_debugging = setting;
|
|
|
|
}
|
|
|
|
|
2002-06-08 19:55:27 -04:00
|
|
|
gboolean
|
|
|
|
meta_get_replace_current_wm (void)
|
|
|
|
{
|
|
|
|
return replace_current;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
meta_set_replace_current_wm (gboolean setting)
|
|
|
|
{
|
|
|
|
replace_current = setting;
|
|
|
|
}
|
|
|
|
|
2002-08-24 16:54:23 -04:00
|
|
|
static int
|
|
|
|
utf8_fputs (const char *str,
|
|
|
|
FILE *f)
|
|
|
|
{
|
|
|
|
char *l;
|
|
|
|
|
|
|
|
l = g_locale_from_utf8 (str, -1, NULL, NULL, NULL);
|
|
|
|
|
|
|
|
if (l == NULL)
|
|
|
|
fputs (str, f); /* just print it anyway, better than nothing */
|
|
|
|
else
|
|
|
|
fputs (l, f);
|
|
|
|
|
|
|
|
g_free (l);
|
|
|
|
}
|
|
|
|
|
2001-05-30 11:36:31 -04:00
|
|
|
void
|
|
|
|
meta_debug_spew (const char *format, ...)
|
|
|
|
{
|
|
|
|
va_list args;
|
|
|
|
gchar *str;
|
2001-06-11 01:47:51 -04:00
|
|
|
FILE *out;
|
|
|
|
|
2001-05-30 11:36:31 -04:00
|
|
|
g_return_if_fail (format != NULL);
|
|
|
|
|
2001-05-31 02:42:58 -04:00
|
|
|
if (!is_debugging)
|
2001-05-30 11:36:31 -04:00
|
|
|
return;
|
|
|
|
|
|
|
|
va_start (args, format);
|
|
|
|
str = g_strdup_vprintf (format, args);
|
|
|
|
va_end (args);
|
|
|
|
|
2001-06-11 01:47:51 -04:00
|
|
|
out = logfile ? logfile : stderr;
|
|
|
|
|
2001-06-10 15:23:28 -04:00
|
|
|
if (no_prefix == 0)
|
2002-08-24 16:54:23 -04:00
|
|
|
utf8_fputs (_("Window manager: "), out);
|
|
|
|
utf8_fputs (str, out);
|
2001-06-21 02:08:35 -04:00
|
|
|
|
|
|
|
fflush (out);
|
2001-05-30 11:36:31 -04:00
|
|
|
|
|
|
|
g_free (str);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
meta_verbose (const char *format, ...)
|
|
|
|
{
|
|
|
|
va_list args;
|
|
|
|
gchar *str;
|
2001-06-11 01:47:51 -04:00
|
|
|
FILE *out;
|
2001-05-30 11:36:31 -04:00
|
|
|
|
|
|
|
g_return_if_fail (format != NULL);
|
|
|
|
|
|
|
|
if (!is_verbose)
|
|
|
|
return;
|
|
|
|
|
|
|
|
va_start (args, format);
|
|
|
|
str = g_strdup_vprintf (format, args);
|
|
|
|
va_end (args);
|
|
|
|
|
2001-06-11 01:47:51 -04:00
|
|
|
out = logfile ? logfile : stderr;
|
|
|
|
|
2001-06-10 15:23:28 -04:00
|
|
|
if (no_prefix == 0)
|
2002-08-24 16:54:23 -04:00
|
|
|
utf8_fputs ("Window manager: ", out);
|
|
|
|
utf8_fputs (str, out);
|
2001-06-21 02:08:35 -04:00
|
|
|
|
|
|
|
fflush (out);
|
2001-05-30 11:36:31 -04:00
|
|
|
|
|
|
|
g_free (str);
|
|
|
|
}
|
|
|
|
|
2002-01-03 18:28:19 -05:00
|
|
|
static const char*
|
|
|
|
topic_name (MetaDebugTopic topic)
|
|
|
|
{
|
|
|
|
switch (topic)
|
|
|
|
{
|
|
|
|
case META_DEBUG_FOCUS:
|
|
|
|
return "FOCUS";
|
2002-02-07 22:34:26 -05:00
|
|
|
case META_DEBUG_WORKAREA:
|
|
|
|
return "WORKAREA";
|
|
|
|
case META_DEBUG_STACK:
|
|
|
|
return "STACK";
|
|
|
|
case META_DEBUG_THEMES:
|
|
|
|
return "THEMES";
|
|
|
|
case META_DEBUG_SM:
|
|
|
|
return "SM";
|
|
|
|
case META_DEBUG_EVENTS:
|
|
|
|
return "EVENTS";
|
|
|
|
case META_DEBUG_WINDOW_STATE:
|
|
|
|
return "WINDOW_STATE";
|
|
|
|
case META_DEBUG_WINDOW_OPS:
|
|
|
|
return "WINDOW_OPS";
|
|
|
|
case META_DEBUG_PLACEMENT:
|
|
|
|
return "PLACEMENT";
|
|
|
|
case META_DEBUG_GEOMETRY:
|
|
|
|
return "GEOMETRY";
|
2002-03-02 10:26:07 -05:00
|
|
|
case META_DEBUG_PING:
|
|
|
|
return "PING";
|
2002-04-21 15:35:02 -04:00
|
|
|
case META_DEBUG_XINERAMA:
|
|
|
|
return "XINERAMA";
|
2002-04-28 00:52:26 -04:00
|
|
|
case META_DEBUG_KEYBINDINGS:
|
|
|
|
return "KEYBINDINGS";
|
2002-10-21 17:44:35 -04:00
|
|
|
case META_DEBUG_SYNC:
|
|
|
|
return "SYNC";
|
|
|
|
case META_DEBUG_ERRORS:
|
|
|
|
return "ERRORS";
|
2002-01-03 18:28:19 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
return "Window manager";
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
meta_topic (MetaDebugTopic topic,
|
|
|
|
const char *format,
|
|
|
|
...)
|
|
|
|
{
|
|
|
|
va_list args;
|
|
|
|
gchar *str;
|
|
|
|
FILE *out;
|
|
|
|
|
|
|
|
g_return_if_fail (format != NULL);
|
|
|
|
|
|
|
|
if (!is_verbose)
|
|
|
|
return;
|
|
|
|
|
|
|
|
va_start (args, format);
|
|
|
|
str = g_strdup_vprintf (format, args);
|
|
|
|
va_end (args);
|
|
|
|
|
|
|
|
out = logfile ? logfile : stderr;
|
|
|
|
|
|
|
|
if (no_prefix == 0)
|
|
|
|
fprintf (out, "%s: ", topic_name (topic));
|
2002-08-24 16:54:23 -04:00
|
|
|
utf8_fputs (str, out);
|
2002-01-03 18:28:19 -05:00
|
|
|
|
|
|
|
fflush (out);
|
|
|
|
|
|
|
|
g_free (str);
|
|
|
|
}
|
|
|
|
|
2001-05-30 23:30:58 -04:00
|
|
|
void
|
|
|
|
meta_bug (const char *format, ...)
|
|
|
|
{
|
|
|
|
va_list args;
|
|
|
|
gchar *str;
|
2001-06-11 01:47:51 -04:00
|
|
|
FILE *out;
|
2001-05-30 23:30:58 -04:00
|
|
|
|
|
|
|
g_return_if_fail (format != NULL);
|
|
|
|
|
|
|
|
va_start (args, format);
|
|
|
|
str = g_strdup_vprintf (format, args);
|
|
|
|
va_end (args);
|
|
|
|
|
2001-06-11 01:47:51 -04:00
|
|
|
out = logfile ? logfile : stderr;
|
|
|
|
|
2001-06-10 15:23:28 -04:00
|
|
|
if (no_prefix == 0)
|
2002-08-24 16:54:23 -04:00
|
|
|
utf8_fputs (_("Bug in window manager: "), out);
|
|
|
|
utf8_fputs (str, out);
|
2001-06-21 02:08:35 -04:00
|
|
|
|
|
|
|
fflush (out);
|
2001-05-30 23:30:58 -04:00
|
|
|
|
|
|
|
g_free (str);
|
|
|
|
|
2002-07-23 15:12:02 -04:00
|
|
|
print_backtrace ();
|
|
|
|
|
2001-05-30 23:30:58 -04:00
|
|
|
/* stop us in a debugger */
|
|
|
|
abort ();
|
|
|
|
}
|
|
|
|
|
2001-05-30 11:36:31 -04:00
|
|
|
void
|
|
|
|
meta_warning (const char *format, ...)
|
|
|
|
{
|
|
|
|
va_list args;
|
|
|
|
gchar *str;
|
2001-06-11 01:47:51 -04:00
|
|
|
FILE *out;
|
|
|
|
|
2001-05-30 11:36:31 -04:00
|
|
|
g_return_if_fail (format != NULL);
|
|
|
|
|
|
|
|
va_start (args, format);
|
|
|
|
str = g_strdup_vprintf (format, args);
|
|
|
|
va_end (args);
|
|
|
|
|
2001-06-11 01:47:51 -04:00
|
|
|
out = logfile ? logfile : stderr;
|
|
|
|
|
2001-06-10 15:23:28 -04:00
|
|
|
if (no_prefix == 0)
|
2002-08-24 16:54:23 -04:00
|
|
|
utf8_fputs (_("Window manager warning: "), out);
|
|
|
|
utf8_fputs (str, out);
|
2002-10-21 17:44:35 -04:00
|
|
|
|
|
|
|
fflush (out);
|
2001-05-30 11:36:31 -04:00
|
|
|
|
|
|
|
g_free (str);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
meta_fatal (const char *format, ...)
|
|
|
|
{
|
|
|
|
va_list args;
|
|
|
|
gchar *str;
|
2001-06-11 01:47:51 -04:00
|
|
|
FILE *out;
|
|
|
|
|
2001-05-30 11:36:31 -04:00
|
|
|
g_return_if_fail (format != NULL);
|
|
|
|
|
|
|
|
va_start (args, format);
|
|
|
|
str = g_strdup_vprintf (format, args);
|
|
|
|
va_end (args);
|
|
|
|
|
2001-06-11 01:47:51 -04:00
|
|
|
out = logfile ? logfile : stderr;
|
|
|
|
|
2001-06-10 15:23:28 -04:00
|
|
|
if (no_prefix == 0)
|
2002-08-24 16:54:23 -04:00
|
|
|
utf8_fputs (_("Window manager error: "), out);
|
|
|
|
utf8_fputs (str, out);
|
2001-06-21 02:08:35 -04:00
|
|
|
|
|
|
|
fflush (out);
|
2001-05-30 11:36:31 -04:00
|
|
|
|
|
|
|
g_free (str);
|
|
|
|
|
|
|
|
meta_exit (META_EXIT_ERROR);
|
|
|
|
}
|
2001-06-10 15:23:28 -04:00
|
|
|
|
|
|
|
void
|
|
|
|
meta_push_no_msg_prefix (void)
|
|
|
|
{
|
|
|
|
++no_prefix;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
meta_pop_no_msg_prefix (void)
|
|
|
|
{
|
|
|
|
g_return_if_fail (no_prefix > 0);
|
|
|
|
|
|
|
|
--no_prefix;
|
|
|
|
}
|
2002-01-27 21:09:12 -05:00
|
|
|
|
|
|
|
void
|
|
|
|
meta_exit (MetaExitCode code)
|
|
|
|
{
|
|
|
|
|
|
|
|
exit (code);
|
|
|
|
}
|
2002-08-12 17:32:13 -04:00
|
|
|
|
|
|
|
gint
|
|
|
|
meta_unsigned_long_equal (gconstpointer v1,
|
|
|
|
gconstpointer v2)
|
|
|
|
{
|
|
|
|
return *((const gulong*) v1) == *((const gulong*) v2);
|
|
|
|
}
|
|
|
|
|
|
|
|
guint
|
|
|
|
meta_unsigned_long_hash (gconstpointer v)
|
|
|
|
{
|
|
|
|
gulong val = * (const gulong *) v;
|
|
|
|
|
|
|
|
/* I'm not sure this works so well. */
|
|
|
|
#if G_SIZEOF_LONG > 4
|
|
|
|
return (guint) (val ^ (val >> 32));
|
|
|
|
#else
|
|
|
|
return val;
|
|
|
|
#endif
|
|
|
|
}
|