diff options
Diffstat (limited to '')
-rw-r--r-- | utils/gdm-runtime-config.c | 75 | ||||
-rw-r--r-- | utils/gdm-screenshot.c | 296 | ||||
-rw-r--r-- | utils/gdmflexiserver.c | 179 | ||||
-rw-r--r-- | utils/meson.build | 41 |
4 files changed, 591 insertions, 0 deletions
diff --git a/utils/gdm-runtime-config.c b/utils/gdm-runtime-config.c new file mode 100644 index 0000000..66bbbf3 --- /dev/null +++ b/utils/gdm-runtime-config.c @@ -0,0 +1,75 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2018 Red Hat, Inc. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "config.h" + +#include <locale.h> +#include <stdlib.h> +#include <sysexits.h> + +#include <glib.h> + +int +main (int argc, char *argv[]) +{ + g_autoptr(GKeyFile) key_file = NULL; + g_autoptr(GError) error = NULL; + gchar *group, *key, *value; + gboolean saved_okay; + + if (argc < 5 || g_strcmp0(argv[1], "set") != 0) { + g_printerr("gdm-runtime-config: command format should be " \ + "'gdm-runtime-config set <group> <key> <value>'\n" \ + "For example, 'gdm-runtime-config set daemon WaylandEnable true'\n"); + return EX_USAGE; + } + + group = argv[2]; + key = argv[3]; + value = argv[4]; + + setlocale (LC_ALL, ""); + + key_file = g_key_file_new (); + + /* Just load the runtime conf file and ignore the error. A new file + * will be created later if it is file not found. + * So that more than one config item can be set. + */ + g_key_file_load_from_file (key_file, + GDM_RUNTIME_CONF, + G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS, + &error); + g_clear_error (&error); + + g_key_file_set_value (key_file, group, key, value); + + g_mkdir_with_parents (GDM_RUN_DIR, 0711); + + saved_okay = g_key_file_save_to_file (key_file, GDM_RUNTIME_CONF, &error); + + if (!saved_okay) { + g_printerr ("gdm-runtime-config: unable to set '%s' in '%s' group to '%s': %s\n", + key, group, value, error->message); + return EX_CANTCREAT; + } + + return EX_OK; +} diff --git a/utils/gdm-screenshot.c b/utils/gdm-screenshot.c new file mode 100644 index 0000000..5d20929 --- /dev/null +++ b/utils/gdm-screenshot.c @@ -0,0 +1,296 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2008 William Jon McCann <jmccann@redhat.com> + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "config.h" + +#include <stdlib.h> +#include <stdio.h> +#include <unistd.h> +#include <string.h> +#include <locale.h> + +#include <glib/gi18n.h> +#include <gtk/gtk.h> +#include <canberra-gtk.h> + +#include <X11/Xatom.h> +#include <gdk/gdkx.h> + +#define SELECTION_NAME "_GDM_SCREENSHOT" +static GtkWidget *selection_window; + +static gboolean debug_in; + +/* Keep all config options for compatibility even if they are noops */ +GOptionEntry options [] = { + { "debug", 'd', 0, G_OPTION_ARG_NONE, &debug_in, N_("Debugging output"), NULL }, + { NULL } +}; + +/* To make sure there is only one screenshot taken at a time, + * (Imagine key repeat for the print screen key) we hold a selection + * until we are done taking the screenshot + */ +/* * Copyright (C) 2001-2006 Jonathan Blandford <jrb@alum.mit.edu> */ +static gboolean +screenshot_grab_lock (void) +{ + Atom selection_atom; + GdkCursor *cursor; + gboolean result = FALSE; + + selection_atom = gdk_x11_get_xatom_by_name (SELECTION_NAME); + XGrabServer (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ())); + if (XGetSelectionOwner (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), selection_atom) != None) { + goto out; + } + + selection_window = gtk_invisible_new (); + gtk_widget_show (selection_window); + + if (!gtk_selection_owner_set (selection_window, + gdk_atom_intern (SELECTION_NAME, FALSE), + GDK_CURRENT_TIME)) { + gtk_widget_destroy (selection_window); + selection_window = NULL; + goto out; + } + + cursor = gdk_cursor_new_for_display (gdk_display_get_default (), GDK_WATCH); + gdk_pointer_grab (gtk_widget_get_window (selection_window), FALSE, 0, NULL, + cursor, GDK_CURRENT_TIME); + g_object_unref (cursor); + + result = TRUE; + + out: + XUngrabServer (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ())); + gdk_flush (); + + return result; +} + +/* * Copyright (C) 2001-2006 Jonathan Blandford <jrb@alum.mit.edu> */ +static void +screenshot_release_lock (void) +{ + if (selection_window != NULL) { + gtk_widget_destroy (selection_window); + selection_window = NULL; + } + gdk_flush (); +} + +/* * Copyright (C) 2001-2006 Jonathan Blandford <jrb@alum.mit.edu> */ +static GdkPixbuf * +screenshot_get_pixbuf (Window w) +{ + GdkWindow *window; + GdkWindow *root; + GdkPixbuf *screenshot; + int x_real_orig; + int y_real_orig; + int x_orig; + int y_orig; + int real_width; + int real_height; + int width; + int height; + + window = gdk_x11_window_foreign_new_for_display (gdk_display_get_default (), w); + if (window == NULL) { + return NULL; + } + + root = gdk_x11_window_foreign_new_for_display (gdk_display_get_default (), GDK_ROOT_WINDOW ()); + gdk_window_get_geometry (window, NULL, NULL, &real_width, &real_height); + gdk_window_get_origin (window, &x_real_orig, &y_real_orig); + + x_orig = x_real_orig; + y_orig = y_real_orig; + width = real_width; + height = real_height; + + if (x_orig < 0) { + width = width + x_orig; + x_orig = 0; + } + if (y_orig < 0) { + height = height + y_orig; + y_orig = 0; + } + + if (x_orig + width > gdk_screen_width ()) { + width = gdk_screen_width () - x_orig; + } + if (y_orig + height > gdk_screen_height ()) { + height = gdk_screen_height () - y_orig; + } + + screenshot = gdk_pixbuf_get_from_window (root, + x_orig, + y_orig, + width, + height); + + return screenshot; +} + +static char * +screenshot_save (GdkPixbuf *pixbuf) +{ + char *filename; + gboolean res; + GError *error; + + filename = g_build_filename (GDM_SCREENSHOT_DIR, + "GDM-Screenshot.png", + NULL); + + error = NULL; + res = gdk_pixbuf_save (pixbuf, + filename, + "png", + &error, + "tEXt::CREATOR", "gdm-screenshot", + NULL); + if (! res) { + g_warning ("Unable to save screenshot: %s", error->message); + g_error_free (error); + g_free (filename); + filename = NULL; + } + + return filename; +} + +static void +sound_effect_finished (ca_context *c, + uint32_t id, + int error_code, + void *userdata) +{ +} + +static void +play_sound_effect (Window xid) +{ + ca_context *c; + ca_proplist *p; + int res; + + c = ca_gtk_context_get (); + + p = NULL; + res = ca_proplist_create (&p); + if (res < 0) { + goto done; + } + + res = ca_proplist_sets (p, CA_PROP_EVENT_ID, "screen-capture"); + if (res < 0) { + goto done; + } + + res = ca_proplist_sets (p, CA_PROP_EVENT_DESCRIPTION, _("Screenshot taken")); + if (res < 0) { + goto done; + } + + res = ca_proplist_setf (p, + CA_PROP_WINDOW_X11_XID, + "%lu", + (unsigned long) xid); + if (res < 0) { + goto done; + } + + ca_context_play_full (c, 0, p, sound_effect_finished, NULL); + + done: + if (p != NULL) { + ca_proplist_destroy (p); + } + +} + +static void +prepare_screenshot (void) +{ + Window win; + GdkPixbuf *screenshot; + char *filename; + + if (!screenshot_grab_lock ()) { + exit (EXIT_SUCCESS); + } + + win = GDK_ROOT_WINDOW (); + + screenshot = screenshot_get_pixbuf (win); + + screenshot_release_lock (); + + if (screenshot == NULL) { + /* FIXME: dialog? */ + exit (EXIT_FAILURE); + } + + play_sound_effect (win); + + filename = screenshot_save (screenshot); + if (filename != NULL) { + g_print ("Wrote %s\n", filename); + /* FIXME: show a dialog or something */ + g_free (filename); + } +} + +int +main (int argc, char *argv[]) +{ + GOptionContext *ctx; + gboolean res; + GError *error; + + bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR); + bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); + textdomain (GETTEXT_PACKAGE); + setlocale (LC_ALL, ""); + + /* Option parsing */ + ctx = g_option_context_new (N_("Take a picture of the screen")); + g_option_context_set_translation_domain (ctx, GETTEXT_PACKAGE); + g_option_context_add_main_entries (ctx, options, NULL); + g_option_context_add_group (ctx, gtk_get_option_group (TRUE)); + error = NULL; + res = g_option_context_parse (ctx, &argc, &argv, &error); + g_option_context_free (ctx); + + if (! res) { + g_warning ("%s", error->message); + g_error_free (error); + exit (EXIT_FAILURE); + } + + prepare_screenshot (); + + return 1; +} diff --git a/utils/gdmflexiserver.c b/utils/gdmflexiserver.c new file mode 100644 index 0000000..68b8ac9 --- /dev/null +++ b/utils/gdmflexiserver.c @@ -0,0 +1,179 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2008 William Jon McCann <jmccann@redhat.com> + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "config.h" + +#include <stdlib.h> +#include <stdio.h> +#include <unistd.h> +#include <string.h> +#include <locale.h> + +#include <glib/gi18n.h> + +#include "common/gdm-common.h" + +static const char *send_command = NULL; +static gboolean use_xnest = FALSE; +static gboolean no_lock = FALSE; +static gboolean debug_in = FALSE; +static gboolean authenticate = FALSE; +static gboolean startnew = FALSE; +static gboolean monte_carlo_pi = FALSE; +static gboolean show_version = FALSE; +static char **args_remaining = NULL; + +/* Keep all config options for compatibility even if they are noops */ +GOptionEntry options [] = { + { "command", 'c', 0, G_OPTION_ARG_STRING, &send_command, N_("Only the VERSION command is supported"), N_("COMMAND") }, + { "xnest", 'n', 0, G_OPTION_ARG_NONE, &use_xnest, N_("Ignored — retained for compatibility"), NULL }, + { "no-lock", 'l', 0, G_OPTION_ARG_NONE, &no_lock, N_("Ignored — retained for compatibility"), NULL }, + { "debug", 'd', 0, G_OPTION_ARG_NONE, &debug_in, N_("Debugging output"), NULL }, + { "authenticate", 'a', 0, G_OPTION_ARG_NONE, &authenticate, N_("Ignored — retained for compatibility"), NULL }, + { "startnew", 's', 0, G_OPTION_ARG_NONE, &startnew, N_("Ignored — retained for compatibility"), NULL }, + { "monte-carlo-pi", 0, 0, G_OPTION_ARG_NONE, &monte_carlo_pi, NULL, NULL }, + { "version", 0, 0, G_OPTION_ARG_NONE, &show_version, N_("Version of this application"), NULL }, + { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, &args_remaining, NULL, NULL }, + { NULL } +}; + +static gboolean +is_program_in_path (const char *program) +{ + char *tmp = g_find_program_in_path (program); + if (tmp != NULL) { + g_free (tmp); + return TRUE; + } else { + return FALSE; + } +} + +static void +maybe_lock_screen (void) +{ + gboolean use_gscreensaver = FALSE; + GError *error = NULL; + char *command; + + if (is_program_in_path ("gnome-screensaver-command")) { + use_gscreensaver = TRUE; + } else if (! is_program_in_path ("xscreensaver-command")) { + return; + } + + if (use_gscreensaver) { + command = g_strdup ("gnome-screensaver-command --lock"); + } else { + command = g_strdup ("xscreensaver-command -lock"); + } + + if (! g_spawn_command_line_async (command, &error)) { + g_warning ("Cannot lock screen: %s", error->message); + g_error_free (error); + } + + g_free (command); + + if (! use_gscreensaver) { + command = g_strdup ("xscreensaver-command -throttle"); + if (! g_spawn_command_line_async (command, &error)) { + g_warning ("Cannot disable screensaver engines: %s", error->message); + g_error_free (error); + } + + g_free (command); + } +} + +static void +calc_pi (void) +{ + unsigned long n = 0, h = 0; + double x, y; + printf ("\n"); + for (;;) { + x = g_random_double (); + y = g_random_double (); + if (x*x + y*y <= 1) + h++; + n++; + if ( ! (n & 0xfff)) + printf ("pi ~~ %1.10f\t(%lu/%lu * 4) iteration: %lu \r", + ((double)h)/(double)n * 4.0, h, n, n); + } +} + +int +main (int argc, char *argv[]) +{ + GOptionContext *ctx; + gboolean res; + GError *error; + + bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR); + bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); + textdomain (GETTEXT_PACKAGE); + setlocale (LC_ALL, ""); + + /* Option parsing */ + ctx = g_option_context_new (_("— New GDM login")); + g_option_context_set_translation_domain (ctx, GETTEXT_PACKAGE); + g_option_context_add_main_entries (ctx, options, NULL); + g_option_context_parse (ctx, &argc, &argv, NULL); + g_option_context_free (ctx); + + + if (show_version) { + g_print ("%s %s\n", argv [0], VERSION); + exit (EXIT_FAILURE); + } + + /* don't support commands other than VERSION */ + if (send_command != NULL) { + if (strcmp (send_command, "VERSION") == 0) { + g_print ("GDM %s \n", VERSION); + return 0; + } else { + g_warning ("No longer supported"); + } + return 1; + } + + if (monte_carlo_pi) { + calc_pi (); + return 0; + } + + if (use_xnest) { + g_warning ("Not yet implemented"); + return 1; + } + + error = NULL; + res = gdm_goto_login_session (&error); + if (! res) { + g_printerr ("%s", error->message); + } else { + maybe_lock_screen (); + } + + return 1; +} diff --git a/utils/meson.build b/utils/meson.build new file mode 100644 index 0000000..d59f167 --- /dev/null +++ b/utils/meson.build @@ -0,0 +1,41 @@ +# gdm-flexiserver +gdm_flexiserver_deps = [ + glib_dep, + libgdmcommon_dep, +] + +gdm_flexiserver = executable('gdmflexiserver', + 'gdmflexiserver.c', + dependencies: gdm_flexiserver_deps, + include_directories: config_h_dir, + install: true, +) + +# gdm-screenshot +gdm_screenshot_deps = [ + glib_dep, + gtk_dep, + x_deps, + libcanberra_gtk_dep, +] + +gdm_screenshot = executable('gdm-screenshot', + 'gdm-screenshot.c', + dependencies: gdm_screenshot_deps, + include_directories: config_h_dir, + install: true, +) + +# gdm-runtime-config +gdm_runtime_config_deps = [ + glib_dep, +] + +gdm_runtime_config = executable('gdm-runtime-config', + 'gdm-runtime-config.c', + dependencies: gdm_runtime_config_deps, + include_directories: config_h_dir, + install: true, + install_dir: get_option('libexecdir'), +) + |