From fb31765cbe33890f325a87015507364156741321 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 19:59:44 +0200 Subject: Adding upstream version 42.0. Signed-off-by: Daniel Baumann --- src/procdialogs.cpp | 336 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 336 insertions(+) create mode 100644 src/procdialogs.cpp (limited to 'src/procdialogs.cpp') diff --git a/src/procdialogs.cpp b/src/procdialogs.cpp new file mode 100644 index 0000000..b0d2a54 --- /dev/null +++ b/src/procdialogs.cpp @@ -0,0 +1,336 @@ +/* -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* Procman - dialogs + * Copyright (C) 2001 Kevin Vandersloot + * + * 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 Library General Public + * License along with this program; if not, see . + * + */ + + +#include + +#include + +#include +#include +#include + +#include "procdialogs.h" +#include "proctable.h" +#include "prettytable.h" +#include "procactions.h" +#include "util.h" +#include "gsm_gnomesu.h" +#include "gsm_gksu.h" +#include "gsm_pkexec.h" +#include "cgroups.h" + +static GtkDialog *renice_dialog = NULL; +static gint new_nice_value = 0; + + +static void +kill_dialog_button_pressed (GtkDialog *dialog, gint id, gpointer data) +{ + struct ProcActionArgs *kargs = static_cast(data); + + gtk_widget_destroy (GTK_WIDGET (dialog)); + + if (id == GTK_RESPONSE_OK) + kill_process (kargs->app, kargs->arg_value); + + proctable_thaw (kargs->app); + proctable_update (kargs->app); + g_free (kargs); +} + +void +procdialog_create_kill_dialog (GsmApplication *app, int signal) +{ + GtkMessageDialog *kill_alert_dialog; + GtkWidget *confirm_button; + + gchar *primary, *secondary, *button_text; + struct ProcActionArgs *kargs; + + proctable_freeze (app); + kargs = g_new(ProcActionArgs, 1); + kargs->app = app; + kargs->arg_value = signal; + gint selected_count = gtk_tree_selection_count_selected_rows (app->selection); + + if ( selected_count == 1 ) { + ProcInfo *selected_process = NULL; + // get the last selected row + gtk_tree_selection_selected_foreach (app->selection, get_last_selected, + &selected_process); + + std::string *process_name = &selected_process->name; + std::string short_process_name = process_name->substr(0, process_name->find(" -")); + + switch (signal) { + case SIGKILL: + /*xgettext: primary alert message for killing single process*/ + primary = g_strdup_printf (_("Are you sure you want to kill the selected process “%s” (PID: %u)?"), + short_process_name.c_str(), + selected_process->pid); + break; + case SIGTERM: + /*xgettext: primary alert message for ending single process*/ + primary = g_strdup_printf (_("Are you sure you want to end the selected process “%s” (PID: %u)?"), + short_process_name.c_str(), + selected_process->pid); + break; + default: // SIGSTOP + /*xgettext: primary alert message for stopping single process*/ + primary = g_strdup_printf (_("Are you sure you want to stop the selected process “%s” (PID: %u)?"), + short_process_name.c_str(), + selected_process->pid); + break; + } + } else { + switch (signal) { + case SIGKILL: + /*xgettext: primary alert message for killing multiple processes*/ + primary = g_strdup_printf (ngettext("Are you sure you want to kill the selected process?", + "Are you sure you want to kill the %d selected processes?", selected_count), + selected_count); + break; + case SIGTERM: + /*xgettext: primary alert message for ending multiple processes*/ + primary = g_strdup_printf (ngettext("Are you sure you want to end the selected process?", + "Are you sure you want to end the %d selected processes?", selected_count), + selected_count); + break; + default: // SIGSTOP + /*xgettext: primary alert message for stopping multiple processes*/ + primary = g_strdup_printf (ngettext("Are you sure you want to stop the selected process?", + "Are you sure you want to stop the %d selected processes?", selected_count), + selected_count); + break; + } + } + + switch (signal) { + case SIGKILL: + /*xgettext: secondary alert message*/ + secondary = _("Killing a process may destroy data, break the " + "session or introduce a security risk. " + "Only unresponsive processes should be killed."); + button_text = ngettext("_Kill Process", "_Kill Processes", selected_count); + break; + case SIGTERM: + /*xgettext: secondary alert message*/ + secondary = _("Ending a process may destroy data, break the " + "session or introduce a security risk. " + "Only unresponsive processes should be ended."); + button_text = ngettext("_End Process", "_End Processes", selected_count); + break; + default: // SIGSTOP + /*xgettext: secondary alert message*/ + secondary = _("Stopping a process may destroy data, break the " + "session or introduce a security risk. " + "Only unresponsive processes should be stopped."); + button_text = ngettext("_Stop Process", "_Stop Processes", selected_count); + break; + } + + kill_alert_dialog = GTK_MESSAGE_DIALOG (gtk_message_dialog_new (GTK_WINDOW (app->main_window), + static_cast(GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT), + GTK_MESSAGE_WARNING, + GTK_BUTTONS_NONE, + "%s", + primary)); + g_free (primary); + + gtk_message_dialog_format_secondary_text (kill_alert_dialog, + "%s", + secondary); + + gtk_dialog_add_button (GTK_DIALOG (kill_alert_dialog), + _("_Cancel"), GTK_RESPONSE_CANCEL); + + confirm_button = gtk_dialog_add_button (GTK_DIALOG (kill_alert_dialog), + button_text, GTK_RESPONSE_OK); + gtk_style_context_add_class (gtk_widget_get_style_context (confirm_button), + GTK_STYLE_CLASS_DESTRUCTIVE_ACTION); + + gtk_dialog_set_default_response (GTK_DIALOG (kill_alert_dialog), + GTK_RESPONSE_CANCEL); + + g_signal_connect (G_OBJECT (kill_alert_dialog), "response", + G_CALLBACK (kill_dialog_button_pressed), kargs); + + gtk_widget_show_all (GTK_WIDGET (kill_alert_dialog)); +} + +static void +renice_scale_changed (GtkAdjustment *adj, gpointer data) +{ + GtkLabel *label = GTK_LABEL (data); + + new_nice_value = int(gtk_adjustment_get_value (adj)); + gchar* text = g_strdup(procman::get_nice_level_with_priority (new_nice_value)); + gtk_label_set_text (label, text); + g_free(text); + +} + +static void +renice_dialog_button_pressed (GtkDialog *dialog, gint id, gpointer data) +{ + GsmApplication *app = static_cast(data); + if (id == 100) { + if (new_nice_value == -100) + return; + renice(app, new_nice_value); + } + + gtk_widget_destroy (GTK_WIDGET (dialog)); + renice_dialog = NULL; +} + +void +procdialog_create_renice_dialog (GsmApplication *app) +{ + ProcInfo *info; + + GtkLabel *label; + GtkLabel *priority_label; + GtkAdjustment *renice_adj; + GtkBuilder *builder; + gchar *text; + gchar *dialog_title; + + if (renice_dialog) + return; + + gtk_tree_selection_selected_foreach (app->selection, get_last_selected, + &info); + gint selected_count = gtk_tree_selection_count_selected_rows (app->selection); + if (!info) + return; + + builder = gtk_builder_new(); + gtk_builder_add_from_resource (builder, "/org/gnome/gnome-system-monitor/data/renice.ui", NULL); + + renice_dialog = GTK_DIALOG (gtk_builder_get_object (builder, "renice_dialog")); + if ( selected_count == 1 ) { + dialog_title = g_strdup_printf (_("Change Priority of Process “%s” (PID: %u)"), + info->name.c_str(), info->pid); + } else { + dialog_title = g_strdup_printf (ngettext("Change Priority of the selected process", "Change Priority of %d selected processes", selected_count), + selected_count); + } + + gtk_window_set_title (GTK_WINDOW(renice_dialog), dialog_title); + + g_free (dialog_title); + + gtk_dialog_set_default_response (GTK_DIALOG (renice_dialog), 100); + new_nice_value = -100; + + renice_adj = GTK_ADJUSTMENT (gtk_builder_get_object (builder, "renice_adj")); + gtk_adjustment_configure( GTK_ADJUSTMENT(renice_adj), info->nice, RENICE_VAL_MIN, RENICE_VAL_MAX, 1, 1, 0); + + new_nice_value = 0; + + priority_label = GTK_LABEL (gtk_builder_get_object (builder, "priority_label")); + gtk_label_set_label (priority_label, procman::get_nice_level_with_priority (info->nice)); + + text = g_strconcat("", _("Note:"), " ", + _("The priority of a process is given by its nice value. A lower nice value corresponds to a higher priority."), + "", NULL); + label = GTK_LABEL (gtk_builder_get_object (builder, "note_label")); + gtk_label_set_label (label, _(text)); + gtk_label_set_line_wrap (label, TRUE); + g_free (text); + + g_signal_connect (G_OBJECT (renice_dialog), "response", + G_CALLBACK (renice_dialog_button_pressed), app); + g_signal_connect (G_OBJECT (renice_adj), "value_changed", + G_CALLBACK (renice_scale_changed), priority_label); + + gtk_window_set_transient_for (GTK_WINDOW (renice_dialog), GTK_WINDOW (GsmApplication::get()->main_window)); + gtk_widget_show_all (GTK_WIDGET (renice_dialog)); + + gtk_builder_connect_signals (builder, NULL); + + g_object_unref (G_OBJECT (builder)); +} + + + +static char * +procman_action_to_command(ProcmanActionType type, + gint pid, + gint extra_value) +{ + switch (type) { + case PROCMAN_ACTION_KILL: + return g_strdup_printf("kill -s %d %d", extra_value, pid); + case PROCMAN_ACTION_RENICE: + return g_strdup_printf("renice %d %d", extra_value, pid); + default: + g_assert_not_reached(); + } +} + + +gboolean +multi_root_check (char *command) +{ + if (procman_has_pkexec ()) { + return gsm_pkexec_create_root_password_dialog (command); + } + + if (procman_has_gksu ()) { + return gsm_gksu_create_root_password_dialog (command); + } + + if (procman_has_gnomesu ()) { + return gsm_gnomesu_create_root_password_dialog (command); + } + + return FALSE; +} + +/* + * type determines whether if dialog is for killing process or renice. + * type == PROCMAN_ACTION_KILL, extra_value -> signal to send + * type == PROCMAN_ACTION_RENICE, extra_value -> new priority. + */ +gboolean +procdialog_create_root_password_dialog(ProcmanActionType type, + GsmApplication *app, + gint pid, + gint extra_value) +{ + char * command; + gboolean ret = FALSE; + + command = procman_action_to_command(type, pid, extra_value); + + procman_debug("Trying to run '%s' as root", command); + + if (procman_has_pkexec()) + ret = gsm_pkexec_create_root_password_dialog(command); + else if (procman_has_gksu()) + ret = gsm_gksu_create_root_password_dialog(command); + else if (procman_has_gnomesu()) + ret = gsm_gnomesu_create_root_password_dialog(command); + + g_free(command); + return ret; +} -- cgit v1.2.3