diff --git a/.gitignore b/.gitignore index 9c0b786da..ec72b01fc 100644 --- a/.gitignore +++ b/.gitignore @@ -11,11 +11,17 @@ doc/*.html Makefile CMakeCache.txt CMakeFiles +cmake_install.cmake +cmake_uninstall.cmake +CPackConfig.cmake +CPackSourceConfig.cmake + data/convertconf.h data/defconfig.h *.so *.a /config.h +/build.h # Compiler cache .cache diff --git a/3rdparty/toluapp/.gitignore b/3rdparty/toluapp/.gitignore index 567609b12..aa2884da8 100644 --- a/3rdparty/toluapp/.gitignore +++ b/3rdparty/toluapp/.gitignore @@ -1 +1,4 @@ build/ + +# ignore generated Makefile; keep stub +Makefile diff --git a/cmake/ConkyBuildOptions.cmake b/cmake/ConkyBuildOptions.cmake index 610ea8454..06cf0fba9 100644 --- a/cmake/ConkyBuildOptions.cmake +++ b/cmake/ConkyBuildOptions.cmake @@ -193,8 +193,8 @@ dependent_option(BUILD_XSHAPE "Enable Xshape support" true "BUILD_X11" false "Xshape support requires X11") dependent_option(BUILD_XINPUT "Build Xinput 2 support" true - "BUILD_X11;BUILD_MOUSE_EVENTS" false - "Xinput 2 support requires X11 and BUILD_MOUSE_EVENTS enabled") + "BUILD_X11" false + "Xinput 2 support requires X11") # if we build with any GUI support if(BUILD_X11) @@ -206,8 +206,8 @@ if(BUILD_WAYLAND) endif(BUILD_WAYLAND) dependent_option(BUILD_MOUSE_EVENTS "Enable mouse event support" true - "BUILD_WAYLAND OR OWN_WINDOW" false - "Mouse event support requires Wayland or OWN_WINDOW enabled") + "BUILD_WAYLAND OR BUILD_X11" false + "Mouse event support requires Wayland or X11 enabled") # Lua library options dependent_option(BUILD_LUA_CAIRO "Build cairo bindings for Lua" false @@ -247,9 +247,11 @@ option(BUILD_IRC "Enable if you want IRC support" false) option(BUILD_HTTP "Enable if you want HTTP support" false) -if(BUILD_HTTP) +if(NOT BUILD_HTTP) set(HTTPPORT "10080" CACHE STRING "Port to use for out_to_http") -endif(BUILD_HTTP) +else(NOT BUILD_HTTP) + set(HTTPPORT "10080") +endif(NOT BUILD_HTTP) option(BUILD_ICONV "Enable iconv support" false) diff --git a/data/conky-dfly-smp.conf b/data/conky-dfly-smp.conf index fac3afb04..09d7918b0 100644 --- a/data/conky-dfly-smp.conf +++ b/data/conky-dfly-smp.conf @@ -10,7 +10,10 @@ -- -- For more on Lua, see: -- https://www.lua.org/pil/contents.html +-- +-- Conky Lua API: https://conky.cc/lua +-- Configuration settings: https://conky.cc/config_settings conky.config = { alignment = 'bottom_left', background = false, @@ -36,7 +39,8 @@ conky.config = { extra_newline = false, own_window = false, own_window_class = 'Conky', - own_window_type = 'desktop', + own_window_type = 'normal', + own_window_hints = 'undecorated,sticky,below,skip_taskbar,skip_pager', stippled_borders = 0, update_interval = 3.0, uppercase = false, @@ -45,6 +49,7 @@ conky.config = { show_graph_range = false } +-- Variables: https://conky.cc/variables conky.text = [[ $sysname $version on $machine $hr diff --git a/data/conky.conf b/data/conky.conf index fc341baaa..ed269e96f 100644 --- a/data/conky.conf +++ b/data/conky.conf @@ -10,7 +10,10 @@ -- -- For more on Lua, see: -- https://www.lua.org/pil/contents.html +-- +-- Conky Lua API: https://conky.cc/lua +-- Configuration settings: https://conky.cc/config_settings conky.config = { alignment = 'top_left', background = false, @@ -39,7 +42,8 @@ conky.config = { out_to_x = true, own_window = true, own_window_class = 'Conky', - own_window_type = 'desktop', + own_window_type = 'normal', + own_window_hints = 'undecorated,sticky,below,skip_taskbar,skip_pager', show_graph_range = false, show_graph_scale = false, stippled_borders = 0, @@ -49,6 +53,7 @@ conky.config = { use_xft = true, } +-- Variables: https://conky.cc/variables conky.text = [[ ${color grey}Info:$color ${scroll 32 Conky $conky_version - $sysname $nodename $kernel $machine} $hr diff --git a/data/conky_no_x11.conf b/data/conky_no_x11.conf index 4246daad9..4ea6e13c0 100644 --- a/data/conky_no_x11.conf +++ b/data/conky_no_x11.conf @@ -10,7 +10,10 @@ -- -- For more on Lua, see: -- https://www.lua.org/pil/contents.html +-- +-- Conky Lua API: https://conky.cc/lua +-- Configuration settings: https://conky.cc/config_settings conky.config = { background = false, cpu_avg_samples = 2, @@ -22,6 +25,7 @@ conky.config = { use_spacer = 'none', }; +-- Variables: https://conky.cc/variables conky.text = [[${scroll 16 $nodename - $sysname $kernel on $machine | } Uptime: $uptime diff --git a/doc/config_settings.yaml b/doc/config_settings.yaml index 7d67dbcee..7cb8d8dc6 100644 --- a/doc/config_settings.yaml +++ b/doc/config_settings.yaml @@ -27,10 +27,38 @@ desc: |- values: - name: alignment desc: |- - Aligned position on screen, may be top_left, top_right, - top_middle, bottom_left, bottom_right, bottom_middle, middle_left, - middle_middle, middle_right, or none (also can be abbreviated as tl, - tr, tm, bl, br, bm, ml, mm, mr). See also gap_x and gap_y. + Aligned position on screen, may be `none` or one of: + + + + + + + + + + + + + + + + + +
top_left (or tl)top_middle (or tm)top_right (or tr)
middle_left (or ml)middle_middle (or mm)middle_right (or mr)
bottom_left (or bl)bottom_middle (or bm)bottom_right (or br)
+ + In case of `panel` and `dock` windows, it might make more sense to use one + of the following aliases: + + | Alias | Value | + |:------:|:-------------:| + | `top` | `top_middle` | + | `left` | `middle_left` | + |`right` |`middle_right` | + |`bottom`|`bottom_middle`| + |`center`|`middle_middle`| + + See also `gap_x` and `gap_y` settings. - name: append_file desc: Append the file given as argument. - name: background @@ -437,7 +465,7 @@ values: default: false - name: own_window_type desc: |- - If own_window is set, under X11 you can specify type of window conky + If `own_window` is set, under X11 you can specify type of window conky displayed as: - `normal` mode makes conky show as normal window. This mode can be @@ -464,6 +492,7 @@ values: panels/windows as those will cover conky. `own_window_hints` are ignored for `override` windows. + To make conky mount on root window, set `own_window` to `false`. default: normal args: - (normal|desktop|dock|panel|utility|override) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d2303d616..e1d1c9143 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -119,14 +119,6 @@ set(conky_sources display-console.hh display-file.cc display-file.hh - display-ncurses.cc - display-ncurses.hh - display-http.cc - display-http.hh - display-x11.cc - display-x11.hh - display-wayland.cc - display-wayland.hh lua-config.cc lua-config.hh setting.cc @@ -236,8 +228,23 @@ if(BUILD_PORT_MONITORS) set(optional_sources ${optional_sources} ${port_monitors}) endif(BUILD_PORT_MONITORS) +if(BUILD_HTTP) + set(http + display-http.cc + display-http.hh + ) + set(optional_sources ${optional_sources} ${http}) +endif(BUILD_HTTP) + if(BUILD_X11) - set(x11 x11.cc x11.h) + set(x11 + display-x11.cc + display-x11.hh + x11-settings.cc + x11-settings.h + x11.cc + x11.h + ) set(optional_sources ${optional_sources} ${x11}) endif(BUILD_X11) @@ -245,14 +252,22 @@ if(BUILD_GUI) set(gui fonts.cc fonts.h gui.cc gui.h) set(optional_sources ${optional_sources} ${gui}) - if(BUILD_MOUSE_EVENTS) + if(BUILD_MOUSE_EVENTS OR BUILD_XINPUT) set(mouse_events mouse-events.cc mouse-events.h) set(optional_sources ${optional_sources} ${mouse_events}) - endif(BUILD_MOUSE_EVENTS) + endif(BUILD_MOUSE_EVENTS OR BUILD_XINPUT) endif(BUILD_GUI) + if(BUILD_WAYLAND) - set(wl_srcs wl.cc wl.h xdg-shell-protocol.c wlr-layer-shell-protocol.c) + set(wl_srcs + wl.cc + wl.h + display-wayland.cc + display-wayland.hh + xdg-shell-protocol.c + wlr-layer-shell-protocol.c + ) set(optional_sources ${optional_sources} ${wl_srcs}) # generate protocol implementations @@ -324,7 +339,12 @@ if(BUILD_ICONV) endif(BUILD_ICONV) if(BUILD_NCURSES) - set(ncurses_srcs nc.cc nc.h) + set(ncurses_srcs + nc.cc + nc.h + display-ncurses.cc + display-ncurses.hh + ) set(optional_sources ${optional_sources} ${ncurses_srcs}) endif(BUILD_NCURSES) diff --git a/src/colours.cc b/src/colours.cc index f40ae3ace..0de586e18 100644 --- a/src/colours.cc +++ b/src/colours.cc @@ -26,25 +26,21 @@ * along with this program. If not, see . * */ -#include "conky.h" -#include "gui.h" + +#include "colours.h" + #include "logging.h" -#include "x11-color.h" + +#include #ifdef BUILD_X11 -std::unordered_map Colour::x11_pixels; +#include +#include +#include #endif /* BUILD_X11 */ -static int hex_nibble_value(char c) { - if (c >= '0' && c <= '9') { - return c - '0'; - } else if (c >= 'a' && c <= 'f') { - return c - 'a' + 10; - } else if (c >= 'A' && c <= 'F') { - return c - 'A' + 10; - } - return -1; -} +// sourced from X11, doesn't actually need X11 +#include "x11-color.h" Colour Colour::from_argb32(uint32_t argb) { Colour out; @@ -55,29 +51,91 @@ Colour Colour::from_argb32(uint32_t argb) { return out; } -Colour error_colour{0xff, 0x00, 0x00, 0xff}; +#ifdef BUILD_X11 +unsigned long Colour::to_x11_color(Display *display, int screen, + bool transparency, bool premultiply) { + static std::unordered_map x11_pixels; -Colour parse_color(const char *name) { + if (display == nullptr) { + /* cannot work if display is not open */ + return 0; + } + + unsigned long pixel; + + /* Either get a cached X11 pixel or allocate one */ + if (auto pixel_iter = x11_pixels.find(*this); + pixel_iter != x11_pixels.end()) { + pixel = pixel_iter->second; + } else { + XColor xcolor{}; + xcolor.red = this->red * 257; + xcolor.green = this->green * 257; + xcolor.blue = this->blue * 257; + if (XAllocColor(display, DefaultColormap(display, screen), &xcolor) == 0) { + // NORM_ERR("can't allocate X color"); + return 0; + } + + /* Save pixel value in the cache to avoid reallocating it */ + x11_pixels[*this] = xcolor.pixel; + pixel = static_cast(xcolor.pixel); + } + + pixel &= 0xffffff; +#ifdef BUILD_ARGB + if (transparency) { + if (premultiply) + pixel = (red * alpha / 255) << 16 | (green * alpha / 255) << 8 | + (blue * alpha / 255); + pixel |= ((unsigned long)alpha << 24); + } +#endif /* BUILD_ARGB */ + return pixel; +} +#endif /* BUILD_X11 */ + +std::optional parse_color_name(const std::string &name) { unsigned short r, g, b; - size_t len = strlen(name); + size_t len = name.length(); // Parse X11 color names. - if (OsLookupColor(-1, name, len, &r, &g, &b)) { - Colour out = {(uint8_t)r, (uint8_t)g, (uint8_t)b, 0xff}; - return out; + if (OsLookupColor(name.c_str(), len, &r, &g, &b)) { + return Colour{(uint8_t)r, (uint8_t)g, (uint8_t)b, 0xff}; + } else { + return std::nullopt; } +} - // Remove a leading '#' if present. +std::optional parse_hex_color(const std::string &color) { + const char *name = color.c_str(); + size_t len = color.length(); + // Skip a leading '#' if present. if (name[0] == '#') { name++; len--; } - unsigned char argb[4] = {0xff, 0, 0, 0}; + static auto hex_nibble_value = [](char c) { + if (c >= '0' && c <= '9') { + return c - '0'; + } else if (c >= 'a' && c <= 'f') { + return c - 'a' + 10; + } else if (c >= 'A' && c <= 'F') { + return c - 'A' + 10; + } + return -1; + }; + const auto none = [&]() { + NORM_ERR("can't parse hex color '%s' (%d)", name, len); + return std::nullopt; + }; + + uint8_t argb[4] = {0xff, 0, 0, 0}; if (len == 3 || len == 4) { bool skip_alpha = (len == 3); for (size_t i = 0; i < len; i++) { int nib = hex_nibble_value(name[i]); - if (nib < 0) { goto err; } + if (nib < 0) { return none(); } // Duplicate the nibble, so "#abc" -> 0xaa, 0xbb, 0xcc int val = (nib << 4) + nib; @@ -88,27 +146,35 @@ Colour parse_color(const char *name) { for (size_t i = 0; i + 1 < len; i += 2) { int nib1 = hex_nibble_value(name[i]); int nib2 = hex_nibble_value(name[i + 1]); - if (nib1 < 0 || nib2 < 0) { goto err; } + if (nib1 < 0 || nib2 < 0) { return none(); } int val = (nib1 << 4) + nib2; argb[skip_alpha + i / 2] = val; } } else { - goto err; + return none(); } - Colour out; - out.alpha = argb[0]; - out.red = argb[1]; - out.green = argb[2]; - out.blue = argb[3]; - return out; - -err: - NORM_ERR("can't parse X color '%s' (%d)", name, len); - return error_colour; + return Colour(argb[1], argb[2], argb[3], argb[0]); } -Colour parse_color(const std::string &colour) { - return parse_color(colour.c_str()); +Colour parse_color(const std::string &color) { + std::optional result; + +#define TRY_PARSER(name) \ + std::optional value_##name = name(color); \ + if (value_##name.has_value()) { return value_##name.value(); } + + std::optional value_parse_color_name = parse_color_name(color); + if (value_parse_color_name.has_value()) { + return value_parse_color_name.value(); + } + std::optional value_parse_hex_color = parse_hex_color(color); + if (value_parse_hex_color.has_value()) { + return value_parse_hex_color.value(); + } + +#undef TRY_PARSER + + return ERROR_COLOUR; } diff --git a/src/colours.h b/src/colours.h index 7b2d2cfe2..a6d526816 100644 --- a/src/colours.h +++ b/src/colours.h @@ -26,31 +26,50 @@ * along with this program. If not, see . * */ -#pragma once -#include +#ifndef _COLOURS_H_ +#define _COLOURS_H_ + +#include "config.h" + #include #include #include #include #include + #ifdef BUILD_X11 -#include "x11.h" +#include #endif /* BUILD_X11 */ struct Colour { uint8_t red; uint8_t green; uint8_t blue; - uint8_t alpha; + uint8_t alpha = 0xff; public: + Colour() = default; + Colour(uint8_t r, uint8_t g, uint8_t b, uint8_t a = UINT8_MAX) + : red(r), green(g), blue(b), alpha(a) {} + Colour(const Colour &) = default; + Colour(Colour &&) = default; + + void operator=(const Colour &c) { + red = c.red; + green = c.green; + blue = c.blue; + alpha = c.alpha; + } + // Compare two instances. bool operator==(const Colour &c) const { return c.red == red && c.green == green && c.blue == blue && c.alpha == alpha; } + uint8_t *data() { return reinterpret_cast(this); } + // Express the color as a 32-bit ARGB integer (alpha in MSB). uint32_t to_argb32(void) const { uint32_t out; @@ -61,58 +80,20 @@ struct Colour { // Construct from a 32-bit ARGB integer (alpha in MSB). static Colour from_argb32(uint32_t argb); -#ifdef BUILD_X11 class Hash { public: size_t operator()(const Colour &c) const { return c.to_argb32(); } }; - static std::unordered_map x11_pixels; +#ifdef BUILD_X11 unsigned long to_x11_color(Display *display, int screen, - bool premultiply = false) { - if (display == nullptr) { - /* cannot work if display is not open */ - return 0; - } - - unsigned long pixel; - - /* Either get a cached X11 pixel or allocate one */ - if (auto pixel_iter = x11_pixels.find(*this); - pixel_iter != x11_pixels.end()) { - pixel = pixel_iter->second; - } else { - XColor xcolor{}; - xcolor.red = red * 257; - xcolor.green = green * 257; - xcolor.blue = blue * 257; - if (XAllocColor(display, DefaultColormap(display, screen), &xcolor) == - 0) { - // NORM_ERR("can't allocate X color"); - return 0; - } - - /* Save pixel value in the cache to avoid reallocating it */ - x11_pixels[*this] = xcolor.pixel; - pixel = static_cast(xcolor.pixel); - } - - pixel &= 0xffffff; -#ifdef BUILD_ARGB - if (have_argb_visual) { - if (premultiply) - pixel = (red * alpha / 255) << 16 | (green * alpha / 255) << 8 | - (blue * alpha / 255); - pixel |= ((unsigned long)alpha << 24); - } -#endif /* BUILD_ARGB */ - return pixel; - } + bool transparency = false, + bool premultiply = false); #endif /* BUILD_X11 */ }; -extern Colour error_colour; +const Colour ERROR_COLOUR = Colour{UINT8_MAX, 0, 0, UINT8_MAX}; + +Colour parse_color(const std::string &color); -Colour parse_color(const std::string &colour); -// XXX: when everyone uses C++ strings, remove this C version -Colour parse_color(const char *); +#endif /* _COLOURS_H_ */ diff --git a/src/conky-imlib2.cc b/src/conky-imlib2.cc index af4728448..042b043d4 100644 --- a/src/conky-imlib2.cc +++ b/src/conky-imlib2.cc @@ -22,8 +22,9 @@ */ #include "conky-imlib2.h" -#include "config.h" -#include "conky.h" + +#include "common.h" +#include "display-output.hh" #include "logging.h" #include "text_object.h" @@ -47,22 +48,24 @@ struct image_list_s { }; struct image_list_s *image_list_start, *image_list_end; +std::array, 100> saved_coordinates; /* areas to update */ Imlib_Updates updates, current_update; /* our virtual framebuffer image we draw into */ Imlib_Image buffer, image; -namespace { -Imlib_Context context; - conky::range_config_setting imlib_cache_flush_interval( "imlib_cache_flush_interval", 0, std::numeric_limits::max(), 0, true); -unsigned int cimlib_cache_flush_last = 0; +conky::simple_config_setting imlib_draw_blended("draw_blended", true, + true); -conky::simple_config_setting draw_blended("draw_blended", true, true); +namespace { +Imlib_Context context; + +unsigned int cimlib_cache_flush_last = 0; } // namespace void imlib_cache_size_setting::lua_setter(lua::state &l, bool init) { @@ -162,8 +165,9 @@ void cimlib_add_image(const char *args) { tmp += 3; int i; if (sscanf(tmp, "%d", &i) == 1) { - cur->x = get_saved_coordinates_x(i); - cur->y = get_saved_coordinates_y(i); + const auto &coordinates = saved_coordinates.at(static_cast(i)); + cur->x = coordinates[0]; + cur->y = coordinates[1]; } } if (cur->flush_interval < 0) { @@ -237,7 +241,8 @@ static void cimlib_draw_all(int *clip_x, int *clip_y, int *clip_x2, } } -void cimlib_render(int x, int y, int width, int height) { +void cimlib_render(int x, int y, int width, int height, uint32_t flush_interval, + bool draw_blended) { int clip_x = INT_MAX, clip_y = INT_MAX; int clip_x2 = 0, clip_y2 = 0; time_t now; @@ -248,8 +253,8 @@ void cimlib_render(int x, int y, int width, int height) { /* cheque if it's time to flush our cache */ now = time(nullptr); - if ((imlib_cache_flush_interval.get(*state) != 0u) && - now - imlib_cache_flush_interval.get(*state) > cimlib_cache_flush_last) { + if ((flush_interval != 0u) && + now - flush_interval > cimlib_cache_flush_last) { int size = imlib_get_cache_size(); imlib_set_cache_size(0); imlib_set_cache_size(size); @@ -265,7 +270,7 @@ void cimlib_render(int x, int y, int width, int height) { imlib_image_clear(); /* check if we should blend when rendering */ - if (draw_blended.get(*state)) { + if (draw_blended) { /* we can blend stuff now */ imlib_context_set_blend(1); } else { @@ -295,3 +300,5 @@ void cimlib_render(int x, int y, int width, int height) { void print_image_callback(struct text_object *obj, char *, unsigned int) { cimlib_add_image(obj->data.s); } + +imlib_cache_size_setting imlib_cache_size; diff --git a/src/conky-imlib2.h b/src/conky-imlib2.h index 4484dc855..11a166979 100644 --- a/src/conky-imlib2.h +++ b/src/conky-imlib2.h @@ -24,17 +24,24 @@ #ifndef _CONKY_IMBLI2_H_ #define _CONKY_IMBLI2_H_ -#include "conky.h" +#include "setting.hh" +#include "text_object.h" + +#include #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wvariadic-macros" #include #pragma GCC diagnostic pop +using saved_coordinates_t = std::array, 100>; +extern saved_coordinates_t saved_coordinates; + void cimlib_add_image(const char *args); void cimlib_set_cache_size(long size); void cimlib_set_cache_flush_interval(long interval); -void cimlib_render(int x, int y, int width, int height); +void cimlib_render(int x, int y, int width, int height, uint32_t flush_interval, + bool draw_blended); void cimlib_cleanup(void); void print_image_callback(struct text_object *, char *, unsigned int); @@ -53,4 +60,7 @@ class imlib_cache_size_setting 4096 * 1024, true) {} }; +extern conky::range_config_setting imlib_cache_flush_interval; +extern conky::simple_config_setting imlib_draw_blended; + #endif /* _CONKY_IMBLI2_H_ */ diff --git a/src/conky.cc b/src/conky.cc index b2dbc4f66..0681782b6 100644 --- a/src/conky.cc +++ b/src/conky.cc @@ -28,6 +28,9 @@ */ #include "conky.h" + +#include "config.h" + #include #include #include @@ -40,24 +43,37 @@ #include #include #include -#include "common.h" -#include "config.h" -#include "text_object.h" -#ifdef HAVE_DIRENT_H -#include -#endif /* HAVE_DIRENT_H */ + +#include +#include +#include +#include #include +#include #include +#include + #ifdef HAVE_SYS_INOTIFY_H #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wc99-extensions" #include #pragma clang diagnostic pop #endif /* HAVE_SYS_INOTIFY_H */ + +#ifdef HAVE_DIRENT_H +#include +#endif /* HAVE_DIRENT_H */ + +#include "common.h" +#include "text_object.h" + #ifdef BUILD_WAYLAND #include "wl.h" #endif /* BUILD_WAYLAND */ + #ifdef BUILD_X11 +#include "x11.h" + #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wvariadic-macros" #include @@ -69,21 +85,18 @@ #include "conky-imlib2.h" #endif /* BUILD_IMLIB2 */ #endif /* BUILD_X11 */ + #ifdef BUILD_NCURSES #include -#endif -#include -#include -#include -#include -#include -#include -#if defined BUILD_RSS -#include -#endif +#endif /* BUILD_NCURSES */ + #ifdef BUILD_CURL #include -#endif +#endif /* BUILD_CURL */ + +#ifdef BUILD_RSS +#include +#endif /* BUILD_RSS */ /* local headers */ #include "colours.h" @@ -97,7 +110,7 @@ #include "fs.h" #ifdef BUILD_ICONV #include "iconv_tools.h" -#endif +#endif /* BUILD_ICONV */ #include "llua.h" #include "logging.h" #include "mail.h" @@ -108,12 +121,13 @@ #include "template.h" #include "timeinfo.h" #include "top.h" + #ifdef BUILD_MYSQL #include "mysql.h" #endif /* BUILD_MYSQL */ #ifdef BUILD_NVIDIA #include "nvidia.h" -#endif +#endif /* BUILD_NVIDIA */ #ifdef BUILD_CURL #include "ccurl_thread.h" #endif /* BUILD_CURL */ @@ -394,18 +408,6 @@ int calc_text_width(const char *s) { return slen; } -int dpi_scale(int value) { -#ifdef BUILD_GUI - if (display_output()) { - return display_output()->dpi_scale(value); - } else { - return value; - } -#else /* BUILD_GUI */ - return value; -#endif /* BUILD_GUI */ -} - #ifdef BUILD_GUI conky::gradient_factory *create_gradient_factory(int width, Colour first_colour, Colour last_colour) { @@ -766,7 +768,7 @@ void remove_first_char(char *s) { memmove(s, s + 1, strlen(s)); } static int get_string_width_special(char *s, int special_index) { char *p, *final; - special_t *current = specials; + special_node *current = specials; int width = 0; long i; @@ -789,22 +791,23 @@ static int get_string_width_special(char *s, int special_index) { /*for (i = 0; i < static_cast(strlen(p)); i++) { *(p + i) = *(p + i + 1); }*/ - if (current->type == GRAPH || current->type == GAUGE || - current->type == BAR) { + if (current->type == text_node_t::GRAPH || + current->type == text_node_t::GAUGE || + current->type == text_node_t::BAR) { width += current->width; } - if (current->type == FONT) { + if (current->type == text_node_t::FONT) { // put all following text until the next fontchange/stringend in // influenced_by_font but do not include specials char *influenced_by_font = strdup(p); - special_t *current_after_font = current; + special_node *current_after_font = current; // influenced_by_font gets special chars removed, so after this loop i // counts the number of letters (not special chars) influenced by font for (i = 0; influenced_by_font[i] != 0; i++) { if (influenced_by_font[i] == SPECIAL_CHAR) { // remove specials and stop at fontchange current_after_font = current_after_font->next; - if (current_after_font->type == FONT) { + if (current_after_font->type == text_node_t::FONT) { influenced_by_font[i] = 0; break; } @@ -867,50 +870,34 @@ void update_text_area() { alignment align = text_alignment.get(*state); /* get text position on workarea */ - switch (align) { - case TOP_LEFT: - case TOP_RIGHT: - case TOP_MIDDLE: + switch (vertical_alignment(align)) { + case axis_align::START: y = workarea[1] + dpi_scale(gap_y.get(*state)); break; - - case BOTTOM_LEFT: - case BOTTOM_RIGHT: - case BOTTOM_MIDDLE: + case axis_align::END: default: y = workarea[3] - text_height - dpi_scale(gap_y.get(*state)); break; - - case MIDDLE_LEFT: - case MIDDLE_RIGHT: - case MIDDLE_MIDDLE: + case axis_align::MIDDLE: y = workarea[1] + (workarea[3] - workarea[1]) / 2 - text_height / 2 - dpi_scale(gap_y.get(*state)); break; } - switch (align) { - case TOP_LEFT: - case BOTTOM_LEFT: - case MIDDLE_LEFT: + switch (horizontal_alignment(align)) { + case axis_align::START: default: x = workarea[0] + dpi_scale(gap_x.get(*state)); break; - - case TOP_RIGHT: - case BOTTOM_RIGHT: - case MIDDLE_RIGHT: + case axis_align::END: x = workarea[2] - text_width - dpi_scale(gap_x.get(*state)); break; - - case TOP_MIDDLE: - case BOTTOM_MIDDLE: - case MIDDLE_MIDDLE: + case axis_align::MIDDLE: x = workarea[0] + (workarea[2] - workarea[0]) / 2 - text_width / 2 - dpi_scale(gap_x.get(*state)); break; } #ifdef OWN_WINDOW - if (align == NONE) { // Let the WM manage the window + if (align == alignment::NONE) { // Let the WM manage the window x = window.x; y = window.y; @@ -941,20 +928,14 @@ static int cur_x, cur_y; /* current x and y for drawing */ #endif // draw_mode also without BUILD_GUI because we only need to print to stdout with // FG -static int draw_mode; /* FG, BG or OUTLINE */ +static draw_mode_t draw_mode; /* FG, BG or OUTLINE */ #ifdef BUILD_GUI /*static*/ Colour current_color; -static int saved_coordinates_x[100]; -static int saved_coordinates_y[100]; - -int get_saved_coordinates_x(int i) { return saved_coordinates_x[i]; } -int get_saved_coordinates_y(int i) { return saved_coordinates_y[i]; } - static int text_size_updater(char *s, int special_index) { int w = 0; char *p; - special_t *current = specials; + special_node *current = specials; for (int i = 0; i < special_index; i++) { current = current->next; } @@ -969,26 +950,27 @@ static int text_size_updater(char *s, int special_index) { w += get_string_width(s); *p = SPECIAL_CHAR; - if (current->type == BAR || current->type == GAUGE || - current->type == GRAPH) { + if (current->type == text_node_t::BAR || + current->type == text_node_t::GAUGE || + current->type == text_node_t::GRAPH) { w += current->width; if (current->height > last_font_height) { last_font_height = current->height; last_font_height += font_height(); } - } else if (current->type == OFFSET) { + } else if (current->type == text_node_t::OFFSET) { if (current->arg > 0) { w += current->arg; } - } else if (current->type == VOFFSET) { + } else if (current->type == text_node_t::VOFFSET) { last_font_height += current->arg; - } else if (current->type == GOTO) { + } else if (current->type == text_node_t::GOTO) { if (current->arg > cur_x) { w = static_cast(current->arg); } - } else if (current->type == TAB) { + } else if (current->type == text_node_t::TAB) { int start = current->arg; int step = current->width; if ((step == 0) || step < 0) { step = 10; } w += step - (cur_x - text_start_x - start) % step; - } else if (current->type == FONT) { + } else if (current->type == text_node_t::FONT) { selected_font = current->font_added; if (font_height() > last_font_height) { last_font_height = font_height(); @@ -1033,7 +1015,7 @@ static void draw_string(const char *s) { #ifdef BUILD_GUI width_of_s = get_string_width(s); #endif /* BUILD_GUI */ - if (draw_mode == FG) { + if (draw_mode == draw_mode_t::FG) { for (auto output : display_outputs()) if (!output->graphical()) output->draw_string(s, 0); } @@ -1163,11 +1145,11 @@ int draw_each_line_inner(char *s, int special_index, int last_special_applied) { s = p + 1; } /* draw special */ - special_t *current = specials; + special_node *current = specials; for (int i = 0; i < special_index; i++) { current = current->next; } switch (current->type) { #ifdef BUILD_GUI - case HORIZONTAL_LINE: + case text_node_t::HORIZONTAL_LINE: if (display_output() && display_output()->graphical()) { int h = current->height; int mid = font_ascent() / 2; @@ -1183,7 +1165,7 @@ int draw_each_line_inner(char *s, int special_index, int last_special_applied) { } break; - case STIPPLED_HR: + case text_node_t::STIPPLED_HR: if (display_output() && display_output()->graphical()) { int h = current->height; char tmp_s = current->arg; @@ -1201,7 +1183,7 @@ int draw_each_line_inner(char *s, int special_index, int last_special_applied) { } break; - case BAR: + case text_node_t::BAR: if (display_output() && display_output()->graphical()) { int h, by; double bar_usage, scale; @@ -1229,7 +1211,7 @@ int draw_each_line_inner(char *s, int special_index, int last_special_applied) { } break; - case GAUGE: /* new GAUGE */ + case text_node_t::GAUGE: /* new GAUGE */ if (display_output() && display_output()->graphical()) { int h, by = 0; Colour last_colour = current_color; @@ -1279,7 +1261,7 @@ int draw_each_line_inner(char *s, int special_index, int last_special_applied) { } break; - case GRAPH: + case text_node_t::GRAPH: if (display_output() && display_output()->graphical()) { int h, by, i = 0, j = 0; int colour_idx = 0; @@ -1415,7 +1397,7 @@ int draw_each_line_inner(char *s, int special_index, int last_special_applied) { } break; - case FONT: + case text_node_t::FONT: if (display_output() && display_output()->graphical()) { int old = font_ascent(); @@ -1431,41 +1413,42 @@ int draw_each_line_inner(char *s, int special_index, int last_special_applied) { } break; #endif /* BUILD_GUI */ - case FG: - if (draw_mode == FG) { + case text_node_t::FG: + if (draw_mode == draw_mode_t::FG) { set_foreground_color(Colour::from_argb32(current->arg)); } break; #ifdef BUILD_GUI - case BG: - if (draw_mode == BG) { + case text_node_t::BG: + if (draw_mode == draw_mode_t::BG) { set_foreground_color(Colour::from_argb32(current->arg)); } break; - case OUTLINE: - if (draw_mode == OUTLINE) { + case text_node_t::OUTLINE: + if (draw_mode == draw_mode_t::OUTLINE) { set_foreground_color(Colour::from_argb32(current->arg)); } break; - case OFFSET: + case text_node_t::OFFSET: w += current->arg; break; - case VOFFSET: + case text_node_t::VOFFSET: cur_y += current->arg; break; - case SAVE_COORDINATES: - saved_coordinates_x[static_cast(current->arg)] = - cur_x - text_start_x; - saved_coordinates_y[static_cast(current->arg)] = - cur_y - text_start_y - last_font_height; + case text_node_t::SAVE_COORDINATES: +#ifdef BUILD_IMLIB2 + saved_coordinates[static_cast(current->arg)] = + std::array{cur_x - text_start_x, + cur_y - text_start_y - last_font_height}; +#endif /* BUILD_IMLIB2 */ break; - case TAB: { + case text_node_t::TAB: { int start = current->arg; int step = current->width; @@ -1474,7 +1457,7 @@ int draw_each_line_inner(char *s, int special_index, int last_special_applied) { break; } - case ALIGNR: { + case text_node_t::ALIGNR: { /* TODO: add back in "+ window.border_inner_margin" to the end of * this line? */ int pos_x = text_start_x + text_width - @@ -1491,7 +1474,7 @@ int draw_each_line_inner(char *s, int special_index, int last_special_applied) { break; } - case ALIGNC: { + case text_node_t::ALIGNC: { int pos_x = (text_width) / 2 - get_string_width_special(s, special_index) / 2 - (cur_x - text_start_x); @@ -1507,17 +1490,20 @@ int draw_each_line_inner(char *s, int special_index, int last_special_applied) { break; } #endif /* BUILD_GUI */ - case GOTO: + case text_node_t::GOTO: if (current->arg >= 0) { #ifdef BUILD_GUI cur_x = static_cast(current->arg); // make sure shades are 1 pixel to the right of the text - if (draw_mode == BG) { cur_x++; } + if (draw_mode == draw_mode_t::BG) { cur_x++; } #endif /* BUILD_GUI */ cur_x = static_cast(current->arg); for (auto output : display_outputs()) output->gotox(cur_x); } break; + default: + // do nothing; not a special node or support not enabled + break; } #ifdef BUILD_GUI @@ -1599,7 +1585,9 @@ void draw_stuff() { #ifdef BUILD_IMLIB2 text_offset_x = text_offset_y = 0; - cimlib_render(text_start_x, text_start_y, window.width, window.height); + cimlib_render(text_start_x, text_start_y, window.width, window.height, + imlib_cache_flush_interval.get(*state), + imlib_draw_blended.get(*state)); #endif /* BUILD_IMLIB2 */ for (auto output : display_outputs()) { @@ -1611,7 +1599,7 @@ void draw_stuff() { if (draw_shades.get(*state) && !draw_outline.get(*state)) { text_offset_x = text_offset_y = 1; set_foreground_color(default_shade_color.get(*state)); - draw_mode = BG; + draw_mode = draw_mode_t::BG; draw_text(); text_offset_x = text_offset_y = 0; } @@ -1623,7 +1611,7 @@ void draw_stuff() { for (text_offset_y = -1; text_offset_y < 2; text_offset_y++) { if (text_offset_x == 0 && text_offset_y == 0) { continue; } set_foreground_color(default_outline_color.get(*state)); - draw_mode = OUTLINE; + draw_mode = draw_mode_t::OUTLINE; draw_text(); } } @@ -1637,7 +1625,7 @@ void draw_stuff() { #endif /* BUILD_GUI */ // always draw text - draw_mode = FG; + draw_mode = draw_mode_t::FG; draw_text(); #ifdef BUILD_GUI @@ -1874,10 +1862,10 @@ static void reload_config() { initialisation(argc_copy, argv_copy); } -void free_specials(special_t *¤t) { +void free_specials(special_node *¤t) { if (current != nullptr) { free_specials(current->next); - if (current->type == GRAPH) { free(current->graph); } + if (current->type == text_node_t::GRAPH) { free(current->graph); } delete current; current = nullptr; } diff --git a/src/conky.h b/src/conky.h index 1592a50b4..c7a357248 100644 --- a/src/conky.h +++ b/src/conky.h @@ -32,11 +32,14 @@ #define __STDC_FORMAT_MACROS +#include "config.h" + #include #include /* defines */ #include /* struct uname_s */ #include #include + #include "colours.h" #include "common.h" /* at least for struct dns_data */ #include "luamm.hh" @@ -311,11 +314,6 @@ void set_updatereset(int); int get_updatereset(void); int get_total_updates(void); -int dpi_scale(int value); - -int get_saved_coordinates_x(int); -int get_saved_coordinates_y(int); - /* defined in conky.c */ int spaced_print(char *, int, const char *, int, ...) __attribute__((format(printf, 3, 5))); diff --git a/src/core.cc b/src/core.cc index ad69e21cc..0ce2cbdcb 100644 --- a/src/core.cc +++ b/src/core.cc @@ -27,9 +27,12 @@ * */ +#include "config.h" + /* local headers */ -#include "core.h" #include "algebra.h" +#include "core.h" + #include "bsdapm.h" #include "build.h" #include "colour-settings.h" @@ -40,11 +43,11 @@ #include "exec.h" #include "i8k.h" #include "misc.h" +#include "proc.h" #include "text_object.h" #ifdef BUILD_IMLIB2 #include "conky-imlib2.h" #endif /* BUILD_IMLIB2 */ -#include "proc.h" #ifdef BUILD_MYSQL #include "mysql.h" #endif /* BUILD_MYSQL */ @@ -1893,9 +1896,10 @@ struct text_object *construct_text_object(char *s, const char *arg, long line, obj->callbacks.print = &print_combine; obj->callbacks.free = &free_combine; #ifdef BUILD_NVIDIA - END OBJ_ARG( - nvidia, 0, - "nvidia needs an argument") if (set_nvidia_query(obj, arg, NONSPECIAL)) { + END OBJ_ARG(nvidia, 0, "nvidia needs an argument") if (set_nvidia_query( + obj, arg, + text_node_t:: + NONSPECIAL)) { CRIT_ERR_FREE(obj, free_at_crash, "nvidia: invalid argument" " specified: '%s'", @@ -1905,7 +1909,8 @@ struct text_object *construct_text_object(char *s, const char *arg, long line, obj->callbacks.free = &free_nvidia; END OBJ_ARG( nvidiabar, 0, - "nvidiabar needs an argument") if (set_nvidia_query(obj, arg, BAR)) { + "nvidiabar needs an argument") if (set_nvidia_query(obj, arg, + text_node_t::BAR)) { CRIT_ERR_FREE(obj, free_at_crash, "nvidiabar: invalid argument" " specified: '%s'", @@ -1915,7 +1920,9 @@ struct text_object *construct_text_object(char *s, const char *arg, long line, obj->callbacks.free = &free_nvidia; END OBJ_ARG( nvidiagraph, 0, - "nvidiagraph needs an argument") if (set_nvidia_query(obj, arg, GRAPH)) { + "nvidiagraph needs an argument") if (set_nvidia_query(obj, arg, + text_node_t:: + GRAPH)) { CRIT_ERR_FREE(obj, free_at_crash, "nvidiagraph: invalid argument" " specified: '%s'", @@ -1925,7 +1932,9 @@ struct text_object *construct_text_object(char *s, const char *arg, long line, obj->callbacks.free = &free_nvidia; END OBJ_ARG( nvidiagauge, 0, - "nvidiagauge needs an argument") if (set_nvidia_query(obj, arg, GAUGE)) { + "nvidiagauge needs an argument") if (set_nvidia_query(obj, arg, + text_node_t:: + GAUGE)) { CRIT_ERR_FREE(obj, free_at_crash, "nvidiagauge: invalid argument" " specified: '%s'", diff --git a/src/display-console.cc b/src/display-console.cc index 7e1732351..eb2eeb0df 100644 --- a/src/display-console.cc +++ b/src/display-console.cc @@ -43,9 +43,11 @@ namespace { conky::display_output_console console_output("console"); } // namespace -void init_console_output() {} -namespace priv {} // namespace priv +template <> +void register_output(display_outputs_t &outputs) { + outputs.push_back(&console_output); +} display_output_console::display_output_console(const std::string &name_) : display_output_base(name_) { diff --git a/src/display-file.cc b/src/display-file.cc index 12dbac882..f1ff4c0f1 100644 --- a/src/display-file.cc +++ b/src/display-file.cc @@ -49,9 +49,10 @@ namespace { conky::display_output_file file_output("file"); } // namespace -extern void init_file_output() {} - -namespace priv {} // namespace priv +template <> +void register_output(display_outputs_t &outputs) { + outputs.push_back(&file_output); +} display_output_file::display_output_file(const std::string &name_) : display_output_base(name_) { diff --git a/src/display-http.cc b/src/display-http.cc index 91e0a458b..78bfeee89 100644 --- a/src/display-http.cc +++ b/src/display-http.cc @@ -33,26 +33,20 @@ #include #include -#ifdef BUILD_HTTP #include -#endif /* BUILD_HTTP */ namespace conky { namespace { - -#ifdef BUILD_HTTP conky::display_output_http http_output; -#else -conky::disabled_display_output http_output_disabled("http", "BUILD_HTTP"); -#endif - } // namespace -extern void init_http_output() {} +template <> +void register_output(display_outputs_t &outputs) { + outputs.push_back(&http_output); +} // TODO: cleanup namespace // namespace priv { -#ifdef BUILD_HTTP #ifdef MHD_YES /* older API */ #define MHD_Result int @@ -130,12 +124,8 @@ std::string string_replace_all(std::string original, const std::string &oldpart, return original; } -#endif /* BUILD_HTTP */ - //} // namespace priv -#ifdef BUILD_HTTP - display_output_http::display_output_http() : display_output_base("http") { priority = 0; httpd = NULL; @@ -192,6 +182,4 @@ void display_output_http::draw_string(const char *s, int) { webpage.append("
"); } -#endif /* BUILD_HTTP */ - } // namespace conky diff --git a/src/display-http.hh b/src/display-http.hh index b9d3ad5e9..300028600 100644 --- a/src/display-http.hh +++ b/src/display-http.hh @@ -23,6 +23,8 @@ #ifndef DISPLAY_HTTP_HH #define DISPLAY_HTTP_HH +#include "config.h" + #include #include #include diff --git a/src/display-ncurses.cc b/src/display-ncurses.cc index 86b1722eb..65fc3e5cc 100644 --- a/src/display-ncurses.cc +++ b/src/display-ncurses.cc @@ -35,33 +35,24 @@ #include #include #include -#ifdef BUILD_NCURSES + #include -#endif -#ifdef BUILD_NCURSES extern WINDOW* ncurses_window; -#endif namespace conky { namespace { - -#ifdef BUILD_NCURSES conky::display_output_ncurses ncurses_output; -#else -conky::disabled_display_output ncurses_output_disabled("ncurses", - "BUILD_NCURSES"); -#endif - } // namespace -extern void init_ncurses_output() {} +template <> +void register_output(display_outputs_t& outputs) { + outputs.push_back(&ncurses_output); +} // namespace priv { //} // namespace priv -#ifdef BUILD_NCURSES - #define COLORS_BUILTIN 8 Colour ncurses_colors[COLORS_BUILTIN + COLORS_CUSTOM] = { @@ -96,7 +87,7 @@ Colour from_ncurses(int nccolor) { if (nccolor >= 0 && nccolor < COLORS_BUILTIN + COLORS_CUSTOM) { return ncurses_colors[nccolor]; } - return error_colour; + return ERROR_COLOUR; } display_output_ncurses::display_output_ncurses() @@ -179,7 +170,4 @@ void display_output_ncurses::flush() { refresh(); clear(); } - -#endif /* BUILD_NCURSES */ - } // namespace conky diff --git a/src/display-ncurses.hh b/src/display-ncurses.hh index d7e1f7c34..2d1c1a0b8 100644 --- a/src/display-ncurses.hh +++ b/src/display-ncurses.hh @@ -23,6 +23,8 @@ #ifndef DISPLAY_NCURSES_HH #define DISPLAY_NCURSES_HH +#include "config.h" + #include #include #include diff --git a/src/display-output.cc b/src/display-output.cc index fe9587419..fafcf8c45 100644 --- a/src/display-output.cc +++ b/src/display-output.cc @@ -27,7 +27,6 @@ #include #include "display-output.hh" -#include "logging.h" #include #include @@ -35,28 +34,37 @@ #include namespace conky { -namespace { -typedef std::unordered_map - display_outputs_t; - -/* - * We cannot construct this object statically, because order of object - * construction in different modules is not defined, so register_source could be - * called before this object is constructed. Therefore, we create it on the - * first call to register_source. - */ -display_outputs_t *display_outputs; - -} // namespace - -// HACK: force the linker to link all the objects in with test enabled -extern void init_console_output(); -extern void init_ncurses_output(); -extern void init_file_output(); -extern void init_http_output(); -extern void init_x11_output(); -extern void init_wayland_output(); +inline void log_missing(const char *name, const char *flag) { + DBGP( + "%s display output disabled. Enable by recompiling with '%s' " + "flag enabled.", + name, flag); +} +#ifndef BUILD_HTTP +template <> +void register_output(display_outputs_t &outputs) { + log_missing("HTTP", "BUILD_HTTP"); +} +#endif +#ifndef BUILD_NCURSES +template <> +void register_output(display_outputs_t &outputs) { + log_missing("ncurses", "BUILD_NCURSES"); +} +#endif +#ifndef BUILD_WAYLAND +template <> +void register_output(display_outputs_t &outputs) { + log_missing("Wayland", "BUILD_WAYLAND"); +} +#endif +#ifndef BUILD_X11 +template <> +void register_output(display_outputs_t &outputs) { + log_missing("X11", "BUILD_X11"); +} +#endif /* * The selected and active display output. @@ -69,55 +77,18 @@ std::vector active_display_outputs; */ std::vector current_display_outputs; -namespace priv { -void do_register_display_output(const std::string &name, - display_output_base *output) { - struct display_output_constructor { - display_output_constructor() { display_outputs = new display_outputs_t(); } - ~display_output_constructor() { - delete display_outputs; - display_outputs = nullptr; - } - }; - static display_output_constructor constructor; - - bool inserted = display_outputs->insert({name, output}).second; - if (!inserted) { - throw std::logic_error("Display output with name '" + name + - "' already registered"); - } -} - -} // namespace priv - -display_output_base::display_output_base(const std::string &name_) - : name(name_), is_active(false), is_graphical(false), priority(-1) { - priv::do_register_display_output(name, this); -} - -disabled_display_output::disabled_display_output(const std::string &name, - const std::string &define) - : display_output_base(name) { - priority = -2; - // XXX some generic way of reporting errors? NORM_ERR? - DBGP( - "Support for display output '%s' has been disabled during compilation. " - "Please recompile with '%s'", - name.c_str(), define.c_str()); -} - bool initialize_display_outputs() { - init_console_output(); - init_ncurses_output(); - init_file_output(); - init_http_output(); - init_x11_output(); - init_wayland_output(); - std::vector outputs; - outputs.reserve(display_outputs->size()); + outputs.reserve(static_cast(output_t::OUTPUT_COUNT)); + register_output(outputs); + register_output(outputs); + register_output(outputs); + register_output(outputs); + register_output(outputs); + register_output(outputs); + + for (auto out : outputs) { NORM_ERR("FOUND: %s", out->name.c_str()); } - for (auto &output : *display_outputs) { outputs.push_back(output.second); } // Sort display outputs by descending priority, to try graphical ones first. sort(outputs.begin(), outputs.end(), &display_output_base::priority_compare); diff --git a/src/display-output.hh b/src/display-output.hh index 45c65856c..e74733ef9 100644 --- a/src/display-output.hh +++ b/src/display-output.hh @@ -30,6 +30,7 @@ #include #include "colours.h" +#include "logging.h" #include "luamm.hh" namespace conky { @@ -57,11 +58,11 @@ class display_output_base { public: const std::string name; - bool is_active; - bool is_graphical; - int priority; + bool is_active = false; + bool is_graphical = false; + int priority = -1; - explicit display_output_base(const std::string &name_); + explicit display_output_base(const std::string &name) : name(name){}; virtual ~display_output_base() {} @@ -106,7 +107,11 @@ class display_output_base { virtual void draw_arc(int /*x*/, int /*y*/, int /*w*/, int /*h*/, int /*a1*/, int /*a2*/) {} virtual void move_win(int /*x*/, int /*y*/) {} - virtual int dpi_scale(int value) { return value; } + template ::value, T>::type> + T dpi_scale(T value) { + return value; + } virtual void begin_draw_stuff() {} virtual void end_draw_stuff() {} @@ -137,6 +142,20 @@ class display_output_base { virtual bool active() { return is_active; } }; +using display_outputs_t = std::vector; + +enum class output_t : uint32_t { + CONSOLE, + NCURSES, + FILE, + HTTP, + X11, + WAYLAND, + OUTPUT_COUNT +}; +template +void register_output(display_outputs_t &outputs); + /* * The selected and active display outputs. */ @@ -148,17 +167,6 @@ extern std::vector active_display_outputs; */ extern std::vector current_display_outputs; -/* - * Use this to declare a display output that has been disabled during - * compilation. We can then print a nice error message telling the used which - * setting to enable. - */ -class disabled_display_output : public display_output_base { - public: - const std::string define; - disabled_display_output(const std::string &name, const std::string &define); -}; - } // namespace conky // XXX: move to namespace? @@ -178,6 +186,21 @@ static inline conky::display_output_base *display_output() { return nullptr; } +template ::value, T>::type> +inline T dpi_scale(T value) { +#ifdef BUILD_GUI + auto output = display_output(); + if (output) { + return output->dpi_scale(value); + } else { + return value; + } +#else /* BUILD_GUI */ + return value; +#endif /* BUILD_GUI */ +} + static inline void unset_display_output() { conky::current_display_outputs.clear(); } diff --git a/src/display-wayland.cc b/src/display-wayland.cc index 9693a4663..9505eb4da 100644 --- a/src/display-wayland.cc +++ b/src/display-wayland.cc @@ -24,9 +24,8 @@ * */ -#include +#include "display-wayland.hh" -#ifdef BUILD_WAYLAND #include // #include "wayland.h" #include @@ -44,23 +43,18 @@ #include #include -#endif /* BUILD_WAYLAND */ - #include #include #include #include "conky.h" -#include "display-wayland.hh" +#include "display-output.hh" #include "gui.h" #include "llua.h" #include "logging.h" -#ifdef BUILD_X11 -#include "x11.h" -#endif -#ifdef BUILD_WAYLAND + #include "fonts.h" -#endif + #ifdef BUILD_MOUSE_EVENTS #include #include @@ -69,9 +63,6 @@ #pragma GCC diagnostic ignored "-Wunused-parameter" -/* TODO: cleanup global namespace */ -#ifdef BUILD_WAYLAND - static int set_cloexec_or_close(int fd) { long flags; @@ -238,24 +229,15 @@ static void wayland_create_window() { update_text_area(); /* to get initial size of the window */ } -#endif /* BUILD_WAYLAND */ - namespace conky { namespace { - -#ifdef BUILD_WAYLAND conky::display_output_wayland wayland_output; -#else -conky::disabled_display_output wayland_output_disabled("wayland", - "BUILD_WAYLAND"); -#endif - } // namespace -extern void init_wayland_output() {} - -namespace priv {} // namespace priv -#ifdef BUILD_WAYLAND +template <> +void register_output(display_outputs_t &outputs) { + outputs.push_back(&wayland_output); +} display_output_wayland::display_output_wayland() : display_output_base("wayland") { @@ -489,7 +471,11 @@ static void on_pointer_button(void *data, struct wl_pointer *pointer, size_t abs_y = w->rectangle.y + y; mouse_button_event event{ - mouse_event_t::MOUSE_RELEASE, x, y, abs_x, abs_y, + mouse_event_t::RELEASE, + x, + y, + abs_x, + abs_y, static_cast(button), }; @@ -498,7 +484,7 @@ static void on_pointer_button(void *data, struct wl_pointer *pointer, // pass; default is MOUSE_RELEASE break; case WL_POINTER_BUTTON_STATE_PRESSED: - event.type = mouse_event_t::MOUSE_PRESS; + event.type = mouse_event_t::PRESS; break; default: return; @@ -519,17 +505,17 @@ void on_pointer_axis(void *data, struct wl_pointer *pointer, std::uint32_t time, size_t abs_y = w->rectangle.y + y; mouse_scroll_event event{ - x, y, abs_x, abs_y, scroll_direction_t::SCROLL_UP, + x, y, abs_x, abs_y, scroll_direction_t::UP, }; switch (static_cast(axis)) { case WL_POINTER_AXIS_VERTICAL_SCROLL: - event.direction = value > 0 ? scroll_direction_t::SCROLL_DOWN - : scroll_direction_t::SCROLL_UP; + event.direction = + value > 0 ? scroll_direction_t::DOWN : scroll_direction_t::UP; break; case WL_POINTER_AXIS_HORIZONTAL_SCROLL: - event.direction = value > 0 ? scroll_direction_t::SCROLL_RIGHT - : scroll_direction_t::SCROLL_LEFT; + event.direction = + value > 0 ? scroll_direction_t::RIGHT : scroll_direction_t::LEFT; break; default: return; @@ -577,7 +563,9 @@ bool display_output_wayland::initialize() { wl_display_roundtrip(global_display); if (wl_globals.layer_shell == nullptr) { - CRIT_ERR("Compositor doesn't support wlr-layer-shell-unstable-v1. Can't run conky."); + CRIT_ERR( + "Compositor doesn't support wlr-layer-shell-unstable-v1. Can't run " + "conky."); } struct wl_surface *surface = @@ -705,48 +693,34 @@ bool display_output_wayland::main_loop_wait(double t) { /* update struts */ if (changed != 0) { - int anchor = -1; + int anchor = 0; DBGP("%s", _(PACKAGE_NAME ": defining struts\n")); fflush(stderr); - switch (text_alignment.get(*state)) { - case TOP_LEFT: - anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP | - ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT; - break; - case TOP_RIGHT: - anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP | - ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT; - break; - case TOP_MIDDLE: { - anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP; + alignment text_align = text_alignment.get(*state); + switch (vertical_alignment(text_align)) { + case axis_align::START: + anchor |= ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP; break; - } - case BOTTOM_LEFT: - anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM | - ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT; + case axis_align::END: + anchor |= ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM; break; - case BOTTOM_RIGHT: - anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM | - ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT; + default: break; - case BOTTOM_MIDDLE: { - anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM; + } + switch (horizontal_alignment(text_align)) { + case axis_align::START: + anchor |= ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT; break; - } - case MIDDLE_LEFT: { - anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT; + case axis_align::END: + anchor |= ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT; break; - } - case MIDDLE_RIGHT: { - anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT; + default: break; - } - - case NONE: - case MIDDLE_MIDDLE: /* XXX What about these? */; } + // middle anchor alignment is the default and requires no special + // handling. if (anchor != -1) { zwlr_layer_surface_v1_set_anchor(global_window->layer_surface, anchor); @@ -939,8 +913,10 @@ void display_output_wayland::move_win(int x, int y) { // window.y = y; // TODO } - -int display_output_wayland::dpi_scale(int value) { return value; } +template +T display_output_wayland::dpi_scale(T value) { + return value; +} void display_output_wayland::end_draw_stuff() { window_commit_buffer(global_window); @@ -1292,6 +1268,4 @@ void window_get_width_height(struct window *window, int *w, int *h) { *h = window->rectangle.height; } -#endif /* BUILD_WAYLAND */ - } // namespace conky diff --git a/src/display-wayland.hh b/src/display-wayland.hh index ab4d1253b..6bc60da5f 100644 --- a/src/display-wayland.hh +++ b/src/display-wayland.hh @@ -23,6 +23,8 @@ #ifndef DISPLAY_WAYLAND_HH #define DISPLAY_WAYLAND_HH +#include "config.h" + #include #include #include @@ -69,7 +71,9 @@ class display_output_wayland : public display_output_base { virtual void fill_rect(int, int, int, int); virtual void draw_arc(int, int, int, int, int, int); virtual void move_win(int, int); - virtual int dpi_scale(int); + template ::value, T>::type> + T dpi_scale(T value); virtual void end_draw_stuff(); virtual void clear_text(int); diff --git a/src/display-x11.cc b/src/display-x11.cc index 30f8b3f5c..f9b179149 100644 --- a/src/display-x11.cc +++ b/src/display-x11.cc @@ -24,10 +24,8 @@ * */ -#include -#include +#include "config.h" -#ifdef BUILD_X11 #include #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wvariadic-macros" @@ -43,13 +41,14 @@ #ifdef BUILD_IMLIB2 #include "conky-imlib2.h" #endif /* BUILD_IMLIB2 */ -#ifdef BUILD_MOUSE_EVENTS +#if defined(BUILD_MOUSE_EVENTS) || defined(BUILD_XINPUT) #include "mouse-events.h" +#endif /* BUILD_MOUSE_EVENTS || BUILD_XINPUT */ #ifdef BUILD_XINPUT +#include #include +#undef COUNT #endif /* BUILD_XINPUT */ -#endif /* BUILD_MOUSE_EVENTS */ -#endif /* BUILD_X11 */ #include #include @@ -65,9 +64,6 @@ #include "gui.h" #include "llua.h" -/* TODO: cleanup global namespace */ -#ifdef BUILD_X11 - #include "logging.h" #include "x11.h" @@ -195,23 +191,15 @@ static void X11_create_window() { update_text_area(); /* to get initial size of the window */ } -#endif /* BUILD_X11 */ - namespace conky { namespace { - -#ifdef BUILD_X11 conky::display_output_x11 x11_output; -#else -conky::disabled_display_output x11_output_disabled("x11", "BUILD_X11"); -#endif - } // namespace -extern void init_x11_output() {} - -namespace priv {} // namespace priv -#ifdef BUILD_X11 +template <> +void register_output(display_outputs_t &outputs) { + outputs.push_back(&x11_output); +} display_output_x11::display_output_x11() : display_output_base("x11") { is_graphical = true; @@ -324,39 +312,38 @@ bool display_output_x11::main_loop_wait(double t) { } /* update struts */ - if ((changed != 0) && own_window_type.get(*state) == TYPE_PANEL) { + if ((changed != 0) && own_window_type.get(*state) == window_type::PANEL) { int sidenum = -1; - DBGP("%s", _(PACKAGE_NAME ": defining struts\n")); - fflush(stderr); + NORM_ERR("defining struts"); - switch (text_alignment.get(*state)) { - case TOP_LEFT: - case TOP_RIGHT: - case TOP_MIDDLE: { + alignment align = text_alignment.get(*state); + switch (align) { + case alignment::TOP_LEFT: + case alignment::TOP_RIGHT: + case alignment::TOP_MIDDLE: { sidenum = 2; break; } - case BOTTOM_LEFT: - case BOTTOM_RIGHT: - case BOTTOM_MIDDLE: { + case alignment::BOTTOM_LEFT: + case alignment::BOTTOM_RIGHT: + case alignment::BOTTOM_MIDDLE: { sidenum = 3; break; } - case MIDDLE_LEFT: { + case alignment::MIDDLE_LEFT: { sidenum = 0; break; } - case MIDDLE_RIGHT: { + case alignment::MIDDLE_RIGHT: { sidenum = 1; break; } - - case NONE: - case MIDDLE_MIDDLE: /* XXX What about these? */; + default: + break; } - set_struts(sidenum); + if (sidenum != -1) set_struts(sidenum); } } #endif @@ -425,11 +412,10 @@ bool display_output_x11::main_loop_wait(double t) { return true; } -enum x_event_handler { +enum class x_event_handler { XINPUT_MOTION, MOUSE_INPUT, PROPERTY_NOTIFY, - EXPOSE, REPARENT, CONFIGURE, @@ -485,8 +471,6 @@ bool handle_event( Window event_window = query_x11_window_at_pos(display, data->root_x, data->root_y); - // query_result is not window.window in some cases. - modifier_state_t mods = x11_modifier_state(data->mods.effective); bool same_window = query_x11_top_parent(display, event_window) == query_x11_top_parent(display, window.window); @@ -518,6 +502,10 @@ bool handle_event( return true; } +#ifdef BUILD_MOUSE_EVENTS + // query_result is not window.window in some cases. + modifier_state_t mods = x11_modifier_state(data->mods.effective); + if (data->evtype == XI_Motion) { // TODO: Make valuator_index names configurable? @@ -556,20 +544,18 @@ bool handle_event( double vertical_value = vertical.value_or(0.0); if (vertical_value != 0.0) { - scroll_direction = vertical_value < 0.0 - ? scroll_direction_t::SCROLL_UP - : scroll_direction_t::SCROLL_DOWN; + scroll_direction = vertical_value < 0.0 ? scroll_direction_t::UP + : scroll_direction_t::DOWN; } else { auto horizontal = data->valuator_relative_value(valuator_t::SCROLL_X); double horizontal_value = horizontal.value_or(0.0); if (horizontal_value != 0.0) { - scroll_direction = horizontal_value < 0.0 - ? scroll_direction_t::SCROLL_LEFT - : scroll_direction_t::SCROLL_RIGHT; + scroll_direction = horizontal_value < 0.0 ? scroll_direction_t::LEFT + : scroll_direction_t::RIGHT; } } - if (scroll_direction != scroll_direction_t::SCROLL_UNKNOWN) { + if (scroll_direction != scroll_direction_t::UNKNOWN) { *consumed = llua_mouse_hook( mouse_scroll_event(data->event_x, data->event_y, data->root_x, data->root_y, scroll_direction, mods)); @@ -583,16 +569,16 @@ bool handle_event( return true; } - mouse_event_t type = mouse_event_t::MOUSE_PRESS; - if (data->evtype == XI_ButtonRelease) { - type = mouse_event_t::MOUSE_RELEASE; - } + mouse_event_t type = mouse_event_t::PRESS; + if (data->evtype == XI_ButtonRelease) { type = mouse_event_t::RELEASE; } mouse_button_t button = x11_mouse_button_code(data->detail); *consumed = llua_mouse_hook(mouse_button_event(type, data->event_x, data->event_y, data->root_x, data->root_y, button, mods)); } +#endif /* BUILD_MOUSE_EVENTS */ + #else /* BUILD_XINPUT */ if (ev.type != ButtonPress && ev.type != ButtonRelease && ev.type != MotionNotify) @@ -612,9 +598,10 @@ bool handle_event( } else { mouse_button_t button = x11_mouse_button_code(ev.xbutton.button); *consumed = llua_mouse_hook(mouse_button_event( - mouse_event_t::MOUSE_PRESS, ev.xbutton.x, ev.xbutton.y, - ev.xbutton.x_root, ev.xbutton.y_root, button, mods)); + mouse_event_t::PRESS, ev.xbutton.x, ev.xbutton.y, ev.xbutton.x_root, + ev.xbutton.y_root, button, mods)); } + break; } case ButtonRelease: { /* don't report scroll release events */ @@ -623,31 +610,35 @@ bool handle_event( modifier_state_t mods = x11_modifier_state(ev.xbutton.state); mouse_button_t button = x11_mouse_button_code(ev.xbutton.button); *consumed = llua_mouse_hook(mouse_button_event( - mouse_event_t::MOUSE_RELEASE, ev.xbutton.x, ev.xbutton.y, - ev.xbutton.x_root, ev.xbutton.y_root, button, mods)); + mouse_event_t::RELEASE, ev.xbutton.x, ev.xbutton.y, ev.xbutton.x_root, + ev.xbutton.y_root, button, mods)); + break; } case MotionNotify: { modifier_state_t mods = x11_modifier_state(ev.xmotion.state); *consumed = llua_mouse_hook(mouse_move_event(ev.xmotion.x, ev.xmotion.y, ev.xmotion.x_root, ev.xmotion.y_root, mods)); + break; } } -#else /* BUILD_MOUSE_EVENTS */ +#endif /* BUILD_MOUSE_EVENTS */ +#endif /* BUILD_XINPUT */ +#ifndef BUILD_MOUSE_EVENTS // always propagate mouse input if not handling mouse events *consumed = false; #endif /* BUILD_MOUSE_EVENTS */ -#endif /* BUILD_XINPUT */ + if (!own_window.get(*state)) return true; switch (own_window_type.get(*state)) { - case window_type::TYPE_NORMAL: - case window_type::TYPE_UTILITY: + case window_type::NORMAL: + case window_type::UTILITY: // decorated normal windows always consume events - if (!TEST_HINT(own_window_hints.get(*state), HINT_UNDECORATED)) { + if (!TEST_HINT(own_window_hints.get(*state), window_hints::UNDECORATED)) { *consumed = true; } break; - case window_type::TYPE_DESKTOP: + case window_type::DESKTOP: // assume conky is always on bottom; nothing to propagate events to *consumed = true; default: @@ -714,6 +705,31 @@ bool handle_event( return true; } + +#ifdef BUILD_MOUSE_EVENTS +template <> +bool handle_event( + conky::display_output_x11 *surface, Display *display, XEvent &ev, + bool *consumed, void **cookie) { + if (ev.type != EnterNotify && ev.type != LeaveNotify) return false; + if (window.xi_opcode != 0) return true; // handled by mouse_input already + + bool not_over_conky = ev.xcrossing.x_root <= window.x || + ev.xcrossing.y_root <= window.y || + ev.xcrossing.x_root >= window.x + window.width || + ev.xcrossing.y_root >= window.y + window.height; + + if ((not_over_conky && ev.xcrossing.type == LeaveNotify) || + (!not_over_conky && ev.xcrossing.type == EnterNotify)) { + llua_mouse_hook(mouse_crossing_event( + ev.xcrossing.type == EnterNotify ? mouse_event_t::AREA_ENTER + : mouse_event_t::AREA_LEAVE, + ev.xcrossing.x, ev.xcrossing.y, ev.xcrossing.x_root, + ev.xcrossing.y_root)); + } + return true; +} +#endif /* BUILD_MOUSE_EVENTS */ #endif /* OWN_WINDOW */ template <> @@ -757,29 +773,6 @@ bool handle_event(conky::display_output_x11 *surface, return true; } -template <> -bool handle_event( - conky::display_output_x11 *surface, Display *display, XEvent &ev, - bool *consumed, void **cookie) { - if (ev.type != EnterNotify && ev.type != LeaveNotify) return false; - if (window.xi_opcode != 0) return true; // handled by mouse_input already - - bool not_over_conky = ev.xcrossing.x_root <= window.x || - ev.xcrossing.y_root <= window.y || - ev.xcrossing.x_root >= window.x + window.width || - ev.xcrossing.y_root >= window.y + window.height; - - if ((not_over_conky && ev.xcrossing.type == LeaveNotify) || - (!not_over_conky && ev.xcrossing.type == EnterNotify)) { - llua_mouse_hook(mouse_crossing_event( - ev.xcrossing.type == EnterNotify ? mouse_event_t::AREA_ENTER - : mouse_event_t::AREA_LEAVE, - ev.xcrossing.x, ev.xcrossing.y, ev.xcrossing.x_root, - ev.xcrossing.y_root)); - } - return true; -} - #ifdef BUILD_XDAMAGE template <> bool handle_event(conky::display_output_x11 *surface, @@ -820,6 +813,8 @@ bool process_event(conky::display_output_x11 *surface, Display *display, HANDLE_EV(BORDER_CROSSING) HANDLE_EV(DAMAGE) +#undef HANDLE_EV + // event not handled return false; } @@ -889,7 +884,7 @@ void display_output_x11::set_foreground_color(Colour c) { } #endif /* BUILD_ARGB */ XSetForeground(display, window.gc, - current_color.to_x11_color(display, screen)); + current_color.to_x11_color(display, screen, have_argb_visual)); } int display_output_x11::calc_text_width(const char *s) { @@ -918,7 +913,7 @@ void display_output_x11::draw_string_at(int x, int y, const char *s, int w) { XColor c{}; XftColor c2{}; - c.pixel = current_color.to_x11_color(display, screen); + c.pixel = current_color.to_x11_color(display, screen, have_argb_visual); // query color on custom colormap XQueryColor(display, window.colourmap, &c); @@ -972,15 +967,19 @@ void display_output_x11::draw_arc(int x, int y, int w, int h, int a1, int a2) { } void display_output_x11::move_win(int x, int y) { +#ifdef OWN_WINDOW window.x = x; window.y = y; XMoveWindow(display, window.window, x, y); +#endif /* OWN_WINDOW */ } -int display_output_x11::dpi_scale(int value) { +const size_t PIXELS_PER_INCH = 96; +template +T display_output_x11::dpi_scale(T value) { #if defined(BUILD_XFT) if (use_xft.get(*state) && xft_dpi > 0) { - return (value * xft_dpi + (value > 0 ? 48 : -48)) / 96; + return (value * xft_dpi + (value > 0 ? 48 : -48)) / PIXELS_PER_INCH; } else { return value; } @@ -1171,6 +1170,4 @@ void display_output_x11::load_fonts(bool utf8) { } } -#endif /* BUILD_X11 */ - } // namespace conky diff --git a/src/display-x11.hh b/src/display-x11.hh index e751f7949..131a886e0 100644 --- a/src/display-x11.hh +++ b/src/display-x11.hh @@ -23,6 +23,8 @@ #ifndef DISPLAY_X11_HH #define DISPLAY_X11_HH +#include "config.h" + #include #include #include @@ -67,7 +69,9 @@ class display_output_x11 : public display_output_base { virtual void fill_rect(int, int, int, int); virtual void draw_arc(int, int, int, int, int, int); virtual void move_win(int, int); - virtual int dpi_scale(int); + template ::value, T>::type> + T dpi_scale(T value); virtual void end_draw_stuff(); virtual void clear_text(int); diff --git a/src/gui.cc b/src/gui.cc index 3c388eaac..5e6d242e2 100644 --- a/src/gui.cc +++ b/src/gui.cc @@ -32,11 +32,14 @@ #include "config.h" #include "conky.h" #include "logging.h" + +#ifdef BUILD_WAYLAND #include "wl.h" +#endif /* BUILD_WAYLAND */ -#ifdef BUILD_IMLIB2 -#include "conky-imlib2.h" -#endif /* BUILD_IMLIB2 */ +// #ifdef BUILD_IMLIB2 +// #include "conky-imlib2.h" +// #endif /* BUILD_IMLIB2 */ #ifndef OWN_WINDOW #include #endif @@ -103,41 +106,46 @@ void own_window_setting::lua_setter(lua::state &l, bool init) { template <> conky::lua_traits::Map conky::lua_traits::map = { - {"top_left", TOP_LEFT}, - {"top_right", TOP_RIGHT}, - {"top_middle", TOP_MIDDLE}, - {"bottom_left", BOTTOM_LEFT}, - {"bottom_right", BOTTOM_RIGHT}, - {"bottom_middle", BOTTOM_MIDDLE}, - {"middle_left", MIDDLE_LEFT}, - {"middle_middle", MIDDLE_MIDDLE}, - {"middle_right", MIDDLE_RIGHT}, - {"tl", TOP_LEFT}, - {"tr", TOP_RIGHT}, - {"tm", TOP_MIDDLE}, - {"bl", BOTTOM_LEFT}, - {"br", BOTTOM_RIGHT}, - {"bm", BOTTOM_MIDDLE}, - {"ml", MIDDLE_LEFT}, - {"mm", MIDDLE_MIDDLE}, - {"mr", MIDDLE_RIGHT}, - {"none", NONE}}; + {"top_left", alignment::TOP_LEFT}, + {"top_right", alignment::TOP_RIGHT}, + {"top_middle", alignment::TOP_MIDDLE}, + {"top", alignment::TOP_MIDDLE}, + {"bottom_left", alignment::BOTTOM_LEFT}, + {"bottom_right", alignment::BOTTOM_RIGHT}, + {"bottom_middle", alignment::BOTTOM_MIDDLE}, + {"bottom", alignment::BOTTOM_MIDDLE}, + {"middle_left", alignment::MIDDLE_LEFT}, + {"left", alignment::MIDDLE_LEFT}, + {"middle_middle", alignment::MIDDLE_MIDDLE}, + {"center", alignment::MIDDLE_MIDDLE}, + {"middle_right", alignment::MIDDLE_RIGHT}, + {"right", alignment::MIDDLE_RIGHT}, + {"tl", alignment::TOP_LEFT}, + {"tr", alignment::TOP_RIGHT}, + {"tm", alignment::TOP_MIDDLE}, + {"bl", alignment::BOTTOM_LEFT}, + {"br", alignment::BOTTOM_RIGHT}, + {"bm", alignment::BOTTOM_MIDDLE}, + {"ml", alignment::MIDDLE_LEFT}, + {"mm", alignment::MIDDLE_MIDDLE}, + {"mr", alignment::MIDDLE_RIGHT}, + {"none", alignment::NONE}}; #ifdef OWN_WINDOW template <> conky::lua_traits::Map conky::lua_traits::map = { - {"normal", TYPE_NORMAL}, {"dock", TYPE_DOCK}, - {"panel", TYPE_PANEL}, {"desktop", TYPE_DESKTOP}, - {"utility", TYPE_UTILITY}, {"override", TYPE_OVERRIDE}}; + {"normal", window_type::NORMAL}, {"dock", window_type::DOCK}, + {"panel", window_type::PANEL}, {"desktop", window_type::DESKTOP}, + {"utility", window_type::UTILITY}, {"override", window_type::OVERRIDE}}; template <> conky::lua_traits::Map conky::lua_traits::map = { - {"undecorated", HINT_UNDECORATED}, - {"below", HINT_BELOW}, - {"above", HINT_ABOVE}, - {"sticky", HINT_STICKY}, - {"skip_taskbar", HINT_SKIP_TASKBAR}, - {"skip_pager", HINT_SKIP_PAGER}}; + {"undecorated", window_hints::UNDECORATED}, + {"below", window_hints::BELOW}, + {"above", window_hints::ABOVE}, + {"sticky", window_hints::STICKY}, + {"skip_taskbar", window_hints::SKIP_TASKBAR}, + {"skip_pager", window_hints::SKIP_PAGER}}; std::pair window_hints_traits::convert( lua::state &l, int index, const std::string &name) { @@ -185,7 +193,8 @@ std::string gethostnamecxx() { * setting.cc. */ -conky::simple_config_setting text_alignment("alignment", BOTTOM_LEFT, +conky::simple_config_setting text_alignment("alignment", + alignment::BOTTOM_LEFT, false); priv::colour_setting default_shade_color("default_shade_color", black_argb32); @@ -209,7 +218,8 @@ conky::simple_config_setting own_window_title( conky::simple_config_setting own_window_class("own_window_class", PACKAGE_NAME, false); conky::simple_config_setting own_window_type("own_window_type", - TYPE_NORMAL, false); + window_type::NORMAL, + false); conky::simple_config_setting own_window_hints( "own_window_hints", 0, false); #endif /* OWN_WINDOW && BUILD_X11 */ diff --git a/src/gui.h b/src/gui.h index 7dd09106a..8b68fe42c 100644 --- a/src/gui.h +++ b/src/gui.h @@ -25,13 +25,145 @@ #include "config.h" +#include "colours.h" +#include "setting.hh" + +#include "colour-settings.h" + #ifdef BUILD_X11 -#include "x11.h" +#include +#include "x11-settings.h" #endif /* BUILD_X11 */ -#include "colour-settings.h" -#include "colours.h" -#include "setting.hh" +/// @brief Represents alignment on a single axis. +enum class axis_align : uint8_t { + /// No alignment + NONE = 0, + /// Top or left alignment + START = 0b01, + /// Middle alignment + MIDDLE = 0b10, + /// Bottom or right alignment + END = 0b11, +}; +constexpr uint8_t operator*(axis_align index) { + return static_cast(index); +} + +/// @brief Represents alignment on a 2D plane. +/// +/// Values are composed of 2 `axis_align` values: 2 bits (at 0x0C) for vertical +/// aligment and 2 least significant bits for horizontal. +enum class alignment : uint8_t { + NONE = 0, + NONE_LEFT = 0b0001, + NONE_MIDDLE = 0b0010, + NONE_RIGHT = 0b0011, + TOP_LEFT = 0b0101, + TOP_MIDDLE = 0b0110, + TOP_RIGHT = 0b0111, + MIDDLE_LEFT = 0b1001, + MIDDLE_MIDDLE = 0b1010, + MIDDLE_RIGHT = 0b1011, + BOTTOM_LEFT = 0b1101, + BOTTOM_MIDDLE = 0b1110, + BOTTOM_RIGHT = 0b1111, +}; +constexpr uint8_t operator*(alignment index) { + return static_cast(index); +} + +/// @brief Returns the horizontal axis alignment component of `alignment`. +/// @param of 2D alignment to extract axis alignment from +/// @return horizontal `axis_align` +[[nodiscard]] inline axis_align horizontal_alignment(alignment of) { + return static_cast(static_cast(of) & 0b11); +} +/// @brief Returns the vertical axis alignment component of `alignment`. +/// @param of 2D alignment to extract axis alignment from +/// @return vertical `axis_align` +[[nodiscard]] inline axis_align vertical_alignment(alignment of) { + return static_cast((static_cast(of) >> 2) & 0b11); +} + +/// @brief Describes how and where a window should be mounted, as well as its +/// behavior. +/// +/// We assume the following order of layers: +/// - Background - behind conky and any other windows, contains icons and +/// desktop menus +/// - Background widgets and docks +/// - Windows +/// - Panels - contains content that covers windows +/// - Override windows - input-override windows on X11, custom overlays, lock +/// screens, etc. +/// +/// See also: +/// - [X11 wm-spec `_NET_WM_WINDOW_TYPE` property]( +/// https://specifications.freedesktop.org/wm-spec/1.3/ar01s05.html#idm45684324619328) +/// - [wlr-layer-shell layers]( +/// https://wayland.app/protocols/wlr-layer-shell-unstable-v1#zwlr_layer_shell_v1:enum:layer) +/// - [xdg-positioner::anchor]( +/// https://wayland.app/protocols/xdg-shell#xdg_positioner:enum:anchor) +enum class window_type : uint8_t { + /// @brief Acts as a normal window - has decorations, above + /// background, widgets and docks, below panels. + NORMAL = 0, + /// @brief Screen background, no decorations, positioned at the very bottom + /// and behind widgets and docks. + DESKTOP, + /// @brief Normal window, always shown above parent window (group). + /// + /// See: [Popup](https://wayland.app/protocols/xdg-shell#xdg_popup) XDG shell + /// surface. + UTILITY, + /// @brief No decorations, between windows and background, attached to screen + /// edge. + DOCK, + /// @brief No decorations, above windows, attached to screen edge, reserves + /// space. + PANEL, +#ifdef BUILD_X11 + /// @brief On top of everything else, not controlled by WM. + OVERRIDE, +#endif /* BUILD_X11 */ +}; +constexpr uint8_t operator*(window_type index) { + return static_cast(index); +} + +#if defined(BUILD_X11) && defined(OWN_WINDOW) +// Only works in X11 because Wayland doesn't support + +/// @brief Hints are used to tell WM how it should treat a window. +/// +/// See: [X11 wm-spec `_NET_WM_STATE` property]( +/// https://specifications.freedesktop.org/wm-spec/1.3/ar01s05.html#idm45684324611552) +enum class window_hints : uint16_t { + UNDECORATED = 0, + BELOW, + ABOVE, + STICKY, + SKIP_TASKBAR, + SKIP_PAGER +}; +constexpr uint8_t operator*(window_hints index) { + return static_cast(index); +} + +inline void SET_HINT(window_hints &mask, window_hints hint) { + mask = static_cast(*mask | (1 << (*hint))); +} +inline void SET_HINT(uint16_t &mask, window_hints hint) { + mask = mask | (1 << (*hint)); +} +inline bool TEST_HINT(window_hints mask, window_hints hint) { + return (*mask & (1 << (*hint))) != 0; +} +inline bool TEST_HINT(uint16_t mask, window_hints hint) { + return (mask & (1 << (*hint))) != 0; +} +#endif #ifdef BUILD_X11 extern Display *display; @@ -70,20 +202,6 @@ void xdbe_swap_buffers(void); void xpmdb_swap_buffers(void); #endif /* BUILD_XDBE */ -/* alignments */ -enum alignment { - TOP_LEFT, - TOP_RIGHT, - TOP_MIDDLE, - BOTTOM_LEFT, - BOTTOM_RIGHT, - BOTTOM_MIDDLE, - MIDDLE_LEFT, - MIDDLE_MIDDLE, - MIDDLE_RIGHT, - NONE -}; - extern conky::simple_config_setting text_alignment; namespace priv { diff --git a/src/llua.cc b/src/llua.cc index 1306e378f..e3eaaba8b 100644 --- a/src/llua.cc +++ b/src/llua.cc @@ -27,13 +27,13 @@ #include "conky.h" #include "logging.h" +#ifdef BUILD_GUI +#include "gui.h" + #ifdef BUILD_X11 #include "x11.h" #endif /* BUILD_X11 */ -#ifdef BUILD_GUI -#include "gui.h" - #ifdef BUILD_MOUSE_EVENTS #include "mouse-events.h" #endif /* BUILD_MOUSE_EVENTS */ diff --git a/src/llua.h b/src/llua.h index d2e373f76..5b2ffe030 100644 --- a/src/llua.h +++ b/src/llua.h @@ -32,12 +32,9 @@ extern "C" { #include -#ifdef BUILD_X11 -#include "x11.h" #ifdef BUILD_MOUSE_EVENTS #include "mouse-events.h" #endif /* BUILD_MOUSE_EVENTS */ -#endif /* BUILD_X11 */ #define LUAPREFIX "conky_" diff --git a/src/mouse-events.cc b/src/mouse-events.cc index ea99bd08a..f1eafab2b 100644 --- a/src/mouse-events.cc +++ b/src/mouse-events.cc @@ -41,6 +41,7 @@ extern "C" { namespace conky { +#ifdef BUILD_MOUSE_EVENTS /* Lua helper functions */ void push_table_value(lua_State *L, std::string key, std::string value) { lua_pushstring(L, key.c_str()); @@ -105,22 +106,22 @@ inline std::size_t current_time_ms() { void push_table_value(lua_State *L, std::string key, mouse_event_t type) { lua_pushstring(L, key.c_str()); switch (type) { - case MOUSE_PRESS: + case mouse_event_t::PRESS: lua_pushstring(L, "button_down"); break; - case MOUSE_RELEASE: + case mouse_event_t::RELEASE: lua_pushstring(L, "button_up"); break; - case MOUSE_SCROLL: + case mouse_event_t::SCROLL: lua_pushstring(L, "mouse_scroll"); break; - case MOUSE_MOVE: + case mouse_event_t::MOVE: lua_pushstring(L, "mouse_move"); break; - case AREA_ENTER: + case mouse_event_t::AREA_ENTER: lua_pushstring(L, "mouse_enter"); break; - case AREA_LEAVE: + case mouse_event_t::AREA_LEAVE: lua_pushstring(L, "mouse_leave"); break; default: @@ -134,16 +135,16 @@ void push_table_value(lua_State *L, std::string key, scroll_direction_t direction) { lua_pushstring(L, key.c_str()); switch (direction) { - case SCROLL_DOWN: + case scroll_direction_t::DOWN: lua_pushstring(L, "down"); break; - case SCROLL_UP: + case scroll_direction_t::UP: lua_pushstring(L, "up"); break; - case SCROLL_LEFT: + case scroll_direction_t::LEFT: lua_pushstring(L, "left"); break; - case SCROLL_RIGHT: + case scroll_direction_t::RIGHT: lua_pushstring(L, "right"); break; default: @@ -156,19 +157,19 @@ void push_table_value(lua_State *L, std::string key, void push_table_value(lua_State *L, std::string key, mouse_button_t button) { lua_pushstring(L, key.c_str()); switch (button) { - case BUTTON_LEFT: + case mouse_button_t::LEFT: lua_pushstring(L, "left"); break; - case BUTTON_RIGHT: + case mouse_button_t::RIGHT: lua_pushstring(L, "right"); break; - case BUTTON_MIDDLE: + case mouse_button_t::MIDDLE: lua_pushstring(L, "middle"); break; - case BUTTON_BACK: + case mouse_button_t::BACK: lua_pushstring(L, "back"); break; - case BUTTON_FORWARD: + case mouse_button_t::FORWARD: lua_pushstring(L, "forward"); break; default: @@ -213,6 +214,7 @@ void mouse_button_event::push_lua_data(lua_State *L) const { push_table_value(L, "button", this->button); push_mods(L, this->mods); } +#endif /* BUILD_MOUSE_EVENTS */ #ifdef BUILD_XINPUT /// Last global device id. @@ -271,10 +273,10 @@ void handle_xi_device_change(const XIHierarchyEvent *event) { /// some device (unlikely). size_t fixed_valuator_index(Display *display, XIDeviceInfo *device, valuator_t valuator) { - const std::array atom_names = { + const std::array atom_names = { "ConkyValuatorMoveX", "ConkyValuatorMoveY", "ConkyValuatorScrollX", "ConkyValuatorScrollY"}; - Atom override_atom = XInternAtom(display, atom_names[valuator], False); + Atom override_atom = XInternAtom(display, atom_names[*valuator], False); unsigned char *value; Atom type_return; int format_return; @@ -290,7 +292,7 @@ size_t fixed_valuator_index(Display *display, XIDeviceInfo *device, NORM_ERR( "invalid '%s' option value, expected a single integer; value will " "be ignored", - atom_names[valuator]); + atom_names[*valuator]); XFree(value); break; } @@ -299,7 +301,7 @@ size_t fixed_valuator_index(Display *display, XIDeviceInfo *device, return static_cast(result); } } while (true); - return valuator; + return *valuator; } /// Allows override of valuator value type in `xorg.conf` in case they're wrong @@ -312,7 +314,7 @@ bool fixed_valuator_relative(Display *display, XIDeviceInfo *device, "ConkyValuatorScrollMode", }; - Atom override_atom = XInternAtom(display, atom_names[valuator >> 1], False); + Atom override_atom = XInternAtom(display, atom_names[*valuator >> 1], False); unsigned char *value_return; Atom type_return; int format_return; @@ -329,7 +331,7 @@ bool fixed_valuator_relative(Display *display, XIDeviceInfo *device, NORM_ERR( "invalid '%s' option value, expected an atom (string); value will " "be ignored", - atom_names[valuator >> 1]); + atom_names[*valuator >> 1]); XFree(value_return); break; } @@ -348,7 +350,7 @@ bool fixed_valuator_relative(Display *display, XIDeviceInfo *device, "unknown '%s' option value: '%s', expected 'absolute' or " "'relative'; " "value will be ignored", - atom_names[valuator >> 1]); + atom_names[*valuator >> 1]); XFree(value); break; } @@ -372,8 +374,8 @@ void device_info::init_xi_device( } if (device == nullptr) return; - std::array valuator_indices; - for (size_t i = 0; i < valuator_t::VALUATOR_COUNT; i++) { + std::array valuator_indices; + for (size_t i = 0; i < VALUATOR_COUNT; i++) { valuator_indices[i] = fixed_valuator_index(display, device, static_cast(i)); } @@ -384,14 +386,14 @@ void device_info::init_xi_device( XIValuatorClassInfo *class_info = (XIValuatorClassInfo *)device->classes[i]; // check if one of used (mapped) valuators - valuator_t valuator = valuator_t::VALUATOR_COUNT; - for (size_t i = 0; i < valuator_t::VALUATOR_COUNT; i++) { + valuator_t valuator = valuator_t::UNKNOWN; + for (size_t i = 0; i < VALUATOR_COUNT; i++) { if (valuator_indices[i] == class_info->number) { valuator = static_cast(i); break; } } - if (valuator == valuator_t::VALUATOR_COUNT) { continue; } + if (valuator == valuator_t::UNKNOWN) { continue; } auto info = conky_valuator_info{ .index = static_cast(class_info->number), @@ -402,7 +404,7 @@ void device_info::init_xi_device( fixed_valuator_relative(display, device, valuator, class_info), }; - this->valuators[valuator] = info; + this->valuators[*valuator] = info; } if (std::holds_alternative(source)) { @@ -410,7 +412,7 @@ void device_info::init_xi_device( } } conky_valuator_info &device_info::valuator(valuator_t valuator) { - return this->valuators[valuator]; + return this->valuators[*valuator]; } xi_event_data *xi_event_data::read_cookie(Display *display, const void *data) { @@ -460,7 +462,7 @@ xi_event_data *xi_event_data::read_cookie(Display *display, const void *data) { .valuators_relative = {0.0, 0.0, 0.0, 0.0}, }; - for (size_t v = 0; v < valuator_t::VALUATOR_COUNT; v++) { + for (size_t v = 0; v < VALUATOR_COUNT; v++) { valuator_t valuator = static_cast(v); auto &valuator_info = device->valuator(valuator); @@ -497,7 +499,7 @@ std::optional xi_event_data::valuator_value(valuator_t valuator) const { std::optional xi_event_data::valuator_relative_value( valuator_t valuator) const { - return this->valuators_relative.at(valuator); + return this->valuators_relative.at(*valuator); } std::vector> xi_event_data::generate_events( diff --git a/src/mouse-events.h b/src/mouse-events.h index ea414b025..aebcefe18 100644 --- a/src/mouse-events.h +++ b/src/mouse-events.h @@ -77,42 +77,50 @@ extern "C" { namespace conky { -enum mouse_event_t { - MOUSE_PRESS = 0, - MOUSE_RELEASE = 1, - MOUSE_SCROLL = 2, - MOUSE_MOVE = 3, +#ifdef BUILD_MOUSE_EVENTS +enum class mouse_event_t : uint32_t { + PRESS = 0, + RELEASE = 1, + SCROLL = 2, + MOVE = 3, AREA_ENTER = 4, AREA_LEAVE = 5, - MOUSE_EVENT_COUNT = 6, }; +const size_t MOUSE_EVENT_COUNT = + static_cast(mouse_event_t::AREA_LEAVE) + 1; +constexpr uint32_t operator*(mouse_event_t index) { + return static_cast(index); +} -enum mouse_button_t : std::uint32_t { - BUTTON_LEFT = BTN_LEFT, - BUTTON_RIGHT = BTN_RIGHT, - BUTTON_MIDDLE = BTN_MIDDLE, - BUTTON_BACK = BTN_BACK, - BUTTON_FORWARD = BTN_FORWARD, +enum class mouse_button_t : uint32_t { + LEFT = BTN_LEFT, + RIGHT = BTN_RIGHT, + MIDDLE = BTN_MIDDLE, + BACK = BTN_BACK, + FORWARD = BTN_FORWARD, }; +constexpr uint32_t operator*(mouse_button_t index) { + return static_cast(index); +} #ifdef BUILD_X11 inline mouse_button_t x11_mouse_button_code(unsigned int x11_mouse_button) { mouse_button_t button; switch (x11_mouse_button) { case Button1: - button = BUTTON_LEFT; + button = mouse_button_t::LEFT; break; case Button2: - button = BUTTON_MIDDLE; + button = mouse_button_t::MIDDLE; break; case Button3: - button = BUTTON_RIGHT; + button = mouse_button_t::RIGHT; break; case 8: - button = BUTTON_BACK; + button = mouse_button_t::BACK; break; case 9: - button = BUTTON_FORWARD; + button = mouse_button_t::FORWARD; break; default: DBGP("X11 button %d is not mapped", x11_mouse_button); @@ -145,26 +153,29 @@ struct mouse_positioned_event : public mouse_event { }; typedef std::bitset<6> modifier_state_t; -enum modifier_key : std::uint32_t { - MOD_SHIFT = 0, - MOD_CONTROL = 1, - MOD_ALT = 2, +enum class modifier_key : uint32_t { + SHIFT = 0, + CONTROL = 1, + ALT = 2, // Windows/MacOS key on most keyboards - MOD_SUPER = 3, - MOD_CAPS_LOCK = 4, - MOD_NUM_LOCK = 5, + SUPER = 3, + CAPS_LOCK = 4, + NUM_LOCK = 5, }; +constexpr uint32_t operator*(modifier_key index) { + return static_cast(index); +} std::string modifier_name(modifier_key key); #ifdef BUILD_X11 inline modifier_state_t x11_modifier_state(unsigned int mods) { modifier_state_t result; - result[MOD_SHIFT] = mods & ShiftMask; - result[MOD_CONTROL] = mods & ControlMask; - result[MOD_ALT] = mods & Mod1Mask; - result[MOD_SUPER] = mods & Mod4Mask; - result[MOD_CAPS_LOCK] = mods & LockMask; - result[MOD_NUM_LOCK] = mods & Mod2Mask; + result[*modifier_key::SHIFT] = mods & ShiftMask; + result[*modifier_key::CONTROL] = mods & ControlMask; + result[*modifier_key::ALT] = mods & Mod1Mask; + result[*modifier_key::SUPER] = mods & Mod4Mask; + result[*modifier_key::CAPS_LOCK] = mods & LockMask; + result[*modifier_key::NUM_LOCK] = mods & Mod2Mask; return result; } #endif /* BUILD_X11 */ @@ -174,35 +185,38 @@ struct mouse_move_event : public mouse_positioned_event { mouse_move_event(std::size_t x, std::size_t y, std::size_t x_abs, std::size_t y_abs, modifier_state_t mods = 0) - : mouse_positioned_event{mouse_event_t::MOUSE_MOVE, x, y, x_abs, y_abs}, + : mouse_positioned_event{mouse_event_t::MOVE, x, y, x_abs, y_abs}, mods(mods){}; void push_lua_data(lua_State *L) const; }; -enum scroll_direction_t : std::uint8_t { - SCROLL_UNKNOWN = 0, - SCROLL_UP, - SCROLL_DOWN, - SCROLL_LEFT, - SCROLL_RIGHT, +enum class scroll_direction_t : uint8_t { + UNKNOWN = 0, + UP, + DOWN, + LEFT, + RIGHT, }; +constexpr uint8_t operator*(scroll_direction_t index) { + return static_cast(index); +} #ifdef BUILD_X11 inline scroll_direction_t x11_scroll_direction(unsigned int x11_mouse_button) { - scroll_direction_t direction = SCROLL_UNKNOWN; + scroll_direction_t direction = scroll_direction_t::UNKNOWN; switch (x11_mouse_button) { case Button4: - direction = SCROLL_UP; + direction = scroll_direction_t::UP; break; case Button5: - direction = SCROLL_DOWN; + direction = scroll_direction_t::DOWN; break; case 6: - direction = SCROLL_LEFT; + direction = scroll_direction_t::LEFT; break; case 7: - direction = SCROLL_RIGHT; + direction = scroll_direction_t::RIGHT; break; } return direction; @@ -216,7 +230,7 @@ struct mouse_scroll_event : public mouse_positioned_event { mouse_scroll_event(std::size_t x, std::size_t y, std::size_t x_abs, std::size_t y_abs, scroll_direction_t direction, modifier_state_t mods = 0) - : mouse_positioned_event{mouse_event_t::MOUSE_SCROLL, x, y, x_abs, y_abs}, + : mouse_positioned_event{mouse_event_t::SCROLL, x, y, x_abs, y_abs}, direction(direction), mods(mods){}; @@ -242,12 +256,17 @@ struct mouse_crossing_event : public mouse_positioned_event { std::size_t x_abs, std::size_t y_abs) : mouse_positioned_event{type, x, y, x_abs, y_abs} {}; }; +#endif /* BUILD_MOUSE_EVENTS */ #ifdef BUILD_XINPUT typedef int xi_device_id; typedef int xi_event_type; -enum valuator_t : size_t { MOVE_X, MOVE_Y, SCROLL_X, SCROLL_Y, VALUATOR_COUNT }; +enum class valuator_t : size_t { MOVE_X, MOVE_Y, SCROLL_X, SCROLL_Y, UNKNOWN }; +const size_t VALUATOR_COUNT = static_cast(valuator_t::UNKNOWN); +constexpr uint8_t operator*(valuator_t index) { + return static_cast(index); +} struct conky_valuator_info { size_t index; @@ -261,7 +280,7 @@ struct device_info { /// @brief Device name. xi_device_id id; std::string name; - std::array valuators{}; + std::array valuators{}; static device_info *from_xi_id(xi_device_id id, Display *display = nullptr); @@ -305,7 +324,7 @@ struct xi_event_data { // Extra data /// Precomputed relative values - std::array valuators_relative; + std::array valuators_relative; static xi_event_data *read_cookie(Display *display, const void *data); diff --git a/src/nvidia.cc b/src/nvidia.cc index 544173e36..6f680339d 100644 --- a/src/nvidia.cc +++ b/src/nvidia.cc @@ -99,6 +99,8 @@ #include "conky.h" #include "logging.h" #include "temphelper.h" + +// Current implementation uses X11 specific system utils #include "x11.h" #include @@ -422,7 +424,7 @@ nvidia_display_setting nvidia_display; // Evaluate module parameters and prepare query int set_nvidia_query(struct text_object *obj, const char *arg, - unsigned int special_type) { + text_node_t special_type) { nvidia_s *nvs; int aid; int ilen; @@ -451,15 +453,15 @@ int set_nvidia_query(struct text_object *obj, const char *arg, // Extract arguments for nvidiabar, etc, and run set_nvidia_query switch (special_type) { - case BAR: + case text_node_t::BAR: arg = scan_bar(obj, arg, 100); break; - case GRAPH: { + case text_node_t::GRAPH: { auto [buf, skip] = scan_command(arg); scan_graph(obj, arg + skip, 100); arg = buf; } break; - case GAUGE: + case text_node_t::GAUGE: arg = scan_gauge(obj, arg, 100); break; default: @@ -483,7 +485,7 @@ int set_nvidia_query(struct text_object *obj, const char *arg, // Save pointers to the arg and command strings for debugging and printing nvs->arg = translate_module_argument[aid]; - nvs->command = translate_nvidia_special_type[special_type]; + nvs->command = translate_nvidia_special_type[*special_type]; // Evaluate parameter switch (aid) { diff --git a/src/nvidia.h b/src/nvidia.h index ffe961814..492274d7a 100644 --- a/src/nvidia.h +++ b/src/nvidia.h @@ -30,7 +30,9 @@ #ifndef NVIDIA_CONKY_H #define NVIDIA_CONKY_H -int set_nvidia_query(struct text_object *, const char *, unsigned int); +#include "specials.h" + +int set_nvidia_query(struct text_object *, const char *, text_node_t); void print_nvidia_value(struct text_object *, char *, unsigned int); double get_nvidia_barval(struct text_object *); void free_nvidia(struct text_object *); diff --git a/src/scroll.cc b/src/scroll.cc index dee6934c0..f7b5c23ce 100644 --- a/src/scroll.cc +++ b/src/scroll.cc @@ -323,7 +323,8 @@ void print_scroll(struct text_object *obj, char *p, unsigned int p_max_size) { #ifdef BUILD_GUI // reset color when scroll is finished if (display_output() && display_output()->graphical()) { - new_special(p + strlen(p), FG)->arg = sd->resetcolor.to_argb32(); + new_special(p + strlen(p), text_node_t::FG)->arg = + sd->resetcolor.to_argb32(); } #endif } diff --git a/src/specials.cc b/src/specials.cc index b45c3ef6f..44cecbf37 100644 --- a/src/specials.cc +++ b/src/specials.cc @@ -46,7 +46,7 @@ #include "conky.h" #include "display-output.hh" -struct special_t *specials = nullptr; +struct special_node *specials = nullptr; int special_count; int graph_count = 0; @@ -354,8 +354,8 @@ bool scan_graph(struct text_object *obj, const char *argstr, double defscale) { * Printing various special text objects */ -struct special_t *new_special_t_node() { - auto *newnode = new special_t; +struct special_node *new_special_t_node() { + auto *newnode = new special_node; memset(newnode, 0, sizeof *newnode); return newnode; @@ -369,8 +369,8 @@ struct special_t *new_special_t_node() { * @param[in] t special type enum, e.g. alignc, alignr, fg, bg, ... * @return pointer to the newly inserted special of type t **/ -struct special_t *new_special(char *buf, enum special_types t) { - special_t *current; +struct special_node *new_special(char *buf, text_node_t t) { + special_node *current; buf[0] = SPECIAL_CHAR; buf[1] = '\0'; @@ -397,14 +397,14 @@ void new_gauge_in_shell(struct text_object *obj, char *p, #ifdef BUILD_GUI void new_gauge_in_gui(struct text_object *obj, char *buf, double usage) { - struct special_t *s = nullptr; + struct special_node *s = nullptr; auto *g = static_cast(obj->special_data); if (display_output() == nullptr || !display_output()->graphical()) { return; } if (g == nullptr) { return; } - s = new_special(buf, GAUGE); + s = new_special(buf, text_node_t::GAUGE); s->arg = usage; s->width = dpi_scale(g->width); @@ -439,14 +439,14 @@ void new_gauge(struct text_object *obj, char *p, unsigned int p_max_size, #ifdef BUILD_GUI void new_font(struct text_object *obj, char *p, unsigned int p_max_size) { - struct special_t *s; + struct special_node *s; unsigned int tmp = selected_font; if (display_output() == nullptr || !display_output()->graphical()) { return; } if (p_max_size == 0) { return; } - s = new_special(p, FONT); + s = new_special(p, text_node_t::FONT); if (obj->data.s != nullptr) { if (s->font_added >= static_cast(fonts.size()) || @@ -463,7 +463,7 @@ void new_font(struct text_object *obj, char *p, unsigned int p_max_size) { /** * Adds value f to graph possibly truncating and scaling the graph **/ -static void graph_append(struct special_t *graph, double f, char showaslog) { +static void graph_append(struct special_node *graph, double f, char showaslog) { int i; /* do nothing if we don't even have a graph yet */ @@ -494,7 +494,7 @@ static void graph_append(struct special_t *graph, double f, char showaslog) { } } -void new_graph_in_shell(struct special_t *s, char *buf, int buf_max_size) { +void new_graph_in_shell(struct special_node *s, char *buf, int buf_max_size) { // Split config string on comma to avoid the hassle of dealing with the // idiosyncrasies of multi-byte unicode on different platforms. // TODO(brenden): Parse config string once and cache result. @@ -537,7 +537,7 @@ double *retrieve_graph(int graph_id, int graph_width) { } } -void store_graph(int graph_id, struct special_t *s) { +void store_graph(int graph_id, struct special_node *s) { if (s->graph == nullptr) { graphs[graph_id] = nullptr; } else { @@ -556,12 +556,12 @@ void store_graph(int graph_id, struct special_t *s) { **/ void new_graph(struct text_object *obj, char *buf, int buf_max_size, double val) { - struct special_t *s = nullptr; + struct special_node *s = nullptr; auto *g = static_cast(obj->special_data); if ((g == nullptr) || (buf_max_size == 0)) { return; } - s = new_special(buf, GRAPH); + s = new_special(buf, text_node_t::GRAPH); /* set graph (special) width to width in obj */ s->width = dpi_scale(g->width); @@ -628,7 +628,7 @@ void new_hr(struct text_object *obj, char *p, unsigned int p_max_size) { if (p_max_size == 0) { return; } - new_special(p, HORIZONTAL_LINE)->height = dpi_scale(obj->data.l); + new_special(p, text_node_t::HORIZONTAL_LINE)->height = dpi_scale(obj->data.l); } void scan_stippled_hr(struct text_object *obj, const char *arg) { @@ -651,14 +651,14 @@ void scan_stippled_hr(struct text_object *obj, const char *arg) { void new_stippled_hr(struct text_object *obj, char *p, unsigned int p_max_size) { - struct special_t *s = nullptr; + struct special_node *s = nullptr; auto *sh = static_cast(obj->special_data); if (display_output() == nullptr || !display_output()->graphical()) { return; } if ((sh == nullptr) || (p_max_size == 0)) { return; } - s = new_special(p, STIPPLED_HR); + s = new_special(p, text_node_t::STIPPLED_HR); s->height = dpi_scale(sh->height); s->arg = dpi_scale(sh->arg); @@ -674,7 +674,7 @@ void new_fg(struct text_object *obj, char *p, unsigned int p_max_size) { || out_to_ncurses.get(*state) #endif /* BUILD_NCURSES */ ) { - new_special(p, FG)->arg = obj->data.l; + new_special(p, text_node_t::FG)->arg = obj->data.l; } UNUSED(obj); UNUSED(p); @@ -687,7 +687,7 @@ void new_bg(struct text_object *obj, char *p, unsigned int p_max_size) { if (p_max_size == 0) { return; } - new_special(p, BG)->arg = obj->data.l; + new_special(p, text_node_t::BG)->arg = obj->data.l; } #endif /* BUILD_GUI */ @@ -716,14 +716,14 @@ static void new_bar_in_shell(struct text_object *obj, char *buffer, #ifdef BUILD_GUI static void new_bar_in_gui(struct text_object *obj, char *buf, double usage) { - struct special_t *s = nullptr; + struct special_node *s = nullptr; auto *b = static_cast(obj->special_data); if (display_output() == nullptr || !display_output()->graphical()) { return; } if (b == nullptr) { return; } - s = new_special(buf, BAR); + s = new_special(buf, text_node_t::BAR); s->arg = usage; s->width = dpi_scale(b->width); @@ -759,39 +759,39 @@ void new_bar(struct text_object *obj, char *p, unsigned int p_max_size, void new_outline(struct text_object *obj, char *p, unsigned int p_max_size) { if (p_max_size == 0) { return; } - new_special(p, OUTLINE)->arg = obj->data.l; + new_special(p, text_node_t::OUTLINE)->arg = obj->data.l; } void new_offset(struct text_object *obj, char *p, unsigned int p_max_size) { if (p_max_size == 0) { return; } - new_special(p, OFFSET)->arg = dpi_scale(obj->data.l); + new_special(p, text_node_t::OFFSET)->arg = dpi_scale(obj->data.l); } void new_voffset(struct text_object *obj, char *p, unsigned int p_max_size) { if (p_max_size == 0) { return; } - new_special(p, VOFFSET)->arg = dpi_scale(obj->data.l); + new_special(p, text_node_t::VOFFSET)->arg = dpi_scale(obj->data.l); } void new_save_coordinates(struct text_object *obj, char *p, unsigned int p_max_size) { if (p_max_size == 0) { return; } - new_special(p, SAVE_COORDINATES)->arg = obj->data.l; + new_special(p, text_node_t::SAVE_COORDINATES)->arg = obj->data.l; } void new_alignr(struct text_object *obj, char *p, unsigned int p_max_size) { if (p_max_size == 0) { return; } - new_special(p, ALIGNR)->arg = dpi_scale(obj->data.l); + new_special(p, text_node_t::ALIGNR)->arg = dpi_scale(obj->data.l); } // A positive offset pushes the text further left void new_alignc(struct text_object *obj, char *p, unsigned int p_max_size) { if (p_max_size == 0) { return; } - new_special(p, ALIGNC)->arg = dpi_scale(obj->data.l); + new_special(p, text_node_t::ALIGNC)->arg = dpi_scale(obj->data.l); } void new_goto(struct text_object *obj, char *p, unsigned int p_max_size) { if (p_max_size == 0) { return; } - new_special(p, GOTO)->arg = dpi_scale(obj->data.l); + new_special(p, text_node_t::GOTO)->arg = dpi_scale(obj->data.l); } void scan_tab(struct text_object *obj, const char *arg) { @@ -813,12 +813,12 @@ void scan_tab(struct text_object *obj, const char *arg) { } void new_tab(struct text_object *obj, char *p, unsigned int p_max_size) { - struct special_t *s = nullptr; + struct special_node *s = nullptr; auto *t = static_cast(obj->special_data); if ((t == nullptr) || (p_max_size == 0)) { return; } - s = new_special(p, TAB); + s = new_special(p, text_node_t::TAB); s->width = dpi_scale(t->width); s->arg = dpi_scale(t->arg); } diff --git a/src/specials.h b/src/specials.h index efbded2e5..c2c9114d7 100644 --- a/src/specials.h +++ b/src/specials.h @@ -40,7 +40,7 @@ #define LOGGRAPH "-l" #define TEMPGRAD "-t" -enum special_types { +enum class text_node_t : uint32_t { NONSPECIAL = 0, HORIZONTAL_LINE = 1, STIPPLED_HR, @@ -59,9 +59,12 @@ enum special_types { GOTO, TAB }; +constexpr uint32_t operator*(text_node_t index) { + return static_cast(index); +} -struct special_t { - int type; +struct special_node { + text_node_t type; short height; short width; double arg; @@ -77,11 +80,11 @@ struct special_t { Colour last_colour; short font_added; char tempgrad; - struct special_t *next; + struct special_node *next; }; /* direct access to the registered specials (FIXME: bad encapsulation) */ -extern struct special_t *specials; +extern struct special_node *specials; extern int special_count; /* forward declare to avoid mutual inclusion between specials.h and @@ -119,6 +122,6 @@ void new_tab(struct text_object *, char *, unsigned int); void clear_stored_graphs(); -struct special_t *new_special(char *buf, enum special_types t); +struct special_node *new_special(char *buf, enum text_node_t t); #endif /* _SPECIALS_H */ diff --git a/src/text_object.h b/src/text_object.h index 3fb5f311e..b6f3c6d5b 100644 --- a/src/text_object.h +++ b/src/text_object.h @@ -29,11 +29,19 @@ #ifndef _TEXT_OBJECT_H #define _TEXT_OBJECT_H -#include /* uint8_t */ -#include "config.h" /* for the defines */ +#include "config.h" + #include "exec.h" #include "specials.h" /* enum special_types */ +#include /* uint8_t */ + +enum class draw_mode_t : uint32_t { + BG = static_cast(text_node_t::BG), + FG = static_cast(text_node_t::FG), + OUTLINE = static_cast(text_node_t::OUTLINE), +}; + /* text object callbacks */ struct obj_cb { /* text object: print obj's output to p */ diff --git a/src/wl.h b/src/wl.h index 11be20fb3..6123680dd 100644 --- a/src/wl.h +++ b/src/wl.h @@ -27,9 +27,15 @@ * */ -#if defined(BUILD_WAYLAND) && !defined(CONKY_WL_H) +#ifndef CONKY_WL_H #define CONKY_WL_H +#include "config.h" + +#ifndef BUILD_WAYLAND +#error wl.h included when BUILD_WAYLAND is disabled +#endif + #include #include "setting.hh" diff --git a/src/x11-color.cc b/src/x11-color.cc index fa2d45f3b..d753ddcdc 100644 --- a/src/x11-color.cc +++ b/src/x11-color.cc @@ -1566,15 +1566,12 @@ static const BuiltinColor BuiltinColors[] = { #define NUM_BUILTIN_COLORS (sizeof(BuiltinColors) / sizeof(BuiltinColors[0])) -int OsLookupColor(int screen, const char *name, unsigned int len, - unsigned short *pred, unsigned short *pgreen, - unsigned short *pblue) { +int OsLookupColor(const char *name, unsigned int len, unsigned short *pred, + unsigned short *pgreen, unsigned short *pblue) { const BuiltinColor *c; int low, mid, high; int r; - (void)screen; - low = 0; high = NUM_BUILTIN_COLORS - 1; while (high >= low) { diff --git a/src/x11-color.h b/src/x11-color.h index d7151b671..ce064a255 100644 --- a/src/x11-color.h +++ b/src/x11-color.h @@ -1,4 +1,3 @@ /* from xorg-server's oscolor.c */ -int OsLookupColor(int screen, const char *name, unsigned int len, - unsigned short *pred, unsigned short *pgreen, - unsigned short *pblue); +int OsLookupColor(const char *name, unsigned int len, unsigned short *pred, + unsigned short *pgreen, unsigned short *pblue); \ No newline at end of file diff --git a/src/x11-settings.cc b/src/x11-settings.cc new file mode 100644 index 000000000..d8b4effa6 --- /dev/null +++ b/src/x11-settings.cc @@ -0,0 +1,126 @@ +#include "x11-settings.h" + +#include "x11.h" + +#include "conky-imlib2.h" + +#include + +conky::simple_config_setting display_name("display", std::string(), + false); + +namespace priv { +void out_to_x_setting::lua_setter(lua::state &l, bool init) { + lua::stack_sentry s(l, -2); + + Base::lua_setter(l, init); + + if (init && do_convert(l, -1).first) { init_x11(); } + + ++s; +} + +void out_to_x_setting::cleanup(lua::state &l) { + lua::stack_sentry s(l, -1); + + if (do_convert(l, -1).first) { deinit_x11(); } + + l.pop(); +} + +#ifdef BUILD_XDBE +bool use_xdbe_setting::set_up(lua::state &l) { + // double_buffer makes no sense when not drawing to X + if (!out_to_x.get(l) || !display || !window.window) { return false; } + + int major, minor; + + if (XdbeQueryExtension(display, &major, &minor) == 0) { + NORM_ERR("No compatible double buffer extension found"); + return false; + } + + window.back_buffer = + XdbeAllocateBackBufferName(display, window.window, XdbeBackground); + if (window.back_buffer != None) { + window.drawable = window.back_buffer; + } else { + NORM_ERR("Failed to allocate back buffer"); + return false; + } + + XFlush(display); + return true; +} + +void use_xdbe_setting::lua_setter(lua::state &l, bool init) { + lua::stack_sentry s(l, -2); + + Base::lua_setter(l, init); + + if (init && do_convert(l, -1).first) { + if (!set_up(l)) { + l.pop(); + l.pushboolean(false); + } + + NORM_ERR("drawing to %s buffer", + do_convert(l, -1).first ? "double" : "single"); + } + + ++s; +} + +#else +bool use_xpmdb_setting::set_up(lua::state &l) { + // double_buffer makes no sense when not drawing to X + if (!out_to_x.get(l)) return false; + + window.back_buffer = + XCreatePixmap(display, window.window, window.width + 1, window.height + 1, + DefaultDepth(display, screen)); + if (window.back_buffer != None) { + window.drawable = window.back_buffer; + } else { + NORM_ERR("Failed to allocate back buffer"); + return false; + } + + XFlush(display); + return true; +} + +void use_xpmdb_setting::lua_setter(lua::state &l, bool init) { + lua::stack_sentry s(l, -2); + + Base::lua_setter(l, init); + + if (init && do_convert(l, -1).first) { + if (!set_up(l)) { + l.pop(); + l.pushboolean(false); + } + + NORM_ERR("drawing to %s buffer", + do_convert(l, -1).first ? "double" : "single"); + } + + ++s; +} +#endif +} // namespace priv + +conky::simple_config_setting head_index("xinerama_head", 0, true); +priv::out_to_x_setting out_to_x; + +#ifdef BUILD_XFT +conky::simple_config_setting use_xft("use_xft", false, false); +#endif + +conky::simple_config_setting forced_redraw("forced_redraw", false, false); + +#ifdef BUILD_XDBE +priv::use_xdbe_setting use_xdbe; +#else +priv::use_xpmdb_setting use_xpmdb; +#endif diff --git a/src/x11-settings.h b/src/x11-settings.h new file mode 100644 index 000000000..3051c00d5 --- /dev/null +++ b/src/x11-settings.h @@ -0,0 +1,60 @@ +#ifndef CONKY_X11_SETTINGS_H +#define CONKY_X11_SETTINGS_H + +#include "setting.hh" + +extern conky::simple_config_setting display_name; + +namespace priv { +class out_to_x_setting : public conky::simple_config_setting { + typedef conky::simple_config_setting Base; + + protected: + virtual void lua_setter(lua::state &l, bool init); + virtual void cleanup(lua::state &l); + + public: + out_to_x_setting() : Base("out_to_x", true, false) {} +}; + +#ifdef BUILD_XDBE +class use_xdbe_setting : public conky::simple_config_setting { + typedef conky::simple_config_setting Base; + + bool set_up(lua::state &l); + + protected: + virtual void lua_setter(lua::state &l, bool init); + + public: + use_xdbe_setting() : Base("double_buffer", false, false) {} +}; + +#else +class use_xpmdb_setting : public conky::simple_config_setting { + typedef conky::simple_config_setting Base; + + bool set_up(lua::state &l); + + protected: + virtual void lua_setter(lua::state &l, bool init); + + public: + use_xpmdb_setting() : Base("double_buffer", false, false) {} +}; +#endif +} /* namespace priv */ + +extern priv::out_to_x_setting out_to_x; + +#ifdef BUILD_XFT +extern conky::simple_config_setting use_xft; +#endif + +#ifdef BUILD_XDBE +extern priv::use_xdbe_setting use_xdbe; +#else +extern priv::use_xpmdb_setting use_xpmdb; +#endif + +#endif /* CONKY_X11_SETTINGS_H */ diff --git a/src/x11.cc b/src/x11.cc index a9146c685..66fab655e 100644 --- a/src/x11.cc +++ b/src/x11.cc @@ -43,13 +43,19 @@ #include #endif +#include #include #include #include #include #include +#include #include +// #ifndef OWN_WINDOW +// #include +// #endif + extern "C" { #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wvariadic-macros" @@ -64,9 +70,6 @@ extern "C" { #ifdef BUILD_IMLIB2 #include "conky-imlib2.h" #endif /* BUILD_IMLIB2 */ -#ifndef OWN_WINDOW -#include -#endif #ifdef BUILD_XFT #include #endif @@ -100,144 +103,12 @@ xcb_errors_context_t *xcb_errors_ctx; /* Window stuff */ struct conky_x11_window window; -#ifdef BUILD_ARGB -bool have_argb_visual; -#endif /* BUILD_ARGB */ - -conky::simple_config_setting display_name("display", std::string(), - false); +bool have_argb_visual = false; /* local prototypes */ static void update_workarea(); static Window find_desktop_window(Window *p_root, Window *p_desktop); static Window find_subwindow(Window win, int w, int h); -static void init_x11(); - -/********************* ************************/ -namespace priv { -void out_to_x_setting::lua_setter(lua::state &l, bool init) { - lua::stack_sentry s(l, -2); - - Base::lua_setter(l, init); - - if (init && do_convert(l, -1).first) { init_x11(); } - - ++s; -} - -void out_to_x_setting::cleanup(lua::state &l) { - lua::stack_sentry s(l, -1); - - if (do_convert(l, -1).first) { deinit_x11(); } - - l.pop(); -} - -#ifdef BUILD_XDBE -bool use_xdbe_setting::set_up(lua::state &l) { - // double_buffer makes no sense when not drawing to X - if (!out_to_x.get(l) || !display || !window.window) { return false; } - - int major, minor; - - if (XdbeQueryExtension(display, &major, &minor) == 0) { - NORM_ERR("No compatible double buffer extension found"); - return false; - } - - window.back_buffer = - XdbeAllocateBackBufferName(display, window.window, XdbeBackground); - if (window.back_buffer != None) { - window.drawable = window.back_buffer; - } else { - NORM_ERR("Failed to allocate back buffer"); - return false; - } - - XFlush(display); - return true; -} - -void use_xdbe_setting::lua_setter(lua::state &l, bool init) { - lua::stack_sentry s(l, -2); - - Base::lua_setter(l, init); - - if (init && do_convert(l, -1).first) { - if (!set_up(l)) { - l.pop(); - l.pushboolean(false); - } - - NORM_ERR("drawing to %s buffer", - do_convert(l, -1).first ? "double" : "single"); - } - - ++s; -} - -#else -bool use_xpmdb_setting::set_up(lua::state &l) { - // double_buffer makes no sense when not drawing to X - if (!out_to_x.get(l)) return false; - - window.back_buffer = - XCreatePixmap(display, window.window, window.width + 1, window.height + 1, - DefaultDepth(display, screen)); - if (window.back_buffer != None) { - window.drawable = window.back_buffer; - } else { - NORM_ERR("Failed to allocate back buffer"); - return false; - } - - XFlush(display); - return true; -} - -void use_xpmdb_setting::lua_setter(lua::state &l, bool init) { - lua::stack_sentry s(l, -2); - - Base::lua_setter(l, init); - - if (init && do_convert(l, -1).first) { - if (!set_up(l)) { - l.pop(); - l.pushboolean(false); - } - - NORM_ERR("drawing to %s buffer", - do_convert(l, -1).first ? "double" : "single"); - } - - ++s; -} -#endif -} // namespace priv - -conky::simple_config_setting head_index("xinerama_head", 0, true); -priv::out_to_x_setting out_to_x; - -#ifdef BUILD_XFT -conky::simple_config_setting use_xft("use_xft", false, false); -#endif - -conky::simple_config_setting forced_redraw("forced_redraw", false, false); - -#ifdef BUILD_XDBE -priv::use_xdbe_setting use_xdbe; -#else -priv::use_xpmdb_setting use_xpmdb; -#endif - -#ifdef BUILD_IMLIB2 -/* - * the only reason this is not in imlib2.cc is so that we can be sure it's - * setter executes after use_xdbe - */ -imlib_cache_size_setting imlib_cache_size; -#endif -/******************** ************************/ /* WARNING, this type not in Xlib spec */ static int x11_error_handler(Display *d, XErrorEvent *err) { @@ -362,7 +233,7 @@ inline Window DefaultVRootWindow(Display *display) { } /* X11 initializer */ -static void init_x11() { +void init_x11() { DBGP("enter init_x11()"); if (display == nullptr) { const std::string &dispstr = display_name.get(*state); @@ -494,7 +365,8 @@ namespace { void do_set_background(Window win, uint8_t alpha) { Colour colour = background_colour.get(*state); colour.alpha = alpha; - unsigned long xcolor = colour.to_x11_color(display, screen, true); + unsigned long xcolor = + colour.to_x11_color(display, screen, have_argb_visual, true); XSetWindowBackground(display, win, xcolor); } } // namespace @@ -624,7 +496,7 @@ void x11_init_window(lua::state &l, bool own) { classHint.res_name = const_cast(class_name.c_str()); classHint.res_class = classHint.res_name; - if (own_window_type.get(l) == TYPE_OVERRIDE) { + if (own_window_type.get(l) == window_type::OVERRIDE) { /* An override_redirect True window. * No WM hints or button processing needed. */ XSetWindowAttributes attrs = {ParentRelative, @@ -678,7 +550,7 @@ void x11_init_window(lua::state &l, bool own) { StructureNotifyMask | ExposureMask | ButtonPressMask | ButtonReleaseMask, 0L, - own_window_type.get(l) == TYPE_UTILITY ? True : False, + own_window_type.get(l) == window_type::UTILITY ? True : False, 0, 0}; @@ -694,7 +566,9 @@ void x11_init_window(lua::state &l, bool own) { } #endif /* BUILD_ARGB */ - if (own_window_type.get(l) == TYPE_DOCK) { window.x = window.y = 0; } + if (own_window_type.get(l) == window_type::DOCK) { + window.x = window.y = 0; + } /* Parent is root window so WM can take control */ window.window = XCreateWindow(display, window.root, window.x, window.y, b, b, 0, @@ -704,10 +578,10 @@ void x11_init_window(lua::state &l, bool own) { wmHint.flags = InputHint | StateHint; /* allow decorated windows to be given input focus by WM */ - wmHint.input = TEST_HINT(hints, HINT_UNDECORATED) ? False : True; + wmHint.input = TEST_HINT(hints, window_hints::UNDECORATED) ? False : True; #ifdef BUILD_XSHAPE #ifdef BUILD_XFIXES - if (own_window_type.get(l) == TYPE_UTILITY) { + if (own_window_type.get(l) == window_type::UTILITY) { XRectangle rect; XserverRegion region = XFixesCreateRegion(display, &rect, 1); XFixesSetWindowShapeRegion(display, window.window, ShapeInput, 0, 0, @@ -723,18 +597,18 @@ void x11_init_window(lua::state &l, bool own) { NORM_ERR("Input shapes are not supported"); } else { if (own_window.get(*state) && - (own_window_type.get(*state) != TYPE_NORMAL || - ((TEST_HINT(own_window_hints.get(*state), HINT_UNDECORATED)) != - 0))) { + (own_window_type.get(*state) != window_type::NORMAL || + ((TEST_HINT(own_window_hints.get(*state), + window_hints::UNDECORATED)) != 0))) { XShapeCombineRectangles(display, window.window, ShapeInput, 0, 0, nullptr, 0, ShapeSet, Unsorted); } } } #endif /* BUILD_XSHAPE */ - if (own_window_type.get(l) == TYPE_DOCK || - own_window_type.get(l) == TYPE_PANEL) { - wmHint.initial_state = WithdrawnState; + if (own_window_type.get(l) == window_type::DOCK || + own_window_type.get(l) == window_type::PANEL) { + // wmHint.initial_state = WithdrawnState; } else { wmHint.initial_state = NormalState; } @@ -751,23 +625,23 @@ void x11_init_window(lua::state &l, bool own) { Atom prop; switch (own_window_type.get(l)) { - case TYPE_DESKTOP: + case window_type::DESKTOP: prop = ATOM(_NET_WM_WINDOW_TYPE_DESKTOP); NORM_ERR("window type - desktop"); break; - case TYPE_DOCK: + case window_type::DOCK: prop = ATOM(_NET_WM_WINDOW_TYPE_DOCK); NORM_ERR("window type - dock"); break; - case TYPE_PANEL: + case window_type::PANEL: prop = ATOM(_NET_WM_WINDOW_TYPE_DOCK); NORM_ERR("window type - panel"); break; - case TYPE_UTILITY: + case window_type::UTILITY: prop = ATOM(_NET_WM_WINDOW_TYPE_UTILITY); NORM_ERR("window type - utility"); break; - case TYPE_NORMAL: + case window_type::NORMAL: default: prop = ATOM(_NET_WM_WINDOW_TYPE_NORMAL); NORM_ERR("window type - normal"); @@ -781,7 +655,7 @@ void x11_init_window(lua::state &l, bool own) { /* Set desired hints */ /* Window decorations */ - if (TEST_HINT(hints, HINT_UNDECORATED)) { + if (TEST_HINT(hints, window_hints::UNDECORATED)) { DBGP("hint - undecorated"); xa = ATOM(_MOTIF_WM_HINTS); if (xa != None) { @@ -792,7 +666,7 @@ void x11_init_window(lua::state &l, bool own) { } /* Below other windows */ - if (TEST_HINT(hints, HINT_BELOW)) { + if (TEST_HINT(hints, window_hints::BELOW)) { DBGP("hint - below"); xa = ATOM(_WIN_LAYER); if (xa != None) { @@ -814,7 +688,7 @@ void x11_init_window(lua::state &l, bool own) { } /* Above other windows */ - if (TEST_HINT(hints, HINT_ABOVE)) { + if (TEST_HINT(hints, window_hints::ABOVE)) { DBGP("hint - above"); xa = ATOM(_WIN_LAYER); if (xa != None) { @@ -836,7 +710,7 @@ void x11_init_window(lua::state &l, bool own) { } /* Sticky */ - if (TEST_HINT(hints, HINT_STICKY)) { + if (TEST_HINT(hints, window_hints::STICKY)) { DBGP("hint - sticky"); xa = ATOM(_NET_WM_DESKTOP); if (xa != None) { @@ -858,7 +732,7 @@ void x11_init_window(lua::state &l, bool own) { } /* Skip taskbar */ - if (TEST_HINT(hints, HINT_SKIP_TASKBAR)) { + if (TEST_HINT(hints, window_hints::SKIP_TASKBAR)) { DBGP("hint - skip taskbar"); xa = ATOM(_NET_WM_STATE); if (xa != None) { @@ -871,7 +745,7 @@ void x11_init_window(lua::state &l, bool own) { } /* Skip pager */ - if (TEST_HINT(hints, HINT_SKIP_PAGER)) { + if (TEST_HINT(hints, window_hints::SKIP_PAGER)) { DBGP("hint - skip pager"); xa = ATOM(_NET_WM_STATE); if (xa != None) { @@ -909,9 +783,12 @@ void x11_init_window(lua::state &l, bool own) { int64_t input_mask = ExposureMask | PropertyChangeMask; #ifdef OWN_WINDOW if (own_window.get(l)) { - input_mask |= StructureNotifyMask | ButtonPressMask | ButtonReleaseMask; + input_mask |= StructureNotifyMask; +#if !defined(BUILD_XINPUT) + input_mask |= ButtonPressMask | ButtonReleaseMask; +#endif } -#ifdef BUILD_MOUSE_EVENTS +#if defined(BUILD_MOUSE_EVENTS) || defined(BUILD_XINPUT) bool xinput_ok = false; #ifdef BUILD_XINPUT // not a loop; substitutes goto with break - if checks fail @@ -934,7 +811,9 @@ void x11_init_window(lua::state &l, bool own) { const std::size_t mask_size = (XI_LASTEVENT + 7) / 8; unsigned char mask_bytes[mask_size] = {0}; /* must be zeroed! */ XISetMask(mask_bytes, XI_HierarchyChanged); +#ifdef BUILD_MOUSE_EVENTS XISetMask(mask_bytes, XI_Motion); +#endif /* BUILD_MOUSE_EVENTS */ // Capture click events for "override" window type if (!own) { XISetMask(mask_bytes, XI_ButtonPress); @@ -948,7 +827,9 @@ void x11_init_window(lua::state &l, bool own) { XISelectEvents(display, window.root, ev_masks, 1); if (own) { +#ifdef BUILD_MOUSE_EVENTS XIClearMask(mask_bytes, XI_Motion); +#endif /* BUILD_MOUSE_EVENTS */ XISetMask(mask_bytes, XI_ButtonPress); XISetMask(mask_bytes, XI_ButtonRelease); @@ -974,10 +855,12 @@ void x11_init_window(lua::state &l, bool own) { // Fallback to basic X11 enter/leave events if xinput fails to init. // It's not recommended to add event masks to special windows in X; causes a // crash (thus own_window_type != TYPE_DESKTOP) - if (!xinput_ok && own && own_window_type.get(l) != TYPE_DESKTOP) { +#ifdef BUILD_MOUSE_EVENTS + if (!xinput_ok && own && own_window_type.get(l) != window_type::DESKTOP) { input_mask |= PointerMotionMask | EnterWindowMask | LeaveWindowMask; } #endif /* BUILD_MOUSE_EVENTS */ +#endif /* BUILD_MOUSE_EVENTS || BUILD_XINPUT */ #endif /* OWN_WINDOW */ window.event_mask = input_mask; XSelectInput(display, window.window, input_mask); @@ -1205,6 +1088,25 @@ void print_desktop_name(struct text_object *obj, char *p, } #ifdef OWN_WINDOW +enum class x11_strut : size_t { + LEFT, + RIGHT, + TOP, + BOTTOM, + LEFT_START_Y, + LEFT_END_Y, + RIGHT_START_Y, + RIGHT_END_Y, + TOP_START_X, + TOP_END_X, + BOTTOM_START_X, + BOTTOM_END_X, +}; +const size_t STRUT_COUNT = static_cast(x11_strut::BOTTOM_END_X) + 1; +constexpr size_t operator*(x11_strut index) { + return static_cast(index); +} + /* reserve window manager space */ void set_struts(int sidenum) { Atom strut; diff --git a/src/x11.h b/src/x11.h index 70f858871..00f36375d 100644 --- a/src/x11.h +++ b/src/x11.h @@ -22,10 +22,14 @@ * */ -#pragma once +#ifndef CONKY_X11_H +#define CONKY_X11_H #include "config.h" -#include "setting.hh" + +#ifndef BUILD_X11 +#error x11.h included when BUILD_X11 is disabled +#endif #include #pragma GCC diagnostic push @@ -44,36 +48,16 @@ #include #include -#ifdef BUILD_ARGB +// TODO: remove lua requirement from x11_init_window +#include "llua.h" + +#include "gui.h" + /* true if use_argb_visual=true and argb visual was found*/ extern bool have_argb_visual; -#endif /* BUILD_ARGB */ #define ATOM(a) XInternAtom(display, #a, False) -#ifdef OWN_WINDOW -enum window_type { - TYPE_NORMAL = 0, - TYPE_DOCK, - TYPE_PANEL, - TYPE_DESKTOP, - TYPE_OVERRIDE, - TYPE_UTILITY -}; - -enum window_hints { - HINT_UNDECORATED = 0, - HINT_BELOW, - HINT_ABOVE, - HINT_STICKY, - HINT_SKIP_TASKBAR, - HINT_SKIP_PAGER -}; - -#define SET_HINT(mask, hint) (mask |= (1 << (hint))) -#define TEST_HINT(mask, hint) (mask & (1 << (hint))) -#endif - extern Display *display; struct conky_x11_window { @@ -99,10 +83,10 @@ struct conky_x11_window { #ifdef BUILD_XFT XftDraw *xftdraw; #endif /*BUILD_XFT*/ -#ifdef BUILD_MOUSE_EVENTS +#if defined(BUILD_MOUSE_EVENTS) || defined(BUILD_XINPUT) // Don't feature gate with BUILD_XINPUT; controls fallback. std::int32_t xi_opcode; -#endif /* BUILD_MOUSE_EVENTS */ +#endif /* BUILD_MOUSE_EVENTS || BUILD_XINPUT */ int width; int height; @@ -113,8 +97,8 @@ struct conky_x11_window { }; extern struct conky_x11_window window; -extern conky::simple_config_setting display_name; +void init_x11(); void destroy_window(void); void create_gc(void); void set_transparent_background(Window win); @@ -195,54 +179,4 @@ void xdbe_swap_buffers(void); void xpmdb_swap_buffers(void); #endif /* BUILD_XDBE */ -namespace priv { -class out_to_x_setting : public conky::simple_config_setting { - typedef conky::simple_config_setting Base; - - protected: - virtual void lua_setter(lua::state &l, bool init); - virtual void cleanup(lua::state &l); - - public: - out_to_x_setting() : Base("out_to_x", true, false) {} -}; - -#ifdef BUILD_XDBE -class use_xdbe_setting : public conky::simple_config_setting { - typedef conky::simple_config_setting Base; - - bool set_up(lua::state &l); - - protected: - virtual void lua_setter(lua::state &l, bool init); - - public: - use_xdbe_setting() : Base("double_buffer", false, false) {} -}; - -#else -class use_xpmdb_setting : public conky::simple_config_setting { - typedef conky::simple_config_setting Base; - - bool set_up(lua::state &l); - - protected: - virtual void lua_setter(lua::state &l, bool init); - - public: - use_xpmdb_setting() : Base("double_buffer", false, false) {} -}; -#endif -} /* namespace priv */ - -extern priv::out_to_x_setting out_to_x; - -#ifdef BUILD_XFT -extern conky::simple_config_setting use_xft; -#endif - -#ifdef BUILD_XDBE -extern priv::use_xdbe_setting use_xdbe; -#else -extern priv::use_xpmdb_setting use_xpmdb; -#endif +#endif /* CONKY_X11_H */