pidgin/pidginapplication.c

Sat, 07 Nov 2020 02:21:44 -0600

author
Elliott Sales de Andrade <quantum.analyst@gmail.com>
date
Sat, 07 Nov 2020 02:21:44 -0600
changeset 40588
abf38be27d21
parent 40555
0bf5825aab0a
child 40600
46d10c72c137
permissions
-rw-r--r--

Rename a few things in Jabber SI xfer to be clearer.

A small followup to the previous review, which I noticed while working on Bonjour's version.

Testing Done:
compile only.

Reviewed at https://reviews.imfreedom.org/r/205/

/*
 * Pidgin - Internet Messenger
 * Copyright (C) Pidgin Developers <devel@pidgin.im>
 *
 * Pidgin is the legal property of its developers, whose names are too numerous
 * to list here.  Please refer to the COPYRIGHT file distributed with this
 * source distribution.
 *
 * 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 <https://www.gnu.org/licenses/>.
 */

#ifdef HAVE_CONFIG_H
# include <config.h>
#endif

#include <glib.h>
#include <glib/gi18n-lib.h>
#include <glib/gstdio.h>

#include <gplugin.h>
#include <purple.h>

#include "pidginapplication.h"

#include "gtkaccount.h"
#include "gtkblist.h"
#include "pidgincore.h"
#include "pidgindebug.h"

struct _PidginApplication {
	GtkApplication parent;
};

/******************************************************************************
 * Globals
 *****************************************************************************/
static gchar *opt_config_dir_arg = NULL;
static gboolean opt_nologin = FALSE;

static GOptionEntry option_entries[] = {
	{
		"config", 'c', 0, G_OPTION_ARG_FILENAME, &opt_config_dir_arg,
		N_("use DIR for config files"), N_("DIR")
	}, {
		"nologin", 'n', 0, G_OPTION_ARG_NONE, &opt_nologin,
		N_("don't automatically login"), NULL
	},
	{
		"version", 'v', 0, G_OPTION_ARG_NONE, NULL,
		N_("display the current version and exit"), NULL
	}, {
		NULL
	}
};

G_DEFINE_TYPE(PidginApplication, pidgin_application, GTK_TYPE_APPLICATION)

/******************************************************************************
 * GApplication Implementation
 *****************************************************************************/
static void
pidgin_application_startup(GApplication *application) {
	GtkCssProvider *provider = NULL;
	GError *error = NULL;
	GList *active_accounts = NULL;
	gchar *search_path = NULL;

	G_APPLICATION_CLASS(pidgin_application_parent_class)->startup(application);

	/* set a user-specified config directory */
	if (opt_config_dir_arg != NULL) {
		if (g_path_is_absolute(opt_config_dir_arg)) {
			purple_util_set_user_dir(opt_config_dir_arg);
		} else {
			/* Make an absolute (if not canonical) path */
			gchar *cwd = g_get_current_dir();
			gchar *path = g_build_filename(cwd, opt_config_dir_arg, NULL);

			purple_util_set_user_dir(path);

			g_free(cwd);
			g_free(path);
		}
	}

	provider = gtk_css_provider_new();

	search_path = g_build_filename(purple_config_dir(), "gtk-3.0.css", NULL);
	gtk_css_provider_load_from_path(provider, search_path, &error);
	if(error != NULL) {
		purple_debug_error("gtk", "Unable to load custom gtk-3.0.css: %s\n",
		                   error->message);
		g_clear_error(&error);
	} else {
		GdkScreen *screen = gdk_screen_get_default();
		gtk_style_context_add_provider_for_screen(screen,
		                                          GTK_STYLE_PROVIDER(provider),
		                                          GTK_STYLE_PROVIDER_PRIORITY_USER);
	}

	g_free(search_path);

#ifdef _WIN32
	winpidgin_init();
#endif

	purple_core_set_ui_ops(pidgin_core_get_ui_ops());

	if(!purple_core_init(PIDGIN_UI)) {
		fprintf(stderr,
				_("Initialization of the libpurple core failed. Aborting!\n"
				  "Please report this!\n"));
		g_abort();
	}

	if(g_getenv("PURPLE_PLUGINS_SKIP")) {
		purple_debug_info("gtk",
				"PURPLE_PLUGINS_SKIP environment variable "
				"set, skipping normal Pidgin plugin paths");
	} else {
		search_path = g_build_filename(purple_data_dir(), "plugins", NULL);

		if(!g_file_test(search_path, G_FILE_TEST_IS_DIR)) {
			g_mkdir(search_path, S_IRUSR | S_IWUSR | S_IXUSR);
		}

		purple_plugins_add_search_path(search_path);
		g_free(search_path);

		purple_plugins_add_search_path(PIDGIN_LIBDIR);
	}

	purple_plugins_refresh();

	/* load plugins we had when we quit */
	purple_plugins_load_saved(PIDGIN_PREFS_ROOT "/plugins/loaded");

	/* gk 20201008: this needs to be moved to the buddy list initialization. */
	pidgin_blist_setup_sort_methods();

	gtk_window_set_default_icon_name("pidgin");

	g_free(opt_config_dir_arg);
	opt_config_dir_arg = NULL;

	/*
	 * We want to show the blist early in the init process so the
	 * user feels warm and fuzzy.
	 */
	purple_blist_show();

	if(purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/debug/enabled")) {
		pidgin_debug_window_show();
	}

	if(opt_nologin) {
		/* Set all accounts to "offline" */
		PurpleSavedStatus *saved_status;

		/* If we've used this type+message before, lookup the transient status */
		saved_status = purple_savedstatus_find_transient_by_type_and_message(
							PURPLE_STATUS_OFFLINE, NULL);

		/* If this type+message is unique then create a new transient saved status */
		if(saved_status == NULL) {
			saved_status = purple_savedstatus_new(NULL, PURPLE_STATUS_OFFLINE);
		}

		/* Set the status for each account */
		purple_savedstatus_activate(saved_status);
	} else {
		/* Everything is good to go--sign on already */
		if (!purple_prefs_get_bool("/purple/savedstatus/startup_current_status")) {
			purple_savedstatus_activate(purple_savedstatus_get_startup());
		}

		purple_accounts_restore_current_statuses();
	}

	if((active_accounts = purple_accounts_get_all_active()) == NULL) {
		pidgin_accounts_window_show();
	} else {
		g_list_free(active_accounts);
	}

	/* GTK clears the notification for us when opening the first window, but we
	 * may have launched with only a status icon, so clear it just in case.
	 */
	gdk_notify_startup_complete();

	/* TODO: Use GtkApplicationWindow or add a window instead */
	g_application_hold(application);
}

