summaryrefslogtreecommitdiff
path: root/devilspie/config.c
diff options
context:
space:
mode:
Diffstat (limited to 'devilspie/config.c')
-rw-r--r--devilspie/config.c282
1 files changed, 282 insertions, 0 deletions
diff --git a/devilspie/config.c b/devilspie/config.c
new file mode 100644
index 0000000..029dad7
--- /dev/null
+++ b/devilspie/config.c
@@ -0,0 +1,282 @@
+/**
+ * This file is part of devilspie2
+ * Copyright (C) 2013-2017 Andreas Rönnquist
+ *
+ * devilspie2 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * devilspie2 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 devilspie2.
+ * If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <glib.h>
+
+#define WNCK_I_KNOW_THIS_IS_UNSTABLE
+#include <libwnck/libwnck.h>
+
+#include <glib/gi18n.h>
+
+#include <locale.h>
+
+
+#include <lua.h>
+#include <lualib.h>
+#include <lauxlib.h>
+
+#include "script.h"
+#include "script_functions.h"
+
+#include "config.h"
+
+/**
+ *
+ */
+GSList *event_lists[W_NUM_EVENTS] = { NULL, NULL, NULL, NULL, NULL };
+const char *const event_names[W_NUM_EVENTS] = {
+ "window_open",
+ "window_close",
+ "window_focus",
+ "window_blur",
+ "window_name_change",
+};
+
+
+/**
+ * filename_list_sortfunc
+ * function to sort the inserted filenames, to be able to determine
+ * which order files are loaded.
+ */
+static gint filename_list_sortfunc(gconstpointer a,gconstpointer b)
+{
+ gchar *file1 = (gchar*)a;
+ gchar *file2 = (gchar*)b;
+
+ return g_ascii_strcasecmp(file1, file2);
+}
+
+
+/**
+ *
+ */
+static GSList *add_lua_file_to_list(GSList *list, gchar *filename)
+{
+ gchar *temp_filename = g_strdup(filename);
+
+ list=g_slist_insert_sorted(list,
+ temp_filename,
+ filename_list_sortfunc);
+
+ return list;
+}
+
+
+
+/**
+ *
+ */
+static GSList *get_table_of_strings(lua_State *luastate,
+ gchar *script_folder,
+ gchar *table_name)
+{
+ GSList *list = NULL;
+
+ if (luastate) {
+
+ lua_getglobal(luastate, table_name);
+
+ // Do we have a value?
+ if (lua_isnil(luastate, -1)) {
+ goto EXITPOINT;
+ }
+
+ // Is it a table?
+ if (!lua_istable(luastate, -1)) {
+ goto EXITPOINT;
+ }
+
+ lua_pushnil(luastate);
+
+ while(lua_next(luastate, -2)) {
+ if (lua_isstring(luastate, -1)) {
+ char *temp = (char *)lua_tostring(luastate, -1);
+
+ gchar *added_filename = g_build_path(G_DIR_SEPARATOR_S,
+ script_folder,
+ temp,
+ NULL);
+
+ list = add_lua_file_to_list(list, added_filename);
+ }
+ lua_pop(luastate, 1);
+ }
+ lua_pop(luastate, 1);
+ }
+
+EXITPOINT:
+
+ return list;
+}
+
+
+/**
+ * is_in_list
+ * Go through _one_ list, and check if the filename is in this list
+ */
+static gboolean is_in_list(GSList *list, gchar *filename)
+{
+ gboolean result = FALSE;
+
+ if (list) {
+ GSList *temp_list = list;
+
+ while (temp_list) {
+ gchar *list_filename = (gchar*)temp_list->data;
+ if (list_filename) {
+
+ if (g_ascii_strcasecmp(list_filename, filename) == 0) {
+ result = TRUE;
+ }
+ }
+ temp_list = temp_list->next;
+ }
+ }
+
+ return result;
+}
+
+
+/**
+ * is_in_any_list
+ * Go through our lists, and check if the file is already in any of them
+ */
+static gboolean is_in_any_list(gchar *filename)
+{
+ win_event_type i;
+
+ for (i=0; i < W_NUM_EVENTS; i++) {
+ if (is_in_list(event_lists[i], filename))
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+
+/**
+ * load_config
+ * Load configuration from a file - From this we set up the lists of files
+ * which decides what script to load on what wnck event.
+ */
+int load_config(gchar *filename)
+{
+ lua_State *config_lua_state = NULL;
+ int result = 0;
+ const gchar *current_file = NULL;
+ GSList *temp_window_open_file_list = NULL;
+
+ // First get list of Lua files in folder - Then read variables from
+ // devilspie2.lua and put the files in the required lists.
+
+ gchar *script_folder = g_path_get_dirname(filename);
+
+ GDir *dir = g_dir_open(script_folder, 0, NULL);
+ if (!g_file_test(script_folder, G_FILE_TEST_IS_DIR)) {
+
+ printf("%s\n", _("script_folder isn't a folder."));
+ return -1;
+ }
+
+ int total_number_of_files = 0;
+
+ config_lua_state = init_script();
+
+ if (g_file_test(filename, G_FILE_TEST_EXISTS)) {
+
+ if (run_script(config_lua_state, filename) != 0) {
+ printf(_("Error: %s\n"), filename);
+ result = -1;
+ goto EXITPOINT;
+ }
+
+ event_lists[W_CLOSE] = get_table_of_strings(config_lua_state,
+ script_folder,
+ "scripts_window_close");
+ event_lists[W_FOCUS] = get_table_of_strings(config_lua_state,
+ script_folder,
+ "scripts_window_focus");
+ event_lists[W_BLUR] = get_table_of_strings(config_lua_state,
+ script_folder,
+ "scripts_window_blur");
+ event_lists[W_NAME_CHANGED] = get_table_of_strings(config_lua_state,
+ script_folder,
+ "scripts_window_name_change");
+ }
+
+ // add the files in the folder to our linked list
+ while ((current_file = g_dir_read_name(dir))) {
+
+ gchar *temp_filename = g_build_path(G_DIR_SEPARATOR_S,
+ script_folder,
+ current_file,
+ NULL);
+
+ // we only bother with *.lua in the folder
+ // we also ignore dot files
+ if (current_file[0] != '.' && g_str_has_suffix(current_file, ".lua")) {
+ if (!is_in_any_list(temp_filename)) {
+ temp_window_open_file_list =
+ add_lua_file_to_list(temp_window_open_file_list, temp_filename);
+ }
+ total_number_of_files++;
+ }
+
+ g_free(temp_filename);
+ }
+
+ event_lists[W_OPEN] = temp_window_open_file_list;
+EXITPOINT:
+ if (config_lua_state)
+ done_script(config_lua_state);
+
+ return result;
+}
+
+
+
+/**
+ *
+ */
+static void unallocate_file_list(GSList *file_list)
+{
+ if (file_list) {
+ while(file_list) {
+ g_free ((gchar*)file_list->data);
+ file_list = file_list->next;
+ }
+ }
+}
+
+
+/**
+ *
+ */
+void clear_file_lists()
+{
+ win_event_type i = 0;
+
+ for (i = 0; i < W_NUM_EVENTS; i++) {
+ if (event_lists[i]) {
+ unallocate_file_list(event_lists[i]);
+ g_slist_free(event_lists[i]);
+ event_lists[i] = NULL;
+ }
+ }
+}