2001-05-30 15:36:31 +00: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-05 02:43:22 +00:00
|
|
|
#include <config.h>
|
2001-05-30 15:36:31 +00:00
|
|
|
#include "util.h"
|
|
|
|
#include "main.h"
|
|
|
|
|
|
|
|
#include <stdio.h>
|
2001-05-31 03:30:58 +00:00
|
|
|
#include <stdlib.h>
|
2001-09-11 03:54:54 +00:00
|
|
|
#include <unistd.h>
|
2002-03-05 02:43:22 +00:00
|
|
|
#include <errno.h>
|
|
|
|
#include <string.h>
|
2001-05-30 15:36:31 +00:00
|
|
|
|
2002-07-23 19:12:02 +00:00
|
|
|
#ifdef HAVE_BACKTRACE
|
|
|
|
#include <execinfo.h>
|
2002-10-27 03:03:32 +00:00
|
|
|
void
|
|
|
|
meta_print_backtrace (void)
|
2002-07-23 19:12:02 +00:00
|
|
|
{
|
|
|
|
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
|
2002-10-27 03:03:32 +00:00
|
|
|
void
|
|
|
|
meta_print_backtrace (void)
|
2002-07-23 19:12:02 +00:00
|
|
|
{
|
|
|
|
meta_verbose ("Not compiled with backtrace support\n");
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2001-05-31 06:42:58 +00:00
|
|
|
static gboolean is_verbose = FALSE;
|
|
|
|
static gboolean is_debugging = FALSE;
|
2002-06-08 23:55:27 +00:00
|
|
|
static gboolean replace_current = FALSE;
|
2001-06-10 19:23:28 +00:00
|
|
|
static int no_prefix = 0;
|
2002-12-09 02:53:16 +00:00
|
|
|
|
|
|
|
#ifdef WITH_VERBOSE_MODE
|
2001-06-11 05:47:51 +00:00
|
|
|
static FILE* logfile = NULL;
|
|
|
|
|
|
|
|
static void
|
|
|
|
ensure_logfile (void)
|
|
|
|
{
|
2002-03-06 22:27:24 +00:00
|
|
|
if (logfile == NULL && g_getenv ("METACITY_USE_LOGFILE"))
|
2001-06-11 05:47:51 +00:00
|
|
|
{
|
2002-03-05 02:43:22 +00:00
|
|
|
char *filename = NULL;
|
|
|
|
char *tmpl;
|
|
|
|
int fd;
|
|
|
|
GError *err;
|
2001-06-11 05:47:51 +00:00
|
|
|
|
2002-03-05 02:43:22 +00:00
|
|
|
tmpl = g_strdup_printf ("metacity-%d-debug-log-XXXXXX",
|
|
|
|
(int) getpid ());
|
2001-09-11 02:57:05 +00:00
|
|
|
|
2002-03-05 02:43:22 +00:00
|
|
|
err = NULL;
|
|
|
|
fd = g_file_open_tmp (tmpl,
|
|
|
|
&filename,
|
|
|
|
&err);
|
2001-06-11 05:47:51 +00:00
|
|
|
|
2002-03-05 02:43:22 +00: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 05:47:51 +00:00
|
|
|
if (logfile == NULL)
|
2002-03-05 02:43:22 +00:00
|
|
|
{
|
|
|
|
meta_warning (_("Failed to fdopen() log file %s: %s\n"),
|
|
|
|
filename, strerror (errno));
|
|
|
|
close (fd);
|
|
|
|
}
|
2001-06-11 05:47:51 +00:00
|
|
|
else
|
2002-03-05 02:43:22 +00:00
|
|
|
{
|
2002-12-08 19:17:17 +00:00
|
|
|
g_printerr (_("Opened log file %s\n"), filename);
|
2002-03-05 02:43:22 +00:00
|
|
|
}
|
2001-06-11 05:47:51 +00:00
|
|
|
|
2002-03-05 02:43:22 +00:00
|
|
|
g_free (filename);
|
2001-06-11 05:47:51 +00:00
|
|
|
}
|
|
|
|
}
|
2002-12-09 02:53:16 +00:00
|
|
|
#endif
|
2001-05-30 15:36:31 +00:00
|
|
|
|
|
|
|
gboolean
|
|
|
|
meta_is_verbose (void)
|
|
|
|
{
|
|
|
|
return is_verbose;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
meta_set_verbose (gboolean setting)
|
|
|
|
{
|
2002-12-08 19:17:17 +00:00
|
|
|
#ifndef WITH_VERBOSE_MODE
|
|
|
|
if (setting)
|
|
|
|
meta_fatal (_("Metacity was compiled without support for verbose mode\n"));
|
|
|
|
#endif
|
|
|
|
|
2001-06-11 05:47:51 +00:00
|
|
|
if (setting)
|
|
|
|
ensure_logfile ();
|
|
|
|
|
2001-05-30 15:36:31 +00:00
|
|
|
is_verbose = setting;
|
|
|
|
}
|
|
|
|
|
2001-05-31 06:42:58 +00:00
|
|
|
gboolean
|
|
|
|
meta_is_debugging (void)
|
|
|
|
{
|
|
|
|
return is_debugging;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
meta_set_debugging (gboolean setting)
|
|
|
|
{
|
2001-06-11 05:47:51 +00:00
|
|
|
if (setting)
|
|
|
|
ensure_logfile ();
|
|
|
|
|
2001-05-31 06:42:58 +00:00
|
|
|
is_debugging = setting;
|
|
|
|
}
|
|
|
|
|
2002-06-08 23:55:27 +00: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 20:54:23 +00:00
|
|
|
static int
|
|
|
|
utf8_fputs (const char *str,
|
|
|
|
FILE *f)
|
|
|
|
{
|
|
|
|
char *l;
|
2002-12-01 03:58:04 +00:00
|
|
|
int retval;
|
|
|
|
|
2002-08-24 20:54:23 +00:00
|
|
|
l = g_locale_from_utf8 (str, -1, NULL, NULL, NULL);
|
|
|
|
|
|
|
|
if (l == NULL)
|
2002-12-01 03:58:04 +00:00
|
|
|
retval = fputs (str, f); /* just print it anyway, better than nothing */
|
2002-08-24 20:54:23 +00:00
|
|
|
else
|
2002-12-01 03:58:04 +00:00
|
|
|
retval = fputs (l, f);
|
2002-08-24 20:54:23 +00:00
|
|
|
|
|
|
|
g_free (l);
|
2002-12-01 03:58:04 +00:00
|
|
|
|
|
|
|
return retval;
|
2002-08-24 20:54:23 +00:00
|
|
|
}
|
|
|
|
|
2002-12-08 19:17:17 +00:00
|
|
|
#ifdef WITH_VERBOSE_MODE
|
2001-05-30 15:36:31 +00:00
|
|
|
void
|
2002-12-08 19:17:17 +00:00
|
|
|
meta_debug_spew_real (const char *format, ...)
|
2001-05-30 15:36:31 +00:00
|
|
|
{
|
|
|
|
va_list args;
|
|
|
|
gchar *str;
|
2001-06-11 05:47:51 +00:00
|
|
|
FILE *out;
|
|
|
|
|
2001-05-30 15:36:31 +00:00
|
|
|
g_return_if_fail (format != NULL);
|
|
|
|
|
2001-05-31 06:42:58 +00:00
|
|
|
if (!is_debugging)
|
2001-05-30 15:36:31 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
va_start (args, format);
|
|
|
|
str = g_strdup_vprintf (format, args);
|
|
|
|
va_end (args);
|
|
|
|
|
2001-06-11 05:47:51 +00:00
|
|
|
out = logfile ? logfile : stderr;
|
|
|
|
|
2001-06-10 19:23:28 +00:00
|
|
|
if (no_prefix == 0)
|
2002-08-24 20:54:23 +00:00
|
|
|
utf8_fputs (_("Window manager: "), out);
|
|
|
|
utf8_fputs (str, out);
|
2001-06-21 06:08:35 +00:00
|
|
|
|
|
|
|
fflush (out);
|
2001-05-30 15:36:31 +00:00
|
|
|
|
|
|
|
g_free (str);
|
|
|
|
}
|
2002-12-08 19:17:17 +00:00
|
|
|
#endif /* WITH_VERBOSE_MODE */
|
2001-05-30 15:36:31 +00:00
|
|
|
|
2002-12-08 19:17:17 +00:00
|
|
|
#ifdef WITH_VERBOSE_MODE
|
2001-05-30 15:36:31 +00:00
|
|
|
void
|
2002-12-08 19:17:17 +00:00
|
|
|
meta_verbose_real (const char *format, ...)
|
2001-05-30 15:36:31 +00:00
|
|
|
{
|
|
|
|
va_list args;
|
|
|
|
gchar *str;
|
2001-06-11 05:47:51 +00:00
|
|
|
FILE *out;
|
2001-05-30 15:36:31 +00: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 05:47:51 +00:00
|
|
|
out = logfile ? logfile : stderr;
|
|
|
|
|
2001-06-10 19:23:28 +00:00
|
|
|
if (no_prefix == 0)
|
2002-08-24 20:54:23 +00:00
|
|
|
utf8_fputs ("Window manager: ", out);
|
|
|
|
utf8_fputs (str, out);
|
2001-06-21 06:08:35 +00:00
|
|
|
|
|
|
|
fflush (out);
|
2001-05-30 15:36:31 +00:00
|
|
|
|
|
|
|
g_free (str);
|
|
|
|
}
|
2002-12-08 19:17:17 +00:00
|
|
|
#endif /* WITH_VERBOSE_MODE */
|
2001-05-30 15:36:31 +00:00
|
|
|
|
2002-12-08 19:17:17 +00:00
|
|
|
#ifdef WITH_VERBOSE_MODE
|
2002-01-03 23:28:19 +00:00
|
|
|
static const char*
|
|
|
|
topic_name (MetaDebugTopic topic)
|
|
|
|
{
|
|
|
|
switch (topic)
|
|
|
|
{
|
|
|
|
case META_DEBUG_FOCUS:
|
|
|
|
return "FOCUS";
|
2002-02-08 03:34:26 +00: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 15:26:07 +00:00
|
|
|
case META_DEBUG_PING:
|
|
|
|
return "PING";
|
2002-04-21 19:35:02 +00:00
|
|
|
case META_DEBUG_XINERAMA:
|
|
|
|
return "XINERAMA";
|
2002-04-28 04:52:26 +00:00
|
|
|
case META_DEBUG_KEYBINDINGS:
|
|
|
|
return "KEYBINDINGS";
|
2002-10-21 21:44:35 +00:00
|
|
|
case META_DEBUG_SYNC:
|
|
|
|
return "SYNC";
|
|
|
|
case META_DEBUG_ERRORS:
|
|
|
|
return "ERRORS";
|
2002-10-25 23:35:50 +00:00
|
|
|
case META_DEBUG_STARTUP:
|
|
|
|
return "STARTUP";
|
2002-11-03 19:06:39 +00:00
|
|
|
case META_DEBUG_PREFS:
|
|
|
|
return "PREFS";
|
2002-12-01 03:58:04 +00:00
|
|
|
case META_DEBUG_GROUPS:
|
|
|
|
return "GROUPS";
|
2002-12-10 03:23:04 +00:00
|
|
|
case META_DEBUG_RESIZING:
|
|
|
|
return "RESIZING";
|
2003-01-05 07:51:02 +00:00
|
|
|
case META_DEBUG_SHAPES:
|
|
|
|
return "SHAPES";
|
2002-01-03 23:28:19 +00:00
|
|
|
}
|
|
|
|
|
2003-01-05 18:36:01 +00:00
|
|
|
return "WM";
|
2002-01-03 23:28:19 +00:00
|
|
|
}
|
|
|
|
|
2002-11-04 00:56:12 +00:00
|
|
|
static int sync_count = 0;
|
|
|
|
|
2002-01-03 23:28:19 +00:00
|
|
|
void
|
2002-12-08 19:17:17 +00:00
|
|
|
meta_topic_real (MetaDebugTopic topic,
|
|
|
|
const char *format,
|
|
|
|
...)
|
2002-01-03 23:28:19 +00:00
|
|
|
{
|
|
|
|
va_list args;
|
|
|
|
gchar *str;
|
|
|
|
FILE *out;
|
|
|
|
|
|
|
|
g_return_if_fail (format != NULL);
|
|
|
|
|
|
|
|
if (!is_verbose)
|
|
|
|
return;
|
|
|
|
|
2002-11-04 00:56:12 +00:00
|
|
|
va_start (args, format);
|
2002-01-03 23:28:19 +00:00
|
|
|
str = g_strdup_vprintf (format, args);
|
|
|
|
va_end (args);
|
|
|
|
|
|
|
|
out = logfile ? logfile : stderr;
|
|
|
|
|
|
|
|
if (no_prefix == 0)
|
|
|
|
fprintf (out, "%s: ", topic_name (topic));
|
2002-11-04 00:56:12 +00:00
|
|
|
|
|
|
|
if (topic == META_DEBUG_SYNC)
|
|
|
|
{
|
|
|
|
++sync_count;
|
|
|
|
fprintf (out, "%d: ", sync_count);
|
|
|
|
}
|
|
|
|
|
2002-08-24 20:54:23 +00:00
|
|
|
utf8_fputs (str, out);
|
2002-01-03 23:28:19 +00:00
|
|
|
|
|
|
|
fflush (out);
|
|
|
|
|
|
|
|
g_free (str);
|
|
|
|
}
|
2002-12-08 19:17:17 +00:00
|
|
|
#endif /* WITH_VERBOSE_MODE */
|
2002-01-03 23:28:19 +00:00
|
|
|
|
2001-05-31 03:30:58 +00:00
|
|
|
void
|
|
|
|
meta_bug (const char *format, ...)
|
|
|
|
{
|
|
|
|
va_list args;
|
|
|
|
gchar *str;
|
2001-06-11 05:47:51 +00:00
|
|
|
FILE *out;
|
2001-05-31 03:30:58 +00:00
|
|
|
|
|
|
|
g_return_if_fail (format != NULL);
|
|
|
|
|
|
|
|
va_start (args, format);
|
|
|
|
str = g_strdup_vprintf (format, args);
|
|
|
|
va_end (args);
|
|
|
|
|
2001-06-11 05:47:51 +00:00
|
|
|
out = logfile ? logfile : stderr;
|
|
|
|
|
2001-06-10 19:23:28 +00:00
|
|
|
if (no_prefix == 0)
|
2002-08-24 20:54:23 +00:00
|
|
|
utf8_fputs (_("Bug in window manager: "), out);
|
|
|
|
utf8_fputs (str, out);
|
2001-06-21 06:08:35 +00:00
|
|
|
|
|
|
|
fflush (out);
|
2001-05-31 03:30:58 +00:00
|
|
|
|
|
|
|
g_free (str);
|
|
|
|
|
2002-10-27 03:03:32 +00:00
|
|
|
meta_print_backtrace ();
|
2002-07-23 19:12:02 +00:00
|
|
|
|
2001-05-31 03:30:58 +00:00
|
|
|
/* stop us in a debugger */
|
|
|
|
abort ();
|
|
|
|
}
|
|
|
|
|
2001-05-30 15:36:31 +00:00
|
|
|
void
|
|
|
|
meta_warning (const char *format, ...)
|
|
|
|
{
|
|
|
|
va_list args;
|
|
|
|
gchar *str;
|
2001-06-11 05:47:51 +00:00
|
|
|
FILE *out;
|
|
|
|
|
2001-05-30 15:36:31 +00:00
|
|
|
g_return_if_fail (format != NULL);
|
|
|
|
|
|
|
|
va_start (args, format);
|
|
|
|
str = g_strdup_vprintf (format, args);
|
|
|
|
va_end (args);
|
|
|
|
|
2001-06-11 05:47:51 +00:00
|
|
|
out = logfile ? logfile : stderr;
|
|
|
|
|
2001-06-10 19:23:28 +00:00
|
|
|
if (no_prefix == 0)
|
2002-08-24 20:54:23 +00:00
|
|
|
utf8_fputs (_("Window manager warning: "), out);
|
|
|
|
utf8_fputs (str, out);
|
2002-10-21 21:44:35 +00:00
|
|
|
|
|
|
|
fflush (out);
|
2001-05-30 15:36:31 +00:00
|
|
|
|
|
|
|
g_free (str);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
meta_fatal (const char *format, ...)
|
|
|
|
{
|
|
|
|
va_list args;
|
|
|
|
gchar *str;
|
2001-06-11 05:47:51 +00:00
|
|
|
FILE *out;
|
|
|
|
|
2001-05-30 15:36:31 +00:00
|
|
|
g_return_if_fail (format != NULL);
|
|
|
|
|
|
|
|
va_start (args, format);
|
|
|
|
str = g_strdup_vprintf (format, args);
|
|
|
|
va_end (args);
|
|
|
|
|
2001-06-11 05:47:51 +00:00
|
|
|
out = logfile ? logfile : stderr;
|
|
|
|
|
2001-06-10 19:23:28 +00:00
|
|
|
if (no_prefix == 0)
|
2002-08-24 20:54:23 +00:00
|
|
|
utf8_fputs (_("Window manager error: "), out);
|
|
|
|
utf8_fputs (str, out);
|
2001-06-21 06:08:35 +00:00
|
|
|
|
|
|
|
fflush (out);
|
2001-05-30 15:36:31 +00:00
|
|
|
|
|
|
|
g_free (str);
|
|
|
|
|
|
|
|
meta_exit (META_EXIT_ERROR);
|
|
|
|
}
|
2001-06-10 19:23:28 +00: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-28 02:09:12 +00:00
|
|
|
|
|
|
|
void
|
|
|
|
meta_exit (MetaExitCode code)
|
|
|
|
{
|
|
|
|
|
|
|
|
exit (code);
|
|
|
|
}
|
2002-08-12 21:32:13 +00: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
|
|
|
|
}
|