/** * 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 . */ #include #define WNCK_I_KNOW_THIS_IS_UNSTABLE #include #include #include #include #include #include #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; } } }