diff options
Diffstat (limited to 'src/core/util.c')
-rw-r--r-- | src/core/util.c | 796 |
1 files changed, 0 insertions, 796 deletions
diff --git a/src/core/util.c b/src/core/util.c deleted file mode 100644 index 74a884c80..000000000 --- a/src/core/util.c +++ /dev/null @@ -1,796 +0,0 @@ -/* - * Copyright (C) 2001 Havoc Pennington - * Copyright (C) 2005 Elijah Newren - * - * 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, see <http://www.gnu.org/licenses/>. - */ - -/** - * SECTION:util - * @title: Utility functions - * @short_description: Miscellaneous utility functions - */ - -#define _POSIX_C_SOURCE 200112L /* for fdopen() */ - -#include "config.h" - -#include "core/util-private.h" - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <errno.h> -#include <string.h> -#include <X11/Xlib.h> /* must explicitly be included for Solaris; #326746 */ -#include <X11/Xutil.h> /* Just for the definition of the various gravities */ - -#ifdef HAVE_SYS_PRCTL -#include <sys/prctl.h> -#endif - -#include "clutter/clutter-mutter.h" -#include "cogl/cogl.h" -#include "meta/common.h" -#include "meta/main.h" - -static const GDebugKey meta_debug_keys[] = { - { "focus", META_DEBUG_FOCUS }, - { "workarea", META_DEBUG_WORKAREA }, - { "stack", META_DEBUG_STACK }, - { "sm", META_DEBUG_SM }, - { "events", META_DEBUG_EVENTS }, - { "window-state", META_DEBUG_WINDOW_STATE }, - { "window-ops", META_DEBUG_WINDOW_OPS }, - { "geometry", META_DEBUG_GEOMETRY }, - { "placement", META_DEBUG_PLACEMENT }, - { "ping", META_DEBUG_PING }, - { "keybindings", META_DEBUG_KEYBINDINGS }, - { "sync", META_DEBUG_SYNC }, - { "startup", META_DEBUG_STARTUP }, - { "prefs", META_DEBUG_PREFS }, - { "groups", META_DEBUG_GROUPS }, - { "resizing", META_DEBUG_RESIZING }, - { "shapes", META_DEBUG_SHAPES }, - { "edge-resistance", META_DEBUG_EDGE_RESISTANCE }, - { "dbus", META_DEBUG_DBUS }, - { "input", META_DEBUG_INPUT }, - { "wayland", META_DEBUG_WAYLAND }, - { "kms", META_DEBUG_KMS }, - { "screen-cast", META_DEBUG_SCREEN_CAST }, - { "remote-desktop", META_DEBUG_REMOTE_DESKTOP }, - { "backend", META_DEBUG_BACKEND }, -}; - -#ifdef WITH_VERBOSE_MODE -static void -meta_topic_real_valist (MetaDebugTopic topic, - const char *format, - va_list args) G_GNUC_PRINTF(2, 0); -#endif - -static gint verbose_topics = 0; -static int no_prefix = 0; -static gboolean is_wayland_compositor = FALSE; -static int debug_paint_flags = 0; - -#ifdef WITH_VERBOSE_MODE -static FILE* logfile = NULL; - -static void -ensure_logfile (void) -{ - if (logfile == NULL && g_getenv ("MUTTER_USE_LOGFILE")) - { - char *filename = NULL; - char *tmpl; - int fd; - GError *err; - - tmpl = g_strdup_printf ("mutter-%d-debug-log-XXXXXX", - (int) getpid ()); - - err = NULL; - fd = g_file_open_tmp (tmpl, - &filename, - &err); - - g_free (tmpl); - - if (err != NULL) - { - meta_warning ("Failed to open debug log: %s", - err->message); - g_error_free (err); - return; - } - - logfile = fdopen (fd, "w"); - - if (logfile == NULL) - { - meta_warning ("Failed to fdopen() log file %s: %s", - filename, strerror (errno)); - close (fd); - } - else - { - g_printerr ("Opened log file %s", filename); - } - - g_free (filename); - } -} -#endif - -gboolean -meta_is_verbose (void) -{ - return verbose_topics != 0; -} - -void -meta_set_verbose (gboolean setting) -{ -#ifndef WITH_VERBOSE_MODE - if (setting) - meta_fatal (_("Mutter was compiled without support for verbose mode")); -#endif - - if (setting) - meta_add_verbose_topic (META_DEBUG_VERBOSE); - else - meta_remove_verbose_topic (META_DEBUG_VERBOSE); -} - -/** - * meta_add_verbose_topic: - * @topic: Topic for which logging will be started - * - * Ensure log messages for the given topic @topic - * will be printed. - */ -void -meta_add_verbose_topic (MetaDebugTopic topic) -{ - if (verbose_topics == META_DEBUG_VERBOSE) - return; - - ensure_logfile (); - - if (topic == META_DEBUG_VERBOSE) - verbose_topics = META_DEBUG_VERBOSE; - else - verbose_topics |= topic; -} - -/** - * meta_remove_verbose_topic: - * @topic: Topic for which logging will be stopped - * - * Stop printing log messages for the given topic @topic. Note - * that this method does not stack with meta_add_verbose_topic(); - * i.e. if two calls to meta_add_verbose_topic() for the same - * topic are made, one call to meta_remove_verbose_topic() will - * remove it. - */ -void -meta_remove_verbose_topic (MetaDebugTopic topic) -{ - if (topic == META_DEBUG_VERBOSE) - verbose_topics = 0; - else - verbose_topics &= ~topic; -} - -void -meta_init_debug_utils (void) -{ - const char *debug_env; - -#ifdef HAVE_SYS_PRCTL - prctl (PR_SET_DUMPABLE, 1); -#endif - - if (g_getenv ("MUTTER_VERBOSE")) - meta_set_verbose (TRUE); - - debug_env = g_getenv ("MUTTER_DEBUG"); - if (debug_env) - { - MetaDebugTopic topics; - - topics = g_parse_debug_string (debug_env, - meta_debug_keys, - G_N_ELEMENTS (meta_debug_keys)); - meta_add_verbose_topic (topics); - } -} - -gboolean -meta_is_wayland_compositor (void) -{ - return is_wayland_compositor; -} - -void -meta_set_is_wayland_compositor (gboolean value) -{ - is_wayland_compositor = value; -} - -char * -meta_g_utf8_strndup (const gchar *src, - gsize n) -{ - const gchar *s = src; - while (n && *s) - { - s = g_utf8_next_char (s); - n--; - } - - return g_strndup (src, s - src); -} - -static int -utf8_fputs (const char *str, - FILE *f) -{ - char *l; - int retval; - - l = g_locale_from_utf8 (str, -1, NULL, NULL, NULL); - - if (l == NULL) - retval = fputs (str, f); /* just print it anyway, better than nothing */ - else - retval = fputs (l, f); - - g_free (l); - - return retval; -} - -#ifdef WITH_VERBOSE_MODE -void -meta_verbose_real (const char *format, ...) -{ - va_list args; - - va_start (args, format); - meta_topic_real_valist (META_DEBUG_VERBOSE, format, args); - va_end (args); -} - -static const char* -topic_name (MetaDebugTopic topic) -{ - switch (topic) - { - case META_DEBUG_FOCUS: - return "FOCUS"; - case META_DEBUG_WORKAREA: - return "WORKAREA"; - case META_DEBUG_STACK: - return "STACK"; - 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"; - case META_DEBUG_PING: - return "PING"; - case META_DEBUG_KEYBINDINGS: - return "KEYBINDINGS"; - case META_DEBUG_SYNC: - return "SYNC"; - case META_DEBUG_STARTUP: - return "STARTUP"; - case META_DEBUG_PREFS: - return "PREFS"; - case META_DEBUG_GROUPS: - return "GROUPS"; - case META_DEBUG_RESIZING: - return "RESIZING"; - case META_DEBUG_SHAPES: - return "SHAPES"; - case META_DEBUG_EDGE_RESISTANCE: - return "EDGE_RESISTANCE"; - case META_DEBUG_DBUS: - return "DBUS"; - case META_DEBUG_INPUT: - return "INPUT"; - case META_DEBUG_KMS: - return "KMS"; - case META_DEBUG_SCREEN_CAST: - return "SCREEN_CAST"; - case META_DEBUG_REMOTE_DESKTOP: - return "REMOTE_DESKTOP"; - case META_DEBUG_BACKEND: - return "BACKEND"; - case META_DEBUG_VERBOSE: - return "VERBOSE"; - case META_DEBUG_WAYLAND: - return "WAYLAND"; - } - - return "WM"; -} - -static int sync_count = 0; - -gboolean -meta_is_topic_enabled (MetaDebugTopic topic) -{ - if (verbose_topics == 0) - return FALSE; - - if (topic == META_DEBUG_VERBOSE && verbose_topics != META_DEBUG_VERBOSE) - return FALSE; - - return !!(verbose_topics & topic); -} - -static void -meta_topic_real_valist (MetaDebugTopic topic, - const char *format, - va_list args) -{ - gchar *str; - FILE *out; - - g_return_if_fail (format != NULL); - - if (!meta_is_topic_enabled (topic)) - return; - - str = g_strdup_vprintf (format, args); - - out = logfile ? logfile : stderr; - - if (no_prefix == 0) - fprintf (out, "%s: ", topic_name (topic)); - - if (topic == META_DEBUG_SYNC) - { - ++sync_count; - fprintf (out, "%d: ", sync_count); - } - - utf8_fputs (str, out); - utf8_fputs ("\n", out); - - fflush (out); - - g_free (str); -} - -void -meta_topic_real (MetaDebugTopic topic, - const char *format, - ...) -{ - va_list args; - - va_start (args, format); - meta_topic_real_valist (topic, format, args); - va_end (args); -} -#endif /* WITH_VERBOSE_MODE */ - -void -meta_bug (const char *format, ...) -{ - va_list args; - gchar *str; - FILE *out; - - g_return_if_fail (format != NULL); - - va_start (args, format); - str = g_strdup_vprintf (format, args); - va_end (args); - -#ifdef WITH_VERBOSE_MODE - out = logfile ? logfile : stderr; -#else - out = stderr; -#endif - - if (no_prefix == 0) - utf8_fputs ("Bug in window manager: ", out); - utf8_fputs (str, out); - utf8_fputs ("\n", out); - - fflush (out); - - g_free (str); - - /* stop us in a debugger */ - abort (); -} - -void -meta_warning (const char *format, ...) -{ - va_list args; - gchar *str; - FILE *out; - - g_return_if_fail (format != NULL); - - va_start (args, format); - str = g_strdup_vprintf (format, args); - va_end (args); - -#ifdef WITH_VERBOSE_MODE - out = logfile ? logfile : stderr; -#else - out = stderr; -#endif - - if (no_prefix == 0) - utf8_fputs ("Window manager warning: ", out); - utf8_fputs (str, out); - utf8_fputs ("\n", out); - - fflush (out); - - g_free (str); -} - -void -meta_fatal (const char *format, ...) -{ - va_list args; - gchar *str; - FILE *out; - - g_warn_if_fail (format); - if (!format) - meta_exit (META_EXIT_ERROR); - - va_start (args, format); - str = g_strdup_vprintf (format, args); - va_end (args); - -#ifdef WITH_VERBOSE_MODE - out = logfile ? logfile : stderr; -#else - out = stderr; -#endif - - if (no_prefix == 0) - utf8_fputs ("Window manager error: ", out); - utf8_fputs (str, out); - utf8_fputs ("\n", out); - - fflush (out); - - g_free (str); - - meta_exit (META_EXIT_ERROR); -} - -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; -} - -void -meta_exit (MetaExitCode code) -{ - - exit (code); -} - -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 GLIB_SIZEOF_LONG > 4 - return (guint) (val ^ (val >> 32)); -#else - return val; -#endif -} - -const char* -meta_gravity_to_string (MetaGravity gravity) -{ - switch (gravity) - { - case META_GRAVITY_NORTH_WEST: - return "META_GRAVITY_NORTH_WEST"; - break; - case META_GRAVITY_NORTH: - return "META_GRAVITY_NORTH"; - break; - case META_GRAVITY_NORTH_EAST: - return "META_GRAVITY_NORTH_EAST"; - break; - case META_GRAVITY_WEST: - return "META_GRAVITY_WEST"; - break; - case META_GRAVITY_CENTER: - return "META_GRAVITY_CENTER"; - break; - case META_GRAVITY_EAST: - return "META_GRAVITY_EAST"; - break; - case META_GRAVITY_SOUTH_WEST: - return "META_GRAVITY_SOUTH_WEST"; - break; - case META_GRAVITY_SOUTH: - return "META_GRAVITY_SOUTH"; - break; - case META_GRAVITY_SOUTH_EAST: - return "META_GRAVITY_SOUTH_EAST"; - break; - case META_GRAVITY_STATIC: - return "META_GRAVITY_STATIC"; - break; - default: - return "META_GRAVITY_NORTH_WEST"; - break; - } -} - -char* -meta_external_binding_name_for_action (guint keybinding_action) -{ - return g_strdup_printf ("external-grab-%u", keybinding_action); -} - -/* Command line arguments are passed in the locale encoding; in almost - * all cases, we'd hope that is UTF-8 and no conversion is necessary. - * If it's not UTF-8, then it's possible that the message isn't - * representable in the locale encoding. - */ -static void -append_argument (GPtrArray *args, - const char *arg) -{ - char *locale_arg = g_locale_from_utf8 (arg, -1, NULL, NULL, NULL); - - /* This is cheesy, but it's better to have a few ???'s in the dialog - * for an unresponsive application than no dialog at all appear */ - if (!locale_arg) - locale_arg = g_strdup ("???"); - - g_ptr_array_add (args, locale_arg); -} - -/** - * meta_show_dialog: (skip) - * @type: type of dialog - * @message: message - * @timeout: timeout - * @display: display - * @ok_text: text for Ok button - * @cancel_text: text for Cancel button - * @icon_name: icon name - * @transient_for: window XID of parent - * @columns: columns - * @entries: entries - * - */ -GPid -meta_show_dialog (const char *type, - const char *message, - const char *timeout, - const char *display, - const char *ok_text, - const char *cancel_text, - const char *icon_name, - const int transient_for, - GSList *columns, - GSList *entries) -{ - GError *error = NULL; - GSList *tmp; - GPid child_pid; - GPtrArray *args; - - args = g_ptr_array_new (); - - append_argument (args, "zenity"); - append_argument (args, type); - - if (display) - { - append_argument (args, "--display"); - append_argument (args, display); - } - - append_argument (args, "--class"); - append_argument (args, "mutter-dialog"); - append_argument (args, "--title"); - append_argument (args, ""); - append_argument (args, "--text"); - append_argument (args, message); - - if (timeout) - { - append_argument (args, "--timeout"); - append_argument (args, timeout); - } - - if (ok_text) - { - append_argument (args, "--ok-label"); - append_argument (args, ok_text); - } - - if (cancel_text) - { - append_argument (args, "--cancel-label"); - append_argument (args, cancel_text); - } - - if (icon_name) - { - append_argument (args, "--icon-name"); - append_argument (args, icon_name); - } - - tmp = columns; - while (tmp) - { - append_argument (args, "--column"); - append_argument (args, tmp->data); - tmp = tmp->next; - } - - tmp = entries; - while (tmp) - { - append_argument (args, tmp->data); - tmp = tmp->next; - } - - if (transient_for) - { - gchar *env = g_strdup_printf("%d", transient_for); - setenv ("WINDOWID", env, 1); - g_free (env); - - append_argument (args, "--modal"); - } - - g_ptr_array_add (args, NULL); /* NULL-terminate */ - - g_spawn_async ( - "/", - (gchar**) args->pdata, - NULL, - G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD, - NULL, NULL, - &child_pid, - &error - ); - - if (transient_for) - unsetenv ("WINDOWID"); - - g_ptr_array_free (args, TRUE); - - if (error) - { - meta_warning ("%s", error->message); - g_error_free (error); - } - - return child_pid; -} - -MetaLocaleDirection -meta_get_locale_direction (void) -{ - switch (gtk_get_locale_direction ()) - { - case GTK_TEXT_DIR_LTR: - return META_LOCALE_DIRECTION_LTR; - case GTK_TEXT_DIR_RTL: - return META_LOCALE_DIRECTION_RTL; - default: - g_assert_not_reached (); - return 0; - } -} - -char * -meta_generate_random_id (GRand *rand, - int length) -{ - char *id; - int i; - - /* Generate a random string of printable ASCII characters. */ - - id = g_new0 (char, length + 1); - for (i = 0; i < length; i++) - id[i] = (char) g_rand_int_range (rand, 32, 127); - - return id; -} - - -void -meta_add_clutter_debug_flags (ClutterDebugFlag debug_flags, - ClutterDrawDebugFlag draw_flags, - ClutterPickDebugFlag pick_flags) -{ - clutter_add_debug_flags (debug_flags, draw_flags, pick_flags); -} - -void -meta_remove_clutter_debug_flags (ClutterDebugFlag debug_flags, - ClutterDrawDebugFlag draw_flags, - ClutterPickDebugFlag pick_flags) -{ - clutter_remove_debug_flags (debug_flags, draw_flags, pick_flags); -} - -void -meta_get_clutter_debug_flags (ClutterDebugFlag *debug_flags, - ClutterDrawDebugFlag *draw_flags, - ClutterPickDebugFlag *pick_flags) -{ - clutter_get_debug_flags (debug_flags, draw_flags, pick_flags); -} - -void -meta_add_debug_paint_flag (MetaDebugPaintFlag flag) -{ - debug_paint_flags |= flag; -} - -void -meta_remove_debug_paint_flag (MetaDebugPaintFlag flag) -{ - debug_paint_flags &= ~flag; -} - -MetaDebugPaintFlag -meta_get_debug_paint_flags (void) -{ - return debug_paint_flags; -} |