static void
pidgin_application_activate(GApplication *application) {
	PidginBuddyList *blist = pidgin_blist_get_default_gtk_blist();

	if(blist != NULL && blist->window != NULL) {
		gtk_window_present(GTK_WINDOW(blist->window));
	}
}

static gint
pidgin_application_command_line(GApplication *application,
                                GApplicationCommandLine *cmdline)
{
	gchar **argv = NULL;
	gint argc = 0, i = 0;

	argv = g_application_command_line_get_arguments(cmdline, &argc);

	if(argc == 1) {
		/* No arguments, just activate */
		g_application_activate(application);
	}

	/* Start at 1 to skip the executable name */
	for (i = 1; i < argc; i++) {
		purple_got_protocol_handler_uri(argv[i]);
	}

	g_strfreev(argv);

	return 0;
}

static gint
pidgin_application_handle_local_options(GApplication *application,
                                        GVariantDict *options)
{
	if (g_variant_dict_contains(options, "version")) {
		printf("%s %s (libpurple %s)\n", PIDGIN_NAME, DISPLAY_VERSION,
		       purple_core_get_version());

		return 0;
	}

	return -1;
}

/******************************************************************************
 * GObject Implementation
 *****************************************************************************/
static void
pidgin_application_init(PidginApplication *application) {
	GApplication *gapp = G_APPLICATION(application);

	g_application_add_main_option_entries(gapp, option_entries);
	g_application_add_option_group(gapp, purple_get_option_group());
	g_application_add_option_group(gapp, gplugin_get_option_group());
}

static void
pidgin_application_class_init(PidginApplicationClass *klass) {
	GApplicationClass *app_class = G_APPLICATION_CLASS(klass);

	app_class->startup = pidgin_application_startup;
	app_class->activate = pidgin_application_activate;
	app_class->command_line = pidgin_application_command_line;
	app_class->handle_local_options = pidgin_application_handle_local_options;
}

/******************************************************************************
 * Public API
 *****************************************************************************/
GApplication *
pidgin_application_new(void) {
	return g_object_new(
		PIDGIN_TYPE_APPLICATION,
		"flags", G_APPLICATION_CAN_OVERRIDE_APP_ID |
		         G_APPLICATION_HANDLES_COMMAND_LINE,
		"register-session", TRUE,
		NULL);
}

mercurial