-#include "wayland-client.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * @page page_xdg_output_unstable_v1 The xdg_output_unstable_v1 protocol
- * Protocol to describe output regions
- *
- * @section page_desc_xdg_output_unstable_v1 Description
- *
- * This protocol aims at describing outputs in a way which is more in line
- * with the concept of an output on desktop oriented systems.
- *
- * Some information are more specific to the concept of an output for
- * a desktop oriented system and may not make sense in other applications,
- * such as IVI systems for example.
- *
- * Typically, the global compositor space on a desktop system is made of
- * a contiguous or overlapping set of rectangular regions.
- *
- * Some of the information provided in this protocol might be identical
- * to their counterparts already available from wl_output, in which case
- * the information provided by this protocol should be preferred to their
- * equivalent in wl_output. The goal is to move the desktop specific
- * concepts (such as output location within the global compositor space,
- * the connector name and types, etc.) out of the core wl_output protocol.
- *
- * Warning! The protocol described in this file is experimental and
- * backward incompatible changes may be made. Backward compatible
- * changes may be added together with the corresponding interface
- * version bump.
- * Backward incompatible changes are done by bumping the version
- * number in the protocol and interface names and resetting the
- * interface version. Once the protocol is to be declared stable,
- * the 'z' prefix and the version number in the protocol and
- * interface names are removed and the interface version number is
- * reset.
- *
- * @section page_ifaces_xdg_output_unstable_v1 Interfaces
- * - @subpage page_iface_zxdg_output_manager_v1 - manage xdg_output objects
- * - @subpage page_iface_zxdg_output_v1 - compositor logical output region
- * @section page_copyright_xdg_output_unstable_v1 Copyright
- *
- *
- * Copyright © 2017 Red Hat Inc.
- *
- * 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 (including the next
- * paragraph) 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.
- *
- */
-struct wl_output;
-struct zxdg_output_manager_v1;
-struct zxdg_output_v1;
-
-/**
- * @page page_iface_zxdg_output_manager_v1 zxdg_output_manager_v1
- * @section page_iface_zxdg_output_manager_v1_desc Description
- *
- * A global factory interface for xdg_output objects.
- * @section page_iface_zxdg_output_manager_v1_api API
- * See @ref iface_zxdg_output_manager_v1.
- */
-/**
- * @defgroup iface_zxdg_output_manager_v1 The zxdg_output_manager_v1 interface
- *
- * A global factory interface for xdg_output objects.
- */
-extern const struct wl_interface zxdg_output_manager_v1_interface;
-/**
- * @page page_iface_zxdg_output_v1 zxdg_output_v1
- * @section page_iface_zxdg_output_v1_desc Description
- *
- * An xdg_output describes part of the compositor geometry.
- *
- * This typically corresponds to a monitor that displays part of the
- * compositor space.
- * @section page_iface_zxdg_output_v1_api API
- * See @ref iface_zxdg_output_v1.
- */
-/**
- * @defgroup iface_zxdg_output_v1 The zxdg_output_v1 interface
- *
- * An xdg_output describes part of the compositor geometry.
- *
- * This typically corresponds to a monitor that displays part of the
- * compositor space.
- */
-extern const struct wl_interface zxdg_output_v1_interface;
-
-#define ZXDG_OUTPUT_MANAGER_V1_DESTROY 0
-#define ZXDG_OUTPUT_MANAGER_V1_GET_XDG_OUTPUT 1
-
-
-/**
- * @ingroup iface_zxdg_output_manager_v1
- */
-#define ZXDG_OUTPUT_MANAGER_V1_DESTROY_SINCE_VERSION 1
-/**
- * @ingroup iface_zxdg_output_manager_v1
- */
-#define ZXDG_OUTPUT_MANAGER_V1_GET_XDG_OUTPUT_SINCE_VERSION 1
-
-/** @ingroup iface_zxdg_output_manager_v1 */
-static inline void
-zxdg_output_manager_v1_set_user_data(struct zxdg_output_manager_v1 *zxdg_output_manager_v1, void *user_data)
-{
- wl_proxy_set_user_data((struct wl_proxy *) zxdg_output_manager_v1, user_data);
-}
-
-/** @ingroup iface_zxdg_output_manager_v1 */
-static inline void *
-zxdg_output_manager_v1_get_user_data(struct zxdg_output_manager_v1 *zxdg_output_manager_v1)
-{
- return wl_proxy_get_user_data((struct wl_proxy *) zxdg_output_manager_v1);
-}
-
-static inline uint32_t
-zxdg_output_manager_v1_get_version(struct zxdg_output_manager_v1 *zxdg_output_manager_v1)
-{
- return wl_proxy_get_version((struct wl_proxy *) zxdg_output_manager_v1);
-}
-
-/**
- * @ingroup iface_zxdg_output_manager_v1
- *
- * Using this request a client can tell the server that it is not
- * going to use the xdg_output_manager object anymore.
- *
- * Any objects already created through this instance are not affected.
- */
-static inline void
-zxdg_output_manager_v1_destroy(struct zxdg_output_manager_v1 *zxdg_output_manager_v1)
-{
- wl_proxy_marshal((struct wl_proxy *) zxdg_output_manager_v1,
- ZXDG_OUTPUT_MANAGER_V1_DESTROY);
-
- wl_proxy_destroy((struct wl_proxy *) zxdg_output_manager_v1);
-}
-
-/**
- * @ingroup iface_zxdg_output_manager_v1
- *
- * This creates a new xdg_output object for the given wl_output.
- */
-static inline struct zxdg_output_v1 *
-zxdg_output_manager_v1_get_xdg_output(struct zxdg_output_manager_v1 *zxdg_output_manager_v1, struct wl_output *output)
-{
- struct wl_proxy *id;
-
- id = wl_proxy_marshal_constructor((struct wl_proxy *) zxdg_output_manager_v1,
- ZXDG_OUTPUT_MANAGER_V1_GET_XDG_OUTPUT, &zxdg_output_v1_interface, NULL, output);
-
- return (struct zxdg_output_v1 *) id;
-}
-
-/**
- * @ingroup iface_zxdg_output_v1
- * @struct zxdg_output_v1_listener
- */
-struct zxdg_output_v1_listener {
- /**
- * position of the output within the global compositor space
- *
- * The position event describes the location of the wl_output
- * within the global compositor space.
- *
- * The logical_position event is sent after creating an xdg_output
- * (see xdg_output_manager.get_xdg_output) and whenever the
- * location of the output changes within the global compositor
- * space.
- * @param x x position within the global compositor space
- * @param y y position within the global compositor space
- */
- void (*logical_position)(void *data,
- struct zxdg_output_v1 *zxdg_output_v1,
- int32_t x,
- int32_t y);
- /**
- * size of the output in the global compositor space
- *
- * The logical_size event describes the size of the output in the
- * global compositor space.
- *
- * For example, a surface without any buffer scale, transformation
- * nor rotation set, with the size matching the logical_size will
- * have the same size as the corresponding output when displayed.
- *
- * Most regular Wayland clients should not pay attention to the
- * logical size and would rather rely on xdg_shell interfaces.
- *
- * Some clients such as Xwayland, however, need this to configure
- * their surfaces in the global compositor space as the compositor
- * may apply a different scale from what is advertised by the
- * output scaling property (to achieve fractional scaling, for
- * example).
- *
- * For example, for a wl_output mode 3840×2160 and a scale factor
- * 2:
- *
- * - A compositor not scaling the surface buffers will advertise a
- * logical size of 3840×2160,
- *
- * - A compositor automatically scaling the surface buffers will
- * advertise a logical size of 1920×1080,
- *
- * - A compositor using a fractional scale of 1.5 will advertise a
- * logical size to 2560×1620.
- *
- * For example, for a wl_output mode 1920×1080 and a 90 degree
- * rotation, the compositor will advertise a logical size of
- * 1080x1920.
- *
- * The logical_size event is sent after creating an xdg_output (see
- * xdg_output_manager.get_xdg_output) and whenever the logical size
- * of the output changes, either as a result of a change in the
- * applied scale or because of a change in the corresponding output
- * mode(see wl_output.mode) or transform (see wl_output.transform).
- * @param width width in global compositor space
- * @param height height in global compositor space
- */
- void (*logical_size)(void *data,
- struct zxdg_output_v1 *zxdg_output_v1,
- int32_t width,
- int32_t height);
- /**
- * all information about the output have been sent
- *
- * This event is sent after all other properties of an xdg_output
- * have been sent.
- *
- * This allows changes to the xdg_output properties to be seen as
- * atomic, even if they happen via multiple events.
- */
- void (*done)(void *data,
- struct zxdg_output_v1 *zxdg_output_v1);
- /**
- * name of this output
- *
- * Many compositors will assign names to their outputs, show them
- * to the user, allow them to be configured by name, etc. The
- * client may wish to know this name as well to offer the user
- * similar behaviors.
- *
- * The naming convention is compositor defined, but limited to
- * alphanumeric characters and dashes (-). Each name is unique
- * among all wl_output globals, but if a wl_output global is
- * destroyed the same name may be reused later. The names will also
- * remain consistent across sessions with the same hardware and
- * software configuration.
- *
- * Examples of names include 'HDMI-A-1', 'WL-1', 'X11-1', etc.
- * However, do not assume that the name is a reflection of an
- * underlying DRM connector, X11 connection, etc.
- *
- * The name event is sent after creating an xdg_output (see
- * xdg_output_manager.get_xdg_output). This event is only sent once
- * per xdg_output, and the name does not change over the lifetime
- * of the wl_output global.
- * @param name output name
- * @since 2
- */
- void (*name)(void *data,
- struct zxdg_output_v1 *zxdg_output_v1,
- const char *name);
- /**
- * human-readable description of this output
- *
- * Many compositors can produce human-readable descriptions of
- * their outputs. The client may wish to know this description as
- * well, to communicate the user for various purposes.
- *
- * The description is a UTF-8 string with no convention defined for
- * its contents. Examples might include 'Foocorp 11" Display' or
- * 'Virtual X11 output via :1'.
- *
- * The description event is sent after creating an xdg_output (see
- * xdg_output_manager.get_xdg_output). This event is only sent once
- * per xdg_output, and the description does not change over the
- * lifetime of the wl_output global. The description is optional,
- * and may not be sent at all.
- * @param description output description
- * @since 2
- */
- void (*description)(void *data,
- struct zxdg_output_v1 *zxdg_output_v1,
- const char *description);
-};
-
-/**
- * @ingroup iface_zxdg_output_v1
- */
-static inline int
-zxdg_output_v1_add_listener(struct zxdg_output_v1 *zxdg_output_v1,
- const struct zxdg_output_v1_listener *listener, void *data)
-{
- return wl_proxy_add_listener((struct wl_proxy *) zxdg_output_v1,
- (void (**)(void)) listener, data);
-}
-
-#define ZXDG_OUTPUT_V1_DESTROY 0
-
-/**
- * @ingroup iface_zxdg_output_v1
- */
-#define ZXDG_OUTPUT_V1_LOGICAL_POSITION_SINCE_VERSION 1
-/**
- * @ingroup iface_zxdg_output_v1
- */
-#define ZXDG_OUTPUT_V1_LOGICAL_SIZE_SINCE_VERSION 1
-/**
- * @ingroup iface_zxdg_output_v1
- */
-#define ZXDG_OUTPUT_V1_DONE_SINCE_VERSION 1
-/**
- * @ingroup iface_zxdg_output_v1
- */
-#define ZXDG_OUTPUT_V1_NAME_SINCE_VERSION 2
-/**
- * @ingroup iface_zxdg_output_v1
- */
-#define ZXDG_OUTPUT_V1_DESCRIPTION_SINCE_VERSION 2
-
-/**
- * @ingroup iface_zxdg_output_v1
- */
-#define ZXDG_OUTPUT_V1_DESTROY_SINCE_VERSION 1
-
-/** @ingroup iface_zxdg_output_v1 */
-static inline void
-zxdg_output_v1_set_user_data(struct zxdg_output_v1 *zxdg_output_v1, void *user_data)
-{
- wl_proxy_set_user_data((struct wl_proxy *) zxdg_output_v1, user_data);
-}
-
-/** @ingroup iface_zxdg_output_v1 */
-static inline void *
-zxdg_output_v1_get_user_data(struct zxdg_output_v1 *zxdg_output_v1)
-{
- return wl_proxy_get_user_data((struct wl_proxy *) zxdg_output_v1);
-}
-
-static inline uint32_t
-zxdg_output_v1_get_version(struct zxdg_output_v1 *zxdg_output_v1)
-{
- return wl_proxy_get_version((struct wl_proxy *) zxdg_output_v1);
-}
-
-/**
- * @ingroup iface_zxdg_output_v1
- *
- * Using this request a client can tell the server that it is not
- * going to use the xdg_output object anymore.
- */
-static inline void
-zxdg_output_v1_destroy(struct zxdg_output_v1 *zxdg_output_v1)
-{
- wl_proxy_marshal((struct wl_proxy *) zxdg_output_v1,
- ZXDG_OUTPUT_V1_DESTROY);
-
- wl_proxy_destroy((struct wl_proxy *) zxdg_output_v1);
-}
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/wofi/man/wofi-api.3 b/wofi/man/wofi-api.3
deleted file mode 100644
index fb067b6..0000000
--- a/wofi/man/wofi-api.3
+++ /dev/null
@@ -1,116 +0,0 @@
-.TH wofi\-api 3
-.SH NAME
-wofi \- API functions and documentation
-
-.SH DESCRIPTION
-The functions documented here are used for interacting with wofi. They are defined in wofi_api.h.
-
-.SH STRUCTURES
-struct cache_line {
-.RS 4
-char* line;
-.br
-struct wl_list link;
-.RE
-};
-
-.SH API FUNCTIONS
-The following functions are used to interact with wofi.
-
-.TP
-.B char* wofi_parse_image_escapes(const char* text)
-This function takes in text containing image escapes and pango markup and will return the plain text with all of that stripped. The string returned is newly allocated and should be freed by the caller when they are done with it.
-
-.B const char* text
-\- The input text containing image escapes and pango markup.
-
-.TP
-.B void wofi_write_cache(struct mode* mode, const char* cmd)
-Writes an entry to the cache file.
-
-.B struct mode* mode
-\- The \fBstruct mode*\fR given to your mode's \fBinit()\fR function.
-
-.B const char* cmd
-\- The entry to write to the cache file. If this entry already exists the number of times it has been written will be incremented.
-
-.TP
-.B void wofi_remove_cache(struct mode* mode, const char* cmd)
-Removes an entry from the cache file.
-
-.B struct mode* mode
-\- The \fBstruct mode*\fR given to your mode's \fBinit()\fR function.
-
-.B const char* cmd
-\- The entry to remove from the cache file. This does NOT decrement the number of times written, it fully removes the entry.
-
-.TP
-.B struct wl_list* wofi_read_cache(struct mode* mode)
-Reads the cache and returns a \fBstruct wl_list*\fR containing the entires. The list is made up of \fBstruct cache_line*\fR entries. The wayland documentation should be referred to for the usage of a wl_list.
-
-.B struct mode* mode
-\- The \fBstruct mode*\fR given to your mode's \fBinit()\fR function.
-
-.TP
-.B struct widget* wofi_create_widget(struct mode* mode, char* text[], char* search_text, char* actions[], size_t action_count)
-Creates a widget from the specified information. This widget should be returned by the mode's \fBget_widget()\fR function in order to be displayed.
-
-.B struct mode* mode
-\- The \fBstruct mode*\fR given to your mode's \fBinit()\fR function.
-
-.B char* text[]
-\- The array of text to display on the entry in wofi. Each element in the array represents the text for 1 action. The array should only be larger than 1 if you're creating a multi\-action entry. Multi\-action entries need to provide 1 string for every action the entry has.
-
-.B char* search_text
-\- The text which the user can search for to find this widget.
-
-.B char* actions[]
-\- The array of actions for the entry. An action is the text given to a mode's \fBexec()\fR function when the user selects an entry. Multi\-action entries need to provide 1 action string for every action the entry has.
-
-.B size_t action_count
-\- The number of actions the entry will have.
-
-.TP
-.B void wofi_insert_widgets(struct mode* mode)
-This will requery the mode for more widgets.
-
-.B struct mode* mode
-\- The \fBstruct mode*\fR given to your mode's \fBinit()\fR function.
-
-.TP
-.B char* wofi_get_dso_path(struct mode* mode)
-Returns the path to this mode's DSO if it's an external mode, returns NULL otherwise.
-
-.B struct mode* mode
-\- The \fBstruct mode*\fR given to your mode's \fBinit()\fR function.
-
-.TP
-.B bool wofi_allow_images(void)
-Returns true if the user enabled images, false otherwise.
-
-.TP
-.B bool wofi_allow_markup(void)
-Returns true if the user enabled pango markup, false otherwise.
-
-.TP
-.B uint64_t wofi_get_image_size(void)
-Returns the user specified image size, 32 by default. Wofi will scale images for you, this is just informational and is not required but can be helpful if multiple sizes are available.
-
-.TP
-.B bool wofi_mod_shift(void)
-Returns true if the user was holding shift when selecting an entry, false otherwise.
-
-.TP
-.B bool wofi_mod_control(void)
-Returns true if the user was holding control when selecting an entry, false otherwise.
-
-.TP
-.B void wofi_term_run(const char* cmd)
-Runs the provided cmd in a terminal emulator. The following order is used for picking a terminal emulator: The user specified terminal, kitty, alacritty, wezterm, foot, termite, gnome\-terminal, weston\-terminal. If none of these can be found execution will fail.
-
-.B const char* cmd
-\- The command to run, this is invoked by doing \fBterm \-\- cmd\fR.
-
-.TP
-.B void wofi_exit(void)
-This function is how you should call to exit wofi. It checks the status given and only sets a custom exit code if you pass EXIT_SUCCESS. If you call the libc exit() function then the custom exit code will always be used even if an error should be reported
diff --git a/wofi/man/wofi-config.3 b/wofi/man/wofi-config.3
deleted file mode 100644
index 75a081e..0000000
--- a/wofi/man/wofi-config.3
+++ /dev/null
@@ -1,61 +0,0 @@
-.TH wofi\-config 3
-.SH NAME
-wofi \- Config functions and documentation
-
-.SH DESCRIPTION
-The functions documented here are used for manipulating maps that represent config entries. They are defined in config.h.
-
-.SH CONFIG FUNCTIONS
-The following functions are used to work with configs.
-
-.TP
-.B void config_put(struct map* map, char* line)
-Parses a single config line and inserts the result into the map
-
-.B struct map* map
-\- The map to insert into.
-
-.B char* line
-\- The config line to insert. Should be in the format of \fBkey=\fIvalue\fR.
-
-.TP
-.B void config_load(struct map* map, const char* config)
-Loads a config file into the given map
-
-.B struct map* map
-\- The map to load the config into.
-
-.B const char* config
-\- The path to a config file. Should contain lines with the format of \fBkey=\fIvalue\fR.
-
-.TP
-.B char* config_get(struct map* config, const char* key, char* def_opt)
-Gets a config entry, if the entry is not set then it returns \fBdef_opt\fR.
-
-.B struct map* config
-\- The map to get the value from.
-
-.B const char* key
-\- The key to lookup.
-
-.B char* def_opt
-\- The default value to be returned if the key does not exist.
-
-.TP
-.B int config_get_mnemonic(struct map* config, const char* key, char* def_opt, int num_choices, ...)
-Gets an enum value from the config. If the value is not set then it returns \fBdef_opt\fR.
-
-.B struct map* config
-\- The map to get the value from.
-
-.B const char* key
-\- The key to lookup.
-
-.B char* def_opt
-\- The default value to be returned if the key does not exist.
-
-.B int num_choices
-\- The number of enum options available.
-
-.B varargs
-\- The list of enum options available.
diff --git a/wofi/man/wofi-keys.7 b/wofi/man/wofi-keys.7
deleted file mode 100644
index e99c726..0000000
--- a/wofi/man/wofi-keys.7
+++ /dev/null
@@ -1,4552 +0,0 @@
-.TH wofi\-keys 7
-.SH NAME
-wofi \- Key names for custom binds
-
-.SH DESCRIPTION
-This is a list of the key names that can be used for custom binding. These are taken from gdk/gdkkeysyms.h with exception to modifiers. Certain keys cannot have the shift modifier attached as holding shift while using these keys causes a completely different key press to be registered. For example Shift\-j is invalid as holding shift while pressing j changes the key into J so Shift-J should be registered as the key instead of Shift\-j. This is the case with all alphanumeric chars as well as Tab which turns into ISO_Left_Tab.
-
-.SH KEY NAMES
-.B BackSpace
-.br
-.B Tab
-.br
-.B Linefeed
-.br
-.B Clear
-.br
-.B Return
-.br
-.B Pause
-.br
-.B Scroll_Lock
-.br
-.B Sys_Req
-.br
-.B Escape
-.br
-.B Delete
-.br
-.B Multi_key
-.br
-.B Codeinput
-.br
-.B SingleCandidate
-.br
-.B MultipleCandidate
-.br
-.B PreviousCandidate
-.br
-.B Kanji
-.br
-.B Muhenkan
-.br
-.B Henkan_Mode
-.br
-.B Henkan
-.br
-.B Romaji
-.br
-.B Hiragana
-.br
-.B Katakana
-.br
-.B Hiragana_Katakana
-.br
-.B Zenkaku
-.br
-.B Hankaku
-.br
-.B Zenkaku_Hankaku
-.br
-.B Touroku
-.br
-.B Massyo
-.br
-.B Kana_Lock
-.br
-.B Kana_Shift
-.br
-.B Eisu_Shift
-.br
-.B Eisu_toggle
-.br
-.B Kanji_Bangou
-.br
-.B Zen_Koho
-.br
-.B Mae_Koho
-.br
-.B Home
-.br
-.B Left
-.br
-.B Up
-.br
-.B Right
-.br
-.B Down
-.br
-.B Prior
-.br
-.B Page_Up
-.br
-.B Next
-.br
-.B Page_Down
-.br
-.B End
-.br
-.B Begin
-.br
-.B Select
-.br
-.B Print
-.br
-.B Execute
-.br
-.B Insert
-.br
-.B Undo
-.br
-.B Redo
-.br
-.B Menu
-.br
-.B Find
-.br
-.B Cancel
-.br
-.B Help
-.br
-.B Break
-.br
-.B Mode_switch
-.br
-.B script_switch
-.br
-.B Num_Lock
-.br
-.B KP_Space
-.br
-.B KP_Tab
-.br
-.B KP_Enter
-.br
-.B KP_F1
-.br
-.B KP_F2
-.br
-.B KP_F3
-.br
-.B KP_F4
-.br
-.B KP_Home
-.br
-.B KP_Left
-.br
-.B KP_Up
-.br
-.B KP_Right
-.br
-.B KP_Down
-.br
-.B KP_Prior
-.br
-.B KP_Page_Up
-.br
-.B KP_Next
-.br
-.B KP_Page_Down
-.br
-.B KP_End
-.br
-.B KP_Begin
-.br
-.B KP_Insert
-.br
-.B KP_Delete
-.br
-.B KP_Equal
-.br
-.B KP_Multiply
-.br
-.B KP_Add
-.br
-.B KP_Separator
-.br
-.B KP_Subtract
-.br
-.B KP_Decimal
-.br
-.B KP_Divide
-.br
-.B KP_0
-.br
-.B KP_1
-.br
-.B KP_2
-.br
-.B KP_3
-.br
-.B KP_4
-.br
-.B KP_5
-.br
-.B KP_6
-.br
-.B KP_7
-.br
-.B KP_8
-.br
-.B KP_9
-.br
-.B F1
-.br
-.B F2
-.br
-.B F3
-.br
-.B F4
-.br
-.B F5
-.br
-.B F6
-.br
-.B F7
-.br
-.B F8
-.br
-.B F9
-.br
-.B F10
-.br
-.B F11
-.br
-.B L1
-.br
-.B F12
-.br
-.B L2
-.br
-.B F13
-.br
-.B L3
-.br
-.B F14
-.br
-.B L4
-.br
-.B F15
-.br
-.B L5
-.br
-.B F16
-.br
-.B L6
-.br
-.B F17
-.br
-.B L7
-.br
-.B F18
-.br
-.B L8
-.br
-.B F19
-.br
-.B L9
-.br
-.B F20
-.br
-.B L10
-.br
-.B F21
-.br
-.B R1
-.br
-.B F22
-.br
-.B R2
-.br
-.B F23
-.br
-.B R3
-.br
-.B F24
-.br
-.B R4
-.br
-.B F25
-.br
-.B R5
-.br
-.B F26
-.br
-.B R6
-.br
-.B F27
-.br
-.B R7
-.br
-.B F28
-.br
-.B R8
-.br
-.B F29
-.br
-.B R9
-.br
-.B F30
-.br
-.B R10
-.br
-.B F31
-.br
-.B R11
-.br
-.B F32
-.br
-.B R12
-.br
-.B F33
-.br
-.B R13
-.br
-.B F34
-.br
-.B R14
-.br
-.B F35
-.br
-.B R15
-.br
-.B Shift_L
-.br
-.B Shift_R
-.br
-.B Control_L
-.br
-.B Control_R
-.br
-.B Caps_Lock
-.br
-.B Shift_Lock
-.br
-.B Meta_L
-.br
-.B Meta_R
-.br
-.B Alt_L
-.br
-.B Alt_R
-.br
-.B Super_L
-.br
-.B Super_R
-.br
-.B Hyper_L
-.br
-.B Hyper_R
-.br
-.B ISO_Lock
-.br
-.B ISO_Level2_Latch
-.br
-.B ISO_Level3_Shift
-.br
-.B ISO_Level3_Latch
-.br
-.B ISO_Level3_Lock
-.br
-.B ISO_Level5_Shift
-.br
-.B ISO_Level5_Latch
-.br
-.B ISO_Level5_Lock
-.br
-.B ISO_Group_Shift
-.br
-.B ISO_Group_Latch
-.br
-.B ISO_Group_Lock
-.br
-.B ISO_Next_Group
-.br
-.B ISO_Next_Group_Lock
-.br
-.B ISO_Prev_Group
-.br
-.B ISO_Prev_Group_Lock
-.br
-.B ISO_First_Group
-.br
-.B ISO_First_Group_Lock
-.br
-.B ISO_Last_Group
-.br
-.B ISO_Last_Group_Lock
-.br
-.B ISO_Left_Tab
-.br
-.B ISO_Move_Line_Up
-.br
-.B ISO_Move_Line_Down
-.br
-.B ISO_Partial_Line_Up
-.br
-.B ISO_Partial_Line_Down
-.br
-.B ISO_Partial_Space_Left
-.br
-.B ISO_Partial_Space_Right
-.br
-.B ISO_Set_Margin_Left
-.br
-.B ISO_Set_Margin_Right
-.br
-.B ISO_Release_Margin_Left
-.br
-.B ISO_Release_Margin_Right
-.br
-.B ISO_Release_Both_Margins
-.br
-.B ISO_Fast_Cursor_Left
-.br
-.B ISO_Fast_Cursor_Right
-.br
-.B ISO_Fast_Cursor_Up
-.br
-.B ISO_Fast_Cursor_Down
-.br
-.B ISO_Continuous_Underline
-.br
-.B ISO_Discontinuous_Underline
-.br
-.B ISO_Emphasize
-.br
-.B ISO_Center_Object
-.br
-.B ISO_Enter
-.br
-.B dead_grave
-.br
-.B dead_acute
-.br
-.B dead_circumflex
-.br
-.B dead_tilde
-.br
-.B dead_perispomeni
-.br
-.B dead_macron
-.br
-.B dead_breve
-.br
-.B dead_abovedot
-.br
-.B dead_diaeresis
-.br
-.B dead_abovering
-.br
-.B dead_doubleacute
-.br
-.B dead_caron
-.br
-.B dead_cedilla
-.br
-.B dead_ogonek
-.br
-.B dead_iota
-.br
-.B dead_voiced_sound
-.br
-.B dead_semivoiced_sound
-.br
-.B dead_belowdot
-.br
-.B dead_hook
-.br
-.B dead_horn
-.br
-.B dead_stroke
-.br
-.B dead_abovecomma
-.br
-.B dead_psili
-.br
-.B dead_abovereversedcomma
-.br
-.B dead_dasia
-.br
-.B dead_doublegrave
-.br
-.B dead_belowring
-.br
-.B dead_belowmacron
-.br
-.B dead_belowcircumflex
-.br
-.B dead_belowtilde
-.br
-.B dead_belowbreve
-.br
-.B dead_belowdiaeresis
-.br
-.B dead_invertedbreve
-.br
-.B dead_belowcomma
-.br
-.B dead_currency
-.br
-.B dead_a
-.br
-.B dead_A
-.br
-.B dead_e
-.br
-.B dead_E
-.br
-.B dead_i
-.br
-.B dead_I
-.br
-.B dead_o
-.br
-.B dead_O
-.br
-.B dead_u
-.br
-.B dead_U
-.br
-.B dead_small_schwa
-.br
-.B dead_capital_schwa
-.br
-.B dead_greek
-.br
-.B First_Virtual_Screen
-.br
-.B Prev_Virtual_Screen
-.br
-.B Next_Virtual_Screen
-.br
-.B Last_Virtual_Screen
-.br
-.B Terminate_Server
-.br
-.B AccessX_Enable
-.br
-.B AccessX_Feedback_Enable
-.br
-.B RepeatKeys_Enable
-.br
-.B SlowKeys_Enable
-.br
-.B BounceKeys_Enable
-.br
-.B StickyKeys_Enable
-.br
-.B MouseKeys_Enable
-.br
-.B MouseKeys_Accel_Enable
-.br
-.B Overlay1_Enable
-.br
-.B Overlay2_Enable
-.br
-.B AudibleBell_Enable
-.br
-.B Pointer_Left
-.br
-.B Pointer_Right
-.br
-.B Pointer_Up
-.br
-.B Pointer_Down
-.br
-.B Pointer_UpLeft
-.br
-.B Pointer_UpRight
-.br
-.B Pointer_DownLeft
-.br
-.B Pointer_DownRight
-.br
-.B Pointer_Button_Dflt
-.br
-.B Pointer_Button1
-.br
-.B Pointer_Button2
-.br
-.B Pointer_Button3
-.br
-.B Pointer_Button4
-.br
-.B Pointer_Button5
-.br
-.B Pointer_DblClick_Dflt
-.br
-.B Pointer_DblClick1
-.br
-.B Pointer_DblClick2
-.br
-.B Pointer_DblClick3
-.br
-.B Pointer_DblClick4
-.br
-.B Pointer_DblClick5
-.br
-.B Pointer_Drag_Dflt
-.br
-.B Pointer_Drag1
-.br
-.B Pointer_Drag2
-.br
-.B Pointer_Drag3
-.br
-.B Pointer_Drag4
-.br
-.B Pointer_Drag5
-.br
-.B Pointer_EnableKeys
-.br
-.B Pointer_Accelerate
-.br
-.B Pointer_DfltBtnNext
-.br
-.B Pointer_DfltBtnPrev
-.br
-.B ch
-.br
-.B Ch
-.br
-.B CH
-.br
-.B c_h
-.br
-.B C_h
-.br
-.B C_H
-.br
-.B 3270_Duplicate
-.br
-.B 3270_FieldMark
-.br
-.B 3270_Right2
-.br
-.B 3270_Left2
-.br
-.B 3270_BackTab
-.br
-.B 3270_EraseEOF
-.br
-.B 3270_EraseInput
-.br
-.B 3270_Reset
-.br
-.B 3270_Quit
-.br
-.B 3270_PA1
-.br
-.B 3270_PA2
-.br
-.B 3270_PA3
-.br
-.B 3270_Test
-.br
-.B 3270_Attn
-.br
-.B 3270_CursorBlink
-.br
-.B 3270_AltCursor
-.br
-.B 3270_KeyClick
-.br
-.B 3270_Jump
-.br
-.B 3270_Ident
-.br
-.B 3270_Rule
-.br
-.B 3270_Copy
-.br
-.B 3270_Play
-.br
-.B 3270_Setup
-.br
-.B 3270_Record
-.br
-.B 3270_ChangeScreen
-.br
-.B 3270_DeleteWord
-.br
-.B 3270_ExSelect
-.br
-.B 3270_CursorSelect
-.br
-.B 3270_PrintScreen
-.br
-.B 3270_Enter
-.br
-.B space
-.br
-.B exclam
-.br
-.B quotedbl
-.br
-.B numbersign
-.br
-.B dollar
-.br
-.B percent
-.br
-.B ampersand
-.br
-.B apostrophe
-.br
-.B quoteright
-.br
-.B parenleft
-.br
-.B parenright
-.br
-.B asterisk
-.br
-.B plus
-.br
-.B comma
-.br
-.B minus
-.br
-.B period
-.br
-.B slash
-.br
-.B 0
-.br
-.B 1
-.br
-.B 2
-.br
-.B 3
-.br
-.B 4
-.br
-.B 5
-.br
-.B 6
-.br
-.B 7
-.br
-.B 8
-.br
-.B 9
-.br
-.B colon
-.br
-.B semicolon
-.br
-.B less
-.br
-.B equal
-.br
-.B greater
-.br
-.B question
-.br
-.B at
-.br
-.B A
-.br
-.B B
-.br
-.B C
-.br
-.B D
-.br
-.B E
-.br
-.B F
-.br
-.B G
-.br
-.B H
-.br
-.B I
-.br
-.B J
-.br
-.B K
-.br
-.B L
-.br
-.B M
-.br
-.B N
-.br
-.B O
-.br
-.B P
-.br
-.B Q
-.br
-.B R
-.br
-.B S
-.br
-.B T
-.br
-.B U
-.br
-.B V
-.br
-.B W
-.br
-.B X
-.br
-.B Y
-.br
-.B Z
-.br
-.B bracketleft
-.br
-.B backslash
-.br
-.B bracketright
-.br
-.B asciicircum
-.br
-.B underscore
-.br
-.B grave
-.br
-.B quoteleft
-.br
-.B a
-.br
-.B b
-.br
-.B c
-.br
-.B d
-.br
-.B e
-.br
-.B f
-.br
-.B g
-.br
-.B h
-.br
-.B i
-.br
-.B j
-.br
-.B k
-.br
-.B l
-.br
-.B m
-.br
-.B n
-.br
-.B o
-.br
-.B p
-.br
-.B q
-.br
-.B r
-.br
-.B s
-.br
-.B t
-.br
-.B u
-.br
-.B v
-.br
-.B w
-.br
-.B x
-.br
-.B y
-.br
-.B z
-.br
-.B braceleft
-.br
-.B bar
-.br
-.B braceright
-.br
-.B asciitilde
-.br
-.B nobreakspace
-.br
-.B exclamdown
-.br
-.B cent
-.br
-.B sterling
-.br
-.B currency
-.br
-.B yen
-.br
-.B brokenbar
-.br
-.B section
-.br
-.B diaeresis
-.br
-.B copyright
-.br
-.B ordfeminine
-.br
-.B guillemotleft
-.br
-.B notsign
-.br
-.B hyphen
-.br
-.B registered
-.br
-.B macron
-.br
-.B degree
-.br
-.B plusminus
-.br
-.B twosuperior
-.br
-.B threesuperior
-.br
-.B acute
-.br
-.B mu
-.br
-.B paragraph
-.br
-.B periodcentered
-.br
-.B cedilla
-.br
-.B onesuperior
-.br
-.B masculine
-.br
-.B guillemotright
-.br
-.B onequarter
-.br
-.B onehalf
-.br
-.B threequarters
-.br
-.B questiondown
-.br
-.B Agrave
-.br
-.B Aacute
-.br
-.B Acircumflex
-.br
-.B Atilde
-.br
-.B Adiaeresis
-.br
-.B Aring
-.br
-.B AE
-.br
-.B Ccedilla
-.br
-.B Egrave
-.br
-.B Eacute
-.br
-.B Ecircumflex
-.br
-.B Ediaeresis
-.br
-.B Igrave
-.br
-.B Iacute
-.br
-.B Icircumflex
-.br
-.B Idiaeresis
-.br
-.B ETH
-.br
-.B Eth
-.br
-.B Ntilde
-.br
-.B Ograve
-.br
-.B Oacute
-.br
-.B Ocircumflex
-.br
-.B Otilde
-.br
-.B Odiaeresis
-.br
-.B multiply
-.br
-.B Oslash
-.br
-.B Ooblique
-.br
-.B Ugrave
-.br
-.B Uacute
-.br
-.B Ucircumflex
-.br
-.B Udiaeresis
-.br
-.B Yacute
-.br
-.B THORN
-.br
-.B Thorn
-.br
-.B ssharp
-.br
-.B agrave
-.br
-.B aacute
-.br
-.B acircumflex
-.br
-.B atilde
-.br
-.B adiaeresis
-.br
-.B aring
-.br
-.B ae
-.br
-.B ccedilla
-.br
-.B egrave
-.br
-.B eacute
-.br
-.B ecircumflex
-.br
-.B ediaeresis
-.br
-.B igrave
-.br
-.B iacute
-.br
-.B icircumflex
-.br
-.B idiaeresis
-.br
-.B eth
-.br
-.B ntilde
-.br
-.B ograve
-.br
-.B oacute
-.br
-.B ocircumflex
-.br
-.B otilde
-.br
-.B odiaeresis
-.br
-.B division
-.br
-.B oslash
-.br
-.B ooblique
-.br
-.B ugrave
-.br
-.B uacute
-.br
-.B ucircumflex
-.br
-.B udiaeresis
-.br
-.B yacute
-.br
-.B thorn
-.br
-.B ydiaeresis
-.br
-.B Aogonek
-.br
-.B breve
-.br
-.B Lstroke
-.br
-.B Lcaron
-.br
-.B Sacute
-.br
-.B Scaron
-.br
-.B Scedilla
-.br
-.B Tcaron
-.br
-.B Zacute
-.br
-.B Zcaron
-.br
-.B Zabovedot
-.br
-.B aogonek
-.br
-.B ogonek
-.br
-.B lstroke
-.br
-.B lcaron
-.br
-.B sacute
-.br
-.B caron
-.br
-.B scaron
-.br
-.B scedilla
-.br
-.B tcaron
-.br
-.B zacute
-.br
-.B doubleacute
-.br
-.B zcaron
-.br
-.B zabovedot
-.br
-.B Racute
-.br
-.B Abreve
-.br
-.B Lacute
-.br
-.B Cacute
-.br
-.B Ccaron
-.br
-.B Eogonek
-.br
-.B Ecaron
-.br
-.B Dcaron
-.br
-.B Dstroke
-.br
-.B Nacute
-.br
-.B Ncaron
-.br
-.B Odoubleacute
-.br
-.B Rcaron
-.br
-.B Uring
-.br
-.B Udoubleacute
-.br
-.B Tcedilla
-.br
-.B racute
-.br
-.B abreve
-.br
-.B lacute
-.br
-.B cacute
-.br
-.B ccaron
-.br
-.B eogonek
-.br
-.B ecaron
-.br
-.B dcaron
-.br
-.B dstroke
-.br
-.B nacute
-.br
-.B ncaron
-.br
-.B odoubleacute
-.br
-.B rcaron
-.br
-.B uring
-.br
-.B udoubleacute
-.br
-.B tcedilla
-.br
-.B abovedot
-.br
-.B Hstroke
-.br
-.B Hcircumflex
-.br
-.B Iabovedot
-.br
-.B Gbreve
-.br
-.B Jcircumflex
-.br
-.B hstroke
-.br
-.B hcircumflex
-.br
-.B idotless
-.br
-.B gbreve
-.br
-.B jcircumflex
-.br
-.B Cabovedot
-.br
-.B Ccircumflex
-.br
-.B Gabovedot
-.br
-.B Gcircumflex
-.br
-.B Ubreve
-.br
-.B Scircumflex
-.br
-.B cabovedot
-.br
-.B ccircumflex
-.br
-.B gabovedot
-.br
-.B gcircumflex
-.br
-.B ubreve
-.br
-.B scircumflex
-.br
-.B kra
-.br
-.B kappa
-.br
-.B Rcedilla
-.br
-.B Itilde
-.br
-.B Lcedilla
-.br
-.B Emacron
-.br
-.B Gcedilla
-.br
-.B Tslash
-.br
-.B rcedilla
-.br
-.B itilde
-.br
-.B lcedilla
-.br
-.B emacron
-.br
-.B gcedilla
-.br
-.B tslash
-.br
-.B ENG
-.br
-.B eng
-.br
-.B Amacron
-.br
-.B Iogonek
-.br
-.B Eabovedot
-.br
-.B Imacron
-.br
-.B Ncedilla
-.br
-.B Omacron
-.br
-.B Kcedilla
-.br
-.B Uogonek
-.br
-.B Utilde
-.br
-.B Umacron
-.br
-.B amacron
-.br
-.B iogonek
-.br
-.B eabovedot
-.br
-.B imacron
-.br
-.B ncedilla
-.br
-.B omacron
-.br
-.B kcedilla
-.br
-.B uogonek
-.br
-.B utilde
-.br
-.B umacron
-.br
-.B Wcircumflex
-.br
-.B wcircumflex
-.br
-.B Ycircumflex
-.br
-.B ycircumflex
-.br
-.B Babovedot
-.br
-.B babovedot
-.br
-.B Dabovedot
-.br
-.B dabovedot
-.br
-.B Fabovedot
-.br
-.B fabovedot
-.br
-.B Mabovedot
-.br
-.B mabovedot
-.br
-.B Pabovedot
-.br
-.B pabovedot
-.br
-.B Sabovedot
-.br
-.B sabovedot
-.br
-.B Tabovedot
-.br
-.B tabovedot
-.br
-.B Wgrave
-.br
-.B wgrave
-.br
-.B Wacute
-.br
-.B wacute
-.br
-.B Wdiaeresis
-.br
-.B wdiaeresis
-.br
-.B Ygrave
-.br
-.B ygrave
-.br
-.B OE
-.br
-.B oe
-.br
-.B Ydiaeresis
-.br
-.B overline
-.br
-.B kana_fullstop
-.br
-.B kana_openingbracket
-.br
-.B kana_closingbracket
-.br
-.B kana_comma
-.br
-.B kana_conjunctive
-.br
-.B kana_middledot
-.br
-.B kana_WO
-.br
-.B kana_a
-.br
-.B kana_i
-.br
-.B kana_u
-.br
-.B kana_e
-.br
-.B kana_o
-.br
-.B kana_ya
-.br
-.B kana_yu
-.br
-.B kana_yo
-.br
-.B kana_tsu
-.br
-.B kana_tu
-.br
-.B prolongedsound
-.br
-.B kana_A
-.br
-.B kana_I
-.br
-.B kana_U
-.br
-.B kana_E
-.br
-.B kana_O
-.br
-.B kana_KA
-.br
-.B kana_KI
-.br
-.B kana_KU
-.br
-.B kana_KE
-.br
-.B kana_KO
-.br
-.B kana_SA
-.br
-.B kana_SHI
-.br
-.B kana_SU
-.br
-.B kana_SE
-.br
-.B kana_SO
-.br
-.B kana_TA
-.br
-.B kana_CHI
-.br
-.B kana_TI
-.br
-.B kana_TSU
-.br
-.B kana_TU
-.br
-.B kana_TE
-.br
-.B kana_TO
-.br
-.B kana_NA
-.br
-.B kana_NI
-.br
-.B kana_NU
-.br
-.B kana_NE
-.br
-.B kana_NO
-.br
-.B kana_HA
-.br
-.B kana_HI
-.br
-.B kana_FU
-.br
-.B kana_HU
-.br
-.B kana_HE
-.br
-.B kana_HO
-.br
-.B kana_MA
-.br
-.B kana_MI
-.br
-.B kana_MU
-.br
-.B kana_ME
-.br
-.B kana_MO
-.br
-.B kana_YA
-.br
-.B kana_YU
-.br
-.B kana_YO
-.br
-.B kana_RA
-.br
-.B kana_RI
-.br
-.B kana_RU
-.br
-.B kana_RE
-.br
-.B kana_RO
-.br
-.B kana_WA
-.br
-.B kana_N
-.br
-.B voicedsound
-.br
-.B semivoicedsound
-.br
-.B kana_switch
-.br
-.B Farsi_0
-.br
-.B Farsi_1
-.br
-.B Farsi_2
-.br
-.B Farsi_3
-.br
-.B Farsi_4
-.br
-.B Farsi_5
-.br
-.B Farsi_6
-.br
-.B Farsi_7
-.br
-.B Farsi_8
-.br
-.B Farsi_9
-.br
-.B Arabic_percent
-.br
-.B Arabic_superscript_alef
-.br
-.B Arabic_tteh
-.br
-.B Arabic_peh
-.br
-.B Arabic_tcheh
-.br
-.B Arabic_ddal
-.br
-.B Arabic_rreh
-.br
-.B Arabic_comma
-.br
-.B Arabic_fullstop
-.br
-.B Arabic_0
-.br
-.B Arabic_1
-.br
-.B Arabic_2
-.br
-.B Arabic_3
-.br
-.B Arabic_4
-.br
-.B Arabic_5
-.br
-.B Arabic_6
-.br
-.B Arabic_7
-.br
-.B Arabic_8
-.br
-.B Arabic_9
-.br
-.B Arabic_semicolon
-.br
-.B Arabic_question_mark
-.br
-.B Arabic_hamza
-.br
-.B Arabic_maddaonalef
-.br
-.B Arabic_hamzaonalef
-.br
-.B Arabic_hamzaonwaw
-.br
-.B Arabic_hamzaunderalef
-.br
-.B Arabic_hamzaonyeh
-.br
-.B Arabic_alef
-.br
-.B Arabic_beh
-.br
-.B Arabic_tehmarbuta
-.br
-.B Arabic_teh
-.br
-.B Arabic_theh
-.br
-.B Arabic_jeem
-.br
-.B Arabic_hah
-.br
-.B Arabic_khah
-.br
-.B Arabic_dal
-.br
-.B Arabic_thal
-.br
-.B Arabic_ra
-.br
-.B Arabic_zain
-.br
-.B Arabic_seen
-.br
-.B Arabic_sheen
-.br
-.B Arabic_sad
-.br
-.B Arabic_dad
-.br
-.B Arabic_tah
-.br
-.B Arabic_zah
-.br
-.B Arabic_ain
-.br
-.B Arabic_ghain
-.br
-.B Arabic_tatweel
-.br
-.B Arabic_feh
-.br
-.B Arabic_qaf
-.br
-.B Arabic_kaf
-.br
-.B Arabic_lam
-.br
-.B Arabic_meem
-.br
-.B Arabic_noon
-.br
-.B Arabic_ha
-.br
-.B Arabic_heh
-.br
-.B Arabic_waw
-.br
-.B Arabic_alefmaksura
-.br
-.B Arabic_yeh
-.br
-.B Arabic_fathatan
-.br
-.B Arabic_dammatan
-.br
-.B Arabic_kasratan
-.br
-.B Arabic_fatha
-.br
-.B Arabic_damma
-.br
-.B Arabic_kasra
-.br
-.B Arabic_shadda
-.br
-.B Arabic_sukun
-.br
-.B Arabic_madda_above
-.br
-.B Arabic_hamza_above
-.br
-.B Arabic_hamza_below
-.br
-.B Arabic_jeh
-.br
-.B Arabic_veh
-.br
-.B Arabic_keheh
-.br
-.B Arabic_gaf
-.br
-.B Arabic_noon_ghunna
-.br
-.B Arabic_heh_doachashmee
-.br
-.B Farsi_yeh
-.br
-.B Arabic_farsi_yeh
-.br
-.B Arabic_yeh_baree
-.br
-.B Arabic_heh_goal
-.br
-.B Arabic_switch
-.br
-.B Cyrillic_GHE_bar
-.br
-.B Cyrillic_ghe_bar
-.br
-.B Cyrillic_ZHE_descender
-.br
-.B Cyrillic_zhe_descender
-.br
-.B Cyrillic_KA_descender
-.br
-.B Cyrillic_ka_descender
-.br
-.B Cyrillic_KA_vertstroke
-.br
-.B Cyrillic_ka_vertstroke
-.br
-.B Cyrillic_EN_descender
-.br
-.B Cyrillic_en_descender
-.br
-.B Cyrillic_U_straight
-.br
-.B Cyrillic_u_straight
-.br
-.B Cyrillic_U_straight_bar
-.br
-.B Cyrillic_u_straight_bar
-.br
-.B Cyrillic_HA_descender
-.br
-.B Cyrillic_ha_descender
-.br
-.B Cyrillic_CHE_descender
-.br
-.B Cyrillic_che_descender
-.br
-.B Cyrillic_CHE_vertstroke
-.br
-.B Cyrillic_che_vertstroke
-.br
-.B Cyrillic_SHHA
-.br
-.B Cyrillic_shha
-.br
-.B Cyrillic_SCHWA
-.br
-.B Cyrillic_schwa
-.br
-.B Cyrillic_I_macron
-.br
-.B Cyrillic_i_macron
-.br
-.B Cyrillic_O_bar
-.br
-.B Cyrillic_o_bar
-.br
-.B Cyrillic_U_macron
-.br
-.B Cyrillic_u_macron
-.br
-.B Serbian_dje
-.br
-.B Macedonia_gje
-.br
-.B Cyrillic_io
-.br
-.B Ukrainian_ie
-.br
-.B Ukranian_je
-.br
-.B Macedonia_dse
-.br
-.B Ukrainian_i
-.br
-.B Ukranian_i
-.br
-.B Ukrainian_yi
-.br
-.B Ukranian_yi
-.br
-.B Cyrillic_je
-.br
-.B Serbian_je
-.br
-.B Cyrillic_lje
-.br
-.B Serbian_lje
-.br
-.B Cyrillic_nje
-.br
-.B Serbian_nje
-.br
-.B Serbian_tshe
-.br
-.B Macedonia_kje
-.br
-.B Ukrainian_ghe_with_upturn
-.br
-.B Byelorussian_shortu
-.br
-.B Cyrillic_dzhe
-.br
-.B Serbian_dze
-.br
-.B numerosign
-.br
-.B Serbian_DJE
-.br
-.B Macedonia_GJE
-.br
-.B Cyrillic_IO
-.br
-.B Ukrainian_IE
-.br
-.B Ukranian_JE
-.br
-.B Macedonia_DSE
-.br
-.B Ukrainian_I
-.br
-.B Ukranian_I
-.br
-.B Ukrainian_YI
-.br
-.B Ukranian_YI
-.br
-.B Cyrillic_JE
-.br
-.B Serbian_JE
-.br
-.B Cyrillic_LJE
-.br
-.B Serbian_LJE
-.br
-.B Cyrillic_NJE
-.br
-.B Serbian_NJE
-.br
-.B Serbian_TSHE
-.br
-.B Macedonia_KJE
-.br
-.B Ukrainian_GHE_WITH_UPTURN
-.br
-.B Byelorussian_SHORTU
-.br
-.B Cyrillic_DZHE
-.br
-.B Serbian_DZE
-.br
-.B Cyrillic_yu
-.br
-.B Cyrillic_a
-.br
-.B Cyrillic_be
-.br
-.B Cyrillic_tse
-.br
-.B Cyrillic_de
-.br
-.B Cyrillic_ie
-.br
-.B Cyrillic_ef
-.br
-.B Cyrillic_ghe
-.br
-.B Cyrillic_ha
-.br
-.B Cyrillic_i
-.br
-.B Cyrillic_shorti
-.br
-.B Cyrillic_ka
-.br
-.B Cyrillic_el
-.br
-.B Cyrillic_em
-.br
-.B Cyrillic_en
-.br
-.B Cyrillic_o
-.br
-.B Cyrillic_pe
-.br
-.B Cyrillic_ya
-.br
-.B Cyrillic_er
-.br
-.B Cyrillic_es
-.br
-.B Cyrillic_te
-.br
-.B Cyrillic_u
-.br
-.B Cyrillic_zhe
-.br
-.B Cyrillic_ve
-.br
-.B Cyrillic_softsign
-.br
-.B Cyrillic_yeru
-.br
-.B Cyrillic_ze
-.br
-.B Cyrillic_sha
-.br
-.B Cyrillic_e
-.br
-.B Cyrillic_shcha
-.br
-.B Cyrillic_che
-.br
-.B Cyrillic_hardsign
-.br
-.B Cyrillic_YU
-.br
-.B Cyrillic_A
-.br
-.B Cyrillic_BE
-.br
-.B Cyrillic_TSE
-.br
-.B Cyrillic_DE
-.br
-.B Cyrillic_IE
-.br
-.B Cyrillic_EF
-.br
-.B Cyrillic_GHE
-.br
-.B Cyrillic_HA
-.br
-.B Cyrillic_I
-.br
-.B Cyrillic_SHORTI
-.br
-.B Cyrillic_KA
-.br
-.B Cyrillic_EL
-.br
-.B Cyrillic_EM
-.br
-.B Cyrillic_EN
-.br
-.B Cyrillic_O
-.br
-.B Cyrillic_PE
-.br
-.B Cyrillic_YA
-.br
-.B Cyrillic_ER
-.br
-.B Cyrillic_ES
-.br
-.B Cyrillic_TE
-.br
-.B Cyrillic_U
-.br
-.B Cyrillic_ZHE
-.br
-.B Cyrillic_VE
-.br
-.B Cyrillic_SOFTSIGN
-.br
-.B Cyrillic_YERU
-.br
-.B Cyrillic_ZE
-.br
-.B Cyrillic_SHA
-.br
-.B Cyrillic_E
-.br
-.B Cyrillic_SHCHA
-.br
-.B Cyrillic_CHE
-.br
-.B Cyrillic_HARDSIGN
-.br
-.B Greek_ALPHAaccent
-.br
-.B Greek_EPSILONaccent
-.br
-.B Greek_ETAaccent
-.br
-.B Greek_IOTAaccent
-.br
-.B Greek_IOTAdieresis
-.br
-.B Greek_IOTAdiaeresis
-.br
-.B Greek_OMICRONaccent
-.br
-.B Greek_UPSILONaccent
-.br
-.B Greek_UPSILONdieresis
-.br
-.B Greek_OMEGAaccent
-.br
-.B Greek_accentdieresis
-.br
-.B Greek_horizbar
-.br
-.B Greek_alphaaccent
-.br
-.B Greek_epsilonaccent
-.br
-.B Greek_etaaccent
-.br
-.B Greek_iotaaccent
-.br
-.B Greek_iotadieresis
-.br
-.B Greek_iotaaccentdieresis
-.br
-.B Greek_omicronaccent
-.br
-.B Greek_upsilonaccent
-.br
-.B Greek_upsilondieresis
-.br
-.B Greek_upsilonaccentdieresis
-.br
-.B Greek_omegaaccent
-.br
-.B Greek_ALPHA
-.br
-.B Greek_BETA
-.br
-.B Greek_GAMMA
-.br
-.B Greek_DELTA
-.br
-.B Greek_EPSILON
-.br
-.B Greek_ZETA
-.br
-.B Greek_ETA
-.br
-.B Greek_THETA
-.br
-.B Greek_IOTA
-.br
-.B Greek_KAPPA
-.br
-.B Greek_LAMDA
-.br
-.B Greek_LAMBDA
-.br
-.B Greek_MU
-.br
-.B Greek_NU
-.br
-.B Greek_XI
-.br
-.B Greek_OMICRON
-.br
-.B Greek_PI
-.br
-.B Greek_RHO
-.br
-.B Greek_SIGMA
-.br
-.B Greek_TAU
-.br
-.B Greek_UPSILON
-.br
-.B Greek_PHI
-.br
-.B Greek_CHI
-.br
-.B Greek_PSI
-.br
-.B Greek_OMEGA
-.br
-.B Greek_alpha
-.br
-.B Greek_beta
-.br
-.B Greek_gamma
-.br
-.B Greek_delta
-.br
-.B Greek_epsilon
-.br
-.B Greek_zeta
-.br
-.B Greek_eta
-.br
-.B Greek_theta
-.br
-.B Greek_iota
-.br
-.B Greek_kappa
-.br
-.B Greek_lamda
-.br
-.B Greek_lambda
-.br
-.B Greek_mu
-.br
-.B Greek_nu
-.br
-.B Greek_xi
-.br
-.B Greek_omicron
-.br
-.B Greek_pi
-.br
-.B Greek_rho
-.br
-.B Greek_sigma
-.br
-.B Greek_finalsmallsigma
-.br
-.B Greek_tau
-.br
-.B Greek_upsilon
-.br
-.B Greek_phi
-.br
-.B Greek_chi
-.br
-.B Greek_psi
-.br
-.B Greek_omega
-.br
-.B Greek_switch
-.br
-.B leftradical
-.br
-.B topleftradical
-.br
-.B horizconnector
-.br
-.B topintegral
-.br
-.B botintegral
-.br
-.B vertconnector
-.br
-.B topleftsqbracket
-.br
-.B botleftsqbracket
-.br
-.B toprightsqbracket
-.br
-.B botrightsqbracket
-.br
-.B topleftparens
-.br
-.B botleftparens
-.br
-.B toprightparens
-.br
-.B botrightparens
-.br
-.B leftmiddlecurlybrace
-.br
-.B rightmiddlecurlybrace
-.br
-.B topleftsummation
-.br
-.B botleftsummation
-.br
-.B topvertsummationconnector
-.br
-.B botvertsummationconnector
-.br
-.B toprightsummation
-.br
-.B botrightsummation
-.br
-.B rightmiddlesummation
-.br
-.B lessthanequal
-.br
-.B notequal
-.br
-.B greaterthanequal
-.br
-.B integral
-.br
-.B therefore
-.br
-.B variation
-.br
-.B infinity
-.br
-.B nabla
-.br
-.B approximate
-.br
-.B similarequal
-.br
-.B ifonlyif
-.br
-.B implies
-.br
-.B identical
-.br
-.B radical
-.br
-.B includedin
-.br
-.B includes
-.br
-.B intersection
-.br
-.B union
-.br
-.B logicaland
-.br
-.B logicalor
-.br
-.B partialderivative
-.br
-.B function
-.br
-.B leftarrow
-.br
-.B uparrow
-.br
-.B rightarrow
-.br
-.B downarrow
-.br
-.B blank
-.br
-.B soliddiamond
-.br
-.B checkerboard
-.br
-.B ht
-.br
-.B ff
-.br
-.B cr
-.br
-.B lf
-.br
-.B nl
-.br
-.B vt
-.br
-.B lowrightcorner
-.br
-.B uprightcorner
-.br
-.B upleftcorner
-.br
-.B lowleftcorner
-.br
-.B crossinglines
-.br
-.B horizlinescan1
-.br
-.B horizlinescan3
-.br
-.B horizlinescan5
-.br
-.B horizlinescan7
-.br
-.B horizlinescan9
-.br
-.B leftt
-.br
-.B rightt
-.br
-.B bott
-.br
-.B topt
-.br
-.B vertbar
-.br
-.B emspace
-.br
-.B enspace
-.br
-.B em3space
-.br
-.B em4space
-.br
-.B digitspace
-.br
-.B punctspace
-.br
-.B thinspace
-.br
-.B hairspace
-.br
-.B emdash
-.br
-.B endash
-.br
-.B signifblank
-.br
-.B ellipsis
-.br
-.B doubbaselinedot
-.br
-.B onethird
-.br
-.B twothirds
-.br
-.B onefifth
-.br
-.B twofifths
-.br
-.B threefifths
-.br
-.B fourfifths
-.br
-.B onesixth
-.br
-.B fivesixths
-.br
-.B careof
-.br
-.B figdash
-.br
-.B leftanglebracket
-.br
-.B decimalpoint
-.br
-.B rightanglebracket
-.br
-.B marker
-.br
-.B oneeighth
-.br
-.B threeeighths
-.br
-.B fiveeighths
-.br
-.B seveneighths
-.br
-.B trademark
-.br
-.B signaturemark
-.br
-.B trademarkincircle
-.br
-.B leftopentriangle
-.br
-.B rightopentriangle
-.br
-.B emopencircle
-.br
-.B emopenrectangle
-.br
-.B leftsinglequotemark
-.br
-.B rightsinglequotemark
-.br
-.B leftdoublequotemark
-.br
-.B rightdoublequotemark
-.br
-.B prescription
-.br
-.B permille
-.br
-.B minutes
-.br
-.B seconds
-.br
-.B latincross
-.br
-.B hexagram
-.br
-.B filledrectbullet
-.br
-.B filledlefttribullet
-.br
-.B filledrighttribullet
-.br
-.B emfilledcircle
-.br
-.B emfilledrect
-.br
-.B enopencircbullet
-.br
-.B enopensquarebullet
-.br
-.B openrectbullet
-.br
-.B opentribulletup
-.br
-.B opentribulletdown
-.br
-.B openstar
-.br
-.B enfilledcircbullet
-.br
-.B enfilledsqbullet
-.br
-.B filledtribulletup
-.br
-.B filledtribulletdown
-.br
-.B leftpointer
-.br
-.B rightpointer
-.br
-.B club
-.br
-.B diamond
-.br
-.B heart
-.br
-.B maltesecross
-.br
-.B dagger
-.br
-.B doubledagger
-.br
-.B checkmark
-.br
-.B ballotcross
-.br
-.B musicalsharp
-.br
-.B musicalflat
-.br
-.B malesymbol
-.br
-.B femalesymbol
-.br
-.B telephone
-.br
-.B telephonerecorder
-.br
-.B phonographcopyright
-.br
-.B caret
-.br
-.B singlelowquotemark
-.br
-.B doublelowquotemark
-.br
-.B cursor
-.br
-.B leftcaret
-.br
-.B rightcaret
-.br
-.B downcaret
-.br
-.B upcaret
-.br
-.B overbar
-.br
-.B downtack
-.br
-.B upshoe
-.br
-.B downstile
-.br
-.B underbar
-.br
-.B jot
-.br
-.B quad
-.br
-.B uptack
-.br
-.B circle
-.br
-.B upstile
-.br
-.B downshoe
-.br
-.B rightshoe
-.br
-.B leftshoe
-.br
-.B lefttack
-.br
-.B righttack
-.br
-.B hebrew_doublelowline
-.br
-.B hebrew_aleph
-.br
-.B hebrew_bet
-.br
-.B hebrew_beth
-.br
-.B hebrew_gimel
-.br
-.B hebrew_gimmel
-.br
-.B hebrew_dalet
-.br
-.B hebrew_daleth
-.br
-.B hebrew_he
-.br
-.B hebrew_waw
-.br
-.B hebrew_zain
-.br
-.B hebrew_zayin
-.br
-.B hebrew_chet
-.br
-.B hebrew_het
-.br
-.B hebrew_tet
-.br
-.B hebrew_teth
-.br
-.B hebrew_yod
-.br
-.B hebrew_finalkaph
-.br
-.B hebrew_kaph
-.br
-.B hebrew_lamed
-.br
-.B hebrew_finalmem
-.br
-.B hebrew_mem
-.br
-.B hebrew_finalnun
-.br
-.B hebrew_nun
-.br
-.B hebrew_samech
-.br
-.B hebrew_samekh
-.br
-.B hebrew_ayin
-.br
-.B hebrew_finalpe
-.br
-.B hebrew_pe
-.br
-.B hebrew_finalzade
-.br
-.B hebrew_finalzadi
-.br
-.B hebrew_zade
-.br
-.B hebrew_zadi
-.br
-.B hebrew_qoph
-.br
-.B hebrew_kuf
-.br
-.B hebrew_resh
-.br
-.B hebrew_shin
-.br
-.B hebrew_taw
-.br
-.B hebrew_taf
-.br
-.B Hebrew_switch
-.br
-.B Thai_kokai
-.br
-.B Thai_khokhai
-.br
-.B Thai_khokhuat
-.br
-.B Thai_khokhwai
-.br
-.B Thai_khokhon
-.br
-.B Thai_khorakhang
-.br
-.B Thai_ngongu
-.br
-.B Thai_chochan
-.br
-.B Thai_choching
-.br
-.B Thai_chochang
-.br
-.B Thai_soso
-.br
-.B Thai_chochoe
-.br
-.B Thai_yoying
-.br
-.B Thai_dochada
-.br
-.B Thai_topatak
-.br
-.B Thai_thothan
-.br
-.B Thai_thonangmontho
-.br
-.B Thai_thophuthao
-.br
-.B Thai_nonen
-.br
-.B Thai_dodek
-.br
-.B Thai_totao
-.br
-.B Thai_thothung
-.br
-.B Thai_thothahan
-.br
-.B Thai_thothong
-.br
-.B Thai_nonu
-.br
-.B Thai_bobaimai
-.br
-.B Thai_popla
-.br
-.B Thai_phophung
-.br
-.B Thai_fofa
-.br
-.B Thai_phophan
-.br
-.B Thai_fofan
-.br
-.B Thai_phosamphao
-.br
-.B Thai_moma
-.br
-.B Thai_yoyak
-.br
-.B Thai_rorua
-.br
-.B Thai_ru
-.br
-.B Thai_loling
-.br
-.B Thai_lu
-.br
-.B Thai_wowaen
-.br
-.B Thai_sosala
-.br
-.B Thai_sorusi
-.br
-.B Thai_sosua
-.br
-.B Thai_hohip
-.br
-.B Thai_lochula
-.br
-.B Thai_oang
-.br
-.B Thai_honokhuk
-.br
-.B Thai_paiyannoi
-.br
-.B Thai_saraa
-.br
-.B Thai_maihanakat
-.br
-.B Thai_saraaa
-.br
-.B Thai_saraam
-.br
-.B Thai_sarai
-.br
-.B Thai_saraii
-.br
-.B Thai_saraue
-.br
-.B Thai_sarauee
-.br
-.B Thai_sarau
-.br
-.B Thai_sarauu
-.br
-.B Thai_phinthu
-.br
-.B Thai_maihanakat_maitho
-.br
-.B Thai_baht
-.br
-.B Thai_sarae
-.br
-.B Thai_saraae
-.br
-.B Thai_sarao
-.br
-.B Thai_saraaimaimuan
-.br
-.B Thai_saraaimaimalai
-.br
-.B Thai_lakkhangyao
-.br
-.B Thai_maiyamok
-.br
-.B Thai_maitaikhu
-.br
-.B Thai_maiek
-.br
-.B Thai_maitho
-.br
-.B Thai_maitri
-.br
-.B Thai_maichattawa
-.br
-.B Thai_thanthakhat
-.br
-.B Thai_nikhahit
-.br
-.B Thai_leksun
-.br
-.B Thai_leknung
-.br
-.B Thai_leksong
-.br
-.B Thai_leksam
-.br
-.B Thai_leksi
-.br
-.B Thai_lekha
-.br
-.B Thai_lekhok
-.br
-.B Thai_lekchet
-.br
-.B Thai_lekpaet
-.br
-.B Thai_lekkao
-.br
-.B Hangul
-.br
-.B Hangul_Start
-.br
-.B Hangul_End
-.br
-.B Hangul_Hanja
-.br
-.B Hangul_Jamo
-.br
-.B Hangul_Romaja
-.br
-.B Hangul_Codeinput
-.br
-.B Hangul_Jeonja
-.br
-.B Hangul_Banja
-.br
-.B Hangul_PreHanja
-.br
-.B Hangul_PostHanja
-.br
-.B Hangul_SingleCandidate
-.br
-.B Hangul_MultipleCandidate
-.br
-.B Hangul_PreviousCandidate
-.br
-.B Hangul_Special
-.br
-.B Hangul_switch
-.br
-.B Hangul_Kiyeog
-.br
-.B Hangul_SsangKiyeog
-.br
-.B Hangul_KiyeogSios
-.br
-.B Hangul_Nieun
-.br
-.B Hangul_NieunJieuj
-.br
-.B Hangul_NieunHieuh
-.br
-.B Hangul_Dikeud
-.br
-.B Hangul_SsangDikeud
-.br
-.B Hangul_Rieul
-.br
-.B Hangul_RieulKiyeog
-.br
-.B Hangul_RieulMieum
-.br
-.B Hangul_RieulPieub
-.br
-.B Hangul_RieulSios
-.br
-.B Hangul_RieulTieut
-.br
-.B Hangul_RieulPhieuf
-.br
-.B Hangul_RieulHieuh
-.br
-.B Hangul_Mieum
-.br
-.B Hangul_Pieub
-.br
-.B Hangul_SsangPieub
-.br
-.B Hangul_PieubSios
-.br
-.B Hangul_Sios
-.br
-.B Hangul_SsangSios
-.br
-.B Hangul_Ieung
-.br
-.B Hangul_Jieuj
-.br
-.B Hangul_SsangJieuj
-.br
-.B Hangul_Cieuc
-.br
-.B Hangul_Khieuq
-.br
-.B Hangul_Tieut
-.br
-.B Hangul_Phieuf
-.br
-.B Hangul_Hieuh
-.br
-.B Hangul_A
-.br
-.B Hangul_AE
-.br
-.B Hangul_YA
-.br
-.B Hangul_YAE
-.br
-.B Hangul_EO
-.br
-.B Hangul_E
-.br
-.B Hangul_YEO
-.br
-.B Hangul_YE
-.br
-.B Hangul_O
-.br
-.B Hangul_WA
-.br
-.B Hangul_WAE
-.br
-.B Hangul_OE
-.br
-.B Hangul_YO
-.br
-.B Hangul_U
-.br
-.B Hangul_WEO
-.br
-.B Hangul_WE
-.br
-.B Hangul_WI
-.br
-.B Hangul_YU
-.br
-.B Hangul_EU
-.br
-.B Hangul_YI
-.br
-.B Hangul_I
-.br
-.B Hangul_J_Kiyeog
-.br
-.B Hangul_J_SsangKiyeog
-.br
-.B Hangul_J_KiyeogSios
-.br
-.B Hangul_J_Nieun
-.br
-.B Hangul_J_NieunJieuj
-.br
-.B Hangul_J_NieunHieuh
-.br
-.B Hangul_J_Dikeud
-.br
-.B Hangul_J_Rieul
-.br
-.B Hangul_J_RieulKiyeog
-.br
-.B Hangul_J_RieulMieum
-.br
-.B Hangul_J_RieulPieub
-.br
-.B Hangul_J_RieulSios
-.br
-.B Hangul_J_RieulTieut
-.br
-.B Hangul_J_RieulPhieuf
-.br
-.B Hangul_J_RieulHieuh
-.br
-.B Hangul_J_Mieum
-.br
-.B Hangul_J_Pieub
-.br
-.B Hangul_J_PieubSios
-.br
-.B Hangul_J_Sios
-.br
-.B Hangul_J_SsangSios
-.br
-.B Hangul_J_Ieung
-.br
-.B Hangul_J_Jieuj
-.br
-.B Hangul_J_Cieuc
-.br
-.B Hangul_J_Khieuq
-.br
-.B Hangul_J_Tieut
-.br
-.B Hangul_J_Phieuf
-.br
-.B Hangul_J_Hieuh
-.br
-.B Hangul_RieulYeorinHieuh
-.br
-.B Hangul_SunkyeongeumMieum
-.br
-.B Hangul_SunkyeongeumPieub
-.br
-.B Hangul_PanSios
-.br
-.B Hangul_KkogjiDalrinIeung
-.br
-.B Hangul_SunkyeongeumPhieuf
-.br
-.B Hangul_YeorinHieuh
-.br
-.B Hangul_AraeA
-.br
-.B Hangul_AraeAE
-.br
-.B Hangul_J_PanSios
-.br
-.B Hangul_J_KkogjiDalrinIeung
-.br
-.B Hangul_J_YeorinHieuh
-.br
-.B Korean_Won
-.br
-.B Armenian_ligature_ew
-.br
-.B Armenian_full_stop
-.br
-.B Armenian_verjaket
-.br
-.B Armenian_separation_mark
-.br
-.B Armenian_but
-.br
-.B Armenian_hyphen
-.br
-.B Armenian_yentamna
-.br
-.B Armenian_exclam
-.br
-.B Armenian_amanak
-.br
-.B Armenian_accent
-.br
-.B Armenian_shesht
-.br
-.B Armenian_question
-.br
-.B Armenian_paruyk
-.br
-.B Armenian_AYB
-.br
-.B Armenian_ayb
-.br
-.B Armenian_BEN
-.br
-.B Armenian_ben
-.br
-.B Armenian_GIM
-.br
-.B Armenian_gim
-.br
-.B Armenian_DA
-.br
-.B Armenian_da
-.br
-.B Armenian_YECH
-.br
-.B Armenian_yech
-.br
-.B Armenian_ZA
-.br
-.B Armenian_za
-.br
-.B Armenian_E
-.br
-.B Armenian_e
-.br
-.B Armenian_AT
-.br
-.B Armenian_at
-.br
-.B Armenian_TO
-.br
-.B Armenian_to
-.br
-.B Armenian_ZHE
-.br
-.B Armenian_zhe
-.br
-.B Armenian_INI
-.br
-.B Armenian_ini
-.br
-.B Armenian_LYUN
-.br
-.B Armenian_lyun
-.br
-.B Armenian_KHE
-.br
-.B Armenian_khe
-.br
-.B Armenian_TSA
-.br
-.B Armenian_tsa
-.br
-.B Armenian_KEN
-.br
-.B Armenian_ken
-.br
-.B Armenian_HO
-.br
-.B Armenian_ho
-.br
-.B Armenian_DZA
-.br
-.B Armenian_dza
-.br
-.B Armenian_GHAT
-.br
-.B Armenian_ghat
-.br
-.B Armenian_TCHE
-.br
-.B Armenian_tche
-.br
-.B Armenian_MEN
-.br
-.B Armenian_men
-.br
-.B Armenian_HI
-.br
-.B Armenian_hi
-.br
-.B Armenian_NU
-.br
-.B Armenian_nu
-.br
-.B Armenian_SHA
-.br
-.B Armenian_sha
-.br
-.B Armenian_VO
-.br
-.B Armenian_vo
-.br
-.B Armenian_CHA
-.br
-.B Armenian_cha
-.br
-.B Armenian_PE
-.br
-.B Armenian_pe
-.br
-.B Armenian_JE
-.br
-.B Armenian_je
-.br
-.B Armenian_RA
-.br
-.B Armenian_ra
-.br
-.B Armenian_SE
-.br
-.B Armenian_se
-.br
-.B Armenian_VEV
-.br
-.B Armenian_vev
-.br
-.B Armenian_TYUN
-.br
-.B Armenian_tyun
-.br
-.B Armenian_RE
-.br
-.B Armenian_re
-.br
-.B Armenian_TSO
-.br
-.B Armenian_tso
-.br
-.B Armenian_VYUN
-.br
-.B Armenian_vyun
-.br
-.B Armenian_PYUR
-.br
-.B Armenian_pyur
-.br
-.B Armenian_KE
-.br
-.B Armenian_ke
-.br
-.B Armenian_O
-.br
-.B Armenian_o
-.br
-.B Armenian_FE
-.br
-.B Armenian_fe
-.br
-.B Armenian_apostrophe
-.br
-.B Georgian_an
-.br
-.B Georgian_ban
-.br
-.B Georgian_gan
-.br
-.B Georgian_don
-.br
-.B Georgian_en
-.br
-.B Georgian_vin
-.br
-.B Georgian_zen
-.br
-.B Georgian_tan
-.br
-.B Georgian_in
-.br
-.B Georgian_kan
-.br
-.B Georgian_las
-.br
-.B Georgian_man
-.br
-.B Georgian_nar
-.br
-.B Georgian_on
-.br
-.B Georgian_par
-.br
-.B Georgian_zhar
-.br
-.B Georgian_rae
-.br
-.B Georgian_san
-.br
-.B Georgian_tar
-.br
-.B Georgian_un
-.br
-.B Georgian_phar
-.br
-.B Georgian_khar
-.br
-.B Georgian_ghan
-.br
-.B Georgian_qar
-.br
-.B Georgian_shin
-.br
-.B Georgian_chin
-.br
-.B Georgian_can
-.br
-.B Georgian_jil
-.br
-.B Georgian_cil
-.br
-.B Georgian_char
-.br
-.B Georgian_xan
-.br
-.B Georgian_jhan
-.br
-.B Georgian_hae
-.br
-.B Georgian_he
-.br
-.B Georgian_hie
-.br
-.B Georgian_we
-.br
-.B Georgian_har
-.br
-.B Georgian_hoe
-.br
-.B Georgian_fi
-.br
-.B Xabovedot
-.br
-.B Ibreve
-.br
-.B Zstroke
-.br
-.B Gcaron
-.br
-.B Ocaron
-.br
-.B Obarred
-.br
-.B xabovedot
-.br
-.B ibreve
-.br
-.B zstroke
-.br
-.B gcaron
-.br
-.B ocaron
-.br
-.B obarred
-.br
-.B SCHWA
-.br
-.B schwa
-.br
-.B EZH
-.br
-.B ezh
-.br
-.B Lbelowdot
-.br
-.B lbelowdot
-.br
-.B Abelowdot
-.br
-.B abelowdot
-.br
-.B Ahook
-.br
-.B ahook
-.br
-.B Acircumflexacute
-.br
-.B acircumflexacute
-.br
-.B Acircumflexgrave
-.br
-.B acircumflexgrave
-.br
-.B Acircumflexhook
-.br
-.B acircumflexhook
-.br
-.B Acircumflextilde
-.br
-.B acircumflextilde
-.br
-.B Acircumflexbelowdot
-.br
-.B acircumflexbelowdot
-.br
-.B Abreveacute
-.br
-.B abreveacute
-.br
-.B Abrevegrave
-.br
-.B abrevegrave
-.br
-.B Abrevehook
-.br
-.B abrevehook
-.br
-.B Abrevetilde
-.br
-.B abrevetilde
-.br
-.B Abrevebelowdot
-.br
-.B abrevebelowdot
-.br
-.B Ebelowdot
-.br
-.B ebelowdot
-.br
-.B Ehook
-.br
-.B ehook
-.br
-.B Etilde
-.br
-.B etilde
-.br
-.B Ecircumflexacute
-.br
-.B ecircumflexacute
-.br
-.B Ecircumflexgrave
-.br
-.B ecircumflexgrave
-.br
-.B Ecircumflexhook
-.br
-.B ecircumflexhook
-.br
-.B Ecircumflextilde
-.br
-.B ecircumflextilde
-.br
-.B Ecircumflexbelowdot
-.br
-.B ecircumflexbelowdot
-.br
-.B Ihook
-.br
-.B ihook
-.br
-.B Ibelowdot
-.br
-.B ibelowdot
-.br
-.B Obelowdot
-.br
-.B obelowdot
-.br
-.B Ohook
-.br
-.B ohook
-.br
-.B Ocircumflexacute
-.br
-.B ocircumflexacute
-.br
-.B Ocircumflexgrave
-.br
-.B ocircumflexgrave
-.br
-.B Ocircumflexhook
-.br
-.B ocircumflexhook
-.br
-.B Ocircumflextilde
-.br
-.B ocircumflextilde
-.br
-.B Ocircumflexbelowdot
-.br
-.B ocircumflexbelowdot
-.br
-.B Ohornacute
-.br
-.B ohornacute
-.br
-.B Ohorngrave
-.br
-.B ohorngrave
-.br
-.B Ohornhook
-.br
-.B ohornhook
-.br
-.B Ohorntilde
-.br
-.B ohorntilde
-.br
-.B Ohornbelowdot
-.br
-.B ohornbelowdot
-.br
-.B Ubelowdot
-.br
-.B ubelowdot
-.br
-.B Uhook
-.br
-.B uhook
-.br
-.B Uhornacute
-.br
-.B uhornacute
-.br
-.B Uhorngrave
-.br
-.B uhorngrave
-.br
-.B Uhornhook
-.br
-.B uhornhook
-.br
-.B Uhorntilde
-.br
-.B uhorntilde
-.br
-.B Uhornbelowdot
-.br
-.B uhornbelowdot
-.br
-.B Ybelowdot
-.br
-.B ybelowdot
-.br
-.B Yhook
-.br
-.B yhook
-.br
-.B Ytilde
-.br
-.B ytilde
-.br
-.B Ohorn
-.br
-.B ohorn
-.br
-.B Uhorn
-.br
-.B uhorn
-.br
-.B EcuSign
-.br
-.B ColonSign
-.br
-.B CruzeiroSign
-.br
-.B FFrancSign
-.br
-.B LiraSign
-.br
-.B MillSign
-.br
-.B NairaSign
-.br
-.B PesetaSign
-.br
-.B RupeeSign
-.br
-.B WonSign
-.br
-.B NewSheqelSign
-.br
-.B DongSign
-.br
-.B EuroSign
-.br
-.B zerosuperior
-.br
-.B foursuperior
-.br
-.B fivesuperior
-.br
-.B sixsuperior
-.br
-.B sevensuperior
-.br
-.B eightsuperior
-.br
-.B ninesuperior
-.br
-.B zerosubscript
-.br
-.B onesubscript
-.br
-.B twosubscript
-.br
-.B threesubscript
-.br
-.B foursubscript
-.br
-.B fivesubscript
-.br
-.B sixsubscript
-.br
-.B sevensubscript
-.br
-.B eightsubscript
-.br
-.B ninesubscript
-.br
-.B partdifferential
-.br
-.B emptyset
-.br
-.B elementof
-.br
-.B notelementof
-.br
-.B containsas
-.br
-.B squareroot
-.br
-.B cuberoot
-.br
-.B fourthroot
-.br
-.B dintegral
-.br
-.B tintegral
-.br
-.B because
-.br
-.B approxeq
-.br
-.B notapproxeq
-.br
-.B notidentical
-.br
-.B stricteq
-.br
-.B braille_dot_1
-.br
-.B braille_dot_2
-.br
-.B braille_dot_3
-.br
-.B braille_dot_4
-.br
-.B braille_dot_5
-.br
-.B braille_dot_6
-.br
-.B braille_dot_7
-.br
-.B braille_dot_8
-.br
-.B braille_dot_9
-.br
-.B braille_dot_10
-.br
-.B braille_blank
-.br
-.B braille_dots_1
-.br
-.B braille_dots_2
-.br
-.B braille_dots_12
-.br
-.B braille_dots_3
-.br
-.B braille_dots_13
-.br
-.B braille_dots_23
-.br
-.B braille_dots_123
-.br
-.B braille_dots_4
-.br
-.B braille_dots_14
-.br
-.B braille_dots_24
-.br
-.B braille_dots_124
-.br
-.B braille_dots_34
-.br
-.B braille_dots_134
-.br
-.B braille_dots_234
-.br
-.B braille_dots_1234
-.br
-.B braille_dots_5
-.br
-.B braille_dots_15
-.br
-.B braille_dots_25
-.br
-.B braille_dots_125
-.br
-.B braille_dots_35
-.br
-.B braille_dots_135
-.br
-.B braille_dots_235
-.br
-.B braille_dots_1235
-.br
-.B braille_dots_45
-.br
-.B braille_dots_145
-.br
-.B braille_dots_245
-.br
-.B braille_dots_1245
-.br
-.B braille_dots_345
-.br
-.B braille_dots_1345
-.br
-.B braille_dots_2345
-.br
-.B braille_dots_12345
-.br
-.B braille_dots_6
-.br
-.B braille_dots_16
-.br
-.B braille_dots_26
-.br
-.B braille_dots_126
-.br
-.B braille_dots_36
-.br
-.B braille_dots_136
-.br
-.B braille_dots_236
-.br
-.B braille_dots_1236
-.br
-.B braille_dots_46
-.br
-.B braille_dots_146
-.br
-.B braille_dots_246
-.br
-.B braille_dots_1246
-.br
-.B braille_dots_346
-.br
-.B braille_dots_1346
-.br
-.B braille_dots_2346
-.br
-.B braille_dots_12346
-.br
-.B braille_dots_56
-.br
-.B braille_dots_156
-.br
-.B braille_dots_256
-.br
-.B braille_dots_1256
-.br
-.B braille_dots_356
-.br
-.B braille_dots_1356
-.br
-.B braille_dots_2356
-.br
-.B braille_dots_12356
-.br
-.B braille_dots_456
-.br
-.B braille_dots_1456
-.br
-.B braille_dots_2456
-.br
-.B braille_dots_12456
-.br
-.B braille_dots_3456
-.br
-.B braille_dots_13456
-.br
-.B braille_dots_23456
-.br
-.B braille_dots_123456
-.br
-.B braille_dots_7
-.br
-.B braille_dots_17
-.br
-.B braille_dots_27
-.br
-.B braille_dots_127
-.br
-.B braille_dots_37
-.br
-.B braille_dots_137
-.br
-.B braille_dots_237
-.br
-.B braille_dots_1237
-.br
-.B braille_dots_47
-.br
-.B braille_dots_147
-.br
-.B braille_dots_247
-.br
-.B braille_dots_1247
-.br
-.B braille_dots_347
-.br
-.B braille_dots_1347
-.br
-.B braille_dots_2347
-.br
-.B braille_dots_12347
-.br
-.B braille_dots_57
-.br
-.B braille_dots_157
-.br
-.B braille_dots_257
-.br
-.B braille_dots_1257
-.br
-.B braille_dots_357
-.br
-.B braille_dots_1357
-.br
-.B braille_dots_2357
-.br
-.B braille_dots_12357
-.br
-.B braille_dots_457
-.br
-.B braille_dots_1457
-.br
-.B braille_dots_2457
-.br
-.B braille_dots_12457
-.br
-.B braille_dots_3457
-.br
-.B braille_dots_13457
-.br
-.B braille_dots_23457
-.br
-.B braille_dots_123457
-.br
-.B braille_dots_67
-.br
-.B braille_dots_167
-.br
-.B braille_dots_267
-.br
-.B braille_dots_1267
-.br
-.B braille_dots_367
-.br
-.B braille_dots_1367
-.br
-.B braille_dots_2367
-.br
-.B braille_dots_12367
-.br
-.B braille_dots_467
-.br
-.B braille_dots_1467
-.br
-.B braille_dots_2467
-.br
-.B braille_dots_12467
-.br
-.B braille_dots_3467
-.br
-.B braille_dots_13467
-.br
-.B braille_dots_23467
-.br
-.B braille_dots_123467
-.br
-.B braille_dots_567
-.br
-.B braille_dots_1567
-.br
-.B braille_dots_2567
-.br
-.B braille_dots_12567
-.br
-.B braille_dots_3567
-.br
-.B braille_dots_13567
-.br
-.B braille_dots_23567
-.br
-.B braille_dots_123567
-.br
-.B braille_dots_4567
-.br
-.B braille_dots_14567
-.br
-.B braille_dots_24567
-.br
-.B braille_dots_124567
-.br
-.B braille_dots_34567
-.br
-.B braille_dots_134567
-.br
-.B braille_dots_234567
-.br
-.B braille_dots_1234567
-.br
-.B braille_dots_8
-.br
-.B braille_dots_18
-.br
-.B braille_dots_28
-.br
-.B braille_dots_128
-.br
-.B braille_dots_38
-.br
-.B braille_dots_138
-.br
-.B braille_dots_238
-.br
-.B braille_dots_1238
-.br
-.B braille_dots_48
-.br
-.B braille_dots_148
-.br
-.B braille_dots_248
-.br
-.B braille_dots_1248
-.br
-.B braille_dots_348
-.br
-.B braille_dots_1348
-.br
-.B braille_dots_2348
-.br
-.B braille_dots_12348
-.br
-.B braille_dots_58
-.br
-.B braille_dots_158
-.br
-.B braille_dots_258
-.br
-.B braille_dots_1258
-.br
-.B braille_dots_358
-.br
-.B braille_dots_1358
-.br
-.B braille_dots_2358
-.br
-.B braille_dots_12358
-.br
-.B braille_dots_458
-.br
-.B braille_dots_1458
-.br
-.B braille_dots_2458
-.br
-.B braille_dots_12458
-.br
-.B braille_dots_3458
-.br
-.B braille_dots_13458
-.br
-.B braille_dots_23458
-.br
-.B braille_dots_123458
-.br
-.B braille_dots_68
-.br
-.B braille_dots_168
-.br
-.B braille_dots_268
-.br
-.B braille_dots_1268
-.br
-.B braille_dots_368
-.br
-.B braille_dots_1368
-.br
-.B braille_dots_2368
-.br
-.B braille_dots_12368
-.br
-.B braille_dots_468
-.br
-.B braille_dots_1468
-.br
-.B braille_dots_2468
-.br
-.B braille_dots_12468
-.br
-.B braille_dots_3468
-.br
-.B braille_dots_13468
-.br
-.B braille_dots_23468
-.br
-.B braille_dots_123468
-.br
-.B braille_dots_568
-.br
-.B braille_dots_1568
-.br
-.B braille_dots_2568
-.br
-.B braille_dots_12568
-.br
-.B braille_dots_3568
-.br
-.B braille_dots_13568
-.br
-.B braille_dots_23568
-.br
-.B braille_dots_123568
-.br
-.B braille_dots_4568
-.br
-.B braille_dots_14568
-.br
-.B braille_dots_24568
-.br
-.B braille_dots_124568
-.br
-.B braille_dots_34568
-.br
-.B braille_dots_134568
-.br
-.B braille_dots_234568
-.br
-.B braille_dots_1234568
-.br
-.B braille_dots_78
-.br
-.B braille_dots_178
-.br
-.B braille_dots_278
-.br
-.B braille_dots_1278
-.br
-.B braille_dots_378
-.br
-.B braille_dots_1378
-.br
-.B braille_dots_2378
-.br
-.B braille_dots_12378
-.br
-.B braille_dots_478
-.br
-.B braille_dots_1478
-.br
-.B braille_dots_2478
-.br
-.B braille_dots_12478
-.br
-.B braille_dots_3478
-.br
-.B braille_dots_13478
-.br
-.B braille_dots_23478
-.br
-.B braille_dots_123478
-.br
-.B braille_dots_578
-.br
-.B braille_dots_1578
-.br
-.B braille_dots_2578
-.br
-.B braille_dots_12578
-.br
-.B braille_dots_3578
-.br
-.B braille_dots_13578
-.br
-.B braille_dots_23578
-.br
-.B braille_dots_123578
-.br
-.B braille_dots_4578
-.br
-.B braille_dots_14578
-.br
-.B braille_dots_24578
-.br
-.B braille_dots_124578
-.br
-.B braille_dots_34578
-.br
-.B braille_dots_134578
-.br
-.B braille_dots_234578
-.br
-.B braille_dots_1234578
-.br
-.B braille_dots_678
-.br
-.B braille_dots_1678
-.br
-.B braille_dots_2678
-.br
-.B braille_dots_12678
-.br
-.B braille_dots_3678
-.br
-.B braille_dots_13678
-.br
-.B braille_dots_23678
-.br
-.B braille_dots_123678
-.br
-.B braille_dots_4678
-.br
-.B braille_dots_14678
-.br
-.B braille_dots_24678
-.br
-.B braille_dots_124678
-.br
-.B braille_dots_34678
-.br
-.B braille_dots_134678
-.br
-.B braille_dots_234678
-.br
-.B braille_dots_1234678
-.br
-.B braille_dots_5678
-.br
-.B braille_dots_15678
-.br
-.B braille_dots_25678
-.br
-.B braille_dots_125678
-.br
-.B braille_dots_35678
-.br
-.B braille_dots_135678
-.br
-.B braille_dots_235678
-.br
-.B braille_dots_1235678
-.br
-.B braille_dots_45678
-.br
-.B braille_dots_145678
-.br
-.B braille_dots_245678
-.br
-.B braille_dots_1245678
-.br
-.B braille_dots_345678
-.br
-.B braille_dots_1345678
-.br
-.B braille_dots_2345678
-.br
-.B braille_dots_12345678
-.br
-.B Sinh_ng
-.br
-.B Sinh_h2
-.br
-.B Sinh_a
-.br
-.B Sinh_aa
-.br
-.B Sinh_ae
-.br
-.B Sinh_aee
-.br
-.B Sinh_i
-.br
-.B Sinh_ii
-.br
-.B Sinh_u
-.br
-.B Sinh_uu
-.br
-.B Sinh_ri
-.br
-.B Sinh_rii
-.br
-.B Sinh_lu
-.br
-.B Sinh_luu
-.br
-.B Sinh_e
-.br
-.B Sinh_ee
-.br
-.B Sinh_ai
-.br
-.B Sinh_o
-.br
-.B Sinh_oo
-.br
-.B Sinh_au
-.br
-.B Sinh_ka
-.br
-.B Sinh_kha
-.br
-.B Sinh_ga
-.br
-.B Sinh_gha
-.br
-.B Sinh_ng2
-.br
-.B Sinh_nga
-.br
-.B Sinh_ca
-.br
-.B Sinh_cha
-.br
-.B Sinh_ja
-.br
-.B Sinh_jha
-.br
-.B Sinh_nya
-.br
-.B Sinh_jnya
-.br
-.B Sinh_nja
-.br
-.B Sinh_tta
-.br
-.B Sinh_ttha
-.br
-.B Sinh_dda
-.br
-.B Sinh_ddha
-.br
-.B Sinh_nna
-.br
-.B Sinh_ndda
-.br
-.B Sinh_tha
-.br
-.B Sinh_thha
-.br
-.B Sinh_dha
-.br
-.B Sinh_dhha
-.br
-.B Sinh_na
-.br
-.B Sinh_ndha
-.br
-.B Sinh_pa
-.br
-.B Sinh_pha
-.br
-.B Sinh_ba
-.br
-.B Sinh_bha
-.br
-.B Sinh_ma
-.br
-.B Sinh_mba
-.br
-.B Sinh_ya
-.br
-.B Sinh_ra
-.br
-.B Sinh_la
-.br
-.B Sinh_va
-.br
-.B Sinh_sha
-.br
-.B Sinh_ssha
-.br
-.B Sinh_sa
-.br
-.B Sinh_ha
-.br
-.B Sinh_lla
-.br
-.B Sinh_fa
-.br
-.B Sinh_al
-.br
-.B Sinh_aa2
-.br
-.B Sinh_ae2
-.br
-.B Sinh_aee2
-.br
-.B Sinh_i2
-.br
-.B Sinh_ii2
-.br
-.B Sinh_u2
-.br
-.B Sinh_uu2
-.br
-.B Sinh_ru2
-.br
-.B Sinh_e2
-.br
-.B Sinh_ee2
-.br
-.B Sinh_ai2
-.br
-.B Sinh_o2
-.br
-.B Sinh_oo2
-.br
-.B Sinh_au2
-.br
-.B Sinh_lu2
-.br
-.B Sinh_ruu2
-.br
-.B Sinh_luu2
-.br
-.B Sinh_kunddaliya
-.br
-.B ModeLock
-.br
-.B MonBrightnessUp
-.br
-.B MonBrightnessDown
-.br
-.B KbdLightOnOff
-.br
-.B KbdBrightnessUp
-.br
-.B KbdBrightnessDown
-.br
-.B Standby
-.br
-.B AudioLowerVolume
-.br
-.B AudioMute
-.br
-.B AudioRaiseVolume
-.br
-.B AudioPlay
-.br
-.B AudioStop
-.br
-.B AudioPrev
-.br
-.B AudioNext
-.br
-.B HomePage
-.br
-.B Mail
-.br
-.B Start
-.br
-.B Search
-.br
-.B AudioRecord
-.br
-.B Calculator
-.br
-.B Memo
-.br
-.B ToDoList
-.br
-.B Calendar
-.br
-.B PowerDown
-.br
-.B ContrastAdjust
-.br
-.B RockerUp
-.br
-.B RockerDown
-.br
-.B RockerEnter
-.br
-.B Back
-.br
-.B Forward
-.br
-.B Stop
-.br
-.B Refresh
-.br
-.B PowerOff
-.br
-.B WakeUp
-.br
-.B Eject
-.br
-.B ScreenSaver
-.br
-.B WWW
-.br
-.B Sleep
-.br
-.B Favorites
-.br
-.B AudioPause
-.br
-.B AudioMedia
-.br
-.B MyComputer
-.br
-.B VendorHome
-.br
-.B LightBulb
-.br
-.B Shop
-.br
-.B History
-.br
-.B OpenURL
-.br
-.B AddFavorite
-.br
-.B HotLinks
-.br
-.B BrightnessAdjust
-.br
-.B Finance
-.br
-.B Community
-.br
-.B AudioRewind
-.br
-.B BackForward
-.br
-.B Launch0
-.br
-.B Launch1
-.br
-.B Launch2
-.br
-.B Launch3
-.br
-.B Launch4
-.br
-.B Launch5
-.br
-.B Launch6
-.br
-.B Launch7
-.br
-.B Launch8
-.br
-.B Launch9
-.br
-.B LaunchA
-.br
-.B LaunchB
-.br
-.B LaunchC
-.br
-.B LaunchD
-.br
-.B LaunchE
-.br
-.B LaunchF
-.br
-.B ApplicationLeft
-.br
-.B ApplicationRight
-.br
-.B Book
-.br
-.B CD
-.br
-.B WindowClear
-.br
-.B Close
-.br
-.B Copy
-.br
-.B Cut
-.br
-.B Display
-.br
-.B DOS
-.br
-.B Documents
-.br
-.B Excel
-.br
-.B Explorer
-.br
-.B Game
-.br
-.B Go
-.br
-.B iTouch
-.br
-.B LogOff
-.br
-.B Market
-.br
-.B Meeting
-.br
-.B MenuKB
-.br
-.B MenuPB
-.br
-.B MySites
-.br
-.B New
-.br
-.B News
-.br
-.B OfficeHome
-.br
-.B Open
-.br
-.B Option
-.br
-.B Paste
-.br
-.B Phone
-.br
-.B Reply
-.br
-.B Reload
-.br
-.B RotateWindows
-.br
-.B RotationPB
-.br
-.B RotationKB
-.br
-.B Save
-.br
-.B ScrollUp
-.br
-.B ScrollDown
-.br
-.B ScrollClick
-.br
-.B Send
-.br
-.B Spell
-.br
-.B SplitScreen
-.br
-.B Support
-.br
-.B TaskPane
-.br
-.B Terminal
-.br
-.B Tools
-.br
-.B Travel
-.br
-.B UserPB
-.br
-.B User1KB
-.br
-.B User2KB
-.br
-.B Video
-.br
-.B WheelButton
-.br
-.B Word
-.br
-.B Xfer
-.br
-.B ZoomIn
-.br
-.B ZoomOut
-.br
-.B Away
-.br
-.B Messenger
-.br
-.B WebCam
-.br
-.B MailForward
-.br
-.B Pictures
-.br
-.B Music
-.br
-.B Battery
-.br
-.B Bluetooth
-.br
-.B WLAN
-.br
-.B UWB
-.br
-.B AudioForward
-.br
-.B AudioRepeat
-.br
-.B AudioRandomPlay
-.br
-.B Subtitle
-.br
-.B AudioCycleTrack
-.br
-.B CycleAngle
-.br
-.B FrameBack
-.br
-.B FrameForward
-.br
-.B Time
-.br
-.B SelectButton
-.br
-.B View
-.br
-.B TopMenu
-.br
-.B Red
-.br
-.B Green
-.br
-.B Yellow
-.br
-.B Blue
-.br
-.B Suspend
-.br
-.B Hibernate
-.br
-.B TouchpadToggle
-.br
-.B TouchpadOn
-.br
-.B TouchpadOff
-.br
-.B AudioMicMute
-.br
-.B Switch_VT_1
-.br
-.B Switch_VT_2
-.br
-.B Switch_VT_3
-.br
-.B Switch_VT_4
-.br
-.B Switch_VT_5
-.br
-.B Switch_VT_6
-.br
-.B Switch_VT_7
-.br
-.B Switch_VT_8
-.br
-.B Switch_VT_9
-.br
-.B Switch_VT_10
-.br
-.B Switch_VT_11
-.br
-.B Switch_VT_12
-.br
-.B Ungrab
-.br
-.B ClearGrab
-.br
-.B Next_VMode
-.br
-.B Prev_VMode
-.br
-.B LogWindowTree
-.br
-.B LogGrabInfo
-
-.SH MODIFIER NAMES
-.B Shift
-.br
-.B Ctrl
-.br
-.B Alt
diff --git a/wofi/man/wofi-map.3 b/wofi/man/wofi-map.3
deleted file mode 100644
index 2324c8b..0000000
--- a/wofi/man/wofi-map.3
+++ /dev/null
@@ -1,74 +0,0 @@
-.TH wofi\-map 3
-.SH NAME
-wofi \- Map API functions and documentation
-
-.SH DESCRIPTION
-The functions documented here are used for interacting with wofi's config and map. They are defined in map.h.
-
-.SH MAP FUNCTIONS
-The following functions are used to interact with a \fBstruct map*\fR
-
-.TP
-.B struct map* map_init(void)
-Allocates and returns a new string map. String maps only support string values.
-
-.TP
-.B struct map* map_init_void(void)
-Allocates and returns a new void map. A void map supports values of any type.
-
-.TP
-.B void map_free(struct map* map)
-Frees the provided map and all it's keys. Values are only freed if it is a string map.
-
-.TP
-.B bool map_put(struct map* map, const char* key, char* value)
-Returns true if the given map is a string map, otherwise returns false and prints a message to stderr.
-
-.B struct map* map
-\- The map to insert into.
-
-.B const char* key
-\- The key to store the value under. This key is given to \fBstrdup()\fR before being saved and will be freed when running \fBmap_free()\fR.
-
-.B char* value
-\- The value to store. This value is given to \fBstrdup()\fR before being saved and will be freed when running \fBmap_free()\fR. If the value is \fBNULL\fR it will not be given to \fBstrdup()\fR.
-
-.TP
-.B bool map_put_void(struct map* map, const char* key, void* value)
-Returns true if the given map is a void map, otherwise returns false and prints a message to stderr.
-
-.B struct map* map
-\- The map to insert into.
-
-.B const char* key
-\- The key to store the value under. This key is given to \fBstrdup()\fR before being saved and will be freed when running \fBmap_free()\fR.
-
-.B void* value
-\- The value to store. This pointer is stored in the map, it is on the caller to free this and it will not be freed when running \fBmap_free()\fR.
-
-.TP
-.B void* map_get(struct map* map, const char* key)
-Returns the value stored under \fBkey\fR or \fBNULL\fR if no key exists. \fBNULL\fR can also be returned if it was stored there with \fBmap_put()\fR or \fBmap_put_void()\fR.
-
-.B struct map* map
-\- The map to get the value from.
-
-.B const char* key
-\- The key to lookup.
-
-.TP
-.B bool map_contains(struct map* map, const char* key)
-Returns true if the key exists, false otherwise. This is implemented as a \fBvalue != NULL\fR check so a \fBNULL\fR value is considered to not exist.
-
-.B struct map* map
-\- The map to check against.
-
-.B const char* key
-\- The key to check for.
-
-.TP
-.B size_t map_size(struct map* map)
-Returns the number of entries in this map.
-
-.B struct map* map
-\- The map to get the size of.
diff --git a/wofi/man/wofi-utils.3 b/wofi/man/wofi-utils.3
deleted file mode 100644
index 761fa7c..0000000
--- a/wofi/man/wofi-utils.3
+++ /dev/null
@@ -1,63 +0,0 @@
-.TH wofi\-utils 3
-.SH NAME
-wofi \- Utility functions and documentation
-
-.SH DESCRIPTION
-The functions documented here are general utility functions. They are defined in utils.h.
-
-.SH UTILITY FUNCTIONS
-The following functions are general convenience functions.
-
-.TP
-.B time_t utils_get_time_millis(void)
-Returns the current unix time in milliseconds.
-
-.TP
-.B void utils_sleep_millis(time_t millis)
-Sleeps for the specified amount of time.
-
-.B time_t millis
-\- The time to sleep for in milliseconds.
-
-.TP
-.B char* utils_concat(size_t arg_count, ...)
-Concatenates strings together. The returned result is newly allocated and must be freed by the caller when finished using it.
-
-.B size_t arg_count
-\- The number of arguments provided
-
-.B varargs
-\- The list of strings to be concatenated.
-
-.TP
-.B size_t utils_min(size_t n1, size_t n2)
-Returns the smaller of the two inputs.
-
-.B size_t n1
-\- The first number.
-
-.B size_t n2
-\- The second number.
-
-.TP
-.B size_t utils_min3(size_t n1, size_t n2, size_t n3)
-Returns the smallest of the three inputs.
-
-.B size_t n1
-\- The first number.
-
-.B size_t n2
-\- The second number.
-
-.B size_t n3
-\- The third number.
-
-.TP
-.B size_t utils_distance(const char* haystack, const char* needle)
-Computes the Levenshtein distance between the two inputs.
-
-.B const char* haystack
-\- The string to search in.
-
-.B const char* needle
-\- The string to search for.
diff --git a/wofi/man/wofi-widget-builder.3 b/wofi/man/wofi-widget-builder.3
deleted file mode 100644
index ae26206..0000000
--- a/wofi/man/wofi-widget-builder.3
+++ /dev/null
@@ -1,112 +0,0 @@
-.TH wofi\-widget\-builder 3
-.SH NAME
-wofi \- Widget builder API functions
-
-.SH DESCRIPTION
-The functions documented here are used for building custom widgets with more power and flexibility than previously allowed. They are defined in wofi_widget_builder_api.h
-
-.TP
-.B struct widget_builder* wofi_widget_builder_init(struct mode* mode, size_t actions)
-Creates multiple widget builders. The number of builders created is specified by actions and is returned as an array.
-
-.B struct mode* mode
-\- The \fBstruct mode*\fR given to your mode's \fBinit()\fR function.
-
-.B size_t actions
-\- The number of builders to create
-
-.TP
-.B void wofi_widget_builder_set_search_text(struct widget_builder* builder, char* search_text)
-Sets the search text for the widget specified by the builder
-
-.B struct widget_builder* builder
-\- The builder that contains the widget to set the search text for
-
-.B char* search_text
-\- The text to set as the search text
-
-.TP
-.B void wofi_widget_builder_set_action(struct widget_builder* builder, char* action)
-Sets the action for the widget specified by the builder
-
-.B struct widget_builder* builder
-\- The builder that contains the widget to set the action for
-
-.B char* action
-\- The text to set as the action
-
-.TP
-.B void wofi_widget_builder_insert_text(struct widget_builder* builder, char* text, ...)
-Inserts text into the widget specified by the builder
-
-.B struct widget_builder* builder
-\- The builder that contains the widget to add the text to
-
-.B char* text
-\- The text to add to the widget
-
-.B ...
-\- The names of the CSS classes for this text. The class that will be assigned is .mode_name-css_name where mode_name is the name of the mode, i.e. drun etc. This should have a NULL sentinel
-
-.TP
-.B void wofi_widget_builder_insert_text_with_list(struct widget_builder* builder, char* text, struct wl_list* classes)
-Inserts text into the widget specified by the builder
-
-.B struct widget_builder* builder
-\- The builder that contains the widget to add the text to
-
-.B char* text
-\- The text to add to the widget
-
-.B struct wl_list* classes
-\- The names of the CSS classes for this text. The class that will be assigned is .mode_name-css_name where mode_name is the name of the mode, i.e. drun etc. This list should contain struct css_class nodes.
-
-.TP
-.B void wofi_widget_builder_insert_image(struct widget_builder* builder, GdkPixbuf* pixbuf, ...)
-Inserts an image into the widget specified by the builder
-
-.B struct widget_builder* builder
-\- The builder that contains the widget to add the image to
-
-.B GdkPixbuf* pixbuf
-\- The image to add to the widget
-
-.B ...
-\- The names of the CSS classes for this image. The class that will be assigned is .mode_name-css_name where mode_name is the name of the mode, i.e. drun etc. This should have a NULL sentinel
-
-.TP
-.B void wofi_widget_builder_insert_image_with_list(struct widget_builder* builder, GdkPixbuf* pixbuf, struct wl_list* classes)
-Inserts an image into the widget specified by the builder
-
-.B struct widget_builder* builder
-\- The builder that contains the widget to add the image to
-
-.B GdkPixbuf* pixbuf
-\- The image to add to the widget
-
-.B struct wl_list* classes
-\- The names of the CSS classes for this image. The class that will be assigned is .mode_name-css_name where mode_name is the name of the mode, i.e. drun etc. This list should contain struct css_class nodes.
-
-.TP
-.B struct widget_builder* wofi_widget_builder_get_idx(struct widget_builder* builder, size_t idx)
-Gets the widget_builder at the provided index in the array
-
-.B struct widget_builder* builder
-\- The array of builders to get the builder from
-
-.B size_t idx
-\- The index in the array to get
-
-.TP
-.B struct widget* wofi_widget_builder_get_widget(struct widget_builder* builder)
-Constructs a new widget from the specified builder, the widget can be returned by \fBstruct widget* get_widget(void)\fR
-
-.B struct widget_builder* builder
-\- The builder to construct a widget for
-
-.TP
-.B void wofi_widget_builder_free(struct widget_builder* builder)
-Frees the specified builder
-
-.B struct widget_builder* builder
-\- The builder to free
diff --git a/wofi/man/wofi.1 b/wofi/man/wofi.1
deleted file mode 100644
index 1307455..0000000
--- a/wofi/man/wofi.1
+++ /dev/null
@@ -1,135 +0,0 @@
-.TH wofi 1
-.SH NAME
-wofi \- A rofi inspired launcher for wlroots compositors
-
-.SH SYNOPSIS
-.B wofi
-[options]
-
-.SH DESCRIPTION
-.B wofi
-is a rofi inspired menu program for wlroots compositors such as sway. It is intended to be highly customizable and flexible with the help of CSS styling and a dmenu mode that allows for endless scriptability. Wofi can be run cacheless in dmenu mode automatically by invoking it as dmenu with symlink.
-
-Wofi was designed specifically for wlroots and makes use of the wlr\-layer\-shell protocol. If your compositor does not support this protocol or if you are in a non\-wayland environment then wofi must be run with \fB\-\-normal\-window\fR or it will crash. If you wish to run wofi this way you can also place \fBnormal_window=true\fR in your config file to avoid specifying the option on the command line.
-
-.SH OPTIONS
-.TP
-.B \-h, \-\-help
-Prints the help message and then exits.
-.TP
-.B \-f, \-\-fork
-Forks the menu so the terminal running it can be closed.
-.TP
-.B \-c, \-\-conf=\fIPATH\fR
-Specifies the config file to use.
-.TP
-.B \-s, \-\-style=\fIPATH\fR
-Specifies the CSS file to use as the stylesheet.
-.TP
-.B \-C, \-\-color=\fIPATH\fR
-Specifies the colors file to use.
-.TP
-.B \-d, \-\-dmenu
-Runs wofi in dmenu mode.
-.TP
-.B \-S, \-\-show=\fIMODE\fR
-Specifies the mode to run in. A list of modes can be found in \fBwofi\fR(7).
-.TP
-.B \-W, \-\-width=\fIWIDTH\fR
-Specifies the menu width in pixels or percent of screen size, default is 50%. Pixels are used unless the number ends with a %.
-.TP
-.B \-H, \-\-height=\fIHEIGHT\fR
-Specifies the menu height in pixels or percent of screen size, default is 40%. Pixels are used unless the number ends with a %.
-.TP
-.B \-p, \-\-prompt=\fIPROMPT\fR
-Sets the prompt to be display in the search box, default is the name of the mode.
-.TP
-.B \-x, \-\-xoffset=\fIOFFSET\fR
-Sets the x offset from the location in pixels, default is 0.
-.TP
-.B \-y, \-\-yoffset=\fIOFFSET\fR
-Sets the y offset from the location in pixels, default is 0.
-.TP
-.B \-n, \-\-normal\-window
-Runs wofi in a normal window instead of using wlr\-layer\-shell.
-.TP
-.B \-I, \-\-allow\-images
-Allows image escape sequences to be processed and rendered.
-.TP
-.B \-m, \-\-allow\-markup
-Allows pango markup to be processed and rendered.
-.TP
-.B \-k, \-\-cache\-file=\fIPATH\fR
-Specifies the cache file to load/store cache, default is $XDG_CACHE_HOME/wofi\- where is the name of the mode, if $XDG_CACHE_HOME is not specified ~/.cache is used.
-.TP
-.B \-t, \-\-term=\fITERM\fR
-Specifies the term to use when running a program in a terminal. This overrides the default terminal run order which is kitty, alacritty, wezterm, foot, termite, gnome\-terminal, weston\-terminal in that order.
-.TP
-.B \-P, \-\-password \fR[character]
-Runs wofi in password mode with an optional password character to use. If no character is specified * is used by default.
-.TP
-.B \-e, \-\-exec\-search
-Activiating a search with enter will execute the search not the first result.
-.TP
-.B \-b, \-\-hide\-scroll
-Hides the scroll bars.
-.TP
-.B \-M, \-\-matching=\fIMODE\fR
-Specifies the matching mode, it can be either contains, multi-contains, or fuzzy, default is contains.
-.TP
-.B \-i, \-\-insensitive
-Enables case insensitive search.
-.TP
-.B \-q, \-\-parse\-search
-Parses out image escapes and pango preventing them from being used for searching.
-.TP
-.B \-v, \-\-version
-Prints the version and then exits.
-.TP
-.B \-l, \-\-location=\fILOCATION\fR
-Specifies the location. See \fBwofi\fR(7) for more information, default is center.
-.TP
-.B \-a, \-\-no\-actions
-Disables multiple actions for modes that support it.
-.TP
-.B \-D, \-\-define=\fIKEY=VALUE\fR
-Sets a config option
-.TP
-.B \-L, \-\-lines=\fILINES\fR
-Specifies the height in number of lines instead of pixels.
-.TP
-.B \-w, \-\-columns=\fICOLUMNS\fR
-Specifies the number of columns to display, default is 1.
-.TP
-.B \-O, \-\-sort\-order=\fIORDER\fR
-Specifies the default sort order. There are currently two orders, default and alphabetical. See \fBwofi\fR(7) for details.
-.TP
-.B \-G, \-\-gtk\-dark
-Instructs wofi to use the dark variant of the current GTK theme, if available.
-.TP
-.B \-Q, \-\-search
-Specifies something to search for immediately on opening
-.TP
-.B \-o, \-\-monitor
-Sets the monitor to open on
-.TP
-.B \-r, \-\-pre\-display\-cmd
-If set, the selectable entry won't be displayed as-is, but will instead be displayed based on the output of this command, which can be anything. Suggested to use with \fB"echo %s | some_cmd"\fR or \fB"some_cmd %s"\fR, as the string gets replaced in a printf-like fashion. This will not affect the output of wofi once a selection has been done, allowing you to display something else than the original output.
-
-
-.SH CONFIGURATION
-Wofi has 3 main files used for configuration. All files are completely optional.
-.IP 1. 4
-The config file which defaults to $XDG_CONFIG_HOME/wofi/config.
-.IP 2. 4
-The CSS file which defaults to $XDG_CONFIG_HOME/wofi/style.css.
-.IP 3. 4
-The colors file which defaults to the pywal cache $XDG_CACHE_HOME/wal/colors.
-
-.P
-All 3 of these paths can be manually specified using the respective command line flag. In the case of the last 2 they can additionally be specified in the config file.
-
-In the event $XDG_CONFIG_HOME is not specified it defaults to ~/.config likewise if $XDG_CACHE_HOME is not specified it defaults to ~/.cache.
-
-Information about the formats for these files can be found in
-.B wofi\fR(5).
diff --git a/wofi/man/wofi.3 b/wofi/man/wofi.3
deleted file mode 100644
index 1a4e08b..0000000
--- a/wofi/man/wofi.3
+++ /dev/null
@@ -1,54 +0,0 @@
-.TH wofi 3
-.SH NAME
-wofi \- Mode functions and documentation
-
-.SH DESCRIPTION
-Wofi provides a C API which can be used for developing 3rd party modes. These modes should be compiled to a shared object which should be placed in $XDG_CONFIG_HOME/wofi/plugins. If $XDG_CONFIG_HOME is not defined then it will default to ~/.config.
-
-It is very important to note that this API is not stable. It's mostly stable however if something comes up that requires a substantial change things will be changed. This shouldn't happen too much but has happened in the past and might in the future.
-
-.SH HEADER FILES
-There are 2 header files required in order to use the wofi API, wofi_api.h and map.h. utils.h might be useful to include if you want a few helper functions but it is not required. utils.h will not be documented here as it's outside the scope of the mode API.
-
-.SH MODE FUNCTIONS
-The following list of functions are the functions which can be defined inside of your mode which will be called to do setup, and acquire various pieces of information from the mode.
-
-.TP
-.B void init(struct mode* mode, struct map* config)
-Defining this function is required. This function is called to setup your plugin and provide it with several pointers which are described below.
-
-.B struct mode* mode
-\- used to identify your mode, it is passed to a large number of the API functions to identify your mode.
-
-.B struct map* config
-\- all of the config options that the user defined for your mode. Information on how to access this can be found in \fBwofi\-map(3)\fR.
-
-.TP
-.B void load(struct mode* mode)
-Defining this function is optional. This function is called before ALL others and provides your mode pointer as early as possible.
-
-.B struct mode* mode
-\- used to identify your mode, it is passed to a large number of the API functions to identify your mode.
-
-.TP
-.B const char** get_arg_names(void)
-Defining this function is optional. This function is called to get an array of config options which can be set by the user. All of these options have the name of your mode prefixed on the front so if your array is for example \fB{"opt1", "opt2"}\fR the config options defined will be \fBmode-opt1=\fIvalue\fR and \fBmode-opt2=\fIvalue\fR where mode is the name of the shared object.
-
-.TP
-.B size_t get_arg_count(void)
-Defining this function is optional. This function is called to get the number of arguments returned by \fBget_arg_names(void)\fR.
-
-.TP
-.B void exec(const char* cmd)
-Defining this function is required. This function is called when the user selects an entry.
-
-.B const char* cmd
-\- The action registered to the selected entry. If your mode allows executing searches directly then this will be the search contents if no matching entries exist.
-
-.TP
-.B struct widget* get_widget(void)
-Defining this function is optional. This function is called to request the next widget to be added. See \fBwofi_create_widget()\fR in \fBwofi\-api(3)\fR on how to obtain a \fBstruct widget*\fR. \fBNULL\fR should be returned to denote no more widgets are available.
-
-.TP
-.B bool no_entry(void)
-Defining this function is optional. This function is called to find out whether or not this mode supports running searches without any matching entries. The default is false, if you wish to allow your mode to take searches directly you must define this and return true.
diff --git a/wofi/man/wofi.5 b/wofi/man/wofi.5
deleted file mode 100644
index 55cb99a..0000000
--- a/wofi/man/wofi.5
+++ /dev/null
@@ -1,258 +0,0 @@
-.TH wofi 5
-.SH NAME
-wofi \- configuration file and styling
-
-.SH DESCRIPTION
-Wofi's configuration format is very simple, consisting of key value pairs in snake case. The majority of the config options are the command line options, there are however a small handful of options only accessible via wofi's config.
-
-Mode specific options for the built\-in modes are documented in \fBwofi\fR(7). They are placed in the config file in the format \fBmode\-example_opt=val\fR. For example dmenu has an option called \fBparse_action\fR which would be placed in the config as \fBdmenu\-parse_action=true\fR.
-
-Anything following a # is considered to be a comment unless the # is prefixed with a \\. For this reason in order to put a backslash in the config it must be escaped as well giving \\\\.
-
-.SH CONFIG OPTIONS
-Most of the options here are the command flags as found in \fBwofi\fR(1) in snake case, however some are unique to the config.
-
-.TP
-.B style=\fIPATH\fR
-Specifies the CSS file to use as the stylesheet.
-.TP
-.B stylesheet=\fIPATH\fR
-Specifies the CSS file to use as the stylesheet. This option is NOT the same as \fBstyle\fR. Absolute paths are absolute however relative paths are relative to the wofi config folder location $XDG_CONFIG_HOME/wofi and NOT the current working directory as they are with \fBstyle\fR. They are also NOT relative to the path as specified by \fB\-\-conf\fR. This option comes from rootbar and is probably more confusing than it's worth. You should probably use \fBstyle\fR unless you're sure this is what you want.
-.TP
-.B color=\fIPATH\fR
-Specifies the colors file to use.
-.TP
-.B colors=\fIPATH\fR
-Specifies the colors file to use. This option is NOT the same as \fBcolor\fR. Absolute paths are absolute however relative paths are relative to the wofi config folder location $XDG_CONFIG_HOME/wofi and NOT the current working directory as they are with \fBcolor\fR. They are also NOT relative to the path as specified by \fB\-\-conf\fR. This option comes from rootbar and is probably more confusing than it's worth. You should probably use \fBcolor\fR unless you're sure this is what you want.
-.TP
-.B show=\fIMODE\fR
-Specifies the mode to run in. A list of modes can be found in \fBwofi\fR(7).
-.TP
-.B mode=\fIMODE\fR
-Identical to \fBshow\fR.
-.TP
-.B width=\fIWIDTH\fR
-Specifies the menu width in pixels or percent of screen size, default is 50%. Pixels are used unless the number ends with a %.
-.TP
-.B height=\fIHEIGHT\fR
-Specifies the menu height in pixels or percent of screen size, default is 40%. Pixels are used unless the number ends with a %.
-.TP
-.B prompt=\fIPROMPT\fR
-Sets the prompt to be display in the search box, default is the name of the mode.
-.TP
-.B xoffset=\fIOFFSET\fR
-Sets the x offset from the location in pixels, default is 0.
-.TP
-.B x=\fIOFFSET\fR
-Identical to \fBxoffset\fR.
-.TP
-.B yoffset=\fIOFFSET\fR
-Sets the y offset from the location in pixels, default is 0.
-.TP
-.B y=\fIOFFSET\fR
-Identical to \fByoffset\fR.
-.TP
-.B normal_window=\fIBOOL\fR
-If true runs wofi in a normal window instead of using wlr\-layer\-shell, default is false.
-.TP
-.B allow_images=\fIBOOL\fR
-If true allows image escape sequences to be processed and rendered, default is false.
-.TP
-.B allow_markup=\fIBOOL\fR
-If true allows pango markup to be processed and rendered, default is false.
-.TP
-.B cache_file=\fIPATH\fR
-Specifies the cache file to load/store cache, default is $XDG_CACHE_HOME/wofi\- where is the name of the mode, if $XDG_CACHE_HOME is not specified ~/.cache is used.
-.TP
-.B term=\fITERM\fR
-Specifies the term to use when running a program in a terminal. This overrides the default terminal run order which is kitty, alacritty, wezterm, foot, termite, gnome\-terminal, weston\-terminal in that order.
-.TP
-.B password=\fICHARACTER\fR
-Runs wofi in password mode using the specified character, default is false.
-.TP
-.B exec_search=\fIBOOL\fR
-If true activiating a search with enter will execute the search not the first result, default is false.
-.TP
-.B hide_scroll=\fIBOOL\fR
-If true hides the scroll bars, default is false.
-.TP
-.B matching=\fIMODE\fR
-Specifies the matching mode, it can be either contains, multi-contains, or fuzzy, default is contains.
-.TP
-.B insensitive=\fIBOOL\fR
-If true enables case insensitive search, default is false.
-.TP
-.B parse_search=\fIBOOL\fR
-If true parses out image escapes and pango preventing them from being used for searching, default is false.
-.TP
-.B location=\fILOCATION\fR
-Specifies the location. See \fBwofi\fR(7) for more information, default is center.
-.TP
-.B no_actions=\fIBOOL\fR
-If true disables multiple actions for modes that support it, default is false.
-.TP
-.B lines=\fILINES\fR
-Specifies the height in number of lines instead of pixels.
-.TP
-.B columns=\fICOLUMNS\fR
-Specifies the number of columns to display, default is 1.
-.TP
-.B sort_order=\fIORDER\fR
-Specifies the default sort order. There are currently two orders, default and alphabetical. See \fBwofi\fR(7) for details.
-.TP
-.B gtk_dark=\fIBOOL\fR
-If true, instructs wofi to use the dark variant of the current GTK theme (if available). Default is false.
-.TP
-.B search=\fISTRING\fR
-Specifies something to search for immediately on opening
-.TP
-.B monitor=\fISTRING\fR
-Sets the monitor to open on
-.TP
-.B pre_display_cmd=\fICOMMAND\fR
-Specifies a printf-like string which is used on the entries prior to displaying them. This command is only used to represent the label widget's string, and won't affect the the output of the selected label.
-.TP
-.B orientation=\fIORIENTATION\fR
-Specifies the orientation, it can be either horizontal or vertical, default is vertical.
-.TP
-.B halign=\fIALIGN\fR
-Specifies the horizontal align for the entire scrolled area, it can be any of fill, start, end, or center, default is fill.
-.TP
-.B content_halign=\fIALIGN\fR
-Specifies the horizontal align for the individual entries, it can be any of fill, start, end, or center, default is fill.
-.TP
-.B valign=\fIALIGN\fR
-Specifies the vertical align for the entire scrolled area, it can be any of fill, start, end, or center, the default is orientation dependent. If vertical then it defaults to start, if horizontal it defaults to center.
-.TP
-.B filter_rate=\fIRATE\fR
-Specifies the rate at which search results are updated in milliseconds, default is 100.
-.TP
-.B image_size=\fISIZE\fR
-Specifies the size of images in pixels when images are enabled, default is 32.
-.TP
-.B key_up=\fIKEY\fR
-Specifies the key to use in order to move up. Default is Up(Up arrow). See \fBwofi\-keys\fR(7) for the key codes.
-.TP
-.B key_down=\fIKEY\fR
-Specifies the key to use in order to move down. Default is Down(Down arrow). See \fBwofi\-keys\fR(7) for the key codes.
-.TP
-.B key_left=\fIKEY\fR
-Specifies the key to use in order to move left. Default is Left(Left arrow). See \fBwofi\-keys\fR(7) for the key codes.
-.TP
-.B key_right=\fIKEY\fR
-Specifies the key to use in order to move right. Default is Right(Right arrow). See \fBwofi\-keys\fR(7) for the key codes.
-.TP
-.B key_forward=\fIKEY\fR
-Specifies the key to use in order to move forward. Default is Tab. See \fBwofi\-keys\fR(7) for the key codes.
-.TP
-.B key_backward=\fIKEY\fR
-Specifies the key to use in order to move backward. Default is ISO_Left_Tab(Shift+Tab). See \fBwofi\-keys\fR(7) for the key codes.
-.TP
-.B key_submit=\fIKEY\fR
-Specifies the key to use in order to submit an action. Default is Return. See \fBwofi\-keys\fR(7) for the key codes.
-.TP
-.B key_exit=\fIKEY\fR
-Specifies the key to use in order to exit wofi. Default is Escape. See \fBwofi\-keys\fR(7) for the key codes.
-.TP
-.B key_pgup=\fIKEY\fR
-Specifies the key to use in order to move one page up. Default is Page_Up. See \fBwofi\-keys\fR(7) for the key codes.
-.TP
-.B key_pgdn=\fIKEY\fR
-Specifies the key to use in order to move one page down. Default is Page_Down. See \fBwofi\-keys\fR(7) for the key codes.
-.TP
-.B key_expand=\fIKEY\fR
-Specifies the key to use in order to expand/contract multi-action entires. There is no default. See \fBwofi\-keys\fR(7) for the key codes.
-.TP
-.B key_hide_search=\fIKEY\fR
-Specifies the key to use in order to hide/show the search bar. There is no default. See \fBwofi\-keys\fR(7) for the key codes.
-.TP
-.B key_copy=\fIKEY\fR
-Specifies the key to use in order to copy the action text for the current entry. The default is Ctrl-c. See \fBwofi\-keys\fR(7) for the key codes.
-.TP
-.B key_custom_(n)=\fIKEY\fR
-Allows for configuring custom exit codes. For example setting key_custom_0=Ctrl-0 will make it so if you press Ctrl-0 wofi will set its exit status to 10. This will not cause wofi to exit, it will only set its exit code for when it does. 20 of these keys are configurable numbered 0-19. The exit status used is 10+n where n is the number attached to key_custom_n. There are no defaults for these. See \fBwofi\-keys\fR(7) for the key codes.
-.TP
-.B line_wrap=\fIMODE\fR
-Specifies the line wrap mode to use. The options are off, word, char, and word_char. Default is off.
-.TP
-.B global_coords=\fIBOOL\fR
-Specifies whether x and y offsets should be calculated using the global compositor space instead of the current monitor. Default is false. This does not play well with locations and using it with them is not advised.
-.TP
-.B hide_search=\fIBOOL\fR
-Specifies whether the search bar should be hidden. Default is false.
-.TP
-.B dynamic_lines=\fIBOOL\fR
-Specifies whether wofi should be dynamically shrunk to fit the number of visible lines or if it should always stay the same size. Default is false.
-.TP
-.B layer=\fILAYER\fR
-Specifies the layer to open on. The options are background, bottom, top, and overlay. Default is top
-.TP
-.B copy_exec=\fIPATH\fR
-Specifies the executable to pipe copy data into. $PATH will be scanned, this is not passed to a shell and must be an executable. Default is wl-copy.
-.TP
-.B single_click=\fIBOOL\fR
-Specifies whether or not actions should be executed on a single click or a double click. Default is false.
-.TP
-.B pre_display_exec=\fIBOOL\fR
-This modifies the behavior of pre_display_cmd and causes the command in question to be directly executed via fork/exec rather than through the shell.
-
-.SH CSS SELECTORS
-Any GTK widget can be selected by using the name of its CSS node, these however might change with updates and are not guaranteed to stay constant. Wofi also provides certain widgets with names and classes which can be referenced from CSS to give access to the most important widgets easily. \fBwofi\fR(7) contains the current widget layout used by wofi so if you want to get into CSS directly using GTK widget names look there for info.
-
-.TP
-.B #window
-.br
-The name of the window itself.
-.TP
-.B #outer\-box
-.br
-The name of the box that contains everything.
-.TP
-.B #input
-.br
-The name of the search bar.
-.TP
-.B #scroll
-.br
-The name of the scrolled window containing all of the entries.
-.TP
-.B #inner\-box
-.br
-The name of the box containing all of the entries.
-.TP
-.B #img
-.br
-The name of all images in entries displayed in image mode.
-.TP
-.B #text
-.br
-The name of all the text in entries.
-.TP
-.B #unselected
-.br
-The name of all entries currently unselected. A better way of doing this is to do #entry and combine that with #entry:selected
-.TP
-.B #selected
-.br
-The name of all entries currently selected. A better way of doing this is to do #entry:selected
-.TP
-.B .entry
-.br
-The class attached to all entries. This is attached to the inside property box and is old, you probably want #entry instead
-.TP
-.B #entry
-.br
-The name of all entries.
-.TP
-.B #expander-box
-.br
-The name of all boxes shown when expanding entries with multiple actions
-
-.SH COLORS
-The colors file should be formatted as new line separated hex values. These values should be in the standard HTML format and begin with a hash. These colors will be loaded however wofi doesn't know what color should be used for what so you must reference them from your CSS.
-
-You can reference these from your CSS by doing \-\-wofi\-color where is the line number \- 1. For example to reference the color on line 1 you would do \fB\-\-wofi\-color0\fR.
-
-The colors can also be referenced by doing \-\-wofi\-rgb\-color where is the line number \- 1. The difference between these is the format used to replace the macro.
-
-\-\-wofi\-color is replaced with an HTML color code in the format #FFFFFF. \-\-wofi\-rgb\-color is replaced with comma separated rgb values in the format 255, 255, 255. The correct usage of \-\-wofi\-rgb\-color is to wrap it in rgb() or rgba(). Note that it does not return an alpha value so combining it with rgba() should be done like so \fBrgba(\-\-wofi\-rgb\-color0, 0.8)\fR. This would set the color to line 1 with an opacity of 80%.
diff --git a/wofi/man/wofi.7 b/wofi/man/wofi.7
deleted file mode 100644
index e1d4faf..0000000
--- a/wofi/man/wofi.7
+++ /dev/null
@@ -1,194 +0,0 @@
-.TH wofi 7
-.SH NAME
-wofi \- Built in modes and other features
-
-.SH DESCRIPTION
-Wofi contains several built in modes as well as a lot of other features including combi which are documented here.
-
-The config options documented here are stripped of mode names. Mode specific config options are placed in the config file in the format \fBmode\-example_opt=val\fR. For example dmenu has an option called \fBparse_action\fR which would be placed in the config as \fBdmenu\-parse_action=true\fR.
-
-.SH MODES
-Currently wofi has 3 built in modes
-.IP 1. 4
-run \- searches $PATH for executables and allows them to be run by selecting them.
-.IP 2. 4
-drun \- searches $XDG_DATA_HOME/applications and $XDG_DATA_DIRS/applications for desktop files and allows them to be run by selecting them.
-.IP 3. 4
-dmenu \- reads from stdin and displays options which when selected will be output to stdout.
-
-.P
-In the event $XDG_DATA_HOME is not specified it defaults to ~/.local/share. If $XDG_DATA_DIRS is not specified it defaults to /usr/local/share:/usr/share.
-
-Combi is not a mode however it does exist as a feature. You can use it by doing \-\-show mode1,mode2,mode3,etc. You can mix and match any number of modes however each mode can only be loaded once so doing something like \-\-show run,drun,run is not supported although I'm not sure why you'd do that in the first place.
-
-.SH DMENU CONFIG OPTIONS
-.TP
-.B parse_action=\fIBOOL\fR
-If true the result returned by dmenu will be stripped of image escape sequences and pango markup, default is false.
-.TP
-.B separator=\fICHAR\fR
-The character used to separate dmenu entries, default is \\n.
-.TP
-.B print_line_num=\fIBOOL\fR
-When an entry is selected the number of the line the entry was on is printed instead of the entry itself. This disables caching as it's fundamentally incompatible with it.
-
-.SH RUN
-In run mode holding ctrl while running an entry will cause arguments to be parsed even if always_parse_args=false. Holding shift will cause the entry to be run in a terminal.
-
-.SH RUN CONFIG OPTIONS
-.TP
-.B always_parse_args=\fIBOOL\fR
-If true spaces will not be treated as part of the executable name but rather as an argument separator equivalent to holding control while pressing enter, default is false.
-.TP
-.B show_all=\fIBOOL\fR
-If true shows all the entries in path, this will show entries that have the same executable name, for example /bin/bash and /usr/bin/bash will be shown separately as bash instead of having one bash entry for the first one encountered, default is true.
-.TP
-.B print_command=\fIBOOL\fR
-If true the executable that would be run will be printed to stdout instead of executing it, default is false.
-
-.SH DRUN CONFIG OPTIONS
-.TP
-.B print_command=\fIBOOL\fR
-If true the command used to launch the desktop file will be printed to stdout instead of invoking it, default is false.
-.TP
-.B display_generic=\fIBOOL\fR
-If true then generic names will be displayed in () next to the application name, default is false.
-.TP
-.B disable_prime=\fIBOOL\fR
-If true then wofi will ignore the PrefersNonDefaultGPU desktop variable, specifically this prevents wofi from setting DRI_PRIME, default is false.
-.TP
-.B print_desktop_file=\fIBOOL\fR
-If true the path to the desktop file and the name of the corresponding action(if present) will be printed to stdout instead of invoking it, default is false.
-
-.SH DRUN
-When images are enabled drun mode will pull icon themes however being a GTK app it's possible you'll need to run gtk\-update\-icon\-cache to get them to apply.
-
-.SH LOCATIONS
-There are 9 possible locations which can be specified either by name or by number, the number scheme is the same as in rofi and the corresponding number is listed next to the names below, the default is center.
-.IP 1. 4
-center 0
-.IP 2. 4
-top_left 1
-.IP 3. 4
-top 2
-.IP 4. 4
-top_right 3
-.IP 5. 4
-right 4
-.IP 6. 4
-bottom_right 5
-.IP 7. 4
-bottom 6
-.IP 8. 4
-bottom_left 7
-.IP 9. 4
-left 8
-
-.P
-The x and y offsets are applied based on layer\-shell anchors which means an x offset can only be applied if wofi is anchored on the x axis, i.e. you can only use an x offset with the top_left, top_right, right, bottom_right, bottom_left, and left locations. center, top, and bottom can't have x offsets as they're not anchored on the x axis. Likewise y offsets can only be applied to top_left, top, top_right, bottom_right, bottom, and bottom_left locations. center, left, and right can't have y offsets because they're not anchored to the y axis. Since center can't have offsets on either as it's not anchored to any axis any x or y offset applied while using center will override the location to top_left for backwards compatibility reasons seeing as not doing so would simply ignore the offsets anyway.
-
-.SH ORDER
-There are 2 order options currently, default and alphabetical. Default means the entries are displayed in the order they are added by the mode, for all built in modes this is cached items first, followed by other entries in no specific order. Alphabetical means entries are alphabetical sorted period. These orders only affect the order when no search has been entered. Once a search is entered the order is re-arranged based on the current matching preference and this order is ignored.
-
-.SH CACHING
-Caching cannot be disabled however the cache file can be set to /dev/null to effectively disable it.
-
-.SH WINDOW SWITCHER
-Wofi does not have the ability to do window switching on its own as there is no way to do this with wayland/wlroots protocols however if you're using sway you can use swaymsg with dmenu mode to accomplish it.
-The following script can be used to do window switching:
-
-swaymsg \-t get_tree |
-.br
- jq \-r '.nodes[].nodes[] | if .nodes then [recurse(.nodes[])] else [] end + .floating_nodes | .[] | select(.nodes==[]) | ((.id | tostring) + " " + .name)' |
-.br
- wofi \-\-show dmenu | {
-.br
- read \-r id name
-.br
- swaymsg "[con_id=$id]" focus
-.br
-}
-
-.SH WIDGET LAYOUT
-This section is for advanced CSS which needs more control than the built in wofi CSS names/classes allow for. This widget layout is subject to change at any time and without warning so your CSS might very well break if you rely on this. Widgets have their corresponding names next to them if they have one.
-
-.B window \- #window
-.RS 4
-.B box \- #outer\-box
-.RS 4
-.B entry \- #input
-
-.B scrolledwindow \- #scroll
-.RS 4
-.B viewport
-.RS 4
-.B box
-.RS 4
-.B flowbox \- #inner\-box
-.RS 4
-.B flowboxchild \- #entry
-.RS 4
-
-.B .entry \- #unselected or #selected
-.br
-This only exists if there's ONLY 1 action. This is a WofiPropertyBox which has no CSS node and should probably not be used, the name is dependent on whether or not the entry is selected. See \fBwofi\fR(5) on #selected and #unselected for info.
-
-.RS 4
-.B image
-.br
-This is only present if an image is present in the entry and might occur multiple times if multiple images are present.
-
-.B label
-.br
-This is only present if text is present in the entry and might occur multiple times if there are multiple text objects in a single entry.
-.RE
-
-.B expander
-.br
-This and its children only exist if there are multiple actions on the entry
-.RS 4
-
-.B .entry \- #unselected or #selected
-.br
-The main action. This is a WofiPropertyBox which has no CSS node and should probably not be used, the name is dependent on whether or not the entry is selected. See \fBwofi\fR(5) on #selected and #unselected for info.
-
-.RS 4
-.B image
-.br
-This is only present if an image is present in the entry and might occur multiple times if multiple images are present.
-
-.B label
-.br
-This is only present if text is present in the entry and might occur multiple times if there are multiple text objects in a single entry.
-.RE
-
-.B list
-.br
-This contains all the secondary actions
-.RS 4
-.B row \- #entry
-.RS 4
-.B .entry \- #unselected or #selected
-.br
-This is a WofiPropertyBox which has no CSS node and should probably not be used, the name is dependent on whether or not the entry is selected. See \fBwofi\fR(5) on #selected and #unselected for info.
-
-.RS 4
-.B image
-.br
-This is only present if an image is present in the entry and might occur multiple times if multiple images are present.
-
-.B label
-.br
-This is only present if text is present in the entry and might occur multiple times if there are multiple text objects in a single entry.
-.RE
-.RE
-.RE
-.RE
-.RE
-.RE
-.RE
-.RE
-.B scrollbar
-.RE
-.RE
-.RE
diff --git a/wofi/meson.build b/wofi/meson.build
deleted file mode 100644
index e141508..0000000
--- a/wofi/meson.build
+++ /dev/null
@@ -1,77 +0,0 @@
-project('wofi', 'c', version : 'hg', default_options : ['c_std=c99', 'buildtype=release', 'warning_level=2'])
-cc = meson.get_compiler('c')
-
-pkgcfg = import('pkgconfig')
-
-inc = include_directories('inc')
-gtk = dependency('gtk+-3.0')
-wayland = dependency('wayland-client')
-threads = dependency('threads')
-dl = cc.find_library('dl')
-
-hg = find_program('hg', native : true, required : false)
-
-version = meson.project_version()
-
-if hg.found()
- version = run_command(hg, 'identify', check : true).stdout().strip()
-endif
-
-add_project_arguments('-D_GNU_SOURCE', '-DVERSION="' + version + '"', language : 'c')
-add_project_link_arguments('-rdynamic', language : 'c')
-
-sources = ['src/config.c',
- 'src/main.c',
- 'src/map.c',
- 'src/match.c',
- 'src/property_box.c',
- 'src/utils_g.c',
- 'src/utils.c',
- 'src/widget_builder.c',
- 'src/wofi.c',
- 'proto/wlr-layer-shell-unstable-v1-protocol.c',
- 'proto/xdg-output-unstable-v1-protocol.c',
- 'proto/xdg-shell-protocol.c']
-
-deps = [gtk, wayland, dl, threads]
-
-if get_option('enable_run')
- sources += 'modes/run.c'
-endif
-
-if get_option('enable_drun')
- sources += 'modes/drun.c'
- deps += dependency('gio-unix-2.0')
-endif
-
-if get_option('enable_dmenu')
- sources += 'modes/dmenu.c'
-endif
-
-install_man('man/wofi.1',
- 'man/wofi.3',
- 'man/wofi.5',
- 'man/wofi.7',
- 'man/wofi-api.3',
- 'man/wofi-config.3',
- 'man/wofi-keys.7',
- 'man/wofi-map.3',
- 'man/wofi-utils.3',
- 'man/wofi-widget-builder.3')
-
-subdir = 'wofi-1'
-
-install_headers('inc/config.h',
- 'inc/map.h',
- 'inc/utils_g.h',
- 'inc/utils.h',
- 'inc/widget_builder_api.h',
- 'inc/wofi_api.h',
- subdir : subdir)
-
-pkgcfg.generate(name : meson.project_name(),
- description : 'Wofi API for developing modes',
- requires : wayland,
- subdirs : subdir)
-
-executable(meson.project_name(), sources, include_directories : inc, dependencies : deps, install : true)
diff --git a/wofi/meson_options.txt b/wofi/meson_options.txt
deleted file mode 100644
index 119b6ca..0000000
--- a/wofi/meson_options.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-option('enable_run', type : 'boolean', value : true, description : 'Whether run mode should be enabled')
-option('enable_drun', type : 'boolean', value : true, description : 'Whether drun mode should be enabled')
-option('enable_dmenu', type : 'boolean', value : true, description : 'Whether dmenu mode should be enabled')
\ No newline at end of file
diff --git a/wofi/modes/dmenu.c b/wofi/modes/dmenu.c
deleted file mode 100644
index 787000d..0000000
--- a/wofi/modes/dmenu.c
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * Copyright (C) 2019-2024 Scoopta
- * This file is part of Wofi
- * Wofi 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.
-
- Wofi 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 Wofi. If not, see .
- */
-
-#include
-#include
-#include
-#include
-
-#include
-#include
-
-#include
-
-static const char* arg_names[] = {"parse_action", "separator", "print_line_num"};
-
-static bool parse_action;
-static char* separator;
-static bool print_line_num;
-static struct mode* mode;
-
-struct node {
- struct widget* widget;
- struct wl_list link;
-};
-
-static struct wl_list widgets;
-
-void wofi_dmenu_init(struct mode* this, struct map* config) {
- mode = this;
- parse_action = strcmp(config_get(config, "parse_action", "false"), "true") == 0;
- separator = config_get(config, "separator", "\n");
- print_line_num = strcmp(config_get(config, "print_line_num", "false"), "true") == 0;
-
- if(strcmp(separator, "\\n") == 0) {
- separator = "\n";
- } else if(strcmp(separator, "\\0") == 0) {
- separator = "\0";
- } else if(strcmp(separator, "\\t") == 0) {
- separator = "\t";
- }
-
- wl_list_init(&widgets);
-
- struct map* cached = map_init();
-
- struct wl_list entries;
- wl_list_init(&entries);
-
- struct map* entry_map = map_init();
-
- if(!isatty(STDIN_FILENO)) {
- char* line = NULL;
- size_t size = 0;
- while(getdelim(&line, &size, separator[0], stdin) != -1) {
- char* delim = strchr(line, separator[0]);
- if(delim != NULL) {
- *delim = 0;
- }
- struct cache_line* node = malloc(sizeof(struct cache_line));
- node->line = strdup(line);
- wl_list_insert(&entries, &node->link);
- map_put(entry_map, line, "true");
- }
- free(line);
- }
-
- if(!print_line_num) {
- struct wl_list* cache = wofi_read_cache(mode);
-
- struct cache_line* node, *tmp;
- wl_list_for_each_safe(node, tmp, cache, link) {
- if(map_contains(entry_map, node->line)) {
- map_put(cached, node->line, "true");
- struct node* widget = malloc(sizeof(struct node));
- widget->widget = wofi_create_widget(mode, &node->line, node->line, &node->line, 1);
- wl_list_insert(&widgets, &widget->link);
- } else {
- wofi_remove_cache(mode, node->line);
- }
- free(node->line);
- wl_list_remove(&node->link);
- free(node);
- }
- free(cache);
- }
-
- map_free(entry_map);
-
- uint16_t line_num = 0;
-
- struct cache_line* node, *tmp;
- wl_list_for_each_reverse_safe(node, tmp, &entries, link) {
- if(!map_contains(cached, node->line)) {
-
- char* action;
- if(print_line_num) {
- action = malloc(6);
- snprintf(action, 6, "%u", line_num++);
- } else {
- action = strdup(node->line);
- }
-
- struct node* widget = malloc(sizeof(struct node));
- widget->widget = wofi_create_widget(mode, &node->line, node->line, &action, 1);
- wl_list_insert(&widgets, &widget->link);
- free(action);
- }
- free(node->line);
- wl_list_remove(&node->link);
- free(node);
- }
- map_free(cached);
-}
-
-struct widget* wofi_dmenu_get_widget(void) {
- struct node* node, *tmp;
- wl_list_for_each_reverse_safe(node, tmp, &widgets, link) {
- struct widget* widget = node->widget;
- wl_list_remove(&node->link);
- free(node);
- return widget;
- }
- return NULL;
-}
-
-void wofi_dmenu_exec(const gchar* cmd) {
- char* action = strdup(cmd);
- if(parse_action) {
- if(wofi_allow_images()) {
- free(action);
- action = wofi_parse_image_escapes(cmd);
- }
- if(wofi_allow_markup()) {
- char* out;
- pango_parse_markup(action, -1, 0, NULL, &out, NULL, NULL);
- free(action);
- action = out;
- }
- }
- if(!print_line_num) {
- wofi_write_cache(mode, cmd);
- }
- printf("%s\n", action);
- free(action);
- wofi_exit(0);
-}
-
-const char** wofi_dmenu_get_arg_names(void) {
- return arg_names;
-}
-
-size_t wofi_dmenu_get_arg_count(void) {
- return sizeof(arg_names) / sizeof(char*);
-}
-
-bool wofi_dmenu_no_entry(void) {
- return true;
-}
diff --git a/wofi/modes/drun.c b/wofi/modes/drun.c
deleted file mode 100644
index ac61afa..0000000
--- a/wofi/modes/drun.c
+++ /dev/null
@@ -1,496 +0,0 @@
-/*
- * Copyright (C) 2019-2024 Scoopta
- * This file is part of Wofi
- * Wofi 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.
-
- Wofi 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 Wofi. If not, see .
- */
-
-#include
-#include
-
-#include
-
-#include
-#include
-#include
-#include
-#include
-
-#include
-#include
-
-static const char* arg_names[] = {"print_command", "display_generic", "disable_prime", "print_desktop_file"};
-
-static struct mode* mode;
-
-struct desktop_entry {
- char* full_path;
- struct wl_list link;
-};
-
-static struct map* entries;
-static struct wl_list desktop_entries;
-
-static bool print_command;
-static bool display_generic;
-static bool disable_prime;
-static bool print_desktop_file;
-
-static char* get_search_text(char* file) {
- GDesktopAppInfo* info = g_desktop_app_info_new_from_filename(file);
- const char* name = g_app_info_get_display_name(G_APP_INFO(info));
- const char* exec = g_app_info_get_executable(G_APP_INFO(info));
- const char* description = g_app_info_get_description(G_APP_INFO(info));
- const char* categories = g_desktop_app_info_get_categories(info);
- const char* const* keywords = g_desktop_app_info_get_keywords(info);
- const char* generic_name = g_desktop_app_info_get_generic_name(info);
-
- char* keywords_str = strdup("");
-
- if(keywords != NULL) {
- for(size_t count = 0; keywords[count] != NULL; ++count) {
- char* tmp = utils_concat(2, keywords_str, keywords[count]);
- free(keywords_str);
- keywords_str = tmp;
- }
- }
-
- char* ret = utils_concat(7, name, file,
- exec == NULL ? "" : exec,
- description == NULL ? "" : description,
- categories == NULL ? "" : categories,
- keywords_str,
- generic_name == NULL ? "" : generic_name);
- free(keywords_str);
- return ret;
-}
-
-static bool populate_widget(char* file, char* action, struct widget_builder* builder) {
- GDesktopAppInfo* info = g_desktop_app_info_new_from_filename(file);
- if(info == NULL || !g_app_info_should_show(G_APP_INFO(info)) ||
- g_desktop_app_info_get_is_hidden(info)) {
- return false;
- }
- const char* name;
- char* generic_name = strdup("");
- if(action == NULL) {
- name = g_app_info_get_display_name(G_APP_INFO(info));
- if(display_generic) {
- const char* gname = g_desktop_app_info_get_generic_name(info);
- if(gname != NULL) {
- free(generic_name);
- generic_name = utils_concat(3, " (", gname, ")");
- }
- }
- } else {
- name = g_desktop_app_info_get_action_name(info, action);
- }
- if(name == NULL) {
- free(generic_name);
- return false;
- }
-
-
-
- if(wofi_allow_images()) {
- GIcon* icon = g_app_info_get_icon(G_APP_INFO(info));
- GdkPixbuf* pixbuf;
- if(G_IS_FILE_ICON(icon)) {
- GFile* file = g_file_icon_get_file(G_FILE_ICON(icon));
- char* path = g_file_get_path(file);
- pixbuf = gdk_pixbuf_new_from_file(path, NULL);
- } else {
- GtkIconTheme* theme = gtk_icon_theme_get_default();
- GtkIconInfo* info = NULL;
- if(icon != NULL) {
- const gchar* const* icon_names = g_themed_icon_get_names(G_THEMED_ICON(icon));
- info = gtk_icon_theme_choose_icon_for_scale(theme, (const gchar**) icon_names, wofi_get_image_size(), wofi_get_window_scale(), 0);
- }
- if(info == NULL) {
- info = gtk_icon_theme_lookup_icon_for_scale(theme, "application-x-executable", wofi_get_image_size(), wofi_get_window_scale(), 0);
- }
- pixbuf = gtk_icon_info_load_icon(info, NULL);
- }
-
- if(pixbuf == NULL) {
- goto img_fail;
- }
-
- pixbuf = utils_g_resize_pixbuf(pixbuf, wofi_get_image_size() * wofi_get_window_scale(), GDK_INTERP_BILINEAR);
-
- wofi_widget_builder_insert_image(builder, pixbuf, "icon", NULL);
- g_object_unref(pixbuf);
- }
-
- img_fail:
- wofi_widget_builder_insert_text(builder, name, "name", NULL);
- wofi_widget_builder_insert_text(builder, generic_name, "generic-name", NULL);
- free(generic_name);
-
- if(action == NULL) {
- wofi_widget_builder_set_action(builder, file);
- } else {
- char* action_txt = utils_concat(3, file, " ", action);
- wofi_widget_builder_set_action(builder, action_txt);
- free(action_txt);
- }
-
-
- char* search_txt = get_search_text(file);
- wofi_widget_builder_set_search_text(builder, search_txt);
- free(search_txt);
-
- return true;
-}
-
-static const gchar* const* get_actions(char* file, size_t* action_count) {
- *action_count = 0;
- GDesktopAppInfo* info = g_desktop_app_info_new_from_filename(file);
- if(info == NULL) {
- return NULL;
- }
- const gchar* const* actions = g_desktop_app_info_list_actions(info);
- if(actions[0] == NULL) {
- return NULL;
- }
-
- for(; actions[*action_count] != NULL; ++*action_count);
-
- return actions;
-}
-
-static struct widget_builder* populate_actions(char* file, size_t* text_count) {
- const gchar* const* action_names = get_actions(file, text_count);
-
- ++*text_count;
-
-
- struct widget_builder* builder = wofi_widget_builder_init(mode, *text_count);
- if(!populate_widget(file, NULL, builder)) {
- wofi_widget_builder_free(builder);
- return NULL;
- }
-
- for(size_t count = 1; count < *text_count; ++count) {
- populate_widget(file, (gchar*) action_names[count - 1], wofi_widget_builder_get_idx(builder, count));
- }
- return builder;
-}
-
-static char* get_id(char* path) {
- char* applications = strstr(path, "applications/");
- if(applications == NULL) {
- return NULL;
- }
- char* name = strchr(applications, '/') + 1;
- char* id = strdup(name);
-
- char* slash;
- while((slash = strchr(id, '/')) != NULL) {
- *slash = '-';
- }
- return id;
-}
-
-static struct widget* create_widget(char* full_path) {
- char* id = get_id(full_path);
- if(id == NULL) {
- free(full_path);
- return NULL;
- }
-
- if(map_contains(entries, id)) {
- free(id);
- free(full_path);
- return NULL;
- }
-
- map_put(entries, id, "true");
-
- size_t action_count;
-
- struct widget_builder* builder = populate_actions(full_path, &action_count);
- if(builder == NULL) {
- wofi_remove_cache(mode, full_path);
- free(id);
- free(full_path);
- return NULL;
- }
-
- struct widget* ret = wofi_widget_builder_get_widget(builder);
-
- free(id);
- free(full_path);
-
- return ret;
-}
-
-static void insert_dir(char* app_dir) {
- DIR* dir = opendir(app_dir);
- if(dir == NULL) {
- return;
- }
- struct dirent* entry;
- while((entry = readdir(dir)) != NULL) {
- if(strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {
- continue;
- }
- char* full_path = utils_concat(3, app_dir, "/", entry->d_name);
- char* id = get_id(full_path);
- if(id == NULL) {
- free(full_path);
- continue;
- }
-
- struct stat info;
- stat(full_path, &info);
- if(S_ISDIR(info.st_mode)) {
- insert_dir(full_path);
- free(id);
- free(full_path);
- continue;
- }
- if(map_contains(entries, id)) {
- free(id);
- free(full_path);
- continue;
- }
-
- struct desktop_entry* entry = malloc(sizeof(struct desktop_entry));
- entry->full_path = full_path;
- wl_list_insert(&desktop_entries, &entry->link);
-
- free(id);
- }
- closedir(dir);
-}
-
-static char* get_data_dirs(void) {
- char* data_dirs = getenv("XDG_DATA_DIRS");
- if(data_dirs == NULL) {
- data_dirs = "/usr/local/share:/usr/share";
- }
- return strdup(data_dirs);
-}
-
-static char* get_data_home(void) {
- char* data_home = getenv("XDG_DATA_HOME");
- if(data_home == NULL) {
- data_home = utils_concat(2, getenv("HOME"), "/.local/share");
- } else {
- data_home = strdup(data_home);
- }
- return data_home;
-}
-
-static bool starts_with_data_dirs(char* path) {
- char* data_dirs = get_data_dirs();
- char* save_ptr;
- char* str = strtok_r(data_dirs, ":", &save_ptr);
- do {
- char* tmpstr = utils_concat(2, str, "/applications");
- char* tmp = strdup(path);
- char* dir = dirname(tmp);
- if(strcmp(dir, tmpstr) == 0) {
- free(tmp);
- free(data_dirs);
- free(tmpstr);
- return true;
- }
- free(tmp);
- free(tmpstr);
- } while((str = strtok_r(NULL, ":", &save_ptr)) != NULL);
-
- free(data_dirs);
- return false;
-}
-
-static bool should_invalidate_cache(char* path) {
- if(starts_with_data_dirs(path)) {
- char* data_home = get_data_home();
- char* tmp = strdup(path);
- char* file = basename(tmp);
- char* full_path = utils_concat(3, data_home, "/applications/", file);
- free(data_home);
- if(access(full_path, F_OK) == 0) {
- free(full_path);
- free(tmp);
- return true;
- }
- free(full_path);
- free(tmp);
- }
- return false;
-}
-
-void wofi_drun_init(struct mode* this, struct map* config) {
- mode = this;
-
- print_command = strcmp(config_get(config, "print_command", "false"), "true") == 0;
- display_generic = strcmp(config_get(config, "display_generic", "false"), "true") == 0;
- disable_prime = strcmp(config_get(config, "disable_prime", "false"), "true") == 0;
- print_desktop_file = strcmp(config_get(config, "print_desktop_file", "false"), "true") == 0;
-
- entries = map_init();
- struct wl_list* cache = wofi_read_cache(mode);
-
- wl_list_init(&desktop_entries);
-
- struct cache_line* node, *tmp;
- wl_list_for_each_safe(node, tmp, cache, link) {
- if(should_invalidate_cache(node->line)) {
- wofi_remove_cache(mode, node->line);
- free(node->line);
- goto cache_cont;
- }
-
- struct desktop_entry* entry = malloc(sizeof(struct desktop_entry));
- entry->full_path = node->line;
- wl_list_insert(&desktop_entries, &entry->link);
-
- cache_cont:
- wl_list_remove(&node->link);
- free(node);
- }
-
- free(cache);
-
- char* data_home = get_data_home();
- char* data_dirs = get_data_dirs();
- char* dirs = utils_concat(3, data_home, ":", data_dirs);
- free(data_home);
- free(data_dirs);
-
- char* save_ptr;
- char* str = strtok_r(dirs, ":", &save_ptr);
- do {
- char* app_dir = utils_concat(2, str, "/applications");
- insert_dir(app_dir);
- free(app_dir);
- } while((str = strtok_r(NULL, ":", &save_ptr)) != NULL);
- free(dirs);
-}
-
-struct widget* wofi_drun_get_widget(void) {
- struct desktop_entry* node, *tmp;
- wl_list_for_each_reverse_safe(node, tmp, &desktop_entries, link) {
- struct widget* widget = create_widget(node->full_path);
- wl_list_remove(&node->link);
- free(node);
- if(widget == NULL) {
- continue;
- }
- return widget;
- }
- return NULL;
-}
-
-static void launch_done(GObject* obj, GAsyncResult* result, gpointer data) {
- GError* err = NULL;
- if(g_app_info_launch_uris_finish(G_APP_INFO(obj), result, &err)) {
- wofi_exit(0);
- } else if(err != NULL) {
- char* cmd = data;
- fprintf(stderr, "%s cannot be executed: %s\n", cmd, err->message);
- g_error_free(err);
- } else {
- char* cmd = data;
- fprintf(stderr, "%s cannot be executed\n", cmd);
- }
- wofi_exit(1);
-}
-
-static void set_dri_prime(GDesktopAppInfo* info) {
- bool dri_prime = g_desktop_app_info_get_boolean(info, "PrefersNonDefaultGPU");
- if(dri_prime && !disable_prime) {
- setenv("DRI_PRIME", "1", true);
- }
-}
-
-static bool uses_dbus(GDesktopAppInfo* info) {
- return g_desktop_app_info_get_boolean(info, "DBusActivatable");
-}
-
-static char* get_cmd(GAppInfo* info) {
- const char* cmd = g_app_info_get_commandline(info);
- size_t cmd_size = strlen(cmd);
- char* new_cmd = calloc(1, cmd_size + 1);
- size_t new_cmd_count = 0;
- for(size_t count = 0; count < cmd_size; ++count) {
- if(cmd[count] == '%') {
- if(cmd[++count] == '%') {
- new_cmd[new_cmd_count++] = cmd[count];
- }
- } else {
- new_cmd[new_cmd_count++] = cmd[count];
- }
- }
- if(new_cmd[--new_cmd_count] == ' ') {
- new_cmd[new_cmd_count] = 0;
- }
- return new_cmd;
-}
-
-void wofi_drun_exec(const gchar* cmd) {
- GDesktopAppInfo* info = g_desktop_app_info_new_from_filename(cmd);
- if(G_IS_DESKTOP_APP_INFO(info)) {
- wofi_write_cache(mode, cmd);
- if(print_command) {
- char* cmd = get_cmd(G_APP_INFO(info));
- printf("%s\n", cmd);
- free(cmd);
- wofi_exit(0);
- } else if(print_desktop_file) {
- printf("%s\n", cmd);
- wofi_exit(0);
- } else {
- set_dri_prime(info);
- if(uses_dbus(info)) {
- g_app_info_launch_uris_async(G_APP_INFO(info), NULL, NULL, NULL, launch_done, (gchar*) cmd);
- } else {
- g_app_info_launch_uris(G_APP_INFO(info), NULL, NULL, NULL);
- wofi_exit(0);
- }
- }
- } else if(strrchr(cmd, ' ') != NULL) {
- char* space = strrchr(cmd, ' ');
- *space = 0;
- wofi_write_cache(mode, cmd);
- info = g_desktop_app_info_new_from_filename(cmd);
- char* action = space + 1;
- if(print_command) {
- char* cmd = get_cmd(G_APP_INFO(info));
- printf("%s\n", cmd);
- free(cmd);
- fprintf(stderr, "Printing the command line for an action is not supported\n");
- } else if(print_desktop_file) {
- printf("%s %s\n", cmd, action);
- wofi_exit(0);
- } else {
- set_dri_prime(info);
- g_desktop_app_info_launch_action(info, action, NULL);
- }
- wofi_exit(0);
- } else {
- fprintf(stderr, "%s cannot be executed\n", cmd);
- wofi_exit(1);
- }
-}
-
-const char** wofi_drun_get_arg_names(void) {
- return arg_names;
-}
-
-size_t wofi_drun_get_arg_count(void) {
- return sizeof(arg_names) / sizeof(char*);
-}
diff --git a/wofi/modes/run.c b/wofi/modes/run.c
deleted file mode 100644
index b505dec..0000000
--- a/wofi/modes/run.c
+++ /dev/null
@@ -1,231 +0,0 @@
-/*
- * Copyright (C) 2019-2024 Scoopta
- * This file is part of Wofi
- * Wofi 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.
-
- Wofi 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 Wofi. If not, see .
- */
-
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include
-
-#include
-#include
-#include
-
-static const char* arg_names[] = {"always_parse_args", "show_all", "print_command"};
-
-static bool always_parse_args;
-static bool show_all;
-static bool print_command;
-static struct mode* mode;
-static const char* arg_str = "__args";
-
-struct node {
- struct widget* widget;
- struct wl_list link;
-};
-
-static struct wl_list widgets;
-
-void wofi_run_init(struct mode* this, struct map* config) {
- mode = this;
- always_parse_args = strcmp(config_get(config, arg_names[0], "false"), "true") == 0;
- show_all = strcmp(config_get(config, arg_names[1], "true"), "true") == 0;
- print_command = strcmp(config_get(config, arg_names[2], "false"), "true") == 0;
-
- wl_list_init(&widgets);
-
- struct map* cached = map_init();
- struct wl_list* cache = wofi_read_cache(mode);
-
- struct map* entries = map_init();
-
- struct cache_line* node, *tmp;
- wl_list_for_each_safe(node, tmp, cache, link) {
- char* text = node->line;
- if(strncmp(node->line, arg_str, strlen(arg_str)) == 0) {
- text = strchr(text, ' ') + 1;
- }
-
- char* full_path = text;
-
- char* final_slash = strrchr(text, '/');
- if(final_slash != NULL) {
- text = final_slash + 1;
- }
-
- struct stat info;
- stat(node->line, &info);
- if(((access(node->line, X_OK) == 0 && S_ISREG(info.st_mode)) ||
- strncmp(node->line, arg_str, strlen(arg_str)) == 0) && !map_contains(cached, full_path)) {
- struct node* widget = malloc(sizeof(struct node));
- widget->widget = wofi_create_widget(mode, &text, text, &node->line, 1);
- wl_list_insert(&widgets, &widget->link);
- map_put(cached, full_path, "true");
- map_put(entries, text, "true");
- } else {
- wofi_remove_cache(mode, node->line);
- }
- free(node->line);
- wl_list_remove(&node->link);
- free(node);
- }
-
- free(cache);
-
- char* path = strdup(getenv("PATH"));
-
- struct map* paths = map_init();
-
- char* save_ptr;
- char* str = strtok_r(path, ":", &save_ptr);
- do {
-
- str = realpath(str, NULL);
- if(str == NULL) {
- continue;
- }
- if(map_contains(paths, str)) {
- free(str);
- continue;
- }
-
- map_put(paths, str, "true");
-
- DIR* dir = opendir(str);
- if(dir == NULL) {
- continue;
- }
- struct dirent* entry;
- while((entry = readdir(dir)) != NULL) {
- if(strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {
- continue;
- }
- char* full_path = utils_concat(3, str, "/", entry->d_name);
- struct stat info;
- stat(full_path, &info);
- if(access(full_path, X_OK) == 0 && S_ISREG(info.st_mode) &&
- !map_contains(cached, full_path) &&
- (show_all || !map_contains(entries, entry->d_name))) {
- char* text = strdup(entry->d_name);
- map_put(entries, text, "true");
- struct node* widget = malloc(sizeof(struct node));
- widget->widget = wofi_create_widget(mode, &text, text, &full_path, 1);
- wl_list_insert(&widgets, &widget->link);
- free(text);
- }
- free(full_path);
- }
- free(str);
- closedir(dir);
- } while((str = strtok_r(NULL, ":", &save_ptr)) != NULL);
- free(path);
- map_free(paths);
- map_free(cached);
- map_free(entries);
-}
-
-struct widget* wofi_run_get_widget(void) {
- struct node* node, *tmp;
- wl_list_for_each_reverse_safe(node, tmp, &widgets, link) {
- struct widget* widget = node->widget;
- wl_list_remove(&node->link);
- free(node);
- return widget;
- }
- return NULL;
-}
-
-static char* parse_args(const char* cmd, size_t* space_count) {
- size_t cmd_l = strlen(cmd);
- char* ret = calloc(1, cmd_l + 1);
-
- bool in_quote = false;
- size_t ret_count = 0;
- for(size_t count = 0; count < cmd_l; ++count) {
- if(cmd[count] == ' ' && !in_quote) {
- ++*space_count;
- ret[ret_count++] = '\n';
- continue;
- }
-
- if(cmd[count] == '"') {
- in_quote = !in_quote;
- continue;
- }
-
- if(cmd[count] == '\\') {
- ++count;
- }
- ret[ret_count++] = cmd[count];
- }
-
- return ret;
-}
-
-void wofi_run_exec(const char* cmd) {
- bool arg_run = wofi_mod_control() || always_parse_args;
- if(strncmp(cmd, arg_str, strlen(arg_str)) == 0) {
- arg_run = true;
- cmd = strchr(cmd, ' ') + 1;
- }
-
- if(wofi_mod_shift()) {
- wofi_write_cache(mode, cmd);
- wofi_term_run(cmd);
- }
- if(print_command) {
- printf("%s\n", cmd);
- wofi_exit(0);
- }
- if(arg_run) {
- size_t space_count = 2;
- char* tmp = parse_args(cmd, &space_count);
-
- char** args = malloc(space_count * sizeof(char*));
- char* save_ptr;
- char* str = strtok_r(tmp, "\n", &save_ptr);
- size_t count = 0;
- do {
- args[count++] = str;
- } while((str = strtok_r(NULL, "\n", &save_ptr)) != NULL);
- args[space_count - 1] = NULL;
- char* cache = utils_concat(2, "__args ", cmd);
- wofi_write_cache(mode, cache);
- free(cache);
- execvp(tmp, args);
- } else {
- wofi_write_cache(mode, cmd);
- execl(cmd, cmd, NULL);
- }
- fprintf(stderr, "%s cannot be executed %s\n", cmd, strerror(errno));
- wofi_exit(errno);
-}
-
-const char** wofi_run_get_arg_names(void) {
- return arg_names;
-}
-
-size_t wofi_run_get_arg_count(void) {
- return sizeof(arg_names) / sizeof(char*);
-}
-
-bool wofi_run_no_entry(void) {
- return true;
-}
diff --git a/wofi/proto/wlr-layer-shell-unstable-v1-protocol.c b/wofi/proto/wlr-layer-shell-unstable-v1-protocol.c
deleted file mode 100644
index 429f067..0000000
--- a/wofi/proto/wlr-layer-shell-unstable-v1-protocol.c
+++ /dev/null
@@ -1,91 +0,0 @@
-/* Generated by wayland-scanner 1.16.0 */
-
-/*
- * Copyright © 2017 Drew DeVault
- *
- * Permission to use, copy, modify, distribute, and sell this
- * software and its documentation for any purpose is hereby granted
- * without fee, provided that the above copyright notice appear in
- * all copies and that both that copyright notice and this permission
- * notice appear in supporting documentation, and that the name of
- * the copyright holders not be used in advertising or publicity
- * pertaining to distribution of the software without specific,
- * written prior permission. The copyright holders make no
- * representations about the suitability of this software for any
- * purpose. It is provided "as is" without express or implied
- * warranty.
- *
- * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
- * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
- * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
- * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
- * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
- * THIS SOFTWARE.
- */
-
-#include
-#include
-#include "wayland-util.h"
-
-#ifndef __has_attribute
-# define __has_attribute(x) 0 /* Compatibility with non-clang compilers. */
-#endif
-
-#if (__has_attribute(visibility) || defined(__GNUC__) && __GNUC__ >= 4)
-#define WL_PRIVATE __attribute__ ((visibility("hidden")))
-#else
-#define WL_PRIVATE
-#endif
-
-extern const struct wl_interface wl_output_interface;
-extern const struct wl_interface wl_surface_interface;
-extern const struct wl_interface xdg_popup_interface;
-extern const struct wl_interface zwlr_layer_surface_v1_interface;
-
-static const struct wl_interface *types[] = {
- NULL,
- NULL,
- NULL,
- NULL,
- &zwlr_layer_surface_v1_interface,
- &wl_surface_interface,
- &wl_output_interface,
- NULL,
- NULL,
- &xdg_popup_interface,
-};
-
-static const struct wl_message zwlr_layer_shell_v1_requests[] = {
- { "get_layer_surface", "no?ous", types + 4 },
-};
-
-WL_PRIVATE const struct wl_interface zwlr_layer_shell_v1_interface = {
- "zwlr_layer_shell_v1", 1,
- 1, zwlr_layer_shell_v1_requests,
- 0, NULL,
-};
-
-static const struct wl_message zwlr_layer_surface_v1_requests[] = {
- { "set_size", "uu", types + 0 },
- { "set_anchor", "u", types + 0 },
- { "set_exclusive_zone", "i", types + 0 },
- { "set_margin", "iiii", types + 0 },
- { "set_keyboard_interactivity", "u", types + 0 },
- { "get_popup", "o", types + 9 },
- { "ack_configure", "u", types + 0 },
- { "destroy", "", types + 0 },
-};
-
-static const struct wl_message zwlr_layer_surface_v1_events[] = {
- { "configure", "uuu", types + 0 },
- { "closed", "", types + 0 },
-};
-
-WL_PRIVATE const struct wl_interface zwlr_layer_surface_v1_interface = {
- "zwlr_layer_surface_v1", 1,
- 8, zwlr_layer_surface_v1_requests,
- 2, zwlr_layer_surface_v1_events,
-};
-
diff --git a/wofi/proto/xdg-output-unstable-v1-protocol.c b/wofi/proto/xdg-output-unstable-v1-protocol.c
deleted file mode 100644
index 329e8bf..0000000
--- a/wofi/proto/xdg-output-unstable-v1-protocol.c
+++ /dev/null
@@ -1,78 +0,0 @@
-/* Generated by wayland-scanner 1.16.0 */
-
-/*
- * Copyright © 2017 Red Hat Inc.
- *
- * 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 (including the next
- * paragraph) 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.
- */
-
-#include
-#include
-#include "wayland-util.h"
-
-#ifndef __has_attribute
-# define __has_attribute(x) 0 /* Compatibility with non-clang compilers. */
-#endif
-
-#if (__has_attribute(visibility) || defined(__GNUC__) && __GNUC__ >= 4)
-#define WL_PRIVATE __attribute__ ((visibility("hidden")))
-#else
-#define WL_PRIVATE
-#endif
-
-extern const struct wl_interface wl_output_interface;
-extern const struct wl_interface zxdg_output_v1_interface;
-
-static const struct wl_interface *types[] = {
- NULL,
- NULL,
- &zxdg_output_v1_interface,
- &wl_output_interface,
-};
-
-static const struct wl_message zxdg_output_manager_v1_requests[] = {
- { "destroy", "", types + 0 },
- { "get_xdg_output", "no", types + 2 },
-};
-
-WL_PRIVATE const struct wl_interface zxdg_output_manager_v1_interface = {
- "zxdg_output_manager_v1", 2,
- 2, zxdg_output_manager_v1_requests,
- 0, NULL,
-};
-
-static const struct wl_message zxdg_output_v1_requests[] = {
- { "destroy", "", types + 0 },
-};
-
-static const struct wl_message zxdg_output_v1_events[] = {
- { "logical_position", "ii", types + 0 },
- { "logical_size", "ii", types + 0 },
- { "done", "", types + 0 },
- { "name", "2s", types + 0 },
- { "description", "2s", types + 0 },
-};
-
-WL_PRIVATE const struct wl_interface zxdg_output_v1_interface = {
- "zxdg_output_v1", 2,
- 1, zxdg_output_v1_requests,
- 5, zxdg_output_v1_events,
-};
-
diff --git a/wofi/proto/xdg-shell-protocol.c b/wofi/proto/xdg-shell-protocol.c
deleted file mode 100644
index 4bff9c9..0000000
--- a/wofi/proto/xdg-shell-protocol.c
+++ /dev/null
@@ -1,174 +0,0 @@
-/* Generated by wayland-scanner 1.16.0 */
-
-/*
- * Copyright © 2008-2013 Kristian Høgsberg
- * Copyright © 2013 Rafael Antognolli
- * Copyright © 2013 Jasper St. Pierre
- * Copyright © 2010-2013 Intel Corporation
- * Copyright © 2015-2017 Samsung Electronics Co., Ltd
- * Copyright © 2015-2017 Red Hat Inc.
- *
- * 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 (including the next
- * paragraph) 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.
- */
-
-#include
-#include
-#include "wayland-util.h"
-
-#ifndef __has_attribute
-# define __has_attribute(x) 0 /* Compatibility with non-clang compilers. */
-#endif
-
-#if (__has_attribute(visibility) || defined(__GNUC__) && __GNUC__ >= 4)
-#define WL_PRIVATE __attribute__ ((visibility("hidden")))
-#else
-#define WL_PRIVATE
-#endif
-
-extern const struct wl_interface wl_output_interface;
-extern const struct wl_interface wl_seat_interface;
-extern const struct wl_interface wl_surface_interface;
-extern const struct wl_interface xdg_popup_interface;
-extern const struct wl_interface xdg_positioner_interface;
-extern const struct wl_interface xdg_surface_interface;
-extern const struct wl_interface xdg_toplevel_interface;
-
-static const struct wl_interface *types[] = {
- NULL,
- NULL,
- NULL,
- NULL,
- &xdg_positioner_interface,
- &xdg_surface_interface,
- &wl_surface_interface,
- &xdg_toplevel_interface,
- &xdg_popup_interface,
- &xdg_surface_interface,
- &xdg_positioner_interface,
- &xdg_toplevel_interface,
- &wl_seat_interface,
- NULL,
- NULL,
- NULL,
- &wl_seat_interface,
- NULL,
- &wl_seat_interface,
- NULL,
- NULL,
- &wl_output_interface,
- &wl_seat_interface,
- NULL,
-};
-
-static const struct wl_message xdg_wm_base_requests[] = {
- { "destroy", "", types + 0 },
- { "create_positioner", "n", types + 4 },
- { "get_xdg_surface", "no", types + 5 },
- { "pong", "u", types + 0 },
-};
-
-static const struct wl_message xdg_wm_base_events[] = {
- { "ping", "u", types + 0 },
-};
-
-WL_PRIVATE const struct wl_interface xdg_wm_base_interface = {
- "xdg_wm_base", 2,
- 4, xdg_wm_base_requests,
- 1, xdg_wm_base_events,
-};
-
-static const struct wl_message xdg_positioner_requests[] = {
- { "destroy", "", types + 0 },
- { "set_size", "ii", types + 0 },
- { "set_anchor_rect", "iiii", types + 0 },
- { "set_anchor", "u", types + 0 },
- { "set_gravity", "u", types + 0 },
- { "set_constraint_adjustment", "u", types + 0 },
- { "set_offset", "ii", types + 0 },
-};
-
-WL_PRIVATE const struct wl_interface xdg_positioner_interface = {
- "xdg_positioner", 2,
- 7, xdg_positioner_requests,
- 0, NULL,
-};
-
-static const struct wl_message xdg_surface_requests[] = {
- { "destroy", "", types + 0 },
- { "get_toplevel", "n", types + 7 },
- { "get_popup", "n?oo", types + 8 },
- { "set_window_geometry", "iiii", types + 0 },
- { "ack_configure", "u", types + 0 },
-};
-
-static const struct wl_message xdg_surface_events[] = {
- { "configure", "u", types + 0 },
-};
-
-WL_PRIVATE const struct wl_interface xdg_surface_interface = {
- "xdg_surface", 2,
- 5, xdg_surface_requests,
- 1, xdg_surface_events,
-};
-
-static const struct wl_message xdg_toplevel_requests[] = {
- { "destroy", "", types + 0 },
- { "set_parent", "?o", types + 11 },
- { "set_title", "s", types + 0 },
- { "set_app_id", "s", types + 0 },
- { "show_window_menu", "ouii", types + 12 },
- { "move", "ou", types + 16 },
- { "resize", "ouu", types + 18 },
- { "set_max_size", "ii", types + 0 },
- { "set_min_size", "ii", types + 0 },
- { "set_maximized", "", types + 0 },
- { "unset_maximized", "", types + 0 },
- { "set_fullscreen", "?o", types + 21 },
- { "unset_fullscreen", "", types + 0 },
- { "set_minimized", "", types + 0 },
-};
-
-static const struct wl_message xdg_toplevel_events[] = {
- { "configure", "iia", types + 0 },
- { "close", "", types + 0 },
-};
-
-WL_PRIVATE const struct wl_interface xdg_toplevel_interface = {
- "xdg_toplevel", 2,
- 14, xdg_toplevel_requests,
- 2, xdg_toplevel_events,
-};
-
-static const struct wl_message xdg_popup_requests[] = {
- { "destroy", "", types + 0 },
- { "grab", "ou", types + 22 },
-};
-
-static const struct wl_message xdg_popup_events[] = {
- { "configure", "iiii", types + 0 },
- { "popup_done", "", types + 0 },
-};
-
-WL_PRIVATE const struct wl_interface xdg_popup_interface = {
- "xdg_popup", 2,
- 2, xdg_popup_requests,
- 2, xdg_popup_events,
-};
-
diff --git a/wofi/src/config.c b/wofi/src/config.c
deleted file mode 100644
index 3fd6359..0000000
--- a/wofi/src/config.c
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright (C) 2019-2024 Scoopta
- * This file is part of Wofi
- * Wofi 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.
-
- Wofi 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 Wofi. If not, see .
- */
-
-#include
-
-#include
-#include
-#include
-#include
-
-#include
-
-void config_put(struct map* map, char* line) {
- size_t line_size = strlen(line);
- char* new_line = calloc(1, line_size + 1);
- size_t new_line_count = 0;
- for(size_t count = 0; count < line_size; ++count) {
- if(line[count] == '\\') {
- new_line[new_line_count++] = line[++count];
- } else if(line[count] == '#') {
- break;
- } else {
- new_line[new_line_count++] = line[count];
- }
- }
- line = new_line;
- char* equals = strchr(line, '=');
- if(equals == NULL) {
- free(line);
- return;
- }
- *equals = 0;
- char* key = equals - 1;
- while(*key == ' ') {
- --key;
- }
- *(key + 1) = 0;
- char* value = equals + 1;
- while(*value == ' ') {
- ++value;
- }
- size_t len = strlen(value);
- char* end = value + len - 1;
- if(*end == '\n' || *end == ' ') {
- *end = 0;
- }
- map_put(map, line, value);
- free(line);
-}
-
-void config_load(struct map* map, const char* config) {
- FILE* file = fopen(config, "r");
- char* line = NULL;
- size_t size = 0;
- while(getline(&line, &size, file) != -1) {
- config_put(map, line);
- }
- free(line);
- fclose(file);
-}
-
-char* config_get(struct map* config, const char* key, char* def_opt) {
- char* opt = map_get(config, key);
- if(opt == NULL) {
- opt = def_opt;
- }
- return opt;
-}
-
-int config_get_mnemonic(struct map* config, const char* key, char* def_opt, int num_choices, ...) {
- char* opt = config_get(config, key, def_opt);
- va_list ap;
- va_start(ap, num_choices);
- int result = 0;
- for(int i = 0; i < num_choices; i++) {
- char* cmp_str = va_arg(ap, char*);
- if(strcmp(opt, cmp_str) == 0) {
- result = i;
- break;
- }
- }
- va_end(ap);
- return result;
-}
diff --git a/wofi/src/main.c b/wofi/src/main.c
deleted file mode 100644
index 5eba651..0000000
--- a/wofi/src/main.c
+++ /dev/null
@@ -1,798 +0,0 @@
-/*
- * Copyright (C) 2019-2020 Scoopta
- * This file is part of Wofi
- * Wofi 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.
-
- Wofi 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 Wofi. If not, see .
- */
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include
-#include
-#include
-#include
-
-#include
-
-#include
-
-static const char* nyan_colors[] = {"#FF0000", "#FFA500", "#FFFF00", "#00FF00", "#0000FF", "#FF00FF"};
-static size_t nyan_color_l = sizeof(nyan_colors) / sizeof(char*);
-
-static char* CONFIG_LOCATION;
-static char* COLORS_LOCATION;
-static struct map* config;
-static char* config_path;
-static char* stylesheet;
-static char* color_path;
-static uint8_t nyan_shift = 0;
-
-struct option_node {
- char* option;
- struct wl_list link;
-};
-
-static char* get_exec_name(char* path) {
- char* slash = strrchr(path, '/');
- uint64_t offset;
- if(slash == NULL) {
- offset = 0;
- } else {
- offset = (slash - path) + 1;
- }
- return path + offset;
-}
-
-static void print_usage(char** argv) {
- printf("%s [options]\n", get_exec_name(argv[0]));
- printf("Options:\n");
- printf("--help\t\t\t-h\tDisplays this help message\n");
- printf("--fork\t\t\t-f\tForks the menu so you can close the terminal\n");
- printf("--conf\t\t\t-c\tSelects a config file to use\n");
- printf("--style\t\t\t-s\tSelects a stylesheet to use\n");
- printf("--color\t\t\t-C\tSelects a colors file to use\n");
- printf("--dmenu\t\t\t-d\tRuns in dmenu mode\n");
- printf("--show\t\t\t-S\tSpecifies the mode to run in. A list can be found in wofi(7)\n");
- printf("--width\t\t\t-W\tSpecifies the surface width\n");
- printf("--height\t\t-H\tSpecifies the surface height\n");
- printf("--prompt\t\t-p\tPrompt to display\n");
- printf("--xoffset\t\t-x\tThe x offset\n");
- printf("--yoffset\t\t-y\tThe y offset\n");
- printf("--normal-window\t\t-n\tRender to a normal window\n");
- printf("--allow-images\t\t-I\tAllows images to be rendered\n");
- printf("--allow-markup\t\t-m\tAllows pango markup\n");
- printf("--cache-file\t\t-k\tSets the cache file to use\n");
- printf("--term\t\t\t-t\tSpecifies the terminal to use when running in a term\n");
- printf("--password\t\t-P\tRuns in password mode\n");
- printf("--exec-search\t\t-e\tMakes enter always use the search contents not the first result\n");
- printf("--hide-scroll\t\t-b\tHides the scroll bars\n");
- printf("--matching\t\t-M\tSets the matching method, default is contains\n");
- printf("--insensitive\t\t-i\tAllows case insensitive searching\n");
- printf("--parse-search\t\t-q\tParses the search text removing image escapes and pango\n");
- printf("--version\t\t-v\tPrints the version and then exits\n");
- printf("--location\t\t-l\tSets the location\n");
- printf("--no-actions\t\t-a\tDisables multiple actions for modes that support it\n");
- printf("--define\t\t-D\tSets a config option\n");
- printf("--lines\t\t\t-L\tSets the height in number of lines\n");
- printf("--columns\t\t-w\tSets the number of columns to display\n");
- printf("--sort-order\t\t-O\tSets the sort order\n");
- printf("--gtk-dark\t\t-G\tUses the dark variant of the current GTK theme\n");
- printf("--search\t\t-Q\tSearch for something immediately on open\n");
- printf("--monitor\t\t-o\tSets the monitor to open on\n");
- printf("--pre-display-cmd\t-r\tRuns command for the displayed entries, without changing the output. %%s for the real string\n");
- exit(0);
-}
-
-void wofi_load_css(bool nyan) {
- if(access(stylesheet, R_OK) == 0) {
- FILE* file = fopen(stylesheet, "r");
- fseek(file, 0, SEEK_END);
- ssize_t size = ftell(file);
- fseek(file, 0, SEEK_SET);
- char* data = malloc(size + 1);
- if (fread(data, 1, size, file) == 0) {
- fprintf(stderr, "failed to read stylesheet data from file\n");
- exit(EXIT_FAILURE);
- }
- fclose(file);
-
- data[size] = 0;
- struct wl_list lines;
- struct node {
- char* line;
- struct wl_list link;
- };
- wl_list_init(&lines);
- if(nyan) {
- for(ssize_t count = nyan_shift; count < 100 + nyan_shift; ++count) {
- size_t i = count % nyan_color_l;
- struct node* entry = malloc(sizeof(struct node));
- entry->line = strdup(nyan_colors[i]);
- wl_list_insert(&lines, &entry->link);
- }
- nyan_shift = (nyan_shift + 1) % nyan_color_l;
- } else {
- if(access(color_path, R_OK) == 0) {
- file = fopen(color_path, "r");
- char* line = NULL;
- size_t line_size = 0;
- ssize_t line_l = 0;
- while((line_l = getline(&line, &line_size, file)) != -1) {
- struct node* entry = malloc(sizeof(struct node));
- line[line_l - 1] = 0;
- entry->line = malloc(line_l + 1);
- strcpy(entry->line, line);
- wl_list_insert(&lines, &entry->link);
- }
- fclose(file);
- free(line);
- }
- }
-
- ssize_t count = wl_list_length(&lines) - 1;
- if(count > 99) {
- fprintf(stderr, "Woah there that's a lot of colors. Try having no more than 100, thanks\n");
- exit(1);
- }
- struct node* node;
- wl_list_for_each(node, &lines, link) {
- //Do --wofi-color replace
- const char* color = node->line;
- const char* wofi_color = "--wofi-color";
- char count_str[3];
- snprintf(count_str, 3, "%zu", count--);
- char* needle = utils_concat(2, wofi_color, count_str);
- size_t color_len = strlen(color);
- size_t needle_len = strlen(needle);
- if(color_len > needle_len) {
- free(needle);
- fprintf(stderr, "What color format is this, try #FFFFFF, kthxbi\n");
- continue;
- }
- char* replace = strstr(data, needle);
- while(replace != NULL) {
- memcpy(replace, color, color_len);
- memset(replace + color_len, ' ', needle_len - color_len);
- replace = strstr(data, needle);
- }
- free(needle);
-
-
- //Do --wofi-rgb-color replace
- if(color_len < 7) {
- fprintf(stderr, "What color format is this, try #FFFFFF, kthxbi\n");
- continue;
- }
- const char* wofi_rgb_color = "--wofi-rgb-color";
- needle = utils_concat(2, wofi_rgb_color, count_str);
- needle_len = strlen(needle);
- replace = strstr(data, needle);
- while(replace != NULL) {
- char r[3];
- char g[3];
- char b[3];
- memcpy(r, color + 1, 2);
- memcpy(g, color + 3, 2);
- memcpy(b, color + 5, 2);
- r[2] = 0;
- g[2] = 0;
- b[2] = 0;
- char rgb[14];
- snprintf(rgb, 14, "%ld, %ld, %ld", strtol(r, NULL, 16), strtol(g, NULL, 16), strtol(b, NULL, 16));
- size_t rgb_len = strlen(rgb);
- memcpy(replace, rgb, rgb_len);
- memset(replace + rgb_len, ' ', needle_len - rgb_len);
- replace = strstr(data, needle);
- }
- free(needle);
- }
- GtkCssProvider* css = gtk_css_provider_new();
- gtk_css_provider_load_from_data(css, data, strlen(data), NULL);
- free(data);
- struct node* tmp;
- wl_list_for_each_safe(node, tmp, &lines, link) {
- free(node->line);
- wl_list_remove(&node->link);
- free(node);
- }
- gtk_style_context_add_provider_for_screen(gdk_screen_get_default(), GTK_STYLE_PROVIDER(css), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
- }
-}
-
-static void sig(int32_t signum) {
- switch(signum) {
- case SIGTERM:
- exit(1);
- break;
- }
-}
-
-int main(int argc, char** argv) {
-
- const struct option opts[] = {
- {
- .name = "help",
- .has_arg = no_argument,
- .flag = NULL,
- .val = 'h'
- },
- {
- .name = "fork",
- .has_arg = no_argument,
- .flag = NULL,
- .val = 'f'
- },
- {
- .name = "conf",
- .has_arg = required_argument,
- .flag = NULL,
- .val = 'c'
- },
- {
- .name = "style",
- .has_arg = required_argument,
- .flag = NULL,
- .val = 's'
- },
- {
- .name = "color",
- .has_arg = required_argument,
- .flag = NULL,
- .val = 'C'
- },
- {
- .name = "dmenu",
- .has_arg = no_argument,
- .flag = NULL,
- .val = 'd'
- },
- {
- .name = "show",
- .has_arg = required_argument,
- .flag = NULL,
- .val = 'S'
- },
- {
- .name = "width",
- .has_arg = required_argument,
- .flag = NULL,
- .val = 'W'
- },
- {
- .name = "height",
- .has_arg = required_argument,
- .flag = NULL,
- .val = 'H'
- },
- {
- .name = "prompt",
- .has_arg = required_argument,
- .flag = NULL,
- .val = 'p'
- },
- {
- .name = "xoffset",
- .has_arg = required_argument,
- .flag = NULL,
- .val = 'x'
- },
- {
- .name = "yoffset",
- .has_arg = required_argument,
- .flag = NULL,
- .val = 'y'
- },
- {
- .name = "normal-window",
- .has_arg = no_argument,
- .flag = NULL,
- .val = 'n'
- },
- {
- .name = "allow-images",
- .has_arg = no_argument,
- .flag = NULL,
- .val = 'I'
- },
- {
- .name = "allow-markup",
- .has_arg = no_argument,
- .flag = NULL,
- .val = 'm'
- },
- {
- .name = "cache-file",
- .has_arg = required_argument,
- .flag = NULL,
- .val = 'k'
- },
- {
- .name = "term",
- .has_arg = required_argument,
- .flag = NULL,
- .val = 't'
- },
- {
- .name = "password",
- .has_arg = optional_argument,
- .flag = NULL,
- .val = 'P'
- },
- {
- .name = "exec-search",
- .has_arg = no_argument,
- .flag = NULL,
- .val = 'e'
- },
- {
- .name = "hide-scroll",
- .has_arg = no_argument,
- .flag = NULL,
- .val = 'b'
- },
- {
- .name = "matching",
- .has_arg = required_argument,
- .flag = NULL,
- .val = 'M'
- },
- {
- .name = "insensitive",
- .has_arg = no_argument,
- .flag = NULL,
- .val = 'i'
- },
- {
- .name = "parse-search",
- .has_arg = no_argument,
- .flag = NULL,
- .val = 'q'
- },
- {
- .name = "version",
- .has_arg = no_argument,
- .flag = NULL,
- .val = 'v'
- },
- {
- .name = "location",
- .has_arg = required_argument,
- .flag = NULL,
- .val = 'l'
- },
- {
- .name = "no-actions",
- .has_arg = no_argument,
- .flag = NULL,
- .val = 'a'
- },
- {
- .name = "define",
- .has_arg = required_argument,
- .flag = NULL,
- .val = 'D'
- },
- {
- .name = "lines",
- .has_arg = required_argument,
- .flag = NULL,
- .val = 'L'
- },
- {
- .name = "columns",
- .has_arg = required_argument,
- .flag = NULL,
- .val = 'w'
- },
- {
- .name = "sort-order",
- .has_arg = required_argument,
- .flag = NULL,
- .val = 'O'
- },
- {
- .name = "gtk-dark",
- .has_arg = no_argument,
- .flag = NULL,
- .val = 'G'
- },
- {
- .name = "search",
- .has_arg = required_argument,
- .flag = NULL,
- .val = 'Q'
- },
- {
- .name = "monitor",
- .has_arg = required_argument,
- .flag = NULL,
- .val = 'o'
- },
- {
- .name = "pre-display-cmd",
- .has_arg = required_argument,
- .flag = NULL,
- .val = 'r'
- },
- {
- .name = NULL,
- .has_arg = 0,
- .flag = NULL,
- .val = 0
- }
- };
-
- const char* config_str = NULL;
- char* style_str = NULL;
- char* color_str = NULL;
- char* mode = NULL;
- char* prompt = NULL;
- char* width = NULL;
- char* height = NULL;
- char* x = NULL;
- char* y = NULL;
- char* normal_window = NULL;
- char* allow_images = NULL;
- char* allow_markup = NULL;
- char* cache_file = NULL;
- char* terminal = NULL;
- char* password_char = "false";
- char* exec_search = NULL;
- char* hide_scroll = NULL;
- char* matching = NULL;
- char* insensitive = NULL;
- char* parse_search = NULL;
- char* location = NULL;
- char* no_actions = NULL;
- char* lines = NULL;
- char* columns = NULL;
- char* sort_order = NULL;
- char* gtk_dark = NULL;
- char* search = NULL;
- char* monitor = NULL;
- char* pre_display_cmd = NULL;
-
- struct wl_list options;
- wl_list_init(&options);
- struct option_node* node;
-
- int opt;
- while((opt = getopt_long(argc, argv, "hfc:s:C:dS:W:H:p:x:y:nImk:t:P::ebM:iqvl:aD:L:w:O:GQ:o:r:", opts, NULL)) != -1) {
- switch(opt) {
- case 'h':
- print_usage(argv);
- break;
- case 'f':
- if(fork() > 0) {
- exit(0);
- }
- fclose(stdout);
- fclose(stderr);
- fclose(stdin);
- break;
- case 'c':
- config_str = optarg;
- break;
- case 's':
- style_str = optarg;
- break;
- case 'C':
- color_str = optarg;
- break;
- case 'd':
- mode = "dmenu";
- break;
- case 'S':
- mode = optarg;
- break;
- case 'W':
- width = optarg;
- break;
- case 'H':
- height = optarg;
- break;
- case 'p':
- prompt = optarg;
- break;
- case 'x':
- x = optarg;
- break;
- case 'y':
- y = optarg;
- break;
- case 'n':
- normal_window = "true";
- break;
- case 'I':
- allow_images = "true";
- break;
- case 'm':
- allow_markup = "true";
- break;
- case 'k':
- cache_file = optarg;
- break;
- case 't':
- terminal = optarg;
- break;
- case 'P':
- password_char = optarg;
- break;
- case 'e':
- exec_search = "true";
- break;
- case 'b':
- hide_scroll = "true";
- break;
- case 'M':
- matching = optarg;
- break;
- case 'i':
- insensitive = "true";
- break;
- case 'q':
- parse_search = "true";
- break;
- case 'v':
- printf(VERSION"\n");
- exit(0);
- break;
- case 'l':
- location = optarg;
- break;
- case 'a':
- no_actions = "true";
- break;
- case 'D':
- node = malloc(sizeof(struct option_node));
- node->option = optarg;
- wl_list_insert(&options, &node->link);
- break;
- case 'L':
- lines = optarg;
- break;
- case 'w':
- columns = optarg;
- break;
- case 'O':
- sort_order = optarg;
- break;
- case 'G':
- gtk_dark = "true";
- break;
- case 'Q':
- search = optarg;
- break;
- case 'o':
- monitor = optarg;
- break;
- case 'r':
- pre_display_cmd = optarg;
- break;
- }
- }
-
- const char* home_dir = getenv("HOME");
- const char* xdg_conf = getenv("XDG_CONFIG_HOME");
- if(xdg_conf == NULL) {
- CONFIG_LOCATION = utils_concat(2, home_dir, "/.config/wofi");
- } else {
- CONFIG_LOCATION = utils_concat(2, xdg_conf, "/wofi");
- }
-
- const char* xdg_cache = getenv("XDG_CACHE_HOME");
- if(xdg_cache == NULL) {
- COLORS_LOCATION = utils_concat(2, home_dir, "/.cache/wal/colors");
- } else {
- COLORS_LOCATION = utils_concat(2, xdg_cache, "/wal/colors");
- }
-
- config = map_init();
-
- //Check if --conf was specified
- if(config_str == NULL) {
- const char* config_f = "/config";
- config_path = utils_concat(2, CONFIG_LOCATION, config_f);
- } else {
- config_path = strdup(config_str);
- }
- if(access(config_path, R_OK) == 0) {
- config_load(config, config_path);
- }
- free(config_path);
-
- if(style_str == NULL) {
- style_str = map_get(config, "style");
- }
-
- //Check if --style was specified
- if(style_str == NULL) {
- style_str = map_get(config, "stylesheet");
- if(style_str == NULL) {
- const char* style_f = "/style.css";
- stylesheet = utils_concat(2, CONFIG_LOCATION, style_f);
- } else {
- if(style_str[0] == '/') {
- stylesheet = strdup(style_str);
- } else {
- stylesheet = utils_concat(3, CONFIG_LOCATION, "/", style_str);
- }
- }
- } else {
- stylesheet = strdup(style_str);
- }
-
- if(color_str == NULL) {
- color_str = map_get(config, "color");
- }
-
- //Check if --color was specified
- if(color_str == NULL) {
- color_str = map_get(config, "colors");
- if(color_str == NULL) {
- color_path = strdup(COLORS_LOCATION);
- } else {
- if(color_str[0] == '/') {
- color_path = strdup(color_str);
- } else {
- color_path = utils_concat(3, CONFIG_LOCATION, "/", color_str);
- }
- }
- } else {
- color_path = strdup(color_str);
- }
-
- //Check if --gtk-dark was specified
- if(gtk_dark == NULL) {
- gtk_dark = map_get(config, "gtk_dark");
- }
-
- free(COLORS_LOCATION);
-
- struct option_node* tmp;
- wl_list_for_each_safe(node, tmp, &options, link) {
- config_put(config, node->option);
- wl_list_remove(&node->link);
- free(node);
- }
-
- if(map_get(config, "show") != NULL) {
- map_put(config, "mode", map_get(config, "show"));
- }
-
- if(strcmp(get_exec_name(argv[0]), "dmenu") == 0) {
- map_put(config, "mode", "dmenu");
- cache_file = "/dev/null";
- } else if(strcmp(get_exec_name(argv[0]), "wofi-askpass") == 0) {
- map_put(config, "mode", "dmenu");
- cache_file = "/dev/null";
- password_char = "*";
- prompt = "Password";
- } else if(mode != NULL) {
- map_put(config, "mode", mode);
- } else if(map_get(config, "mode") == NULL) {
- fprintf(stderr, "I need a mode, please give me a mode, that's what --show is for\n");
- exit(1);
- }
-
- map_put(config, "config_dir", CONFIG_LOCATION);
-
- if(width != NULL) {
- map_put(config, "width", width);
- }
- if(height != NULL) {
- map_put(config, "height", height);
- }
- if(prompt != NULL) {
- map_put(config, "prompt", prompt);
- }
- if(map_get(config, "xoffset") != NULL) {
- map_put(config, "x", map_get(config, "xoffset"));
- }
- if(x != NULL) {
- map_put(config, "x", x);
- }
- if(map_get(config, "yoffset") != NULL) {
- map_put(config, "y", map_get(config, "yoffset"));
- }
- if(y != NULL) {
- map_put(config, "y", y);
- }
- if(normal_window != NULL) {
- map_put(config, "normal_window", normal_window);
- }
- if(allow_images != NULL) {
- map_put(config, "allow_images", allow_images);
- }
- if(allow_markup != NULL) {
- map_put(config, "allow_markup", allow_markup);
- }
- if(cache_file != NULL) {
- map_put(config, "cache_file", cache_file);
- }
- if(terminal != NULL) {
- map_put(config, "term", terminal);
- }
- if(map_get(config, "password") != NULL) {
- map_put(config, "password_char", map_get(config, "password"));
- }
- if(password_char == NULL || (password_char != NULL && strcmp(password_char, "false") != 0)) {
- if(password_char == NULL) {
- password_char = "*";
- }
- map_put(config, "password_char", password_char);
- }
- if(exec_search != NULL) {
- map_put(config, "exec_search", exec_search);
- }
- if(hide_scroll != NULL) {
- map_put(config, "hide_scroll", hide_scroll);
- }
- if(matching != NULL) {
- map_put(config, "matching", matching);
- }
- if(insensitive != NULL) {
- map_put(config, "insensitive", insensitive);
- }
- if(parse_search != NULL) {
- map_put(config, "parse_search", parse_search);
- }
- if(location != NULL) {
- map_put(config, "location", location);
- }
- if(no_actions != NULL) {
- map_put(config, "no_actions", no_actions);
- }
- if(lines != NULL) {
- map_put(config, "lines", lines);
- }
- if(columns != NULL) {
- map_put(config, "columns", columns);
- }
- if(sort_order != NULL) {
- map_put(config, "sort_order", sort_order);
- }
- if(search != NULL) {
- map_put(config, "search", search);
- }
- if(monitor != NULL) {
- map_put(config, "monitor", monitor);
- }
- if(pre_display_cmd != NULL) {
- map_put(config, "pre_display_cmd", pre_display_cmd);
- }
-
- struct sigaction sigact = {0};
- sigact.sa_handler = sig;
- sigaction(SIGTERM, &sigact, NULL);
-
-
- gtk_init(&argc, &argv);
-
- if(gtk_dark != NULL && strcmp(gtk_dark, "true") == 0) {
- g_object_set(gtk_settings_get_default(),
- "gtk-application-prefer-dark-theme", TRUE, NULL);
- }
- wofi_load_css(false);
-
- wofi_init(config);
- gtk_main();
- return 0;
-}
diff --git a/wofi/src/map.c b/wofi/src/map.c
deleted file mode 100644
index 8bf3db4..0000000
--- a/wofi/src/map.c
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright (C) 2019-2020 Scoopta
- * This file is part of Wofi
- * Wofi 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.
-
- Wofi 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 Wofi. If not, see .
- */
-
-#include
-
-#include
-#include
-#include
-
-#include
-
-struct map {
- GTree* tree;
- bool mman;
-};
-
-static gint compare(gconstpointer p1, gconstpointer p2, gpointer data) {
- (void) data;
- const char* str1 = p1;
- const char* str2 = p2;
- return strcmp(str1, str2);
-}
-
-struct map* map_init(void) {
- struct map* map = malloc(sizeof(struct map));
- map->tree = g_tree_new_full(compare, NULL, free, free);
- map->mman = true;
- return map;
-}
-
-struct map* map_init_void(void) {
- struct map* map = malloc(sizeof(struct map));
- map->tree = g_tree_new_full(compare, NULL, free, NULL);
- map->mman = false;
- return map;
-}
-
-void map_free(struct map* map) {
- g_tree_destroy(map->tree);
- free(map);
-}
-
-static void put(struct map* map, const char* key, void* value) {
- char* k = strdup(key);
- char* v = value;
- if(map->mman && value != NULL) {
- v = strdup(value);
- }
- g_tree_insert(map->tree, k, v);
-}
-
-bool map_put(struct map* map, const char* key, char* value) {
- if(map->mman) {
- put(map, key, value);
- return true;
- } else {
- fprintf(stderr, "This is an unmanaged map please use map_put_void\n");
- return false;
- }
-}
-
-bool map_put_void(struct map* map, const char* key, void* value) {
- if(map->mman) {
- fprintf(stderr, "This is an managed map please use map_put\n");
- return false;
- } else {
- put(map, key, value);
- return true;
- }
-}
-
-void* map_get(struct map* map, const char* key) {
- return g_tree_lookup(map->tree, key);
-}
-
-bool map_contains(struct map* map, const char* key) {
- return map_get(map, key) != NULL;
-}
-
-size_t map_size(struct map* map) {
- return g_tree_nnodes(map->tree);
-}
diff --git a/wofi/src/match.c b/wofi/src/match.c
deleted file mode 100644
index 29936ce..0000000
--- a/wofi/src/match.c
+++ /dev/null
@@ -1,412 +0,0 @@
-/*
- * Copyright (C) 2019-2022 Scoopta
- * This file is part of Wofi
- * Wofi 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.
-
- Wofi 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 Wofi. If not, see .
- */
-
-#include
-#include
-#include
-
-// leading gap
-#define SCORE_GAP_LEADING -0.005
-// trailing gap
-#define SCORE_GAP_TRAILING -0.005
-// gap in the middle
-#define SCORE_GAP_INNER -0.01
-// we matched the characters consecutively
-#define SCORE_MATCH_CONSECUTIVE 1.0
-// we got a consecutive match, but insensitive is on
-// and we didn't match the case.
-#define SCORE_MATCH_NOT_MATCH_CASE 0.9
-// we are matching after a slash
-#define SCORE_MATCH_SLASH 0.9
-// we are matching after a space dash or hyphen
-#define SCORE_MATCH_WORD 0.8
-// we are matching a camel case letter
-#define SCORE_MATCH_CAPITAL 0.7
-// we are matching after a dot
-#define SCORE_MATCH_DOT 0.6
-
-#define SWAP(x, y, T) \
- do { \
- T SWAP = x; \
- x = y; \
- y = SWAP; \
- } while(0)
-
-#define max(a, b) (((a) > (b)) ? (a) : (b))
-
-// matching
-static bool contains_match(const char* filter, const char* text, bool insensitive) {
- if(filter == NULL || strcmp(filter, "") == 0) {
- return true;
- }
- if(text == NULL) {
- return false;
- }
- if(insensitive) {
- return strcasestr(text, filter) != NULL;
- } else {
- return strstr(text, filter) != NULL;
- }
-}
-
-static char* strcasechr(const char* s,char c, bool insensitive) {
- if(insensitive) {
- const char accept[3] = {tolower(c), toupper(c), 0};
- return strpbrk(s, accept);
- } else {
- return strchr(s, c);
- }
-}
-
-static bool fuzzy_match(const char* filter, const char* text, bool insensitive) {
- if(filter == NULL || strcmp(filter, "") == 0) {
- return true;
- }
- if(text == NULL) {
- return false;
- }
- // we just check that all the characters (ignoring case) are in the
- // search text possibly case insensitively in the correct order
- while(*filter != 0) {
- char nch = *filter++;
-
- if(!(text = strcasechr(text, nch, insensitive))) {
- return false;
- }
- text++;
- }
- return true;
-}
-
-static bool multi_contains_match(const char* filter, const char* text, bool insensitive) {
- if(filter == NULL || strcmp(filter, "") == 0) {
- return true;
- }
- if(text == NULL) {
- return false;
- }
- char new_filter[MAX_MULTI_CONTAINS_FILTER_SIZE];
- strncpy(new_filter, filter, sizeof(new_filter));
- new_filter[sizeof(new_filter) - 1] = '\0';
- char* token;
- char* rest = new_filter;
- while((token = strtok_r(rest, " ", &rest))) {
- if(contains_match(token, text, insensitive) == false) {
- return false;
- }
- }
- return true;
-}
-
-bool match_for_matching_mode(const char* filter, const char* text,
- enum matching_mode matching, bool insensitive) {
- bool retval;
- switch(matching) {
- case MATCHING_MODE_MULTI_CONTAINS:
- retval = multi_contains_match(filter, text, insensitive);
- break;
- case MATCHING_MODE_CONTAINS:
- retval = contains_match(filter, text, insensitive);
- break;
- case MATCHING_MODE_FUZZY:
- retval = fuzzy_match(filter, text, insensitive);
- break;
- default:
- return false;
- }
- return retval;
-}
-
-// end matching
-
-// fuzzy matching
-static void precompute_bonus(const char* haystack, score_t* match_bonus) {
- /* Which positions are beginning of words */
- int m = strlen(haystack);
- char last_ch = '\0';
- for(int i = 0; i < m; i++) {
- char ch = haystack[i];
-
- score_t score = 0;
- if(isalnum(ch)) {
- if(!last_ch || last_ch == '/') {
- score = SCORE_MATCH_SLASH;
- } else if(last_ch == '-' || last_ch == '_' ||
- last_ch == ' ') {
- score = SCORE_MATCH_WORD;
- } else if(last_ch >= 'a' && last_ch <= 'z' &&
- ch >= 'A' && ch <= 'Z') {
- /* CamelCase */
- score = SCORE_MATCH_CAPITAL;
- } else if(last_ch == '.') {
- score = SCORE_MATCH_DOT;
- }
- }
-
- match_bonus[i] = score;
- last_ch = ch;
- }
-}
-
-static inline bool match_with_case(char a, char b, bool insensitive) {
- if(insensitive) {
- return tolower(a) == tolower(b);
- } else {
- return a == b;
- }
-}
-
-static inline void match_row(int row, score_t* curr_D, score_t* curr_M,
- const score_t* last_D, const score_t* last_M,
- const char* needle, const char* haystack, int n, int m, score_t* match_bonus, bool insensitive) {
- int i = row;
-
- score_t prev_score = SCORE_MIN;
- score_t gap_score = i == n - 1 ? SCORE_GAP_TRAILING : SCORE_GAP_INNER;
-
- for(int j = 0; j < m; j++) {
- if(match_with_case(needle[i], haystack[j], insensitive)) {
- score_t score = SCORE_MIN;
- if(!i) {
- // first line we fill in a row for non-matching
- score = (j * SCORE_GAP_LEADING) + match_bonus[j];
- } else if(j) { /* i > 0 && j > 0*/
- // we definitely match case insensitively already so if
- // our character isn't the same then we have a different case
- score_t consecutive_bonus = needle[i] == haystack[j] ? SCORE_MATCH_CONSECUTIVE : SCORE_MATCH_NOT_MATCH_CASE;
-
- score = max(last_M[j - 1] + match_bonus[j],
- /* consecutive match, doesn't stack
- with match_bonus */
- last_D[j - 1] + consecutive_bonus);
- }
- curr_D[j] = score;
- curr_M[j] = prev_score = max(score, prev_score + gap_score);
- } else {
- curr_D[j] = SCORE_MIN;
- curr_M[j] = prev_score = prev_score + gap_score;
- }
- }
-}
-
-// Fuzzy matching scoring. Adapted from
-// https://github.com/jhawthorn/fzy/blob/master/src/match.c and
-// https://github.com/jhawthorn/fzy/blob/master/ALGORITHM.md
-// For a fuzzy match string needle being searched for in haystack we provide a
-// number score for how well we match.
-// We create two matrices of size needle_len (n) by haystack_len (m).
-// The first matrix is the score matrix. Each position (i,j) within this matrix
-// consists of the score that corresponds to the score that would be generated
-// by matching the first i characters of the needle with the first j
-// characters of the haystack. Gaps have a fixed penalty for having a gap along
-// with a linear penalty for gap size (c.f. gotoh's algorithm).
-// matches give a positive score, with a slight weight given to matches after
-// certain special characters (i.e. the first character after a `/` will be
-// "almost" consecutive but lower than an actual consecutive match).
-// Our second matrix is our diagonal matrix where we store the best match
-// that ends at a match. This allows us to calculate our gap penalties alongside
-// our consecutive match scores.
-// In addition, since we only rely on the current, and previous row of the
-// matrices and we only want to compute the score, we only store those scores
-// and reuse the previous rows (rather than storing the entire (n*m) matrix).
-// In addition we've simplified some of the algorithm compared to fzy to
-// improve legibility. (Can reimplement lookup tables later if wanted.)
-// Also, the reference algorithm does not take into account case sensitivity
-// which has been implemented here.
-
-static score_t fuzzy_score(const char* haystack, const char* needle, bool insensitive) {
- if(*needle == 0)
- return SCORE_MIN;
-
- int n = strlen(needle);
- int m = strlen(haystack);
- score_t match_bonus[m];
- precompute_bonus(haystack, match_bonus);
-
- if(m > MATCH_FUZZY_MAX_LEN || n > m) {
- /*
- * Unreasonably large candidate: return no score
- * If it is a valid match it will still be returned, it will
- * just be ranked below any reasonably sized candidates
- */
- return SCORE_MIN;
- } else if(n == m) {
- /* Since this method can only be called with a haystack which
- * matches needle. If the lengths of the strings are equal the
- * strings themselves must also be equal (ignoring case).
- */
- return SCORE_MAX;
- }
-
- /*
- * D[][] Stores the best score for this position ending with a match.
- * M[][] Stores the best possible score at this position.
- */
- score_t D[2][MATCH_FUZZY_MAX_LEN], M[2][MATCH_FUZZY_MAX_LEN];
-
- score_t* last_D, *last_M;
- score_t* curr_D, *curr_M;
-
- last_D = D[0];
- last_M = M[0];
- curr_D = D[1];
- curr_M = M[1];
-
- for(int i = 0; i < n; i++) {
- match_row(i, curr_D, curr_M, last_D, last_M, needle, haystack, n, m, match_bonus, insensitive);
-
- SWAP(curr_D, last_D, score_t *);
- SWAP(curr_M, last_M, score_t *);
- }
-
- return last_M[m - 1];
-}
-// end fuzzy matching
-
-// sorting
-static int fuzzy_sort(const char* text1, const char* text2, const char* filter, bool insensitive) {
- bool match1 = fuzzy_match(filter, text1, insensitive);
- bool match2 = fuzzy_match(filter, text2, insensitive);
- // both filters match do fuzzy scoring
- if(match1 && match2) {
- score_t dist1 = fuzzy_score(text1, filter, insensitive);
- score_t dist2 = fuzzy_score(text2, filter, insensitive);
- if(dist1 == dist2) {
- // same same
- return 0;
- } else if(dist1 > dist2) { // highest score wins.
- // text1 goes first
- return -1;
- } else {
- // text2 goes first
- return 1;
- }
- } else if(match1) {
- // text1 goes first
- return -1;
- } else if(match2) {
- // text2 goes first
- return 1;
- } else {
- // same same.
- return 0;
- }
-}
-
-// we sort based on how early in the string all the matches are.
-// if there are matches for each.
-static int multi_contains_sort(const char* text1, const char* text2, const char* filter, bool insensitive) {
- // sum of string positions of each match
- int t1_count = 0;
- int t2_count = 0;
- // does this string match with mult-contains
- bool t1_match = true;
- bool t2_match = true;
-
- char new_filter[MAX_MULTI_CONTAINS_FILTER_SIZE];
- strncpy(new_filter, filter, sizeof(new_filter));
- new_filter[sizeof(new_filter) - 1] = '\0';
-
- char* token;
- char* rest = new_filter;
- while((token = strtok_r(rest, " ", &rest))) {
- char* str1, *str2;
- if(insensitive) {
- str1 = strcasestr(text1, token);
- str2 = strcasestr(text2, token);
- } else {
- str1 = strstr(text1, token);
- str2 = strstr(text2, token);
- }
- t1_match = t1_match && str1 != NULL;
- t2_match = t2_match && str2 != NULL;
- if(str1 != NULL) {
- int pos1 = str1 - text1;
- t1_count += pos1;
- }
- if(str2 != NULL) {
- int pos2 = str2 - text2;
- t2_count += pos2;
- }
- }
- if(t1_match && t2_match) {
- // both match
- // return the one with the smallest count.
- return t1_count - t2_count;
- } else if(t1_match) {
- return -1;
- } else if(t2_match) {
- return 1;
- } else {
- return 0;
- }
-}
-static int contains_sort(const char* text1, const char* text2, const char* filter, bool insensitive) {
- char* str1, *str2;
-
- if(insensitive) {
- str1 = strcasestr(text1, filter);
- str2 = strcasestr(text2, filter);
- } else {
- str1 = strstr(text1, filter);
- str2 = strstr(text2, filter);
- }
- bool tx1 = str1 == text1;
- bool tx2 = str2 == text2;
- bool txc1 = str1 != NULL;
- bool txc2 = str2 != NULL;
-
- if(tx1 && tx2) {
- return 0;
- } else if(tx1) {
- return -1;
- } else if(tx2) {
- return 1;
- } else if(txc1 && txc2) {
- return 0;
- } else if(txc1) {
- return -1;
- } else if(txc2) {
- return 1;
- } else {
- return 0;
- }
-}
-
-int sort_for_matching_mode(const char* text1, const char* text2, int fallback,
- enum matching_mode match_type, const char* filter, bool insensitive) {
- int primary = 0;
- switch(match_type) {
- case MATCHING_MODE_MULTI_CONTAINS:
- primary = multi_contains_sort(text1, text2, filter, insensitive);
- break;
- case MATCHING_MODE_CONTAINS:
- primary = contains_sort(text1, text2, filter, insensitive);
- break;
- case MATCHING_MODE_FUZZY:
- primary = fuzzy_sort(text1, text2, filter, insensitive);
- break;
- default:
- return 0;
- }
- if(primary == 0) {
- return fallback;
- }
- return primary;
-}
-// end sorting
-
diff --git a/wofi/src/property_box.c b/wofi/src/property_box.c
deleted file mode 100644
index a7fdd06..0000000
--- a/wofi/src/property_box.c
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2019-2020 Scoopta
- * This file is part of Wofi
- * Wofi 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.
-
- Wofi 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 Wofi. If not, see .
- */
-
-#include
-
-#include
-
-struct _WofiPropertyBox {
- GtkBox super;
-};
-
-typedef struct {
- struct map* properties;
-} WofiPropertyBoxPrivate;
-
-G_DEFINE_TYPE_WITH_PRIVATE(WofiPropertyBox, wofi_property_box, GTK_TYPE_BOX)
-
-static void wofi_property_box_init(WofiPropertyBox* box) {
- WofiPropertyBoxPrivate* this = wofi_property_box_get_instance_private(box);
- this->properties = map_init();
-}
-
-static void finalize(GObject* obj) {
- WofiPropertyBoxPrivate* this = wofi_property_box_get_instance_private(WOFI_PROPERTY_BOX(obj));
- map_free(this->properties);
- G_OBJECT_CLASS(wofi_property_box_parent_class)->finalize(obj);
-}
-
-static void wofi_property_box_class_init(WofiPropertyBoxClass* class) {
- GObjectClass* g_class = G_OBJECT_CLASS(class);
- g_class->finalize = finalize;
-}
-
-GtkWidget* wofi_property_box_new(GtkOrientation orientation, gint spacing) {
- return g_object_new(WOFI_TYPE_PROPERTY_BOX, "orientation", orientation, "spacing", spacing, NULL);
-}
-
-void wofi_property_box_add_property(WofiPropertyBox* box, const gchar* key, gchar* value) {
- WofiPropertyBoxPrivate* this = wofi_property_box_get_instance_private(box);
- map_put(this->properties, key, value);
-}
-
-const gchar* wofi_property_box_get_property(WofiPropertyBox* box, const gchar* key) {
- WofiPropertyBoxPrivate* this = wofi_property_box_get_instance_private(box);
- return map_get(this->properties, key);
-}
diff --git a/wofi/src/utils.c b/wofi/src/utils.c
deleted file mode 100644
index 116d460..0000000
--- a/wofi/src/utils.c
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Copyright (C) 2019-2020 Scoopta
- * This file is part of Wofi
- * Wofi 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.
-
- Wofi 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 Wofi. If not, see .
- */
-
-#include
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include
-#include
-
-time_t utils_get_time_millis(void) {
- struct timeval time;
- gettimeofday(&time, NULL);
- return (time.tv_sec * 1000) + (time.tv_usec / 1000);
-}
-
-void utils_sleep_millis(time_t millis) {
- struct timespec time;
- time.tv_sec = millis / 1000;
- time.tv_nsec = (millis % 1000) * pow(1000, 2);
- nanosleep(&time, NULL);
-}
-
-char* utils_concat(size_t arg_count, ...) {
- va_list args;
- va_start(args, arg_count);
- size_t buf_s = 1;
- for(size_t count = 0; count < arg_count; ++count) {
- buf_s += strlen(va_arg(args, char*));
- }
- va_end(args);
- va_start(args, arg_count);
- char* buffer = malloc(buf_s);
- strcpy(buffer, va_arg(args, char*));
- for(size_t count = 0; count < arg_count - 1; ++count) {
- strcat(buffer, va_arg(args, char*));
- }
- va_end(args);
- return buffer;
-}
-
-size_t utils_min(size_t n1, size_t n2) {
- return n1 < n2 ? n1 : n2;
-}
-
-size_t utils_max(size_t n1, size_t n2) {
- return n1 > n2 ? n1 : n2;
-}
-
-size_t utils_min3(size_t n1, size_t n2, size_t n3) {
- if(n1 < n2 && n1 < n3) {
- return n1;
- } else if(n2 < n1 && n2 < n3) {
- return n2;
- } else {
- return n3;
- }
-}
-
-size_t utils_distance(const char* haystack, const char* needle) {
- size_t str1_len = strlen(haystack);
- size_t str2_len = strlen(needle);
-
- size_t arr[str1_len + 1][str2_len + 1];
- arr[0][0] = 0;
- for(size_t count = 1; count <= str1_len; ++count) {
- arr[count][0] = count;
- }
- for(size_t count = 1; count <= str2_len; ++count) {
- arr[0][count] = count;
- }
-
- uint8_t cost;
- for(size_t c1 = 1; c1 <= str1_len; ++c1) {
- for(size_t c2 = 1; c2 <= str2_len; ++c2) {
- if(haystack[c1 - 1] == needle[c2 - 1]) {
- cost = 0;
- } else {
- cost = 1;
- }
- arr[c1][c2] = utils_min3(arr[c1 - 1][c2] + 1, arr[c1][c2 - 1] + 1, arr[c1 - 1][c2 - 1] + cost);
- }
- }
-
- if(strstr(haystack, needle) != NULL) {
- arr[str1_len][str2_len] -= str2_len;
- }
-
- return arr[str1_len][str2_len];
-}
-
-void utils_mkdir(char* path, mode_t mode) {
- if(access(path, F_OK) != 0) {
- char* tmp = strdup(path);
- utils_mkdir(dirname(tmp), mode);
- mkdir(path, mode);
- free(tmp);
- }
-}
diff --git a/wofi/src/utils_g.c b/wofi/src/utils_g.c
deleted file mode 100644
index 7f5d065..0000000
--- a/wofi/src/utils_g.c
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2020 Scoopta
- * This file is part of Wofi
- * Wofi 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.
-
- Wofi 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 Wofi. If not, see .
- */
-
-#include
-
-#include
-
-GdkPixbuf* utils_g_resize_pixbuf(GdkPixbuf* pixbuf, uint64_t image_size, GdkInterpType interp) {
- int width = gdk_pixbuf_get_width(pixbuf);
- int height = gdk_pixbuf_get_height(pixbuf);
-
- if(height > width) {
- float percent = (float) image_size / height;
- GdkPixbuf* tmp = gdk_pixbuf_scale_simple(pixbuf, width * percent, image_size, interp);
- g_object_unref(pixbuf);
- return tmp;
- } else {
- float percent = (float) image_size / width;
- GdkPixbuf* tmp = gdk_pixbuf_scale_simple(pixbuf, image_size, height * percent, interp);
- g_object_unref(pixbuf);
- return tmp;
- }
-}
-
-GdkPixbuf* utils_g_pixbuf_from_base64(char* base64) {
- char* str = strdup(base64);
- char* original_str = str;
-
- if(strncmp(str, "data:", sizeof("data:") - 1) == 0) {
- str += sizeof("data:") - 1;
- }
-
- GError* err = NULL;
- GdkPixbufLoader* loader;
- if(strncmp(str, "image/", sizeof("image/") - 1) == 0) {
- char* mime = strchr(str, ';');
- *mime = 0;
- loader = gdk_pixbuf_loader_new_with_mime_type(str, &err);
- if(err != NULL) {
- goto fail;
- }
- str = mime + 1;
- str = strchr(str, ',') + 1;
- } else {
- loader = gdk_pixbuf_loader_new();
- }
-
- gsize data_l;
- guchar* data = g_base64_decode(str, &data_l);
-
- gdk_pixbuf_loader_write(loader, data, data_l, &err);
- if(err != NULL) {
- g_free(data);
- goto fail;
- }
-
- g_free(data);
-
- free(original_str);
- return gdk_pixbuf_loader_get_pixbuf(loader);
-
- fail:
- free(str);
- fprintf(stderr, "Error loading base64 %s\n", err->message);
- return NULL;
-}
diff --git a/wofi/src/widget_builder.c b/wofi/src/widget_builder.c
deleted file mode 100644
index 31fbc85..0000000
--- a/wofi/src/widget_builder.c
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * Copyright (C) 2020-2022 Scoopta
- * This file is part of Wofi
- * Wofi 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.
-
- Wofi 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 Wofi. If not, see .
- */
-
-#include
-
-#include
-#include
-
-struct widget_builder* wofi_widget_builder_init(struct mode* mode, size_t actions) {
- struct widget_builder* builder = calloc(actions, sizeof(struct widget_builder));
-
- for(size_t count = 0; count < actions; ++count) {
- builder[count].mode = mode;
- builder[count].box = WOFI_PROPERTY_BOX(wofi_property_box_new(GTK_ORIENTATION_HORIZONTAL, 0));
-
- if(count == 0) {
- builder->actions = actions;
- }
- }
- return builder;
-}
-
-void wofi_widget_builder_set_search_text(struct widget_builder* builder, char* search_text) {
- wofi_property_box_add_property(builder->box, "filter", search_text);
-}
-
-void wofi_widget_builder_set_action(struct widget_builder* builder, char* action) {
- wofi_property_box_add_property(builder->box, "action", action);
-}
-
-static void va_to_list(struct wl_list* classes, va_list args) {
- char* arg;
- while((arg = va_arg(args, char*)) != NULL) {
- struct css_class* class = malloc(sizeof(struct css_class));
- class->class = arg;
- wl_list_insert(classes, &class->link);
- }
-}
-
-void wofi_widget_builder_insert_text(struct widget_builder* builder, const char* text, ...) {
- struct wl_list classes;
- wl_list_init(&classes);
-
- va_list args;
- va_start(args, text);
- va_to_list(&classes, args);
- va_end(args);
-
- wofi_widget_builder_insert_text_with_list(builder, text, &classes);
-
- struct css_class* node, *tmp;
- wl_list_for_each_safe(node, tmp, &classes, link) {
- free(node);
- }
-}
-
-void wofi_widget_builder_insert_text_with_list(struct widget_builder* builder, const char* text, struct wl_list* classes) {
- GtkWidget* label = gtk_label_new(text);
- gtk_container_add(GTK_CONTAINER(builder->box), label);
- gtk_widget_set_name(label, "text");
-
- GtkStyleContext* ctx = gtk_widget_get_style_context(label);
-
- struct css_class* node;
- wl_list_for_each(node, classes, link) {
- char* tmp = utils_concat(3, builder->mode->name, "-", node->class);
- gtk_style_context_add_class(ctx, tmp);
- free(tmp);
- }
-}
-
-void wofi_widget_builder_insert_image(struct widget_builder* builder, GdkPixbuf* pixbuf, ...) {
- struct wl_list classes;
- wl_list_init(&classes);
-
- va_list args;
- va_start(args, pixbuf);
- va_to_list(&classes, args);
- va_end(args);
-
- wofi_widget_builder_insert_image_with_list(builder, pixbuf, &classes);
-
- struct css_class* node, *tmp;
- wl_list_for_each_safe(node, tmp, &classes, link) {
- free(node);
- }
-}
-
-void wofi_widget_builder_insert_image_with_list(struct widget_builder* builder, GdkPixbuf* pixbuf, struct wl_list* classes) {
- GtkWidget* img = gtk_image_new();
- cairo_surface_t* surface = gdk_cairo_surface_create_from_pixbuf(pixbuf, wofi_get_window_scale(), gtk_widget_get_window(img));
- gtk_image_set_from_surface(GTK_IMAGE(img), surface);
- cairo_surface_destroy(surface);
- gtk_container_add(GTK_CONTAINER(builder->box), img);
- gtk_widget_set_name(img, "img");
-
- GtkStyleContext* ctx = gtk_widget_get_style_context(img);
-
- struct css_class* node;
- wl_list_for_each(node, classes, link) {
- char* tmp = utils_concat(3, builder->mode->name, "-", node->class);
- gtk_style_context_add_class(ctx, tmp);
- free(tmp);
- }
-}
-
-struct widget_builder* wofi_widget_builder_get_idx(struct widget_builder* builder, size_t idx) {
- return builder + idx;
-}
-
-struct widget* wofi_widget_builder_get_widget(struct widget_builder* builder) {
- if(builder->actions == 0) {
- fprintf(stderr, "%s: This is not the 0 index of the widget_builder array\n", builder->mode->name);
- return NULL;
- }
-
- if(builder->widget == NULL) {
- builder->widget = malloc(sizeof(struct widget));
- builder->widget->builder = builder;
- builder->widget->action_count = builder->actions;
- }
-
- for(size_t count = 0; count < builder->actions; ++count) {
- }
-
- return builder->widget;
-}
-
-void wofi_widget_builder_free(struct widget_builder* builder) {
- if(builder->widget != NULL) {
- free(builder->widget);
- }
- free(builder);
-}
diff --git a/wofi/src/wofi.c b/wofi/src/wofi.c
deleted file mode 100644
index ada9dc5..0000000
--- a/wofi/src/wofi.c
+++ /dev/null
@@ -1,2093 +0,0 @@
-/*
- * Copyright (C) 2019-2024 Scoopta
- * This file is part of Wofi
- * Wofi 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.
-
- Wofi 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 Wofi. If not, see .
- */
-
-#include
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include
-#include
-
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include
-#include
-
-#include
-#include
-
-#define PROTO_VERSION(v1, v2) (v1 < v2 ? v1 : v2)
-#define _UNUSED(x) (void)(x)
-#define CUSTOM_KEY_NUMBER 20
-
-static const char* terminals[] = {"kitty", "alacritty", "wezterm", "foot", "termite", "gnome-terminal", "weston-terminal"};
-
-enum location {
- LOCATION_CENTER,
- LOCATION_TOP_LEFT,
- LOCATION_TOP,
- LOCATION_TOP_RIGHT,
- LOCATION_RIGHT,
- LOCATION_BOTTOM_RIGHT,
- LOCATION_BOTTOM,
- LOCATION_BOTTOM_LEFT,
- LOCATION_LEFT
-};
-
-enum sort_order {
- SORT_ORDER_DEFAULT,
- SORT_ORDER_ALPHABETICAL
-};
-
-static uint64_t width, height;
-static char* x, *y;
-static struct zwlr_layer_shell_v1* shell = NULL;
-static GtkWidget* window, *outer_box, *scroll, *entry, *inner_box, *previous_selection = NULL;
-static gchar* filter = NULL;
-static char* mode = NULL;
-static bool allow_images, allow_markup;
-static uint64_t image_size;
-static char* cache_file = NULL;
-static char* config_dir;
-static bool mod_shift;
-static bool mod_ctrl;
-static char* terminal;
-static GtkOrientation outer_orientation;
-static bool exec_search;
-static struct map* modes;
-static enum matching_mode matching;
-static bool insensitive;
-static bool parse_search;
-static GtkAlign content_halign;
-static struct map* config;
-static enum location location;
-static bool no_actions;
-static uint64_t columns;
-static bool user_moved = false;
-static uint32_t widget_count = 0;
-static enum sort_order sort_order;
-static int64_t max_height = 0;
-static uint32_t lines, max_lines;
-static int8_t line_wrap;
-static int64_t ix, iy;
-static uint8_t konami_cycle;
-static bool is_konami = false;
-static GDBusProxy* dbus = NULL;
-static GdkRectangle resolution = {0};
-static bool resize_expander = false;
-static uint32_t line_count = 0;
-static bool dynamic_lines;
-static struct wl_list mode_list;
-static pthread_t mode_thread;
-static bool has_joined_mode = false;
-static char* copy_exec = NULL;
-static char* pre_display_cmd = NULL;
-static bool pre_display_exec = false;
-static bool single_click = false;
-static bool hide_search = false;
-static GdkModifierType shift_mask = GDK_SHIFT_MASK;
-static GdkModifierType ctrl_mask = GDK_CONTROL_MASK;
-static GdkModifierType alt_mask = GDK_MOD1_MASK;
-
-static struct map* keys;
-static struct map* mods;
-
-static struct wl_display* wl = NULL;
-static struct wl_surface* wl_surface;
-static struct wl_list outputs;
-static struct zxdg_output_manager_v1* output_manager;
-static struct zwlr_layer_surface_v1* wlr_surface;
-
-struct output_node {
- char* name;
- struct wl_output* output;
- int32_t width, height, x, y;
- struct wl_list link;
-};
-
-struct key_entry {
- char* mod;
- void (*action)(void);
-};
-
-static int custom_key_return_code = EXIT_SUCCESS;
-
-static void nop() {}
-
-static void add_interface(void* data, struct wl_registry* registry, uint32_t name, const char* interface, uint32_t version) {
- (void) data;
- if(strcmp(interface, zwlr_layer_shell_v1_interface.name) == 0) {
- shell = wl_registry_bind(registry, name, &zwlr_layer_shell_v1_interface, PROTO_VERSION(version, 4));
- } else if(strcmp(interface, wl_output_interface.name) == 0) {
- struct output_node* node = malloc(sizeof(struct output_node));
- node->output = wl_registry_bind(registry, name, &wl_output_interface, PROTO_VERSION(version, 4));
- wl_list_insert(&outputs, &node->link);
- } else if(strcmp(interface, zxdg_output_manager_v1_interface.name) == 0) {
- output_manager = wl_registry_bind(registry, name, &zxdg_output_manager_v1_interface, PROTO_VERSION(version, 3));
- }
-}
-
-static void config_surface(void* data, struct zwlr_layer_surface_v1* surface, uint32_t serial, uint32_t width, uint32_t height) {
- (void) data;
- (void) width;
- (void) height;
- zwlr_layer_surface_v1_ack_configure(surface, serial);
-}
-
-static void setup_surface(struct zwlr_layer_surface_v1* surface) {
- zwlr_layer_surface_v1_set_size(surface, width, height);
- zwlr_layer_surface_v1_set_keyboard_interactivity(surface, true);
-
- if(location > 8) {
- location -= 9;
- }
-
- if(x != NULL || y != NULL) {
- if(location == LOCATION_CENTER) {
- location = LOCATION_TOP_LEFT;
- }
-
- zwlr_layer_surface_v1_set_margin(surface, iy, -ix, -iy, ix);
- }
-
- if(location > 0) {
- enum zwlr_layer_surface_v1_anchor anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP | ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT;
-
- switch(location) {
- case LOCATION_CENTER:
- break;
- case LOCATION_TOP_LEFT:
- anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP | ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT;
- break;
- case LOCATION_TOP:
- anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP;
- break;
- case LOCATION_TOP_RIGHT:
- anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP | ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT;
- break;
- case LOCATION_LEFT:
- anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT;
- break;
- case LOCATION_RIGHT:
- anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT;
- break;
- case LOCATION_BOTTOM_LEFT:
- anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM | ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT;
- break;
- case LOCATION_BOTTOM:
- anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM;
- break;
- case LOCATION_BOTTOM_RIGHT:
- anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM | ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT;
- break;
- }
- zwlr_layer_surface_v1_set_anchor(surface, anchor);
- }
-}
-
-static gboolean do_search(gpointer data) {
- (void) data;
- const gchar* new_filter = gtk_entry_get_text(GTK_ENTRY(entry));
- if(filter == NULL || strcmp(new_filter, filter) != 0) {
- if(filter != NULL) {
- free(filter);
- }
- filter = strdup(new_filter);
- gtk_flow_box_invalidate_filter(GTK_FLOW_BOX(inner_box));
- gtk_flow_box_invalidate_sort(GTK_FLOW_BOX(inner_box));
- GtkFlowBoxChild* child = gtk_flow_box_get_child_at_index(GTK_FLOW_BOX(inner_box), 0);
- if(child != NULL) {
- gtk_flow_box_select_child(GTK_FLOW_BOX(inner_box), child);
- }
- }
- return G_SOURCE_CONTINUE;
-}
-
-static void get_img_data(char* original, char* str, struct map* mode_map, bool first, char** mode, char** data) {
- char* colon = strchr(str, ':');
- if(colon == NULL) {
- if(first) {
- *mode = "text";
- *data = str;
- return;
- } else {
- *mode = NULL;
- *data = NULL;
- return;
- }
- }
-
- *colon = 0;
-
- if(map_contains(mode_map, str)) {
- if(original != str) {
- *(str - 1) = 0;
- }
- *mode = str;
- *data = colon + 1;
- } else if(first) {
- *colon = ':';
- *mode = "text";
- *data = str;
- } else {
- *colon = ':';
- get_img_data(original, colon + 1, mode_map, first, mode, data);
- }
-}
-
-//This is hideous, why did I do this to myself
-static char* parse_images(WofiPropertyBox* box, const char* text, bool create_widgets) {
- char* ret = strdup("");
- struct map* mode_map = map_init();
- map_put(mode_map, "img", "true");
- map_put(mode_map, "img-noscale", "true");
- map_put(mode_map, "img-base64", "true");
- map_put(mode_map, "img-base64-noscale", "true");
- map_put(mode_map, "text", "true");
-
- if(text == NULL) {
- return NULL;
- }
- char* original = strdup(text);
- char* mode1 = NULL;
- char* mode2 = NULL;
- char* data1 = NULL;
- char* data2 = NULL;
-
- get_img_data(original, original, mode_map, true, &mode2, &data2);
-
- while(true) {
- if(mode1 == NULL) {
- mode1 = mode2;
- data1 = data2;
- if(data1 != NULL) {
- get_img_data(original, data1, mode_map, false, &mode2, &data2);
- } else {
- break;
- }
- } else {
- if(strcmp(mode1, "img") == 0 && create_widgets) {
- GdkPixbuf* buf = gdk_pixbuf_new_from_file(data1, NULL);
- if(buf == NULL) {
- fprintf(stderr, "Image %s cannot be loaded\n", data1);
- goto done;
- }
-
- buf = utils_g_resize_pixbuf(buf, image_size * wofi_get_window_scale(), GDK_INTERP_BILINEAR);
-
- GtkWidget* img = gtk_image_new();
- cairo_surface_t* surface = gdk_cairo_surface_create_from_pixbuf(buf, wofi_get_window_scale(), gtk_widget_get_window(img));
- gtk_image_set_from_surface(GTK_IMAGE(img), surface);
- cairo_surface_destroy(surface);
- g_object_unref(buf);
-
- gtk_widget_set_name(img, "img");
- gtk_container_add(GTK_CONTAINER(box), img);
- } else if(strcmp(mode1, "img-noscale") == 0 && create_widgets) {
- GdkPixbuf* buf = gdk_pixbuf_new_from_file(data1, NULL);
- if(buf == NULL) {
- fprintf(stderr, "Image %s cannot be loaded\n", data1);
- goto done;
- }
-
- GtkWidget* img = gtk_image_new();
- cairo_surface_t* surface = gdk_cairo_surface_create_from_pixbuf(buf, wofi_get_window_scale(), gtk_widget_get_window(img));
- gtk_image_set_from_surface(GTK_IMAGE(img), surface);
- cairo_surface_destroy(surface);
- g_object_unref(buf);
-
- gtk_widget_set_name(img, "img");
- gtk_container_add(GTK_CONTAINER(box), img);
- } else if(strcmp(mode1, "img-base64") == 0 && create_widgets) {
- GdkPixbuf* buf = utils_g_pixbuf_from_base64(data1);
- if(buf == NULL) {
- fprintf(stderr, "base64 image cannot be loaded\n");
- goto done;
- }
-
- buf = utils_g_resize_pixbuf(buf, image_size, GDK_INTERP_BILINEAR);
-
- GtkWidget* img = gtk_image_new();
- cairo_surface_t* surface = gdk_cairo_surface_create_from_pixbuf(buf, wofi_get_window_scale(), gtk_widget_get_window(img));
- gtk_image_set_from_surface(GTK_IMAGE(img), surface);
- cairo_surface_destroy(surface);
- g_object_unref(buf);
-
- gtk_widget_set_name(img, "img");
- gtk_container_add(GTK_CONTAINER(box), img);
- } else if(strcmp(mode1, "img-base64-noscale") == 0 && create_widgets) {
- GdkPixbuf* buf = utils_g_pixbuf_from_base64(data1);
- if(buf == NULL) {
- fprintf(stderr, "base64 image cannot be loaded\n");
- goto done;
- }
- GtkWidget* img = gtk_image_new();
- cairo_surface_t* surface = gdk_cairo_surface_create_from_pixbuf(buf, wofi_get_window_scale(), gtk_widget_get_window(img));
- gtk_image_set_from_surface(GTK_IMAGE(img), surface);
- cairo_surface_destroy(surface);
- g_object_unref(buf);
-
- gtk_widget_set_name(img, "img");
- gtk_container_add(GTK_CONTAINER(box), img);
- } else if(strcmp(mode1, "text") == 0) {
- if(create_widgets) {
- GtkWidget* label = gtk_label_new(data1);
- gtk_widget_set_name(label, "text");
- gtk_label_set_use_markup(GTK_LABEL(label), allow_markup);
- gtk_label_set_xalign(GTK_LABEL(label), 0);
- if(line_wrap >= 0) {
- gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
- gtk_label_set_line_wrap_mode(GTK_LABEL(label), line_wrap);
- }
- gtk_container_add(GTK_CONTAINER(box), label);
- } else {
- char* tmp = ret;
- ret = utils_concat(2, ret, data1);
- free(tmp);
- }
- }
- done:
- mode1 = NULL;
- }
- }
- free(original);
- map_free(mode_map);
-
- if(create_widgets) {
- free(ret);
- return NULL;
- } else {
- return ret;
- }
-}
-
-char* wofi_parse_image_escapes(const char* text) {
- return parse_images(NULL, text, false);
-}
-
-static void setup_label(char* mode, WofiPropertyBox* box) {
- wofi_property_box_add_property(box, "mode", mode);
- char index[11];
- snprintf(index, sizeof(index), "%u", ++widget_count);
- wofi_property_box_add_property(box, "index", index);
-
- gtk_widget_set_name(GTK_WIDGET(box), "unselected");
-
- GtkStyleContext* style = gtk_widget_get_style_context(GTK_WIDGET(box));
- gtk_style_context_add_class(style, "entry");
-}
-
-static GtkWidget* create_label(char* mode, char* text, char* search_text, char* action) {
- GtkWidget* box = wofi_property_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
-
- wofi_property_box_add_property(WOFI_PROPERTY_BOX(box), "action", action);
-
- setup_label(mode, WOFI_PROPERTY_BOX(box));
-
- char* nodetext = text;
- if (pre_display_cmd != NULL) {
- text = NULL;
- FILE *fp_labeltext;
- char *cmd_labeltext;
- char line[128]; // you'd think this caps the line's length to 128, but it's just a buffer which due to the nature of fgets() splits on lines
- size_t size = 0;
- // first, prepare cmd_labeltext to be each entry's actual comamand to run, aka replacing 'cat %s' to be 'cat filename'
- if(asprintf(&cmd_labeltext, pre_display_cmd, nodetext) == -1) {
- fprintf(stderr, "error parsing pre_display_cmd to run\n");
- wofi_exit(EXIT_FAILURE);
- }
- // then, run the command
- if(pre_display_exec) {
- int fds[2];
- if(pipe(fds) == -1) {
- perror("pipe broken");
- wofi_exit(1);
- }
- if(fork() == 0) {
- close(fds[0]);
- dup2(fds[1], STDOUT_FILENO);
-
- char* cmd = strdup(pre_display_cmd);
- char* space = strchr(cmd, ' ');
- if(space != NULL) {
- *space = 0;
- }
-
-
- size_t space_count = 0;
- char* tmp_space = space;
- for(; (tmp_space = strchr(tmp_space + 1, ' ')) != NULL; ++space_count);
-
- char** args = malloc((sizeof(char*) * (space_count + 2)));
- args[0] = cmd;
- args[1] = space + 1;
- args[space_count + 2] = NULL;
-
- //> 0 is used because args[0] is the command
- for(size_t count = space_count; count > 0; --count) {
- char* arg = strrchr(space + 1, ' ');
- args[count + 1] = arg + 1;
- *arg = 0;
- }
-
- for(size_t count = 1; count <= space_count + 1; ++count) {
- if(strstr(args[count], "%s") != NULL) {
- if(asprintf(&args[count], args[count], nodetext) == -1) {
- fprintf(stderr, "error parsing pre_display_cmd to run\n");
- exit(EXIT_FAILURE);
- }
- }
- }
-
- execvp(cmd, args);
- free(cmd);
- free(args);
- fprintf(stderr, "error executing '%s'\n", cmd_labeltext);
- exit(1);
- }
- close(fds[1]);
-
- fp_labeltext = fdopen(fds[0], "r");
- } else {
- fp_labeltext = popen(cmd_labeltext, "r");
- }
- if(fp_labeltext == NULL) {
- fprintf(stderr, "error executing '%s'\n", cmd_labeltext);
- wofi_exit(EXIT_FAILURE);
- } else if(fgets(line, sizeof(line), fp_labeltext) != NULL) {
- // lastly, read the output of said command, and put it into the text variable to be used for the label widgets
- // consider using 'printf %.10s as your --pre-display-cmd to limit a string to a determined width. 10 here is an example
- size += strlen(line)+1; // we need place for the \0 of strcpy
- text = (char *) realloc(text, size);
- strcpy(text, line);
- while(fgets(line, sizeof(line), fp_labeltext) != NULL) {
- size += strlen(line);
- text = (char *) realloc(text, size);
- strncat(text, line, size);
- }
- }
-
- if(pre_display_exec) {
- fclose(fp_labeltext);
- while(waitpid(-1, NULL, WNOHANG) > 0);
- } else {
- pclose(fp_labeltext);
- }
- }
-
- if(allow_images) {
- parse_images(WOFI_PROPERTY_BOX(box), text, true);
- } else {
- GtkWidget* label = gtk_label_new(text);
- gtk_widget_set_name(label, "text");
- gtk_label_set_use_markup(GTK_LABEL(label), allow_markup);
- gtk_label_set_xalign(GTK_LABEL(label), 0);
- if(line_wrap >= 0) {
- gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
- gtk_label_set_line_wrap_mode(GTK_LABEL(label), line_wrap);
- }
- gtk_container_add(GTK_CONTAINER(box), label);
- }
- if(parse_search) {
- search_text = strdup(search_text);
- if(allow_images) {
- char* tmp = search_text;
- search_text = parse_images(WOFI_PROPERTY_BOX(box), search_text, false);
- free(tmp);
- }
- if(allow_markup) {
- char* out = NULL;
- pango_parse_markup(search_text, -1, 0, NULL, &out, NULL, NULL);
- free(search_text);
- search_text = out;
- }
- }
- wofi_property_box_add_property(WOFI_PROPERTY_BOX(box), "filter", search_text);
- if(parse_search) {
- free(search_text);
- }
- return box;
-}
-
-static char* get_cache_path(const gchar* mode) {
- if(cache_file != NULL) {
- return strdup(cache_file);
- }
- char* cache_path = getenv("XDG_CACHE_HOME");
- if(cache_path == NULL) {
- cache_path = utils_concat(3, getenv("HOME"), "/.cache/wofi-", mode);
- } else {
- cache_path = utils_concat(3, cache_path, "/wofi-", mode);
- }
- return cache_path;
-}
-
-static void execute_action(const gchar* mode, const gchar* cmd) {
- struct mode* mode_ptr = map_get(modes, mode);
- mode_ptr->mode_exec(cmd);
-}
-
-static void activate_item(GtkFlowBox* flow_box, GtkFlowBoxChild* row, gpointer data) {
- (void) flow_box;
- (void) data;
- GtkWidget* box = gtk_bin_get_child(GTK_BIN(row));
- bool primary_action = GTK_IS_EXPANDER(box);
- if(primary_action) {
- box = gtk_expander_get_label_widget(GTK_EXPANDER(box));
- }
- execute_action(wofi_property_box_get_property(WOFI_PROPERTY_BOX(box), "mode"), wofi_property_box_get_property(WOFI_PROPERTY_BOX(box), "action"));
-}
-
-static void expand(GtkExpander* expander, gpointer data) {
- (void) data;
- GtkWidget* box = gtk_bin_get_child(GTK_BIN(expander));
- resize_expander = !gtk_expander_get_expanded(expander);
- gtk_widget_set_visible(box, resize_expander);
-}
-
-static void update_surface_size(void) {
- if(lines > 0) {
- height = max_height * lines;
- height += 5;
- }
- if(shell != NULL) {
- zwlr_layer_surface_v1_set_size(wlr_surface, width, height);
- wl_surface_commit(wl_surface);
- wl_display_roundtrip(wl);
- }
-
- gtk_window_resize(GTK_WINDOW(window), width, height);
- GtkAllocation alloc;
- gtk_widget_get_allocated_size(entry, &alloc, NULL);
- if(outer_orientation == GTK_ORIENTATION_HORIZONTAL) {
- if(alloc.width > 0) {
- gtk_widget_set_size_request(scroll, width - alloc.width, height);
- }
- } else {
- if(alloc.height > 0) {
- gtk_widget_set_size_request(scroll, width, height - alloc.height);
- }
- }
-}
-
-static void widget_allocate(GtkWidget* widget, GdkRectangle* allocation, gpointer data) {
- (void) data;
- if(widget == entry) {
- update_surface_size();
- return;
- }
-
- if(resize_expander) {
- return;
- }
-
- if(max_height > 0) {
- if(allocation->height > max_height) {
- int64_t ratio = allocation->height / max_height;
- int64_t mod = allocation->height % max_height;
- if(mod >= max_height / 2) {
- ++ratio;
- }
- if(ratio > 1) {
- gtk_widget_set_size_request(widget, -1, max_height * ratio);
- } else {
- max_height = allocation->height;
- }
- } else {
- gtk_widget_set_size_request(widget, -1, max_height);
- }
- } else {
- max_height = allocation->height;
- }
- if(lines > 0) {
- update_surface_size();
- }
-}
-
-static gboolean _insert_widget(gpointer data) {
- struct mode* mode = data;
- struct widget* node;
- if(mode->mode_get_widget == NULL) {
- return FALSE;
- } else {
- node = mode->mode_get_widget();
- }
- if(node == NULL) {
- return FALSE;
- }
-
- GtkWidget* parent;
- if(node->action_count > 1 && !no_actions) {
- parent = gtk_expander_new("");
- g_signal_connect(parent, "activate", G_CALLBACK(expand), NULL);
- GtkWidget* box;
- if(node->builder == NULL) {
- box = create_label(node->mode, node->text[0], node->search_text, node->actions[0]);
- } else {
- box = GTK_WIDGET(node->builder->box);
- setup_label(node->builder->mode->name, WOFI_PROPERTY_BOX(box));
- }
- gtk_expander_set_label_widget(GTK_EXPANDER(parent), box);
-
- GtkWidget* exp_box = gtk_list_box_new();
- gtk_widget_set_name(exp_box, "expander-box");
- gtk_list_box_set_activate_on_single_click(GTK_LIST_BOX(exp_box), single_click);
- g_signal_connect(exp_box, "row-activated", G_CALLBACK(activate_item), NULL);
- gtk_container_add(GTK_CONTAINER(parent), exp_box);
- for(size_t count = 1; count < node->action_count; ++count) {
- if(node->builder == NULL) {
- box = create_label(node->mode, node->text[count], node->search_text, node->actions[count]);
- } else {
- box = GTK_WIDGET(node->builder[count].box);
- setup_label(node->builder->mode->name, WOFI_PROPERTY_BOX(box));
- }
-
- GtkWidget* row = gtk_list_box_row_new();
- gtk_widget_set_name(row, "entry");
-
- gtk_container_add(GTK_CONTAINER(row), box);
- gtk_container_add(GTK_CONTAINER(exp_box), row);
- }
- } else {
- if(node->builder == NULL) {
- parent = create_label(node->mode, node->text[0], node->search_text, node->actions[0]);
- } else {
- parent = GTK_WIDGET(node->builder->box);
- setup_label(node->builder->mode->name, WOFI_PROPERTY_BOX(parent));
- }
- }
-
- gtk_widget_set_halign(parent, content_halign);
- GtkWidget* child = gtk_flow_box_child_new();
- gtk_widget_set_name(child, "entry");
- g_signal_connect(child, "size-allocate", G_CALLBACK(widget_allocate), NULL);
-
- gtk_container_add(GTK_CONTAINER(child), parent);
- gtk_widget_show_all(child);
- gtk_container_add(GTK_CONTAINER(inner_box), child);
- ++line_count;
-
- if(!user_moved) {
- GtkFlowBoxChild* child = gtk_flow_box_get_child_at_index(GTK_FLOW_BOX(inner_box), 0);
- gtk_flow_box_select_child(GTK_FLOW_BOX(inner_box), child);
- gtk_widget_grab_focus(GTK_WIDGET(child));
- }
-
- if(GTK_IS_EXPANDER(parent)) {
- GtkWidget* box = gtk_bin_get_child(GTK_BIN(parent));
- gtk_widget_set_visible(box, FALSE);
- }
-
- if(node->builder != NULL) {
- wofi_widget_builder_free(node->builder);
- } else {
- free(node->mode);
- for(size_t count = 0; count < node->action_count; ++count) {
- free(node->text[count]);
- }
- free(node->text);
- free(node->search_text);
- for(size_t count = 0; count < node->action_count; ++count) {
- free(node->actions[count]);
- }
- free(node->actions);
- free(node);
- }
- return TRUE;
-}
-
-static gboolean insert_all_widgets(gpointer data) {
- if(!has_joined_mode) {
- pthread_join(mode_thread, NULL);
- has_joined_mode = true;
- }
- struct wl_list* modes = data;
- if(modes->prev == modes) {
- return FALSE;
- } else {
- struct mode* mode = wl_container_of(modes->prev, mode, link);
- if(!_insert_widget(mode)) {
- wl_list_remove(&mode->link);
- }
- return TRUE;
- }
-}
-
-static char* escape_lf(const char* cmd) {
- size_t len = strlen(cmd);
- char* buffer = calloc(1, (len + 1) * 2);
-
- size_t buf_count = 0;
- for(size_t count = 0; count < len; ++count) {
- char chr = cmd[count];
- if(chr == '\n') {
- buffer[buf_count++] = '\\';
- buffer[buf_count++] = 'n';
- } else if(chr == '\\') {
- buffer[buf_count++] = '\\';
- buffer[buf_count++] = '\\';
- } else {
- buffer[buf_count++] = chr;
- }
- }
- return buffer;
-}
-
-static char* remove_escapes(const char* cmd) {
- size_t len = strlen(cmd);
- char* buffer = calloc(1, len + 1);
-
- size_t buf_count = 0;
- for(size_t count = 0; count < len; ++count) {
- char chr = cmd[count];
- if(chr == '\\') {
- chr = cmd[++count];
- if(chr == 'n') {
- buffer[buf_count++] = '\n';
- } else if(chr == '\\') {
- buffer[buf_count++] = '\\';
- }
- } else {
- buffer[buf_count++] = chr;
- }
- }
- return buffer;
-}
-
-void wofi_write_cache(struct mode* mode, const char* _cmd) {
- char* cmd = escape_lf(_cmd);
-
- char* cache_path = get_cache_path(mode->name);
-
- char* tmp_dir = strdup(cache_path);
- utils_mkdir(dirname(tmp_dir), S_IRWXU | S_IRGRP | S_IXGRP);
- free(tmp_dir);
-
- struct wl_list lines;
- wl_list_init(&lines);
- bool inc_count = false;
- if(access(cache_path, R_OK) == 0) {
- FILE* file = fopen(cache_path, "r");
- char* line = NULL;
- size_t size = 0;
- while(getline(&line, &size, file) != -1) {
- char* space = strchr(line, ' ');
- char* lf = strchr(line, '\n');
- if(lf != NULL) {
- *lf = 0;
- }
- if(space != NULL && strcmp(cmd, space + 1) == 0) {
- struct cache_line* node = malloc(sizeof(struct cache_line));
- uint64_t count = strtol(line, NULL, 10) + 1;
- char num[6];
- snprintf(num, 5, "%" PRIu64, count);
- node->line = utils_concat(4, num, " ", cmd, "\n");
- inc_count = true;
- wl_list_insert(&lines, &node->link);
- }
- }
- free(line);
- line = NULL;
- size = 0;
- fseek(file, 0, SEEK_SET);
- while(getline(&line, &size, file) != -1) {
- char* space = strchr(line, ' ');
- char* nl = strchr(line, '\n');
- if(nl != NULL) {
- *nl = 0;
- }
- if(space == NULL || strcmp(cmd, space + 1) != 0) {
- struct cache_line* node = malloc(sizeof(struct cache_line));
- node->line = utils_concat(2, line, "\n");
- wl_list_insert(&lines, &node->link);
- }
- }
- free(line);
- fclose(file);
- }
- char* tmp_path = strdup(cache_path);
- char* dir = dirname(tmp_path);
-
- if(access(dir, W_OK) == 0) {
- if(!inc_count) {
- struct cache_line* node = malloc(sizeof(struct cache_line));
- node->line = utils_concat(3, "1 ", cmd, "\n");
- wl_list_insert(&lines, &node->link);
- }
- FILE* file = fopen(cache_path, "w");
- struct cache_line* node, *tmp;
- wl_list_for_each_safe(node, tmp, &lines, link) {
- fwrite(node->line, 1, strlen(node->line), file);
- free(node->line);
- wl_list_remove(&node->link);
- free(node);
- }
-
- fclose(file);
- }
- free(cache_path);
- free(tmp_path);
- free(cmd);
-}
-
-void wofi_remove_cache(struct mode* mode, const char* _cmd) {
- char* cmd = escape_lf(_cmd);
-
- char* cache_path = get_cache_path(mode->name);
- if(access(cache_path, R_OK | W_OK) == 0) {
- struct wl_list lines;
- wl_list_init(&lines);
-
- FILE* file = fopen(cache_path, "r");
- char* line = NULL;
- size_t size = 0;
- while(getline(&line, &size, file) != -1) {
- char* space = strchr(line, ' ');
- char* lf = strchr(line, '\n');
- if(lf != NULL) {
- *lf = 0;
- }
- if(space == NULL || strcmp(cmd, space + 1) != 0) {
- struct cache_line* node = malloc(sizeof(struct cache_line));
- node->line = utils_concat(2, line, "\n");
- wl_list_insert(&lines, &node->link);
- }
- }
- free(line);
- fclose(file);
-
- file = fopen(cache_path, "w");
- struct cache_line* node, *tmp;
- wl_list_for_each_safe(node, tmp, &lines, link) {
- fwrite(node->line, 1, strlen(node->line), file);
- free(node->line);
- wl_list_remove(&node->link);
- free(node);
- }
- fclose(file);
- }
- free(cache_path);
- free(cmd);
-}
-
-struct wl_list* wofi_read_cache(struct mode* mode) {
- char* cache_path = get_cache_path(mode->name);
- struct wl_list* cache = malloc(sizeof(struct wl_list));
- wl_list_init(cache);
- struct wl_list lines;
- wl_list_init(&lines);
- if(access(cache_path, R_OK) == 0) {
- FILE* file = fopen(cache_path, "r");
- char* line = NULL;
- size_t size = 0;
- while(getline(&line, &size, file) != -1) {
- struct cache_line* node = malloc(sizeof(struct cache_line));
- char* lf = strchr(line, '\n');
- if(lf != NULL) {
- *lf = 0;
- }
- node->line = remove_escapes(line);
- wl_list_insert(&lines, &node->link);
- }
- free(line);
- fclose(file);
- }
- while(!wl_list_empty(&lines)) {
- uint64_t smallest = UINT64_MAX;
- struct cache_line* node, *smallest_node = NULL;
- wl_list_for_each(node, &lines, link) {
- uint64_t num = strtol(node->line, NULL, 10);
- if(num < smallest) {
- smallest = num;
- smallest_node = node;
- }
- }
-
- char* space = strchr(smallest_node->line, ' ');
-
- if(space == NULL) {
- free(smallest_node->line);
- wl_list_remove(&smallest_node->link);
- continue;
- }
-
- char* tmp = strdup(space + 1);
- free(smallest_node->line);
- smallest_node->line = tmp;
- wl_list_remove(&smallest_node->link);
- wl_list_insert(cache, &smallest_node->link);
- }
- free(cache_path);
- return cache;
-}
-
-struct widget* wofi_create_widget(struct mode* mode, char* text[], char* search_text, char* actions[], size_t action_count) {
- struct widget* widget = calloc(1, sizeof(struct widget));
- widget->mode = strdup(mode->name);
- widget->text = malloc(action_count * sizeof(char*));
- for(size_t count = 0; count < action_count; ++count) {
- widget->text[count] = strdup(text[count]);
- }
- widget->search_text = strdup(search_text);
- widget->action_count = action_count;
- widget->actions = malloc(action_count * sizeof(char*));
- for(size_t count = 0; count < action_count; ++count) {
- widget->actions[count] = strdup(actions[count]);
- }
- return widget;
-}
-
-void wofi_insert_widgets(struct mode* mode) {
- gdk_threads_add_idle(_insert_widget, mode);
-}
-
-char* wofi_get_dso_path(struct mode* mode) {
- return mode->dso;
-}
-
-bool wofi_allow_images(void) {
- return allow_images;
-}
-
-bool wofi_allow_markup(void) {
- return allow_markup;
-}
-
-uint64_t wofi_get_image_size(void) {
- return image_size;
-}
-
-uint64_t wofi_get_window_scale(void) {
- return gdk_window_get_scale_factor(gtk_widget_get_window(window));
-}
-
-bool wofi_mod_shift(void) {
- return mod_shift;
-}
-
-bool wofi_mod_control(void) {
- return mod_ctrl;
-}
-
-void wofi_term_run(const char* cmd) {
- if(terminal != NULL) {
- execlp(terminal, terminal, "-e", cmd, NULL);
- }
- size_t term_count = sizeof(terminals) / sizeof(char*);
- for(size_t count = 0; count < term_count; ++count) {
- execlp(terminals[count], terminals[count], "-e", cmd, NULL);
- }
- fprintf(stderr, "No terminal emulator found please set term in config or use --term\n");
- wofi_exit(1);
-}
-
-static void flag_box(GtkBox* box, GtkStateFlags flags) {
- GList* selected_children = gtk_container_get_children(GTK_CONTAINER(box));
- for(GList* list = selected_children; list != NULL; list = list->next) {
- GtkWidget* child = list->data;
- gtk_widget_set_state_flags(child, flags, TRUE);
- }
- g_list_free(selected_children);
-}
-
-static void select_item(GtkFlowBox* flow_box, gpointer data) {
- (void) data;
- if(previous_selection != NULL) {
- gtk_widget_set_name(previous_selection, "unselected");
- flag_box(GTK_BOX(previous_selection), GTK_STATE_FLAG_NORMAL);
- }
- GList* selected_children = gtk_flow_box_get_selected_children(flow_box);
- GtkWidget* box = gtk_bin_get_child(GTK_BIN(selected_children->data));
- g_list_free(selected_children);
- if(GTK_IS_EXPANDER(box)) {
- box = gtk_expander_get_label_widget(GTK_EXPANDER(box));
- }
- flag_box(GTK_BOX(box), GTK_STATE_FLAG_SELECTED);
- gtk_widget_set_name(box, "selected");
- previous_selection = box;
-}
-
-static void activate_search(GtkEntry* entry, gpointer data) {
- (void) data;
- GtkFlowBoxChild* child = gtk_flow_box_get_child_at_index(GTK_FLOW_BOX(inner_box), 0);
- gboolean is_visible = gtk_widget_get_visible(GTK_WIDGET(child));
- if(mode != NULL && (exec_search || child == NULL || !is_visible)) {
- execute_action(mode, gtk_entry_get_text(entry));
- } else if(child != NULL) {
- GtkWidget* box = gtk_bin_get_child(GTK_BIN(child));
- bool primary_action = GTK_IS_EXPANDER(box);
- if(primary_action) {
- box = gtk_expander_get_label_widget(GTK_EXPANDER(box));
- }
- execute_action(wofi_property_box_get_property(WOFI_PROPERTY_BOX(box), "mode"), wofi_property_box_get_property(WOFI_PROPERTY_BOX(box), "action"));
- }
-}
-
-static gboolean filter_proxy(GtkFlowBoxChild* row) {
- GtkWidget* box = gtk_bin_get_child(GTK_BIN(row));
- if(GTK_IS_EXPANDER(box)) {
- box = gtk_expander_get_label_widget(GTK_EXPANDER(box));
- }
- const gchar* text =
- wofi_property_box_get_property(WOFI_PROPERTY_BOX(box), "filter");
- return match_for_matching_mode(filter, text, matching, insensitive);
-}
-
-static void do_resize_surface_after_filter(GtkFlowBoxChild *row, gboolean filter_return) {
-
- if(gtk_widget_get_visible(GTK_WIDGET(row)) == !filter_return &&
- dynamic_lines) {
- if(filter_return) {
- ++line_count;
- } else {
- --line_count;
- }
-
- if(line_count < max_lines) {
- lines = line_count;
- update_surface_size();
- } else {
- lines = max_lines;
- update_surface_size();
- }
- }
-
- gtk_widget_set_visible(GTK_WIDGET(row), filter_return);
-}
-
-static gboolean do_filter(GtkFlowBoxChild* row, gpointer data) {
- (void) data;
- gboolean ret = filter_proxy(row);
-
- do_resize_surface_after_filter(row, ret);
-
- return ret;
-}
-
-static gint do_sort(GtkFlowBoxChild* child1, GtkFlowBoxChild* child2, gpointer data) {
- (void) data;
- gtk_flow_box_get_child_at_index(GTK_FLOW_BOX(inner_box), 0);
-
- GtkWidget* box1 = gtk_bin_get_child(GTK_BIN(child1));
- GtkWidget* box2 = gtk_bin_get_child(GTK_BIN(child2));
- if(GTK_IS_EXPANDER(box1)) {
- box1 = gtk_expander_get_label_widget(GTK_EXPANDER(box1));
- }
- if(GTK_IS_EXPANDER(box2)) {
- box2 = gtk_expander_get_label_widget(GTK_EXPANDER(box2));
- }
-
- const gchar* text1 = wofi_property_box_get_property(WOFI_PROPERTY_BOX(box1), "filter");
- const gchar* text2 = wofi_property_box_get_property(WOFI_PROPERTY_BOX(box2), "filter");
- uint64_t index1 = strtol(wofi_property_box_get_property(WOFI_PROPERTY_BOX(box1), "index"), NULL, 10);
- uint64_t index2 = strtol(wofi_property_box_get_property(WOFI_PROPERTY_BOX(box2), "index"), NULL, 10);
-
- if(text1 == NULL || text2 == NULL) {
- return index1 - index2;
- }
-
- int fallback = 0;
- switch(sort_order) {
- case SORT_ORDER_DEFAULT:
- fallback = index1 - index2;
- break;
- case SORT_ORDER_ALPHABETICAL:
- if(insensitive) {
- fallback = strcasecmp(text1, text2);
- } else {
- fallback = strcmp(text1, text2);
- }
- break;
- }
-
- if(filter == NULL || strcmp(filter, "") == 0) {
- return fallback;
- }
- return sort_for_matching_mode(text1, text2, fallback, matching, filter, insensitive);
-}
-
-static void select_idx(gint idx) {
- GtkFlowBoxChild* child = gtk_flow_box_get_child_at_index(GTK_FLOW_BOX(inner_box), idx);
- gtk_widget_grab_focus(GTK_WIDGET(child));
- gtk_flow_box_select_child(GTK_FLOW_BOX(inner_box), GTK_FLOW_BOX_CHILD(child));
-}
-
-static GdkModifierType get_mask_from_keystate(guint state) {
- if ((state & GDK_SHIFT_MASK) == GDK_SHIFT_MASK) {
- return GDK_SHIFT_MASK;
- }
-
- if ((state & GDK_CONTROL_MASK) == GDK_CONTROL_MASK) {
- return GDK_CONTROL_MASK;
- }
-
- // Alt
- if ((state & GDK_MOD1_MASK) == GDK_MOD1_MASK) {
- return GDK_MOD1_MASK;
- }
-
- return 0;
-}
-
-static char* get_name_from_mask(GdkModifierType mask) {
- switch(mask) {
- case GDK_SHIFT_MASK:
- return "Shift";
- case GDK_CONTROL_MASK:
- return "Ctrl";
- case GDK_MOD1_MASK:
- return "Alt";
- default:
- return NULL;
- }
-}
-
-static GdkModifierType get_mask_from_name(char* name) {
- GdkModifierType* mask = map_get(mods, name);
- if (mask) {
- return *mask;
- }
-
- return 0;
-}
-
-static void move_up(void) {
- user_moved = true;
- gtk_widget_child_focus(window, GTK_DIR_UP);
-}
-
-static void move_down(void) {
- user_moved = true;
- if(outer_orientation == GTK_ORIENTATION_VERTICAL) {
- if(gtk_widget_has_focus(entry) || gtk_widget_has_focus(scroll)) {
- select_idx(1);
- return;
- }
- }
- gtk_widget_child_focus(window, GTK_DIR_DOWN);
-}
-
-static void move_left(void) {
- user_moved = true;
- gtk_widget_child_focus(window, GTK_DIR_LEFT);
-}
-
-static void move_right(void) {
- user_moved = true;
- if(outer_orientation == GTK_ORIENTATION_HORIZONTAL) {
- if(gtk_widget_has_focus(entry) || gtk_widget_has_focus(scroll)) {
- select_idx(1);
- return;
- }
- }
- gtk_widget_child_focus(window, GTK_DIR_RIGHT);
-}
-
-static void move_forward(void) {
- user_moved = true;
- if(gtk_widget_has_focus(entry) || gtk_widget_has_focus(scroll)) {
- select_idx(1);
- return;
- }
-
- gtk_widget_child_focus(window, GTK_DIR_TAB_FORWARD);
-
- if(gtk_widget_has_focus(entry)) {
- select_idx(0);
- }
-}
-
-static void move_backward(void) {
- user_moved = true;
- gtk_widget_child_focus(window, GTK_DIR_TAB_BACKWARD);
-
- if(gtk_widget_has_focus(entry)) {
- move_backward();
- }
-}
-
-static void move_pgup(void) {
- uint64_t lines = height / max_height;
- for(size_t count = 0; count < lines; ++count) {
- move_up();
- }
-}
-
-static void move_pgdn(void) {
- uint64_t lines = height / max_height;
- for(size_t count = 0; count < lines; ++count) {
- move_down();
- }
-}
-
-static void do_exit(void) {
- wofi_exit(1);
-}
-
-static void do_expand(void) {
- GList* children = gtk_flow_box_get_selected_children(GTK_FLOW_BOX(inner_box));
- if(children->data != NULL && gtk_widget_has_focus(children->data)) {
- GtkWidget* expander = gtk_bin_get_child(children->data);
- if(GTK_IS_EXPANDER(expander)) {
- g_signal_emit_by_name(expander, "activate");
- }
- }
- g_list_free(children);
-}
-
-static void do_hide_search(void) {
- gtk_widget_set_visible(entry, !gtk_widget_get_visible(entry));
- update_surface_size();
-}
-
-static void do_copy(void) {
- GList* children = gtk_flow_box_get_selected_children(GTK_FLOW_BOX(inner_box));
- if(children->data != NULL && gtk_widget_has_focus(children->data)) {
- GtkWidget* widget = gtk_bin_get_child(children->data);
- if(GTK_IS_EXPANDER(widget)) {
- GtkWidget* box = gtk_bin_get_child(GTK_BIN(widget));
- GtkListBoxRow* row = gtk_list_box_get_selected_row(GTK_LIST_BOX(box));
- if(row == NULL) {
- widget = gtk_expander_get_label_widget(GTK_EXPANDER(widget));
- } else {
- widget = gtk_bin_get_child(GTK_BIN(row));
- }
- }
- if(WOFI_IS_PROPERTY_BOX(widget)) {
- const gchar* action = wofi_property_box_get_property(WOFI_PROPERTY_BOX(widget), "action");
- if(action == NULL) {
- return;
- }
-
- int fds[2];
- if (pipe(fds) == -1) {
- perror("pipe broken");
- wofi_exit(EXIT_FAILURE);
- }
- if(fork() == 0) {
- close(fds[1]);
- dup2(fds[0], STDIN_FILENO);
- execlp(copy_exec, copy_exec, NULL);
- fprintf(stderr, "%s could not be executed: %s\n", copy_exec, strerror(errno));
- exit(errno);
- }
- close(fds[0]);
-
- if(write(fds[1], action, strlen(action)) <= 0) {
- fprintf(stderr, "fd pipe failed to write\n");
- }
-
- close(fds[1]);
-
- while(waitpid(-1, NULL, WNOHANG) > 0);
- }
- }
-}
-
-static void on_exit_set_custom_key_return_code(void) {
- fflush(stdout);
- fflush(stderr);
- _exit(custom_key_return_code);
-}
-
-void wofi_exit(int status) {
- fflush(stdout);
- fflush(stderr);
-
- if(status == EXIT_SUCCESS) {
- _exit(custom_key_return_code);
- }
-
- _exit(status);
-}
-
-static void do_custom_key(int custom_key_num) {
- custom_key_return_code = custom_key_num + 10;
-}
-
-static void do_custom_key_0(void) {do_custom_key(0);}
-static void do_custom_key_1(void) {do_custom_key(1);}
-static void do_custom_key_2(void) {do_custom_key(2);}
-static void do_custom_key_3(void) {do_custom_key(3);}
-static void do_custom_key_4(void) {do_custom_key(4);}
-static void do_custom_key_5(void) {do_custom_key(5);}
-static void do_custom_key_6(void) {do_custom_key(6);}
-static void do_custom_key_7(void) {do_custom_key(7);}
-static void do_custom_key_8(void) {do_custom_key(8);}
-static void do_custom_key_9(void) {do_custom_key(9);}
-static void do_custom_key_10(void) {do_custom_key(10);}
-static void do_custom_key_11(void) {do_custom_key(11);}
-static void do_custom_key_12(void) {do_custom_key(12);}
-static void do_custom_key_13(void) {do_custom_key(13);}
-static void do_custom_key_14(void) {do_custom_key(14);}
-static void do_custom_key_15(void) {do_custom_key(15);}
-static void do_custom_key_16(void) {do_custom_key(16);}
-static void do_custom_key_17(void) {do_custom_key(17);}
-static void do_custom_key_18(void) {do_custom_key(18);}
-static void do_custom_key_19(void) {do_custom_key(19);}
-
-static bool do_key_action(GdkEvent* event, char* mod, void (*action)(void)) {
- // GTK children focus gets all messed up if we don't first blow away any
- // modifier keystate that's currently happening.
- if(mod != NULL) {
- GdkModifierType mask = get_mask_from_name(mod);
- if((event->key.state & mask) == mask) {
- event->key.state &= ~mask;
- action();
- return true;
- }
- return false;
- } else {
- action();
- return true;
- }
-}
-
-static bool has_mod(guint state) {
- return (state & GDK_SHIFT_MASK) == GDK_SHIFT_MASK || (state & GDK_CONTROL_MASK) == GDK_CONTROL_MASK || (state & GDK_MOD1_MASK) == GDK_MOD1_MASK;
-}
-
-static gboolean do_nyan(gpointer data) {
- (void) data;
- wofi_load_css(true);
- return G_SOURCE_CONTINUE;
-}
-
-static guint get_konami_key(uint8_t cycle) {
- switch(cycle) {
- case 0:
- return GDK_KEY_Up;
- case 1:
- return GDK_KEY_Up;
- case 2:
- return GDK_KEY_Down;
- case 3:
- return GDK_KEY_Down;
- case 4:
- return GDK_KEY_Left;
- case 5:
- return GDK_KEY_Right;
- case 6:
- return GDK_KEY_Left;
- case 7:
- return GDK_KEY_Right;
- case 8:
- return GDK_KEY_b;
- case 9:
- return GDK_KEY_a;
- case 10:
- return GDK_KEY_Return;
- default:
- return GDK_KEY_VoidSymbol;
- }
-}
-
-static gboolean key_press(GtkWidget* widget, GdkEvent* event, gpointer data) {
- (void) widget;
- (void) data;
- gchar* name = gdk_keyval_name(event->key.keyval);
- bool printable = strlen(name) == 1 && isprint(name[0]) && !has_mod(event->key.state);
-
- guint konami_key = get_konami_key(konami_cycle);
- if(event->key.keyval == konami_key) {
- if(konami_cycle == 10) {
- konami_cycle = 0;
- if(!is_konami) {
- is_konami = true;
- gdk_threads_add_timeout(500, do_nyan, NULL);
- }
- return TRUE;
- } else {
- ++konami_cycle;
- }
- } else {
- konami_cycle = 0;
- }
-
- if(gtk_widget_has_focus(entry) && printable) {
- return FALSE;
- }
-
- bool key_success = true;
- struct key_entry* key_ent = NULL;
- char* mod = NULL;
-
- if (has_mod(event->key.state)) {
- char* keyval = gdk_keyval_name(event->key.keyval);
- GdkModifierType mask = get_mask_from_keystate(event->key.state);
- mod = get_name_from_mask(mask);
- size_t len = strlen(mod) + 1 + strlen(keyval) + 1;
- char* mod_keyval = malloc(len);
- strcpy(mod_keyval, mod);
- strcat(mod_keyval, "-");
- strcat(mod_keyval, keyval);
- key_ent = map_get(keys, mod_keyval);
- free(mod_keyval);
- } else {
- key_ent = map_get(keys, gdk_keyval_name(event->key.keyval));
- }
-
- if(key_ent != NULL && key_ent->action != NULL) {
- key_success = do_key_action(event, key_ent->mod, key_ent->action);
- } else if(key_ent != NULL) {
- mod_shift = (event->key.state & GDK_SHIFT_MASK) == GDK_SHIFT_MASK;
- mod_ctrl = (event->key.state & GDK_CONTROL_MASK) == GDK_CONTROL_MASK;
- if(mod_shift) {
- event->key.state &= ~GDK_SHIFT_MASK;
- }
- if(mod_ctrl) {
- event->key.state &= ~GDK_CONTROL_MASK;
- }
- if(gtk_widget_has_focus(scroll)) {
- gtk_entry_grab_focus_without_selecting(GTK_ENTRY(entry));
- }
- GList* children = gtk_flow_box_get_selected_children(GTK_FLOW_BOX(inner_box));
- if(gtk_widget_has_focus(entry)) {
- g_signal_emit_by_name(entry, "activate", entry, NULL);
- } else if(gtk_widget_has_focus(inner_box) || children->data != NULL) {
- gpointer obj = children->data;
-
- if(obj != NULL) {
- GtkWidget* exp = gtk_bin_get_child(GTK_BIN(obj));
- if(GTK_IS_EXPANDER(exp)) {
- GtkWidget* box = gtk_bin_get_child(GTK_BIN(exp));
- GtkListBoxRow* row = gtk_list_box_get_selected_row(GTK_LIST_BOX(box));
- if(row != NULL) {
- obj = row;
- }
- }
- g_signal_emit_by_name(obj, "activate", obj, NULL);
- }
- }
- g_list_free(children);
- } else if(event->key.keyval == GDK_KEY_Shift_L || event->key.keyval == GDK_KEY_Shift_R) {
- } else if(event->key.keyval == GDK_KEY_Control_L || event->key.keyval == GDK_KEY_Control_R) {
- } else if(event->key.keyval == GDK_KEY_Alt_L || event->key.keyval == GDK_KEY_Alt_R) {
- } else {
- key_success = false;
- }
-
- if(key_success) {
- return TRUE;
- }
- if(!gtk_widget_has_focus(entry)) {
- gtk_entry_grab_focus_without_selecting(GTK_ENTRY(entry));
- }
- return FALSE;
-}
-
-static gboolean focus(GtkWidget* widget, GdkEvent* event, gpointer data) {
- (void) data;
- if(event->focus_change.in) {
- gtk_widget_set_state_flags(widget, GTK_STATE_FLAG_FOCUSED, TRUE);
- } else {
- gtk_widget_set_state_flags(widget, GTK_STATE_FLAG_NORMAL, TRUE);
- }
- return FALSE;
-}
-
-static gboolean focus_entry(GtkWidget* widget, GdkEvent* event, gpointer data) {
- (void) data;
- if(widget == entry && dbus != NULL) {
- GError* err = NULL;
- GVariant* ret = g_dbus_proxy_call_sync(dbus, "SetVisible", g_variant_new("(b)", event->focus_change.in), G_DBUS_CALL_FLAGS_NONE, 2000, NULL, &err);
- if(err != NULL) {
- if(err->code != G_DBUS_ERROR_SERVICE_UNKNOWN) {
- fprintf(stderr, "Error while changing OSK state %s\n", err->message);
- }
- g_error_free(err);
- } else {
- g_variant_unref(ret);
- }
- }
- return FALSE;
-}
-
-static void* get_plugin_proc(const char* prefix, const char* suffix) {
- char* proc_name = utils_concat(3, "wofi_", prefix, suffix);
- void* proc = dlsym(RTLD_DEFAULT, proc_name);
- free(proc_name);
- return proc;
-}
-
-static void* load_mode(char* _mode, char* name, struct mode* mode_ptr, struct map* props) {
- char* dso = strstr(_mode, ".so");
-
- mode_ptr->name = strdup(name);
-
- void (*init)(struct mode* _mode, struct map* props);
- void (*load)(struct mode* _mode);
- const char** (*get_arg_names)(void);
- size_t (*get_arg_count)(void);
- bool (*no_entry)(void);
- if(dso == NULL) {
- mode_ptr->dso = NULL;
- init = get_plugin_proc(_mode, "_init");
- load = get_plugin_proc(_mode, "_load");
- get_arg_names = get_plugin_proc(_mode, "_get_arg_names");
- get_arg_count = get_plugin_proc(_mode, "_get_arg_count");
- mode_ptr->mode_exec = get_plugin_proc(_mode, "_exec");
- mode_ptr->mode_get_widget = get_plugin_proc(_mode, "_get_widget");
- no_entry = get_plugin_proc(_mode, "_no_entry");
- } else {
- char* plugins_dir = utils_concat(2, config_dir, "/plugins/");
- char* full_name = utils_concat(2, plugins_dir, _mode);
- mode_ptr->dso = strdup(full_name);
- void* plugin = dlopen(full_name, RTLD_LAZY | RTLD_LOCAL);
- free(full_name);
- free(plugins_dir);
- init = dlsym(plugin, "init");
- load = dlsym(plugin, "load");
- get_arg_names = dlsym(plugin, "get_arg_names");
- get_arg_count = dlsym(plugin, "get_arg_count");
- mode_ptr->mode_exec = dlsym(plugin, "exec");
- mode_ptr->mode_get_widget = dlsym(plugin, "get_widget");
- no_entry = dlsym(plugin, "no_entry");
- }
-
- if(load != NULL) {
- load(mode_ptr);
- }
-
- const char** arg_names = NULL;
- size_t arg_count = 0;
- if(get_arg_names != NULL && get_arg_count != NULL) {
- arg_names = get_arg_names();
- arg_count = get_arg_count();
- }
-
- if(mode == NULL && no_entry != NULL && no_entry()) {
- mode = mode_ptr->name;
- }
-
- for(size_t count = 0; count < arg_count; ++count) {
- const char* arg = arg_names[count];
- char* full_name = utils_concat(3, name, "-", arg);
- map_put(props, arg, config_get(config, full_name, NULL));
- free(full_name);
- }
- return init;
-}
-
-static struct mode* add_mode(char* _mode) {
- struct mode* mode_ptr = calloc(1, sizeof(struct mode));
- struct map* props = map_init();
- void (*init)(struct mode* _mode, struct map* props) = load_mode(_mode, _mode, mode_ptr, props);
-
- if(init == NULL) {
- free(mode_ptr->name);
- free(mode_ptr->dso);
- free(mode_ptr);
- map_free(props);
-
- mode_ptr = calloc(1, sizeof(struct mode));
- props = map_init();
-
- char* name = utils_concat(3, "lib", _mode, ".so");
- init = load_mode(name, _mode, mode_ptr, props);
- free(name);
-
- if(init == NULL) {
- free(mode_ptr->name);
- free(mode_ptr->dso);
- free(mode_ptr);
- map_free(props);
-
- mode_ptr = calloc(1, sizeof(struct mode));
- props = map_init();
-
- init = load_mode("external", _mode, mode_ptr, props);
-
- map_put(props, "exec", _mode);
-
- if(init == NULL) {
- fprintf(stderr, "I would love to show %s but Idk what it is\n", _mode);
- wofi_exit(1);
- }
- }
- }
- map_put_void(modes, _mode, mode_ptr);
- init(mode_ptr, props);
-
- map_free(props);
- return mode_ptr;
-}
-
-static void* start_mode_thread(void* data) {
- char* mode = data;
- if(strchr(mode, ',') != NULL) {
- char* save_ptr;
- char* str = strtok_r(mode, ",", &save_ptr);
- do {
- struct mode* mode_ptr = add_mode(str);
- wl_list_insert(&mode_list, &mode_ptr->link);
- } while((str = strtok_r(NULL, ",", &save_ptr)) != NULL);
- } else {
- struct mode* mode_ptr = add_mode(mode);
- wl_list_insert(&mode_list, &mode_ptr->link);
- }
- return NULL;
-}
-
-static void add_key_entry(char* key, void (*action)(void)) {
- char* tmp = strdup(key);
- char* save_ptr;
- char* str = strtok_r(tmp, ",", &save_ptr);
- do {
- if(str == NULL) {
- break;
- }
- char* hyphen = strchr(str, '-');
- char* mod = NULL;
- GdkModifierType modifier = 0;
- if(hyphen != NULL) {
- *hyphen = '\0';
- modifier = get_mask_from_name(str);
- if (modifier) {
- mod = str;
- str = hyphen + 1;
- } else {
- fprintf(stderr,
- "Could not parse %s as a modifier. Valid modifiers are "
- "Ctrl, Shift, and Alt.\n",
- str);
- }
- }
- struct key_entry* entry = malloc(sizeof(struct key_entry));
- if(mod == NULL) {
- entry->mod = NULL;
- } else {
- entry->mod = strdup(mod);
- }
- entry->action = action;
- char* map_key = NULL;
-
- if (mod) {
- size_t len = strlen(mod) + 1 + strlen(str) + 1;
- map_key = malloc(len);
- strcpy(map_key, mod);
- strcat(map_key, "-");
- strcat(map_key, str);
- } else {
- map_key = strdup(str);
- }
-
- map_put_void(keys, map_key, entry);
- free(map_key);
- } while((str = strtok_r(NULL, ",", &save_ptr)) != NULL);
- free(tmp);
-}
-
-static void get_output_name(void* data, struct zxdg_output_v1* output, const char* name) {
- (void) output;
- struct output_node* node = data;
- node->name = strdup(name);
-}
-
-static void get_output_res(void* data, struct zxdg_output_v1* output, int32_t width, int32_t height) {
- (void) output;
- struct output_node* node = data;
- node->width = width;
- node->height = height;
-}
-
-static void get_output_pos(void* data, struct zxdg_output_v1* output, int32_t x, int32_t y) {
- (void) output;
- struct output_node* node = data;
- node->x = x;
- node->y = y;
-}
-
-static gboolean do_percent_size(gpointer data) {
- char** geo_str = data;
- bool width_percent = strchr(geo_str[0], '%') != NULL;
- bool height_percent = strchr(geo_str[1], '%') != NULL && lines == 0;
-
- GdkMonitor* monitor = gdk_display_get_monitor_at_window(gdk_display_get_default(), gtk_widget_get_window(window));
-
- GdkRectangle rect;
- gdk_monitor_get_geometry(monitor, &rect);
-
- if(rect.width == resolution.width && rect.height == resolution.height) {
- return G_SOURCE_CONTINUE;
- }
-
- resolution = rect;
-
- if(width_percent) {
- uint64_t w_percent = strtol(geo_str[0], NULL, 10);
- width = (w_percent / 100.f) * rect.width;
- }
- if(height_percent) {
- uint64_t h_percent = strtol(geo_str[1], NULL, 10);
- height = (h_percent / 100.f) * rect.height;
- }
- update_surface_size();
- return G_SOURCE_CONTINUE;
-}
-
-static gboolean do_percent_size_first(gpointer data){
- gdk_threads_add_timeout(50, do_percent_size, data);
- do_percent_size(data);
- return G_SOURCE_REMOVE;
-}
-
-static gboolean hide_search_first(gpointer data) {
- (void) data;
- gtk_widget_set_visible(entry, !hide_search);
- return G_SOURCE_REMOVE;
-}
-
-void wofi_init(struct map* _config) {
- config = _config;
- char* width_str = config_get(config, "width", "50%");
- char* height_str = config_get(config, "height", "40%");
- width = strtol(width_str, NULL, 10);
- height = strtol(height_str, NULL, 10);
-
- if(width > UINT16_MAX || height > UINT16_MAX) {
- fprintf(stderr, "Do you actually have a monitor big enough to see this O_o? Dimensions can be no larger than %ux%u\n", UINT16_MAX, UINT16_MAX);
- wofi_exit(1);
- }
-
- x = map_get(config, "x");
- y = map_get(config, "y");
- bool normal_window = strcmp(config_get(config, "normal_window", "false"), "true") == 0;
- char* mode = map_get(config, "mode");
- GtkOrientation orientation = config_get_mnemonic(config, "orientation", "vertical", 2, "vertical", "horizontal");
- outer_orientation = config_get_mnemonic(config, "orientation", "vertical", 2, "horizontal", "vertical");
- GtkAlign halign = config_get_mnemonic(config, "halign", "fill", 4, "fill", "start", "end", "center");
- content_halign = config_get_mnemonic(config, "content_halign", "fill", 4, "fill", "start", "end", "center");
- char* default_valign = "start";
- if(outer_orientation == GTK_ORIENTATION_HORIZONTAL) {
- default_valign = "center";
- }
- GtkAlign valign = config_get_mnemonic(config, "valign", default_valign, 4, "fill", "start", "end", "center");
- char* prompt = config_get(config, "prompt", mode);
- uint64_t filter_rate = strtol(config_get(config, "filter_rate", "100"), NULL, 10);
- allow_images = strcmp(config_get(config, "allow_images", "false"), "true") == 0;
- allow_markup = strcmp(config_get(config, "allow_markup", "false"), "true") == 0;
- image_size = strtol(config_get(config, "image_size", "32"), NULL, 10);
- cache_file = map_get(config, "cache_file");
- config_dir = map_get(config, "config_dir");
- terminal = map_get(config, "term");
- char* password_char = map_get(config, "password_char");
- exec_search = strcmp(config_get(config, "exec_search", "false"), "true") == 0;
- bool hide_scroll = strcmp(config_get(config, "hide_scroll", "false"), "true") == 0;
- matching = config_get_mnemonic(config, "matching", "contains", 3, "contains", "multi-contains", "fuzzy");
- insensitive = strcmp(config_get(config, "insensitive", "false"), "true") == 0;
- parse_search = strcmp(config_get(config, "parse_search", "false"), "true") == 0;
- location = config_get_mnemonic(config, "location", "center", 18,
- "center", "top_left", "top", "top_right", "right", "bottom_right", "bottom", "bottom_left", "left",
- "0", "1", "2", "3", "4", "5", "6", "7", "8");
- no_actions = strcmp(config_get(config, "no_actions", "false"), "true") == 0;
- lines = strtol(config_get(config, "lines", "0"), NULL, 10);
- max_lines = lines;
- columns = strtol(config_get(config, "columns", "1"), NULL, 10);
- sort_order = config_get_mnemonic(config, "sort_order", "default", 2, "default", "alphabetical");
- line_wrap = config_get_mnemonic(config, "line_wrap", "off", 4, "off", "word", "char", "word_char") - 1;
- bool global_coords = strcmp(config_get(config, "global_coords", "false"), "true") == 0;
- hide_search = strcmp(config_get(config, "hide_search", "false"), "true") == 0;
- char* search = map_get(config, "search");
- dynamic_lines = strcmp(config_get(config, "dynamic_lines", "false"), "true") == 0;
- char* monitor = map_get(config, "monitor");
- char* layer = config_get(config, "layer", "top");
- copy_exec = config_get(config, "copy_exec", "wl-copy");
- pre_display_cmd = map_get(config, "pre_display_cmd");
- pre_display_exec = strcmp(config_get(config, "pre_display_exec", "false"), "true") == 0;
- single_click = strcmp(config_get(config, "single_click", "false"), "true") == 0;
-
- keys = map_init_void();
- mods = map_init_void();
-
- map_put_void(mods, "Shift", &shift_mask);
- map_put_void(mods, "Ctrl", &ctrl_mask);
- map_put_void(mods, "Alt", &alt_mask);
-
- // First pass maps the default key entries.
- // Second pass maps any custom key entry configs in addition to (or
- // replacing) defaults.
- for (int i = 0; i < 2; i++) {
- char* key_default;
-
- key_default = "Up";
- char* key_up = (i == 0) ? "Up" : config_get(config, "key_up", key_default);
- key_default = "Down";
- char* key_down = (i == 0) ? key_default : config_get(config, "key_down", key_default);
- key_default = "Left";
- char* key_left = (i == 0) ? key_default : config_get(config, "key_left", key_default);
- key_default = "Right";
- char* key_right = (i == 0) ? key_default : config_get(config, "key_right", key_default);
- key_default = "Tab";
- char* key_forward = (i == 0) ? key_default : config_get(config, "key_forward", key_default);
- key_default = "Shift-ISO_Left_Tab";
- char* key_backward = (i == 0) ? key_default : config_get(config, "key_backward", key_default);
- key_default = "Return";
- char* key_submit = (i == 0) ? key_default : config_get(config, "key_submit", key_default);
- key_default = "Escape";
- char* key_exit = (i == 0) ? key_default : config_get(config, "key_exit", key_default);
- key_default = "Page_Up";
- char* key_pgup = (i == 0) ? key_default : config_get(config, "key_pgup", key_default);
- key_default = "Page_Down";
- char* key_pgdn = (i == 0) ? key_default : config_get(config, "key_pgdn", key_default);
- key_default = "";
- char* key_expand = (i == 0) ? key_default: config_get(config, "key_expand", key_default);
- key_default = "";
- char* key_hide_search = (i == 0) ? key_default: config_get(config, "key_hide_search", key_default);
- key_default = "Ctrl-c";
- char* key_copy = (i == 0) ? key_default : config_get(config, "key_copy", key_default);
-
- char* keys_custom[CUSTOM_KEY_NUMBER];
- key_default = "";
- for (uint8_t kc_index = 0; kc_index < (sizeof(keys_custom) / sizeof(char*)); kc_index++) {
- char config_entry[15];
- sprintf(config_entry, "key_custom_%d", kc_index);
- keys_custom[kc_index] = (i == 0) ? key_default : config_get(config, config_entry, key_default);
- }
-
- add_key_entry(key_up, move_up);
- add_key_entry(key_down, move_down);
- add_key_entry(key_left, move_left);
- add_key_entry(key_right, move_right);
- add_key_entry(key_forward, move_forward);
- add_key_entry(key_backward, move_backward);
- add_key_entry(key_submit, NULL); //submit is a special case, when a NULL action is encountered submit is used instead
- add_key_entry(key_exit, do_exit);
- add_key_entry(key_pgup, move_pgup);
- add_key_entry(key_pgdn, move_pgdn);
- add_key_entry(key_expand, do_expand);
- add_key_entry(key_hide_search, do_hide_search);
- add_key_entry(key_copy, do_copy);
-
- #define CUSTOM_KEY_FUNC(index) do_custom_key_##index
-
- add_key_entry(keys_custom[0], CUSTOM_KEY_FUNC(0));
- add_key_entry(keys_custom[1], CUSTOM_KEY_FUNC(1));
- add_key_entry(keys_custom[2], CUSTOM_KEY_FUNC(2));
- add_key_entry(keys_custom[3], CUSTOM_KEY_FUNC(3));
- add_key_entry(keys_custom[4], CUSTOM_KEY_FUNC(4));
- add_key_entry(keys_custom[5], CUSTOM_KEY_FUNC(5));
- add_key_entry(keys_custom[6], CUSTOM_KEY_FUNC(6));
- add_key_entry(keys_custom[7], CUSTOM_KEY_FUNC(7));
- add_key_entry(keys_custom[8], CUSTOM_KEY_FUNC(8));
- add_key_entry(keys_custom[9], CUSTOM_KEY_FUNC(9));
- add_key_entry(keys_custom[10], CUSTOM_KEY_FUNC(10));
- add_key_entry(keys_custom[11], CUSTOM_KEY_FUNC(11));
- add_key_entry(keys_custom[12], CUSTOM_KEY_FUNC(12));
- add_key_entry(keys_custom[13], CUSTOM_KEY_FUNC(13));
- add_key_entry(keys_custom[14], CUSTOM_KEY_FUNC(14));
- add_key_entry(keys_custom[15], CUSTOM_KEY_FUNC(15));
- add_key_entry(keys_custom[16], CUSTOM_KEY_FUNC(16));
- add_key_entry(keys_custom[17], CUSTOM_KEY_FUNC(17));
- add_key_entry(keys_custom[18], CUSTOM_KEY_FUNC(18));
- add_key_entry(keys_custom[19], CUSTOM_KEY_FUNC(19));
- }
-
- modes = map_init_void();
-
- if(lines > 0) {
- height = 1;
- }
-
- window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
- gtk_widget_realize(window);
- gtk_widget_set_name(window, "window");
- gtk_window_set_default_size(GTK_WINDOW(window), width, height);
- gtk_window_resize(GTK_WINDOW(window), width, height);
- gtk_window_set_resizable(GTK_WINDOW(window), FALSE);
- gtk_window_set_decorated(GTK_WINDOW(window), FALSE);
-
- if(!normal_window) {
- wl_list_init(&outputs);
- wl = gdk_wayland_display_get_wl_display(gdk_display_get_default());
-
- if(wl == NULL) {
- fprintf(stderr, "Failed to connect to wayland compositor\n");
- wofi_exit(1);
- }
-
- struct wl_registry* registry = wl_display_get_registry(wl);
- struct wl_registry_listener listener = {
- .global = add_interface,
- .global_remove = nop
- };
- wl_registry_add_listener(registry, &listener, NULL);
- wl_display_roundtrip(wl);
-
- if(shell == NULL) {
- fprintf(stderr, "Compositor does not support wlr_layer_shell protocol, switching to normal window mode\n");
- normal_window = true;
- goto normal_win;
- }
-
- struct output_node* node;
- wl_list_for_each(node, &outputs, link) {
- struct zxdg_output_v1* xdg_output = zxdg_output_manager_v1_get_xdg_output(output_manager, node->output);
- struct zxdg_output_v1_listener* xdg_listener = malloc(sizeof(struct zxdg_output_v1_listener));
- xdg_listener->description = nop;
- xdg_listener->done = nop;
- xdg_listener->logical_position = get_output_pos;
- xdg_listener->logical_size = get_output_res;
- xdg_listener->name = get_output_name;
- zxdg_output_v1_add_listener(xdg_output, xdg_listener, node);
- }
- wl_display_roundtrip(wl);
-
- ix = x == NULL ? 0 : strtol(x, NULL, 10);
- iy = y == NULL ? 0 : strtol(y, NULL, 10);
-
- struct wl_output* output = NULL;
- if(global_coords) {
- wl_list_for_each(node, &outputs, link) {
- if(ix >= node->x && ix <= node->width + node->x
- && iy >= node->y && iy <= node->height + node->y) {
- output = node->output;
- ix -= node->x;
- iy -= node->y;
- break;
- }
- }
- } else if(monitor != NULL) {
- wl_list_for_each(node, &outputs, link) {
- if(strcmp(monitor, node->name) == 0) {
- output = node->output;
- break;
- }
- }
- }
-
- GdkWindow* gdk_win = gtk_widget_get_window(window);
-
- gdk_wayland_window_set_use_custom_surface(gdk_win);
- wl_surface = gdk_wayland_window_get_wl_surface(gdk_win);
-
- enum zwlr_layer_shell_v1_layer wlr_layer = ZWLR_LAYER_SHELL_V1_LAYER_TOP;
-
- if(strcmp(layer, "background") == 0) {
- wlr_layer = ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND;
- } else if(strcmp(layer, "bottom") == 0) {
- wlr_layer = ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM;
- } else if(strcmp(layer, "top") == 0) {
- wlr_layer = ZWLR_LAYER_SHELL_V1_LAYER_TOP;
- } else if(strcmp(layer, "overlay") == 0) {
- wlr_layer = ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY;
- }
-
- wlr_surface = zwlr_layer_shell_v1_get_layer_surface(shell, wl_surface, output, wlr_layer, "wofi");
- setup_surface(wlr_surface);
- struct zwlr_layer_surface_v1_listener* surface_listener = malloc(sizeof(struct zwlr_layer_surface_v1_listener));
- surface_listener->configure = config_surface;
- surface_listener->closed = nop;
- zwlr_layer_surface_v1_add_listener(wlr_surface, surface_listener, NULL);
- wl_surface_commit(wl_surface);
- wl_display_roundtrip(wl);
- }
-
- normal_win:
-
- outer_box = gtk_box_new(outer_orientation, 0);
- gtk_widget_set_name(outer_box, "outer-box");
- gtk_container_add(GTK_CONTAINER(window), outer_box);
- entry = gtk_search_entry_new();
- g_signal_connect(entry, "size-allocate", G_CALLBACK(widget_allocate), NULL);
-
- gtk_widget_set_name(entry, "input");
- gtk_entry_set_placeholder_text(GTK_ENTRY(entry), prompt);
- gtk_container_add(GTK_CONTAINER(outer_box), entry);
-
- if(search != NULL) {
- gtk_entry_set_text(GTK_ENTRY(entry), search);
- }
-
- if(password_char != NULL) {
- gtk_entry_set_visibility(GTK_ENTRY(entry), FALSE);
- gtk_entry_set_invisible_char(GTK_ENTRY(entry), password_char[0]);
- }
-
- scroll = gtk_scrolled_window_new(NULL, NULL);
- gtk_widget_set_name(scroll, "scroll");
- gtk_container_add(GTK_CONTAINER(outer_box), scroll);
- if(hide_scroll) {
- gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll), GTK_POLICY_EXTERNAL, GTK_POLICY_EXTERNAL);
- }
-
- inner_box = gtk_flow_box_new();
- gtk_flow_box_set_selection_mode(GTK_FLOW_BOX(inner_box), GTK_SELECTION_BROWSE);
- gtk_flow_box_set_max_children_per_line(GTK_FLOW_BOX(inner_box), columns);
- gtk_orientable_set_orientation(GTK_ORIENTABLE(inner_box), orientation);
- gtk_widget_set_halign(inner_box, halign);
- gtk_widget_set_valign(inner_box, valign);
-
- gtk_widget_set_name(inner_box, "inner-box");
- gtk_flow_box_set_activate_on_single_click(GTK_FLOW_BOX(inner_box), single_click);
-
- GtkWidget* wrapper_box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
- gtk_box_set_homogeneous(GTK_BOX(wrapper_box), TRUE);
- gtk_container_add(GTK_CONTAINER(wrapper_box), inner_box);
- gtk_container_add(GTK_CONTAINER(scroll), wrapper_box);
-
- gtk_flow_box_set_filter_func(GTK_FLOW_BOX(inner_box), do_filter, NULL, NULL);
- gtk_flow_box_set_sort_func(GTK_FLOW_BOX(inner_box), do_sort, NULL, NULL);
-
- g_signal_connect(inner_box, "child-activated", G_CALLBACK(activate_item), NULL);
- g_signal_connect(inner_box, "selected-children-changed", G_CALLBACK(select_item), NULL);
- g_signal_connect(entry, "activate", G_CALLBACK(activate_search), NULL);
- g_signal_connect(window, "key-press-event", G_CALLBACK(key_press), NULL);
- g_signal_connect(window, "focus-in-event", G_CALLBACK(focus), NULL);
- g_signal_connect(window, "focus-out-event", G_CALLBACK(focus), NULL);
- g_signal_connect(entry, "focus-in-event", G_CALLBACK(focus_entry), NULL);
- g_signal_connect(entry, "focus-out-event", G_CALLBACK(focus_entry), NULL);
- g_signal_connect(window, "destroy", G_CALLBACK(do_exit), NULL);
-
- dbus = g_dbus_proxy_new_for_bus_sync(G_BUS_TYPE_SESSION, G_DBUS_PROXY_FLAGS_NONE, NULL, "sm.puri.OSK0", "/sm/puri/OSK0", "sm.puri.OSK0", NULL, NULL);
-
- gdk_threads_add_timeout(filter_rate, do_search, NULL);
-
-
- bool width_percent = strchr(width_str, '%') != NULL;
- bool height_percent = strchr(height_str, '%') != NULL && lines == 0;
- if(width_percent || height_percent) {
- static char* geo_str[2];
- geo_str[0] = width_str;
- geo_str[1] = height_str;
- gdk_threads_add_timeout(25, do_percent_size_first, geo_str);
- }
-
- gdk_threads_add_timeout(5, hide_search_first, NULL);
-
- wl_list_init(&mode_list);
-
- pthread_create(&mode_thread, NULL, start_mode_thread, mode);
-
- gdk_threads_add_idle(insert_all_widgets, &mode_list);
-
- gtk_window_set_title(GTK_WINDOW(window), prompt);
- gtk_widget_show_all(window);
-
- atexit(on_exit_set_custom_key_return_code);
-}