diff options
author | Dave Davenport <qball@blame.services> | 2022-02-23 23:18:53 +0100 |
---|---|---|
committer | Dave Davenport <qball@blame.services> | 2022-02-23 23:18:53 +0100 |
commit | 534aa6ad5439809f46b0fece92c7923dcd2b9e8f (patch) | |
tree | 4ab2708087c8da50108c688a60d398f5b6ea7f31 /source/dialogs | |
parent | 32d33ade16c3b962b4957c37edf114476cdd22ce (diff) |
Rename Dialogs -> Modes
Try to fix some of old syntax.
Diffstat (limited to 'source/dialogs')
-rw-r--r-- | source/dialogs/combi.c | 336 | ||||
-rw-r--r-- | source/dialogs/dmenu.c | 827 | ||||
-rw-r--r-- | source/dialogs/drun.c | 1490 | ||||
-rw-r--r-- | source/dialogs/filebrowser.c | 668 | ||||
-rw-r--r-- | source/dialogs/help-keys.c | 121 | ||||
-rw-r--r-- | source/dialogs/run.c | 589 | ||||
-rw-r--r-- | source/dialogs/script.c | 468 | ||||
-rw-r--r-- | source/dialogs/ssh.c | 649 | ||||
-rw-r--r-- | source/dialogs/window.c | 1079 |
9 files changed, 0 insertions, 6227 deletions
diff --git a/source/dialogs/combi.c b/source/dialogs/combi.c deleted file mode 100644 index 27fc4a3a..00000000 --- a/source/dialogs/combi.c +++ /dev/null @@ -1,336 +0,0 @@ -/* - * rofi - * - * MIT/X11 License - * Copyright © 2013-2022 Qball Cow <qball@gmpclient.org> - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -/** The log domain of this dialog. */ -#define G_LOG_DOMAIN "Dialogs.Combi" - -#include "helper.h" -#include "settings.h" -#include <rofi.h> -#include <stdio.h> -#include <stdlib.h> - -#include "mode-private.h" -#include "widgets/textbox.h" -#include <dialogs/dialogs.h> -#include <pango/pango.h> -#include <theme.h> - -/** - * Combi Mode - */ -typedef struct { - Mode *mode; - gboolean disable; -} CombiMode; - -typedef struct { - // List of (combined) entries. - unsigned int cmd_list_length; - // List to validate where each switcher starts. - unsigned int *starts; - unsigned int *lengths; - // List of switchers to combine. - unsigned int num_switchers; - CombiMode *switchers; -} CombiModePrivateData; - -static void combi_mode_parse_switchers(Mode *sw) { - CombiModePrivateData *pd = mode_get_private_data(sw); - char *savept = NULL; - // Make a copy, as strtok will modify it. - char *switcher_str = g_strdup(config.combi_modes); - const char *const sep = ",#"; - // Split token on ','. This modifies switcher_str. - for (char *token = strtok_r(switcher_str, sep, &savept); token != NULL; - token = strtok_r(NULL, sep, &savept)) { - /* Check against recursion. */ - if (g_strcmp0(token, sw->name) == 0) { - g_warning("You cannot add '%s' to the list of combined modes.", sw->name); - continue; - } - // Resize and add entry. - pd->switchers = (CombiMode *)g_realloc( - pd->switchers, sizeof(CombiMode) * (pd->num_switchers + 1)); - - Mode *mode = rofi_collect_modes_search(token); - if (mode != NULL) { - pd->switchers[pd->num_switchers].disable = FALSE; - pd->switchers[pd->num_switchers++].mode = mode; - continue; - } - // If not build in, use custom switchers. - mode = script_mode_parse_setup(token); - if (mode != NULL) { - pd->switchers[pd->num_switchers].disable = FALSE; - pd->switchers[pd->num_switchers++].mode = mode; - continue; - } - // Report error, don't continue. - g_warning("Invalid script switcher: %s", token); - token = NULL; - } - // Free string that was modified by strtok_r - g_free(switcher_str); -} -static unsigned int combi_mode_get_num_entries(const Mode *sw) { - const CombiModePrivateData *pd = - (const CombiModePrivateData *)mode_get_private_data(sw); - unsigned int length = 0; - for (unsigned int i = 0; i < pd->num_switchers; i++) { - unsigned int entries = mode_get_num_entries(pd->switchers[i].mode); - pd->starts[i] = length; - pd->lengths[i] = entries; - length += entries; - } - return length; -} - -static int combi_mode_init(Mode *sw) { - if (mode_get_private_data(sw) == NULL) { - CombiModePrivateData *pd = g_malloc0(sizeof(*pd)); - mode_set_private_data(sw, (void *)pd); - combi_mode_parse_switchers(sw); - pd->starts = g_malloc0(sizeof(int) * pd->num_switchers); - pd->lengths = g_malloc0(sizeof(int) * pd->num_switchers); - for (unsigned int i = 0; i < pd->num_switchers; i++) { - if (!mode_init(pd->switchers[i].mode)) { - return FALSE; - } - } - if (pd->cmd_list_length == 0) { - pd->cmd_list_length = combi_mode_get_num_entries(sw); - } - } - return TRUE; -} -static void combi_mode_destroy(Mode *sw) { - CombiModePrivateData *pd = (CombiModePrivateData *)mode_get_private_data(sw); - if (pd != NULL) { - g_free(pd->starts); - g_free(pd->lengths); - // Cleanup switchers. - for (unsigned int i = 0; i < pd->num_switchers; i++) { - mode_destroy(pd->switchers[i].mode); - } - g_free(pd->switchers); - g_free(pd); - mode_set_private_data(sw, NULL); - } -} -static ModeMode combi_mode_result(Mode *sw, int mretv, char **input, - unsigned int selected_line) { - CombiModePrivateData *pd = mode_get_private_data(sw); - - if (input[0][0] == '!') { - int switcher = -1; - // Implement strchrnul behaviour. - char *eob = g_utf8_strchr(input[0], -1, ' '); - if (eob == NULL) { - eob = &(input[0][strlen(input[0])]); - } - ssize_t bang_len = g_utf8_pointer_to_offset(input[0], eob) - 1; - if (bang_len > 0) { - for (unsigned i = 0; i < pd->num_switchers; i++) { - const char *mode_name = mode_get_name(pd->switchers[i].mode); - size_t mode_name_len = g_utf8_strlen(mode_name, -1); - if ((size_t)bang_len <= mode_name_len && - utf8_strncmp(&input[0][1], mode_name, bang_len) == 0) { - switcher = i; - break; - } - } - } - if (switcher >= 0) { - if (eob[0] == ' ') { - char *n = eob + 1; - return mode_result(pd->switchers[switcher].mode, mretv, &n, - selected_line - pd->starts[switcher]); - } - return MODE_EXIT; - } - } else if ((mretv & MENU_COMPLETE)) { - return RELOAD_DIALOG; - } - - for (unsigned i = 0; i < pd->num_switchers; i++) { - if (selected_line >= pd->starts[i] && - selected_line < (pd->starts[i] + pd->lengths[i])) { - return mode_result(pd->switchers[i].mode, mretv, input, - selected_line - pd->starts[i]); - } - } - if ((mretv & MENU_CUSTOM_INPUT)) { - return mode_result(pd->switchers[0].mode, mretv, input, selected_line); - } - return MODE_EXIT; -} -static int combi_mode_match(const Mode *sw, rofi_int_matcher **tokens, - unsigned int index) { - CombiModePrivateData *pd = mode_get_private_data(sw); - for (unsigned i = 0; i < pd->num_switchers; i++) { - if (pd->switchers[i].disable) { - continue; - } - if (index >= pd->starts[i] && index < (pd->starts[i] + pd->lengths[i])) { - return mode_token_match(pd->switchers[i].mode, tokens, - index - pd->starts[i]); - } - } - return 0; -} -static char *combi_mgrv(const Mode *sw, unsigned int selected_line, int *state, - GList **attr_list, int get_entry) { - CombiModePrivateData *pd = mode_get_private_data(sw); - if (!get_entry) { - for (unsigned i = 0; i < pd->num_switchers; i++) { - if (selected_line >= pd->starts[i] && - selected_line < (pd->starts[i] + pd->lengths[i])) { - mode_get_display_value(pd->switchers[i].mode, - selected_line - pd->starts[i], state, attr_list, - FALSE); - return NULL; - } - } - return NULL; - } - for (unsigned i = 0; i < pd->num_switchers; i++) { - if (selected_line >= pd->starts[i] && - selected_line < (pd->starts[i] + pd->lengths[i])) { - char *retv; - char *str = retv = mode_get_display_value(pd->switchers[i].mode, - selected_line - pd->starts[i], - state, attr_list, TRUE); - const char *dname = mode_get_display_name(pd->switchers[i].mode); - - if (!config.combi_hide_mode_prefix) { - if (!(*state & MARKUP)) { - char *tmp = str; - str = g_markup_escape_text(tmp, -1); - g_free(tmp); - *state |= MARKUP; - } - - retv = helper_string_replace_if_exists( - config.combi_display_format, "{mode}", dname, "{text}", str, NULL); - g_free(str); - - if (attr_list != NULL) { - ThemeWidget *wid = rofi_config_find_widget(sw->name, NULL, TRUE); - Property *p = rofi_theme_find_property( - wid, P_COLOR, pd->switchers[i].mode->name, TRUE); - if (p != NULL) { - PangoAttribute *pa = pango_attr_foreground_new( - p->value.color.red * 65535, p->value.color.green * 65535, - p->value.color.blue * 65535); - pa->start_index = PANGO_ATTR_INDEX_FROM_TEXT_BEGINNING; - pa->end_index = strlen(dname); - *attr_list = g_list_append(*attr_list, pa); - } - } - } - return retv; - } - } - - return NULL; -} -static char *combi_get_completion(const Mode *sw, unsigned int index) { - CombiModePrivateData *pd = mode_get_private_data(sw); - for (unsigned i = 0; i < pd->num_switchers; i++) { - if (index >= pd->starts[i] && index < (pd->starts[i] + pd->lengths[i])) { - char *comp = - mode_get_completion(pd->switchers[i].mode, index - pd->starts[i]); - char *mcomp = - g_strdup_printf("!%s %s", mode_get_name(pd->switchers[i].mode), comp); - g_free(comp); - return mcomp; - } - } - // Should never get here. - g_assert_not_reached(); - return NULL; -} - -static cairo_surface_t *combi_get_icon(const Mode *sw, unsigned int index, - int height) { - CombiModePrivateData *pd = mode_get_private_data(sw); - for (unsigned i = 0; i < pd->num_switchers; i++) { - if (index >= pd->starts[i] && index < (pd->starts[i] + pd->lengths[i])) { - cairo_surface_t *icon = - mode_get_icon(pd->switchers[i].mode, index - pd->starts[i], height); - return icon; - } - } - return NULL; -} - -static char *combi_preprocess_input(Mode *sw, const char *input) { - CombiModePrivateData *pd = mode_get_private_data(sw); - for (unsigned i = 0; i < pd->num_switchers; i++) { - pd->switchers[i].disable = FALSE; - } - if (input != NULL && input[0] == '!') { - // Implement strchrnul behaviour. - const char *eob = g_utf8_strchr(input, -1, ' '); - if (eob == NULL) { - // Set it to end. - eob = &(input[strlen(input)]); - } - ssize_t bang_len = g_utf8_pointer_to_offset(input, eob) - 1; - if (bang_len > 0) { - for (unsigned i = 0; i < pd->num_switchers; i++) { - const char *mode_name = mode_get_name(pd->switchers[i].mode); - size_t mode_name_len = g_utf8_strlen(mode_name, -1); - if (!((size_t)bang_len <= mode_name_len && - utf8_strncmp(&input[1], mode_name, bang_len) == 0)) { - // No match. - pd->switchers[i].disable = TRUE; - } - } - if (eob[0] == '\0' || eob[1] == '\0') { - return NULL; - } - return g_strdup(eob + 1); - } - } - return g_strdup(input); -} - -Mode combi_mode = {.name = "combi", - .cfg_name_key = "display-combi", - ._init = combi_mode_init, - ._get_num_entries = combi_mode_get_num_entries, - ._result = combi_mode_result, - ._destroy = combi_mode_destroy, - ._token_match = combi_mode_match, - ._get_completion = combi_get_completion, - ._get_display_value = combi_mgrv, - ._get_icon = combi_get_icon, - ._preprocess_input = combi_preprocess_input, - .private_data = NULL, - .free = NULL}; diff --git a/source/dialogs/dmenu.c b/source/dialogs/dmenu.c deleted file mode 100644 index 5ca6d353..00000000 --- a/source/dialogs/dmenu.c +++ /dev/null @@ -1,827 +0,0 @@ -/* - * rofi - * - * MIT/X11 License - * Copyright © 2013-2022 Qball Cow <qball@gmpclient.org> - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -/** The log domain of this dialog. */ -#define G_LOG_DOMAIN "Dialogs.DMenu" - -#include "dialogs/dmenu.h" -#include "helper.h" -#include "rofi-icon-fetcher.h" -#include "rofi.h" -#include "settings.h" -#include "view.h" -#include "widgets/textbox.h" -#include "xrmoptions.h" -#include <ctype.h> -#include <errno.h> -#include <fcntl.h> -#include <gio/gio.h> -#include <gio/gunixinputstream.h> -#include <stdint.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <strings.h> -#include <sys/stat.h> -#include <sys/types.h> -#include <unistd.h> - -#include "dialogs/dmenuscriptshared.h" - -static int dmenu_mode_init(Mode *sw); -static int dmenu_token_match(const Mode *sw, rofi_int_matcher **tokens, - unsigned int index); -static cairo_surface_t *dmenu_get_icon(const Mode *sw, - unsigned int selected_line, int height); -static char *dmenu_get_message(const Mode *sw); - -static inline unsigned int bitget(uint32_t *array, unsigned int index) { - uint32_t bit = index % 32; - uint32_t val = array[index / 32]; - return (val >> bit) & 1; -} - -static inline void bittoggle(uint32_t *array, unsigned int index) { - uint32_t bit = index % 32; - uint32_t *v = &array[index / 32]; - *v ^= 1 << bit; -} - -typedef struct { - /** Settings */ - // Separator. - char separator; - - unsigned int selected_line; - char *message; - char *format; - struct rofi_range_pair *urgent_list; - unsigned int num_urgent_list; - struct rofi_range_pair *active_list; - unsigned int num_active_list; - uint32_t *selected_list; - unsigned int num_selected_list; - unsigned int do_markup; - // List with entries. - DmenuScriptEntry *cmd_list; - unsigned int cmd_list_real_length; - unsigned int cmd_list_length; - unsigned int only_selected; - unsigned int selected_count; - - gchar **columns; - gchar *column_separator; - gboolean multi_select; - - GCancellable *cancel; - gulong cancel_source; - GInputStream *input_stream; - GDataInputStream *data_input_stream; -} DmenuModePrivateData; - -static void async_close_callback(GObject *source_object, GAsyncResult *res, - G_GNUC_UNUSED gpointer user_data) { - g_input_stream_close_finish(G_INPUT_STREAM(source_object), res, NULL); - g_debug("Closing data stream."); -} - -static void read_add(DmenuModePrivateData *pd, char *data, gsize len) { - gsize data_len = len; - if ((pd->cmd_list_length + 2) > pd->cmd_list_real_length) { - pd->cmd_list_real_length = MAX(pd->cmd_list_real_length * 2, 512); - pd->cmd_list = g_realloc(pd->cmd_list, (pd->cmd_list_real_length) * - sizeof(DmenuScriptEntry)); - } - // Init. - pd->cmd_list[pd->cmd_list_length].icon_fetch_uid = 0; - pd->cmd_list[pd->cmd_list_length].icon_name = NULL; - pd->cmd_list[pd->cmd_list_length].meta = NULL; - pd->cmd_list[pd->cmd_list_length].info = NULL; - pd->cmd_list[pd->cmd_list_length].nonselectable = FALSE; - char *end = data; - while (end < data + len && *end != '\0') { - end++; - } - if (end != data + len) { - data_len = end - data; - dmenuscript_parse_entry_extras(NULL, &(pd->cmd_list[pd->cmd_list_length]), - end + 1, len - data_len); - } - char *utfstr = rofi_force_utf8(data, data_len); - pd->cmd_list[pd->cmd_list_length].entry = utfstr; - pd->cmd_list[pd->cmd_list_length + 1].entry = NULL; - - pd->cmd_list_length++; -} -static void async_read_callback(GObject *source_object, GAsyncResult *res, - gpointer user_data) { - GDataInputStream *stream = (GDataInputStream *)source_object; - DmenuModePrivateData *pd = (DmenuModePrivateData *)user_data; - gsize len; - char *data = g_data_input_stream_read_upto_finish(stream, res, &len, NULL); - if (data != NULL) { - // Absorb separator, already in buffer so should not block. - g_data_input_stream_read_byte(stream, NULL, NULL); - read_add(pd, data, len); - g_free(data); - rofi_view_reload(); - - g_data_input_stream_read_upto_async(pd->data_input_stream, &(pd->separator), - 1, G_PRIORITY_LOW, pd->cancel, - async_read_callback, pd); - return; - } else { - GError *error = NULL; - // Absorb separator, already in buffer so should not block. - // If error == NULL end of stream.. - g_data_input_stream_read_byte(stream, NULL, &error); - if (error == NULL) { - // Add empty line. - read_add(pd, "", 0); - rofi_view_reload(); - - g_data_input_stream_read_upto_async(pd->data_input_stream, - &(pd->separator), 1, G_PRIORITY_LOW, - pd->cancel, async_read_callback, pd); - return; - } - g_error_free(error); - } - if (!g_cancellable_is_cancelled(pd->cancel)) { - // Hack, don't use get active. - g_debug("Clearing overlay"); - rofi_view_set_overlay(rofi_view_get_active(), NULL); - g_input_stream_close_async(G_INPUT_STREAM(stream), G_PRIORITY_LOW, - pd->cancel, async_close_callback, pd); - } -} - -static void async_read_cancel(G_GNUC_UNUSED GCancellable *cancel, - G_GNUC_UNUSED gpointer data) { - g_debug("Cancelled the async read."); -} - -static int get_dmenu_async(DmenuModePrivateData *pd, int sync_pre_read) { - while (sync_pre_read--) { - gsize len = 0; - char *data = g_data_input_stream_read_upto( - pd->data_input_stream, &(pd->separator), 1, &len, NULL, NULL); - if (data == NULL) { - g_input_stream_close_async(G_INPUT_STREAM(pd->input_stream), - G_PRIORITY_LOW, pd->cancel, - async_close_callback, pd); - return FALSE; - } - g_data_input_stream_read_byte(pd->data_input_stream, NULL, NULL); - read_add(pd, data, len); - g_free(data); - } - g_data_input_stream_read_upto_async(pd->data_input_stream, &(pd->separator), - 1, G_PRIORITY_LOW, pd->cancel, - async_read_callback, pd); - return TRUE; -} -static void get_dmenu_sync(DmenuModePrivateData *pd) { - while (TRUE) { - gsize len = 0; - char *data = g_data_input_stream_read_upto( - pd->data_input_stream, &(pd->separator), 1, &len, NULL, NULL); - if (data == NULL) { - break; - } - g_data_input_stream_read_byte(pd->data_input_stream, NULL, NULL); - read_add(pd, data, len); - g_free(data); - } - g_input_stream_close_async(G_INPUT_STREAM(pd->input_stream), G_PRIORITY_LOW, - pd->cancel, async_close_callback, pd); -} - -static unsigned int dmenu_mode_get_num_entries(const Mode *sw) { - const DmenuModePrivateData *rmpd = - (const DmenuModePrivateData *)mode_get_private_data(sw); - return rmpd->cmd_list_length; -} - -static gchar *dmenu_format_output_string(const DmenuModePrivateData *pd, - const char *input) { - if (pd->columns == NULL) { - return g_strdup(input); - } - char *retv = NULL; - char **splitted = - g_regex_split_simple(pd->column_separator, input, G_REGEX_CASELESS, 00); - uint32_t ns = 0; - for (; splitted && splitted[ns]; ns++) { - ; - } - GString *str_retv = g_string_new(""); - for (uint32_t i = 0; pd->columns && pd->columns[i]; i++) { - unsigned int index = - (unsigned int)g_ascii_strtoull(pd->columns[i], NULL, 10); - if (index <= ns && index > 0) { - if (index == 1) { - g_string_append(str_retv, splitted[index - 1]); - } else { - g_string_append_c(str_retv, '\t'); - g_string_append(str_retv, splitted[index - 1]); - } - } - } - g_strfreev(splitted); - retv = str_retv->str; - g_string_free(str_retv, FALSE); - return retv; -} - -static inline unsigned int get_index(unsigned int length, int index) { - if (index >= 0) { - return index; - } - if (((unsigned int)-index) <= length) { - return length + index; - } - // Out of range. - return UINT_MAX; -} - -static char *get_display_data(const Mode *data, unsigned int index, int *state, - G_GNUC_UNUSED GList **list, int get_entry) { - Mode *sw = (Mode *)data; - DmenuModePrivateData *pd = (DmenuModePrivateData *)mode_get_private_data(sw); - DmenuScriptEntry *retv = (DmenuScriptEntry *)pd->cmd_list; - for (unsigned int i = 0; i < pd->num_active_list; i++) { - unsigned int start = - get_index(pd->cmd_list_length, pd->active_list[i].start); - unsigned int stop = get_index(pd->cmd_list_length, pd->active_list[i].stop); - if (index >= start && index <= stop) { - *state |= ACTIVE; - } - } - for (unsigned int i = 0; i < pd->num_urgent_list; i++) { - unsigned int start = - get_index(pd->cmd_list_length, pd->urgent_list[i].start); - unsigned int stop = get_index(pd->cmd_list_length, pd->urgent_list[i].stop); - if (index >= start && index <= stop) { - *state |= URGENT; - } - } - if (pd->selected_list && bitget(pd->selected_list, index) == TRUE) { - *state |= SELECTED; - } - if (pd->do_markup) { - *state |= MARKUP; - } - return get_entry ? dmenu_format_output_string(pd, retv[index].entry) : NULL; -} - -static void dmenu_mode_free(Mode *sw) { - if (mode_get_private_data(sw) == NULL) { - return; - } - DmenuModePrivateData *pd = (DmenuModePrivateData *)mode_get_private_data(sw); - if (pd != NULL) { - if (pd->cancel) { - // If open, cancel reads. - if (pd->input_stream && !g_input_stream_is_closed(pd->input_stream)) { - g_cancellable_cancel(pd->cancel); - } - // This blocks until cancel is done. - g_cancellable_disconnect(pd->cancel, pd->cancel_source); - if (pd->input_stream) { - // Should close the stream if not yet done. - g_object_unref(pd->data_input_stream); - g_object_unref(pd->input_stream); - } - g_object_unref(pd->cancel); - } - - for (size_t i = 0; i < pd->cmd_list_length; i++) { - if (pd->cmd_list[i].entry) { - g_free(pd->cmd_list[i].entry); - g_free(pd->cmd_list[i].icon_name); - g_free(pd->cmd_list[i].meta); - g_free(pd->cmd_list[i].info); - } - } - g_free(pd->cmd_list); - g_free(pd->urgent_list); - g_free(pd->active_list); - g_free(pd->selected_list); - - g_free(pd); - mode_set_private_data(sw, NULL); - } -} - -#include "mode-private.h" -/** dmenu Mode object. */ -Mode dmenu_mode = {.name = "dmenu", - .cfg_name_key = "display-combi", - ._init = dmenu_mode_init, - ._get_num_entries = dmenu_mode_get_num_entries, - ._result = NULL, - ._destroy = dmenu_mode_free, - ._token_match = dmenu_token_match, - ._get_display_value = get_display_data, - ._get_icon = dmenu_get_icon, - ._get_completion = NULL, - ._preprocess_input = NULL, - ._get_message = dmenu_get_message, - .private_data = NULL, - .free = NULL, - .display_name = "dmenu"}; - -static int dmenu_mode_init(Mode *sw) { - if (mode_get_private_data(sw) != NULL) { - return TRUE; - } - mode_set_private_data(sw, g_malloc0(sizeof(DmenuModePrivateData))); - DmenuModePrivateData *pd = (DmenuModePrivateData *)mode_get_private_data(sw); - - pd->separator = '\n'; - pd->selected_line = UINT32_MAX; - - find_arg_str("-mesg", &(pd->message)); - - // Input data separator. - find_arg_char("-sep", &(pd->separator)); - - find_arg_uint("-selected-row", &(pd->selected_line)); - // By default we print the unescaped line back. - pd->format = "s"; - - // Allow user to override the output format. - find_arg_str("-format", &(pd->format)); - // Urgent. - char *str = NULL; - find_arg_str("-u", &str); - if (str != NULL) { - parse_ranges(str, &(pd->urgent_list), &(pd->num_urgent_list)); - } - // Active - str = NULL; - find_arg_str("-a", &str); - if (str != NULL) { - parse_ranges(str, &(pd->active_list), &(pd->num_active_list)); - } - - // DMENU COMPATIBILITY - unsigned int lines = DEFAULT_MENU_LINES; - find_arg_uint("-l", &(lines)); - if (lines != DEFAULT_MENU_LINES) { - Property *p = rofi_theme_property_create(P_INTEGER); - p->name = g_strdup("lines"); - p->value.i = lines; - ThemeWidget *widget = - rofi_theme_find_or_create_name(rofi_theme, "listview"); - GHashTable *table = - g_hash_table_new_full(g_str_hash, g_str_equal, NULL, - (GDestroyNotify)rofi_theme_property_free); - - g_hash_table_replace(table, p->name, p); - rofi_theme_widget_add_properties(widget, table); - g_hash_table_destroy(table); - } - - str = NULL; - find_arg_str("-window-title", &str); - if (str) { - dmenu_mode.display_name = str; - } - - /** - * Dmenu compatibility. - * `-b` put on bottom. - */ - if (find_arg("-b") >= 0) { - config.location = 6; - } - /* -i case insensitive */ - config.case_sensitive = TRUE; - if (find_arg("-i") >= 0) { - config.case_sensitive = FALSE; - } - int fd = STDIN_FILENO; - str = NULL; - if (find_arg_str("-input", &str)) { - char *estr = rofi_expand_path(str); - fd = open(str, O_RDONLY); - if (fd < 0) { - char *msg = g_markup_printf_escaped( - "Failed to open file: <b>%s</b>:\n\t<i>%s</i>", estr, - g_strerror(errno)); - rofi_view_error_dialog(msg, TRUE); - g_free(msg); - g_free(estr); - return TRUE; - } - g_free(estr); - } - // If input is stdin, and a tty, do not read as rofi grabs input and therefore - // blocks. - if (!(fd == STDIN_FILENO && isatty(fd) == 1)) { - pd->cancel = g_cancellable_new(); - pd->cancel_source = g_cancellable_connect( - pd->cancel, G_CALLBACK(async_read_cancel), pd, NULL); - pd->input_stream = g_unix_input_stream_new(fd, fd != STDIN_FILENO); - pd->data_input_stream = g_data_input_stream_new(pd->input_stream); - } - gchar *columns = NULL; - if (find_arg_str("-display-columns", &columns)) { - pd->columns = g_strsplit(columns, ",", 0); - pd->column_separator = "\t"; - find_arg_str("-display-column-separator", &pd->column_separator); - } - return TRUE; -} - -static int dmenu_token_match(const Mode *sw, rofi_int_matcher **tokens, - unsigned int index) { - DmenuModePrivateData *rmpd = - (DmenuModePrivateData *)mode_get_private_data(sw); - /** Strip out the markup when matching. */ - char *esc = NULL; - if (rmpd->do_markup) { - pango_parse_markup(rmpd->cmd_list[index].entry, -1, 0, NULL, &esc, NULL, - NULL); - } else { - esc = rmpd->cmd_list[index].entry; - } - if (esc) { - // int retv = helper_token_match ( tokens, esc ); - int match = 1; - if (tokens) { - for (int j = 0; match && tokens != NULL && tokens[j] != NULL; j++) { - rofi_int_matcher *ftokens[2] = {tokens[j], NULL}; - int test = 0; - test = helper_token_match(ftokens, esc); - if (test == tokens[j]->invert && rmpd->cmd_list[index].meta) { - test = helper_token_match(ftokens, rmpd->cmd_list[index].meta); - } - - if (test == 0) { - match = 0; - } - } - } - if (rmpd->do_markup) { - g_free(esc); - } - return match; - } - return FALSE; -} -static char *dmenu_get_message(const Mode *sw) { - DmenuModePrivateData *pd = (DmenuModePrivateData *)mode_get_private_data(sw); - if (pd->message) { - return g_strdup(pd->message); - } - return NULL; -} -static cairo_surface_t *dmenu_get_icon(const Mode *sw, - unsigned int selected_line, int height) { - DmenuModePrivateData *pd = (DmenuModePrivateData *)mode_get_private_data(sw); - g_return_val_if_fail(pd->cmd_list != NULL, NULL); - DmenuScriptEntry *dr = &(pd->cmd_list[selected_line]); - if (dr->icon_name == NULL) { - return NULL; - } - if (dr->icon_fetch_uid > 0) { - return rofi_icon_fetcher_get(dr->icon_fetch_uid); - } - dr->icon_fetch_uid = rofi_icon_fetcher_query(dr->icon_name, height); - return rofi_icon_fetcher_get(dr->icon_fetch_uid); -} - -static void dmenu_finish(RofiViewState *state, int retv) { - if (retv == FALSE) { - rofi_set_return_code(EXIT_FAILURE); - } else if (retv >= 10) { - rofi_set_return_code(retv); - } else { - rofi_set_return_code(EXIT_SUCCESS); - } - rofi_view_set_active(NULL); - rofi_view_free(state); - mode_destroy(&dmenu_mode); -} - -static void dmenu_print_results(DmenuModePrivateData *pd, const char *input) { - DmenuScriptEntry *cmd_list = pd->cmd_list; - int seen = FALSE; - if (pd->selected_list != NULL) { - for (unsigned int st = 0; st < pd->cmd_list_length; st++) { - if (bitget(pd->selected_list, st)) { - seen = TRUE; - rofi_output_formatted_line(pd->format, cmd_list[st].entry, st, input); - } - } - } - if (!seen) { - const char *cmd = input; - if (pd->selected_line != UINT32_MAX) { - cmd = cmd_list[pd->selected_line].entry; - } - if (cmd) { - rofi_output_formatted_line(pd->format, cmd, pd->selected_line, input); - } - } -} - -static void dmenu_finalize(RofiViewState *state) { - int retv = FALSE; - DmenuModePrivateData *pd = - (DmenuModePrivateData *)rofi_view_get_mode(state)->private_data; - unsigned int cmd_list_length = pd->cmd_list_length; - DmenuScriptEntry *cmd_list = pd->cmd_list; - - char *input = g_strdup(rofi_view_get_user_input(state)); - pd->selected_line = rofi_view_get_selected_line(state); - ; - MenuReturn mretv = rofi_view_get_return_value(state); - unsigned int next_pos = rofi_view_get_next_position(state); - int restart = 0; - // Special behavior. - if (pd->only_selected) { - /** - * Select item mode. - */ - restart = 1; - // Skip if no valid item is selected. - if ((mretv & MENU_CANCEL) == MENU_CANCEL) { |