mirror of
https://github.com/Llewellynvdm/conky.git
synced 2024-12-25 12:10:03 +00:00
move X11 stuff from conky.cc to display-x11
Still some things to sort out, but seems to work. A lot of variables and calls had to be made non-static.
This commit is contained in:
parent
e97be17f7f
commit
281097a2a5
@ -224,8 +224,13 @@ if(BUILD_PORT_MONITORS)
|
||||
set(optional_sources ${optional_sources} ${port_monitors})
|
||||
endif(BUILD_PORT_MONITORS)
|
||||
|
||||
if(BUILD_GUI)
|
||||
set(gui fonts.cc fonts.h)
|
||||
set(optional_sources ${optional_sources} ${gui})
|
||||
endif(BUILD_GUI)
|
||||
|
||||
if(BUILD_X11)
|
||||
set(x11 x11.cc x11.h fonts.cc fonts.h)
|
||||
set(x11 x11.cc x11.h)
|
||||
set(optional_sources ${optional_sources} ${x11})
|
||||
|
||||
if(BUILD_XINERAMA)
|
||||
|
934
src/conky.cc
934
src/conky.cc
File diff suppressed because it is too large
Load Diff
13
src/conky.h
13
src/conky.h
@ -292,7 +292,15 @@ extern conky::range_config_setting<double> update_interval;
|
||||
extern conky::range_config_setting<double> update_interval_on_battery;
|
||||
double active_update_interval();
|
||||
|
||||
extern conky::simple_config_setting<bool> show_graph_scale;
|
||||
extern conky::simple_config_setting<bool> show_graph_range;
|
||||
extern conky::simple_config_setting<int> gap_x;
|
||||
extern conky::simple_config_setting<int> gap_y;
|
||||
extern conky::simple_config_setting<bool> draw_borders;
|
||||
extern conky::simple_config_setting<bool> draw_graph_borders;
|
||||
extern conky::range_config_setting<char> stippled_borders;
|
||||
extern conky::simple_config_setting<bool> draw_shades;
|
||||
extern conky::simple_config_setting<bool> draw_outline;
|
||||
|
||||
void set_current_text_color(long colour);
|
||||
long get_current_text_color(void);
|
||||
@ -301,7 +309,7 @@ void set_updatereset(int);
|
||||
int get_updatereset(void);
|
||||
int get_total_updates(void);
|
||||
|
||||
int xft_dpi_scale(int value);
|
||||
int dpi_scale(int value);
|
||||
|
||||
int get_saved_coordinates_x(int);
|
||||
int get_saved_coordinates_y(int);
|
||||
@ -322,6 +330,9 @@ void extract_object_args_to_sub(struct text_object *, const char *);
|
||||
|
||||
void generate_text_internal(char *, int, struct text_object);
|
||||
|
||||
void update_text_area();
|
||||
void draw_stuff();
|
||||
|
||||
int percent_print(char *, int, unsigned);
|
||||
void human_readable(long long, char *, int);
|
||||
|
||||
|
@ -28,10 +28,10 @@
|
||||
|
||||
#include "display-output.hh"
|
||||
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
namespace conky {
|
||||
namespace {
|
||||
@ -101,8 +101,11 @@ bool initialize_display_outputs() {
|
||||
outputs.reserve(display_outputs->size());
|
||||
|
||||
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);
|
||||
|
||||
int graphical_count = 0;
|
||||
|
||||
for (auto output : outputs) {
|
||||
if (output->priority < 0) continue;
|
||||
std::cerr << "Testing display output '" << output->name << "'... "
|
||||
@ -110,23 +113,43 @@ bool initialize_display_outputs() {
|
||||
if (output->detect()) {
|
||||
std::cerr << "Detected display output '" << output->name << "'... "
|
||||
<< std::endl;
|
||||
|
||||
if (graphical_count && output->graphical()) continue;
|
||||
|
||||
// X11 init needs to draw, so we must add it to the list first.
|
||||
active_display_outputs.push_back(output);
|
||||
|
||||
if (output->initialize()) {
|
||||
std::cerr << "Initialized display output '" << output->name << "'... "
|
||||
<< std::endl;
|
||||
|
||||
output->is_active = true;
|
||||
active_display_outputs.push_back(output);
|
||||
if (output->graphical()) graphical_count++;
|
||||
/*
|
||||
* We only support a single graphical display for now.
|
||||
* More than one text display (ncurses + http, ...) should be ok.
|
||||
*/
|
||||
// if (graphical_count)
|
||||
// return true;
|
||||
} else {
|
||||
// failed, so remove from list
|
||||
active_display_outputs.pop_back();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (active_display_outputs.size()) return true;
|
||||
|
||||
std::cerr << "Unable to find a usable display output." << std::endl;
|
||||
return true; // false;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool shutdown_display_outputs() {
|
||||
bool ret = true;
|
||||
for (auto output : active_display_outputs) ret = output->shutdown();
|
||||
for (auto output : active_display_outputs) {
|
||||
output->is_active = false;
|
||||
ret = output->shutdown();
|
||||
}
|
||||
active_display_outputs.clear();
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include <limits>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
#include "luamm.hh"
|
||||
|
||||
@ -102,10 +103,10 @@ class display_output_base {
|
||||
virtual void fill_rect(int x, int y, int w, int h) {}
|
||||
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; }
|
||||
|
||||
virtual void begin_draw_stuff() {}
|
||||
virtual void end_draw_stuff() {}
|
||||
virtual void swap_buffers() {}
|
||||
virtual void clear_text(int exposures) {}
|
||||
virtual void load_fonts(bool utf8) {}
|
||||
|
||||
|
@ -26,12 +26,112 @@
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "display-x11.hh"
|
||||
#ifdef BUILD_X11
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wvariadic-macros"
|
||||
#include <X11/Xutil.h>
|
||||
#ifdef BUILD_XFT
|
||||
#include <X11/Xlib.h>
|
||||
#endif /* BUILD_XFT */
|
||||
#pragma GCC diagnostic pop
|
||||
#include "x11.h"
|
||||
#ifdef BUILD_XDAMAGE
|
||||
#include <X11/extensions/Xdamage.h>
|
||||
#endif
|
||||
#ifdef BUILD_IMLIB2
|
||||
#include "imlib2.h"
|
||||
#endif /* BUILD_IMLIB2 */
|
||||
#endif /* BUILD_X11 */
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "conky.h"
|
||||
#include "display-x11.hh"
|
||||
#include "llua.h"
|
||||
#include "x11.h"
|
||||
#ifdef BUILD_X11
|
||||
#include "fonts.h"
|
||||
#endif
|
||||
|
||||
/* TODO: cleanup global namespace */
|
||||
#ifdef BUILD_X11
|
||||
|
||||
// TODO: cleanup externs (move to conky.h ?)
|
||||
#ifdef OWN_WINDOW
|
||||
extern int fixed_size, fixed_pos;
|
||||
#endif
|
||||
extern int text_start_x, text_start_y; /* text start position in window */
|
||||
extern int text_offset_x, text_offset_y; /* offset for start position */
|
||||
extern int text_width,
|
||||
text_height; /* initially 1 so no zero-sized window is created */
|
||||
extern double current_update_time, next_update_time, last_update_time;
|
||||
void update_text();
|
||||
extern int need_to_update;
|
||||
int get_border_total();
|
||||
extern conky::range_config_setting<int> maximum_width;
|
||||
extern long current_color;
|
||||
#ifdef BUILD_XFT
|
||||
static int xft_dpi = -1;
|
||||
#endif /* BUILD_XFT */
|
||||
|
||||
static void X11_create_window();
|
||||
|
||||
struct _x11_stuff_s {
|
||||
Region region;
|
||||
#ifdef BUILD_XDAMAGE
|
||||
Damage damage;
|
||||
XserverRegion region2, part;
|
||||
int event_base, error_base;
|
||||
#endif
|
||||
} x11_stuff;
|
||||
|
||||
static void X11_create_window() {
|
||||
setup_fonts();
|
||||
load_fonts(utf8_mode.get(*state));
|
||||
#ifdef BUILD_XFT
|
||||
if (use_xft.get(*state)) {
|
||||
auto dpi = XGetDefault(display, "Xft", "dpi");
|
||||
if (dpi) { xft_dpi = atoi(dpi); }
|
||||
}
|
||||
#endif /* BUILD_XFT */
|
||||
update_text_area(); /* to position text/window on screen */
|
||||
|
||||
#ifdef OWN_WINDOW
|
||||
if (own_window.get(*state)) {
|
||||
if (fixed_pos == 0) {
|
||||
XMoveWindow(display, window.window, window.x, window.y);
|
||||
}
|
||||
|
||||
set_transparent_background(window.window);
|
||||
}
|
||||
#endif
|
||||
|
||||
create_gc();
|
||||
|
||||
draw_stuff();
|
||||
|
||||
x11_stuff.region = XCreateRegion();
|
||||
#ifdef BUILD_XDAMAGE
|
||||
if (XDamageQueryExtension(display, &x11_stuff.event_base,
|
||||
&x11_stuff.error_base) == 0) {
|
||||
NORM_ERR("Xdamage extension unavailable");
|
||||
x11_stuff.damage = 0;
|
||||
} else {
|
||||
x11_stuff.damage =
|
||||
XDamageCreate(display, window.window, XDamageReportNonEmpty);
|
||||
x11_stuff.region2 = XFixesCreateRegionFromWindow(display, window.window, 0);
|
||||
x11_stuff.part = XFixesCreateRegionFromWindow(display, window.window, 0);
|
||||
}
|
||||
#endif /* BUILD_XDAMAGE */
|
||||
|
||||
selected_font = 0;
|
||||
update_text_area(); /* to get initial size of the window */
|
||||
}
|
||||
|
||||
#endif /* BUILD_X11 */
|
||||
|
||||
namespace conky {
|
||||
namespace {
|
||||
|
||||
@ -48,6 +148,7 @@ namespace priv {} // namespace priv
|
||||
#ifdef BUILD_X11
|
||||
|
||||
display_output_x11::display_output_x11() : display_output_base("x11") {
|
||||
is_graphical = true;
|
||||
priority = 2;
|
||||
}
|
||||
|
||||
@ -60,10 +161,503 @@ bool display_output_x11::detect() {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool display_output_x11::initialize() { return false; }
|
||||
bool display_output_x11::initialize() {
|
||||
X11_create_window();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool display_output_x11::shutdown() { return false; }
|
||||
|
||||
bool display_output_x11::main_loop_wait(double t) {
|
||||
/* wait for X event or timeout */
|
||||
|
||||
if (XPending(display) == 0) {
|
||||
fd_set fdsr;
|
||||
struct timeval tv {};
|
||||
int s;
|
||||
// t = next_update_time - get_time();
|
||||
|
||||
t = std::min(std::max(t, 0.0), active_update_interval());
|
||||
|
||||
tv.tv_sec = static_cast<long>(t);
|
||||
tv.tv_usec = static_cast<long>(t * 1000000) % 1000000;
|
||||
FD_ZERO(&fdsr);
|
||||
FD_SET(ConnectionNumber(display), &fdsr);
|
||||
|
||||
s = select(ConnectionNumber(display) + 1, &fdsr, nullptr, nullptr, &tv);
|
||||
if (s == -1) {
|
||||
if (errno != EINTR) { NORM_ERR("can't select(): %s", strerror(errno)); }
|
||||
} else {
|
||||
/* timeout */
|
||||
if (s == 0) { update_text(); }
|
||||
}
|
||||
}
|
||||
|
||||
if (need_to_update != 0) {
|
||||
#ifdef OWN_WINDOW
|
||||
int wx = window.x, wy = window.y;
|
||||
#endif
|
||||
|
||||
need_to_update = 0;
|
||||
selected_font = 0;
|
||||
update_text_area();
|
||||
|
||||
#ifdef OWN_WINDOW
|
||||
if (own_window.get(*state)) {
|
||||
int changed = 0;
|
||||
int border_total = get_border_total();
|
||||
|
||||
/* resize window if it isn't right size */
|
||||
if ((fixed_size == 0) &&
|
||||
(text_width + 2 * border_total != window.width ||
|
||||
text_height + 2 * border_total != window.height)) {
|
||||
window.width = text_width + 2 * border_total;
|
||||
window.height = text_height + 2 * border_total;
|
||||
draw_stuff(); /* redraw everything in our newly sized window */
|
||||
XResizeWindow(display, window.window, window.width,
|
||||
window.height); /* resize window */
|
||||
set_transparent_background(window.window);
|
||||
#ifdef BUILD_XDBE
|
||||
/* swap buffers */
|
||||
xdbe_swap_buffers();
|
||||
#else
|
||||
if (use_xpmdb.get(*state)) {
|
||||
XFreePixmap(display, window.back_buffer);
|
||||
window.back_buffer =
|
||||
XCreatePixmap(display, window.window, window.width, window.height,
|
||||
DefaultDepth(display, screen));
|
||||
|
||||
if (window.back_buffer != None) {
|
||||
window.drawable = window.back_buffer;
|
||||
} else {
|
||||
// this is probably reallllly bad
|
||||
NORM_ERR("Failed to allocate back buffer");
|
||||
}
|
||||
XSetForeground(display, window.gc, 0);
|
||||
XFillRectangle(display, window.drawable, window.gc, 0, 0,
|
||||
window.width, window.height);
|
||||
}
|
||||
#endif
|
||||
|
||||
changed++;
|
||||
/* update lua window globals */
|
||||
llua_update_window_table(text_start_x, text_start_y, text_width,
|
||||
text_height);
|
||||
}
|
||||
|
||||
/* move window if it isn't in right position */
|
||||
if ((fixed_pos == 0) && (window.x != wx || window.y != wy)) {
|
||||
XMoveWindow(display, window.window, window.x, window.y);
|
||||
changed++;
|
||||
}
|
||||
|
||||
/* update struts */
|
||||
if ((changed != 0) && own_window_type.get(*state) == TYPE_PANEL) {
|
||||
int sidenum = -1;
|
||||
|
||||
DBGP("%s", _(PACKAGE_NAME ": defining struts\n"));
|
||||
fflush(stderr);
|
||||
|
||||
switch (text_alignment.get(*state)) {
|
||||
case TOP_LEFT:
|
||||
case TOP_RIGHT:
|
||||
case TOP_MIDDLE: {
|
||||
sidenum = 2;
|
||||
break;
|
||||
}
|
||||
case BOTTOM_LEFT:
|
||||
case BOTTOM_RIGHT:
|
||||
case BOTTOM_MIDDLE: {
|
||||
sidenum = 3;
|
||||
break;
|
||||
}
|
||||
case MIDDLE_LEFT: {
|
||||
sidenum = 0;
|
||||
break;
|
||||
}
|
||||
case MIDDLE_RIGHT: {
|
||||
sidenum = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
case NONE:
|
||||
case MIDDLE_MIDDLE: /* XXX What about these? */;
|
||||
}
|
||||
|
||||
set_struts(sidenum);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
clear_text(1);
|
||||
|
||||
#if defined(BUILD_XDBE)
|
||||
if (use_xdbe.get(*state)) {
|
||||
#else
|
||||
if (use_xpmdb.get(*state)) {
|
||||
#endif
|
||||
XRectangle r;
|
||||
int border_total = get_border_total();
|
||||
|
||||
r.x = text_start_x - border_total;
|
||||
r.y = text_start_y - border_total;
|
||||
r.width = text_width + 2 * border_total;
|
||||
r.height = text_height + 2 * border_total;
|
||||
XUnionRectWithRegion(&r, x11_stuff.region, x11_stuff.region);
|
||||
}
|
||||
}
|
||||
|
||||
/* handle X events */
|
||||
while (XPending(display) != 0) {
|
||||
XEvent ev;
|
||||
|
||||
XNextEvent(display, &ev);
|
||||
switch (ev.type) {
|
||||
case Expose: {
|
||||
XRectangle r;
|
||||
r.x = ev.xexpose.x;
|
||||
r.y = ev.xexpose.y;
|
||||
r.width = ev.xexpose.width;
|
||||
r.height = ev.xexpose.height;
|
||||
XUnionRectWithRegion(&r, x11_stuff.region, x11_stuff.region);
|
||||
XSync(display, False);
|
||||
break;
|
||||
}
|
||||
|
||||
case PropertyNotify: {
|
||||
if (ev.xproperty.state == PropertyNewValue) {
|
||||
get_x11_desktop_info(ev.xproperty.display, ev.xproperty.atom);
|
||||
}
|
||||
#ifdef USE_ARGB
|
||||
if (!have_argb_visual) {
|
||||
#endif
|
||||
if (ev.xproperty.atom == ATOM(_XROOTPMAP_ID) ||
|
||||
ev.xproperty.atom == ATOM(_XROOTMAP_ID)) {
|
||||
if (forced_redraw.get(*state)) {
|
||||
draw_stuff();
|
||||
next_update_time = get_time();
|
||||
need_to_update = 1;
|
||||
}
|
||||
}
|
||||
#ifdef USE_ARGB
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef OWN_WINDOW
|
||||
case ReparentNotify:
|
||||
/* make background transparent */
|
||||
if (own_window.get(*state)) {
|
||||
set_transparent_background(window.window);
|
||||
}
|
||||
break;
|
||||
|
||||
case ConfigureNotify:
|
||||
if (own_window.get(*state)) {
|
||||
/* if window size isn't what expected, set fixed size */
|
||||
if (ev.xconfigure.width != window.width ||
|
||||
ev.xconfigure.height != window.height) {
|
||||
if (window.width != 0 && window.height != 0) { fixed_size = 1; }
|
||||
|
||||
/* clear old stuff before screwing up
|
||||
* size and pos */
|
||||
clear_text(1);
|
||||
|
||||
{
|
||||
XWindowAttributes attrs;
|
||||
if (XGetWindowAttributes(display, window.window, &attrs) != 0) {
|
||||
window.width = attrs.width;
|
||||
window.height = attrs.height;
|
||||
}
|
||||
}
|
||||
|
||||
int border_total = get_border_total();
|
||||
|
||||
text_width = window.width - 2 * border_total;
|
||||
text_height = window.height - 2 * border_total;
|
||||
int mw = this->dpi_scale(maximum_width.get(*state));
|
||||
if (text_width > mw && mw > 0) { text_width = mw; }
|
||||
}
|
||||
|
||||
/* if position isn't what expected, set fixed pos
|
||||
* total_updates avoids setting fixed_pos when window
|
||||
* is set to weird locations when started */
|
||||
/* // this is broken
|
||||
if (total_updates >= 2 && !fixed_pos
|
||||
&& (window.x != ev.xconfigure.x
|
||||
|| window.y != ev.xconfigure.y)
|
||||
&& (ev.xconfigure.x != 0
|
||||
|| ev.xconfigure.y != 0)) {
|
||||
fixed_pos = 1;
|
||||
} */
|
||||
}
|
||||
break;
|
||||
|
||||
case ButtonPress:
|
||||
if (own_window.get(*state)) {
|
||||
/* if an ordinary window with decorations */
|
||||
if ((own_window_type.get(*state) == TYPE_NORMAL &&
|
||||
!TEST_HINT(own_window_hints.get(*state), HINT_UNDECORATED)) ||
|
||||
own_window_type.get(*state) == TYPE_DESKTOP) {
|
||||
/* allow conky to hold input focus. */
|
||||
break;
|
||||
}
|
||||
/* forward the click to the desktop window */
|
||||
XUngrabPointer(display, ev.xbutton.time);
|
||||
ev.xbutton.window = window.desktop;
|
||||
ev.xbutton.x = ev.xbutton.x_root;
|
||||
ev.xbutton.y = ev.xbutton.y_root;
|
||||
XSendEvent(display, ev.xbutton.window, False, ButtonPressMask, &ev);
|
||||
XSetInputFocus(display, ev.xbutton.window, RevertToParent,
|
||||
ev.xbutton.time);
|
||||
}
|
||||
break;
|
||||
|
||||
case ButtonRelease:
|
||||
if (own_window.get(*state)) {
|
||||
/* if an ordinary window with decorations */
|
||||
if ((own_window_type.get(*state) == TYPE_NORMAL) &&
|
||||
!TEST_HINT(own_window_hints.get(*state), HINT_UNDECORATED)) {
|
||||
/* allow conky to hold input focus. */
|
||||
break;
|
||||
}
|
||||
/* forward the release to the desktop window */
|
||||
ev.xbutton.window = window.desktop;
|
||||
ev.xbutton.x = ev.xbutton.x_root;
|
||||
ev.xbutton.y = ev.xbutton.y_root;
|
||||
XSendEvent(display, ev.xbutton.window, False, ButtonReleaseMask, &ev);
|
||||
}
|
||||
break;
|
||||
|
||||
#endif
|
||||
|
||||
default:
|
||||
#ifdef BUILD_XDAMAGE
|
||||
if (ev.type == x11_stuff.event_base + XDamageNotify) {
|
||||
auto *dev = reinterpret_cast<XDamageNotifyEvent *>(&ev);
|
||||
|
||||
XFixesSetRegion(display, x11_stuff.part, &dev->area, 1);
|
||||
XFixesUnionRegion(display, x11_stuff.region2, x11_stuff.region2,
|
||||
x11_stuff.part);
|
||||
}
|
||||
#endif /* BUILD_XDAMAGE */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BUILD_XDAMAGE
|
||||
if (x11_stuff.damage) {
|
||||
XDamageSubtract(display, x11_stuff.damage, x11_stuff.region2, None);
|
||||
XFixesSetRegion(display, x11_stuff.region2, nullptr, 0);
|
||||
}
|
||||
#endif /* BUILD_XDAMAGE */
|
||||
|
||||
/* XDBE doesn't seem to provide a way to clear the back buffer
|
||||
* without interfering with the front buffer, other than passing
|
||||
* XdbeBackground to XdbeSwapBuffers. That means that if we're
|
||||
* using XDBE, we need to redraw the text even if it wasn't part of
|
||||
* the exposed area. OTOH, if we're not going to call draw_stuff at
|
||||
* all, then no swap happens and we can safely do nothing. */
|
||||
|
||||
if (XEmptyRegion(x11_stuff.region) == 0) {
|
||||
#if defined(BUILD_XDBE)
|
||||
if (use_xdbe.get(*state)) {
|
||||
#else
|
||||
if (use_xpmdb.get(*state)) {
|
||||
#endif
|
||||
XRectangle r;
|
||||
int border_total = get_border_total();
|
||||
|
||||
r.x = text_start_x - border_total;
|
||||
r.y = text_start_y - border_total;
|
||||
r.width = text_width + 2 * border_total;
|
||||
r.height = text_height + 2 * border_total;
|
||||
XUnionRectWithRegion(&r, x11_stuff.region, x11_stuff.region);
|
||||
}
|
||||
XSetRegion(display, window.gc, x11_stuff.region);
|
||||
#ifdef BUILD_XFT
|
||||
if (use_xft.get(*state)) {
|
||||
XftDrawSetClip(window.xftdraw, x11_stuff.region);
|
||||
}
|
||||
#endif
|
||||
draw_stuff();
|
||||
XDestroyRegion(x11_stuff.region);
|
||||
x11_stuff.region = XCreateRegion();
|
||||
}
|
||||
|
||||
// handled
|
||||
return true;
|
||||
}
|
||||
|
||||
void display_output_x11::sigterm_cleanup() {
|
||||
XDestroyRegion(x11_stuff.region);
|
||||
x11_stuff.region = nullptr;
|
||||
#ifdef BUILD_XDAMAGE
|
||||
if (x11_stuff.damage) {
|
||||
XDamageDestroy(display, x11_stuff.damage);
|
||||
XFixesDestroyRegion(display, x11_stuff.region2);
|
||||
XFixesDestroyRegion(display, x11_stuff.part);
|
||||
}
|
||||
#endif /* BUILD_XDAMAGE */
|
||||
}
|
||||
|
||||
void display_output_x11::cleanup() {
|
||||
if (window_created == 1) {
|
||||
int border_total = get_border_total();
|
||||
|
||||
XClearArea(display, window.window, text_start_x - border_total,
|
||||
text_start_y - border_total, text_width + 2 * border_total,
|
||||
text_height + 2 * border_total, 0);
|
||||
}
|
||||
destroy_window();
|
||||
free_fonts(utf8_mode.get(*state));
|
||||
if (x11_stuff.region != nullptr) {
|
||||
XDestroyRegion(x11_stuff.region);
|
||||
x11_stuff.region = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void display_output_x11::set_foreground_color(long c) {
|
||||
#ifdef BUILD_ARGB
|
||||
if (have_argb_visual) {
|
||||
current_color = c | (own_window_argb_value.get(*state) << 24);
|
||||
} else {
|
||||
#endif /* BUILD_ARGB */
|
||||
current_color = c;
|
||||
#ifdef BUILD_ARGB
|
||||
}
|
||||
#endif /* BUILD_ARGB */
|
||||
XSetForeground(display, window.gc, current_color);
|
||||
}
|
||||
|
||||
int display_output_x11::calc_text_width(const char *s) {
|
||||
size_t slen = strlen(s);
|
||||
#ifdef BUILD_XFT
|
||||
if (use_xft.get(*state)) {
|
||||
XGlyphInfo gi;
|
||||
|
||||
if (utf8_mode.get(*state)) {
|
||||
XftTextExtentsUtf8(display, fonts[selected_font].xftfont,
|
||||
reinterpret_cast<const FcChar8 *>(s), slen, &gi);
|
||||
} else {
|
||||
XftTextExtents8(display, fonts[selected_font].xftfont,
|
||||
reinterpret_cast<const FcChar8 *>(s), slen, &gi);
|
||||
}
|
||||
return gi.xOff;
|
||||
}
|
||||
#endif /* BUILD_XFT */
|
||||
|
||||
return XTextWidth(fonts[selected_font].font, s, slen);
|
||||
}
|
||||
|
||||
void display_output_x11::draw_string_at(int x, int y, const char *s, int w) {
|
||||
#ifdef BUILD_XFT
|
||||
if (use_xft.get(*state)) {
|
||||
XColor c;
|
||||
XftColor c2;
|
||||
|
||||
c.pixel = current_color;
|
||||
// query color on custom colormap
|
||||
XQueryColor(display, window.colourmap, &c);
|
||||
|
||||
c2.pixel = c.pixel;
|
||||
c2.color.red = c.red;
|
||||
c2.color.green = c.green;
|
||||
c2.color.blue = c.blue;
|
||||
c2.color.alpha = fonts[selected_font].font_alpha;
|
||||
if (utf8_mode.get(*state)) {
|
||||
XftDrawStringUtf8(window.xftdraw, &c2, fonts[selected_font].xftfont, x, y,
|
||||
reinterpret_cast<const XftChar8 *>(s), w);
|
||||
} else {
|
||||
XftDrawString8(window.xftdraw, &c2, fonts[selected_font].xftfont, x, y,
|
||||
reinterpret_cast<const XftChar8 *>(s), w);
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
if (utf8_mode.get(*state)) {
|
||||
Xutf8DrawString(display, window.drawable, fonts[selected_font].fontset,
|
||||
window.gc, x, y, s, w);
|
||||
} else {
|
||||
XDrawString(display, window.drawable, window.gc, x, y, s, w);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void display_output_x11::set_line_style(int w, bool solid) {
|
||||
XSetLineAttributes(display, window.gc, w, solid ? LineSolid : LineOnOffDash,
|
||||
CapButt, JoinMiter);
|
||||
}
|
||||
|
||||
void display_output_x11::set_dashes(char *s) {
|
||||
XSetDashes(display, window.gc, 0, s, 2);
|
||||
}
|
||||
|
||||
void display_output_x11::draw_line(int x1, int y1, int x2, int y2) {
|
||||
XDrawLine(display, window.drawable, window.gc, x1, y1, x2, y2);
|
||||
}
|
||||
|
||||
void display_output_x11::draw_rect(int x, int y, int w, int h) {
|
||||
XDrawRectangle(display, window.drawable, window.gc, x, y, w, h);
|
||||
}
|
||||
|
||||
void display_output_x11::fill_rect(int x, int y, int w, int h) {
|
||||
XFillRectangle(display, window.drawable, window.gc, x, y, w, h);
|
||||
}
|
||||
|
||||
void display_output_x11::draw_arc(int x, int y, int w, int h, int a1, int a2) {
|
||||
XDrawArc(display, window.drawable, window.gc, x, y, w, h, a1, a2);
|
||||
}
|
||||
|
||||
void display_output_x11::move_win(int x, int y) {
|
||||
XMoveWindow(display, window.window, window.x, window.y);
|
||||
}
|
||||
|
||||
int display_output_x11::dpi_scale(int value) {
|
||||
#if defined(BUILD_XFT)
|
||||
if (use_xft.get(*state) && xft_dpi > 0) {
|
||||
return (value * xft_dpi + (value > 0 ? 48 : -48)) / 96;
|
||||
} else {
|
||||
return value;
|
||||
}
|
||||
#else /* defined(BUILD_XFT) */
|
||||
return value;
|
||||
#endif /* defined(BUILD_XFT) */
|
||||
}
|
||||
|
||||
void display_output_x11::end_draw_stuff() {
|
||||
#if defined(BUILD_XDBE)
|
||||
xdbe_swap_buffers();
|
||||
#else
|
||||
xpmdb_swap_buffers();
|
||||
#endif
|
||||
}
|
||||
|
||||
void display_output_x11::clear_text(int exposures) {
|
||||
#ifdef BUILD_XDBE
|
||||
if (use_xdbe.get(*state)) {
|
||||
/* The swap action is XdbeBackground, which clears */
|
||||
return;
|
||||
}
|
||||
#else
|
||||
if (use_xpmdb.get(*state)) {
|
||||
return;
|
||||
} else
|
||||
#endif
|
||||
if ((display != nullptr) &&
|
||||
(window.window != 0u)) { // make sure these are !null
|
||||
/* there is some extra space for borders and outlines */
|
||||
int border_total = get_border_total();
|
||||
|
||||
XClearArea(display, window.window, text_start_x - border_total,
|
||||
text_start_y - border_total, text_width + 2 * border_total,
|
||||
text_height + 2 * border_total, exposures != 0 ? True : 0);
|
||||
}
|
||||
}
|
||||
|
||||
void display_output_x11::load_fonts(bool utf8) { ::load_fonts(utf8); }
|
||||
|
||||
#endif /* BUILD_X11 */
|
||||
|
||||
} // namespace conky
|
||||
|
@ -47,6 +47,32 @@ class display_output_x11 : public display_output_base {
|
||||
virtual bool initialize();
|
||||
virtual bool shutdown();
|
||||
|
||||
virtual bool main_loop_wait(double t);
|
||||
|
||||
virtual void sigterm_cleanup();
|
||||
virtual void cleanup();
|
||||
|
||||
// drawing primitives
|
||||
virtual void set_foreground_color(long c);
|
||||
|
||||
virtual int calc_text_width(const char *s);
|
||||
|
||||
// GUI interface
|
||||
virtual void draw_string_at(int x, int y, const char *s, int w);
|
||||
// X11 lookalikes
|
||||
virtual void set_line_style(int w, bool solid);
|
||||
virtual void set_dashes(char *s);
|
||||
virtual void draw_line(int x1, int y1, int x2, int y2);
|
||||
virtual void draw_rect(int x, int y, int w, int h);
|
||||
virtual void fill_rect(int x, int y, int w, int h);
|
||||
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);
|
||||
|
||||
virtual void end_draw_stuff();
|
||||
virtual void clear_text(int exposures);
|
||||
virtual void load_fonts(bool utf8);
|
||||
|
||||
// X11-specific
|
||||
};
|
||||
|
||||
|
@ -133,19 +133,15 @@ void cimlib_add_image(const char *args) {
|
||||
if (tmp != nullptr) {
|
||||
tmp += 3;
|
||||
sscanf(tmp, "%i,%i", &cur->x, &cur->y);
|
||||
#ifdef BUILD_XFT
|
||||
cur->x = xft_dpi_scale(cur->x);
|
||||
cur->y = xft_dpi_scale(cur->y);
|
||||
#endif /* BUILD_XFT */
|
||||
cur->x = dpi_scale(cur->x);
|
||||
cur->y = dpi_scale(cur->y);
|
||||
}
|
||||
tmp = strstr(args, "-s ");
|
||||
if (tmp != nullptr) {
|
||||
tmp += 3;
|
||||
if (sscanf(tmp, "%ix%i", &cur->w, &cur->h) != 0) { cur->wh_set = 1; }
|
||||
#ifdef BUILD_XFT
|
||||
cur->w = xft_dpi_scale(cur->w);
|
||||
cur->h = xft_dpi_scale(cur->h);
|
||||
#endif /* BUILD_XFT */
|
||||
cur->w = dpi_scale(cur->w);
|
||||
cur->h = dpi_scale(cur->h);
|
||||
}
|
||||
|
||||
tmp = strstr(args, "-n");
|
||||
@ -208,8 +204,8 @@ static void cimlib_draw_image(struct image_list_s *cur, int *clip_x,
|
||||
w = imlib_image_get_width();
|
||||
h = imlib_image_get_height();
|
||||
if (cur->wh_set == 0) {
|
||||
cur->w = xft_dpi_scale(w);
|
||||
cur->h = xft_dpi_scale(h);
|
||||
cur->w = dpi_scale(w);
|
||||
cur->h = dpi_scale(h);
|
||||
}
|
||||
imlib_context_set_image(buffer);
|
||||
imlib_blend_image_onto_image(image, 1, 0, 0, w, h, cur->x, cur->y, cur->w,
|
||||
|
@ -396,8 +396,8 @@ void new_gauge_in_x11(struct text_object *obj, char *buf, double usage) {
|
||||
s = new_special(buf, GAUGE);
|
||||
|
||||
s->arg = usage;
|
||||
s->width = xft_dpi_scale(g->width);
|
||||
s->height = xft_dpi_scale(g->height);
|
||||
s->width = dpi_scale(g->width);
|
||||
s->height = dpi_scale(g->height);
|
||||
s->scale = g->scale;
|
||||
}
|
||||
#endif /* BUILD_GUI */
|
||||
@ -551,7 +551,7 @@ void new_graph(struct text_object *obj, char *buf, int buf_max_size,
|
||||
s = new_special(buf, GRAPH);
|
||||
|
||||
/* set graph (special) width to width in obj */
|
||||
s->width = xft_dpi_scale(g->width);
|
||||
s->width = dpi_scale(g->width);
|
||||
if (s->width != 0) { s->graph_width = s->width; }
|
||||
|
||||
if (s->graph_width != s->graph_allocated) {
|
||||
@ -576,7 +576,7 @@ void new_graph(struct text_object *obj, char *buf, int buf_max_size,
|
||||
s->graph_allocated = s->graph_width;
|
||||
graphs[g->id] = graph;
|
||||
}
|
||||
s->height = xft_dpi_scale(g->height);
|
||||
s->height = dpi_scale(g->height);
|
||||
s->first_colour = adjust_colours(g->first_colour);
|
||||
s->last_colour = adjust_colours(g->last_colour);
|
||||
if (g->scale != 0) {
|
||||
@ -610,7 +610,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 = xft_dpi_scale(obj->data.l);
|
||||
new_special(p, HORIZONTAL_LINE)->height = dpi_scale(obj->data.l);
|
||||
}
|
||||
|
||||
void scan_stippled_hr(struct text_object *obj, const char *arg) {
|
||||
@ -642,8 +642,8 @@ void new_stippled_hr(struct text_object *obj, char *p,
|
||||
|
||||
s = new_special(p, STIPPLED_HR);
|
||||
|
||||
s->height = xft_dpi_scale(sh->height);
|
||||
s->arg = xft_dpi_scale(sh->arg);
|
||||
s->height = dpi_scale(sh->height);
|
||||
s->arg = dpi_scale(sh->arg);
|
||||
}
|
||||
#endif /* BUILD_GUI */
|
||||
|
||||
@ -704,8 +704,8 @@ static void new_bar_in_x11(struct text_object *obj, char *buf, double usage) {
|
||||
s = new_special(buf, BAR);
|
||||
|
||||
s->arg = usage;
|
||||
s->width = xft_dpi_scale(b->width);
|
||||
s->height = xft_dpi_scale(b->height);
|
||||
s->width = dpi_scale(b->width);
|
||||
s->height = dpi_scale(b->height);
|
||||
s->scale = b->scale;
|
||||
}
|
||||
#endif /* BUILD_GUI */
|
||||
@ -740,12 +740,12 @@ void new_outline(struct text_object *obj, char *p, unsigned int p_max_size) {
|
||||
|
||||
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 = xft_dpi_scale(obj->data.l);
|
||||
new_special(p, 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 = xft_dpi_scale(obj->data.l);
|
||||
new_special(p, VOFFSET)->arg = dpi_scale(obj->data.l);
|
||||
}
|
||||
|
||||
void new_save_coordinates(struct text_object *obj, char *p,
|
||||
@ -756,18 +756,18 @@ void new_save_coordinates(struct text_object *obj, char *p,
|
||||
|
||||
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 = xft_dpi_scale(obj->data.l);
|
||||
new_special(p, 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 = xft_dpi_scale(obj->data.l);
|
||||
new_special(p, 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 = xft_dpi_scale(obj->data.l);
|
||||
new_special(p, GOTO)->arg = dpi_scale(obj->data.l);
|
||||
}
|
||||
|
||||
void scan_tab(struct text_object *obj, const char *arg) {
|
||||
@ -795,8 +795,8 @@ void new_tab(struct text_object *obj, char *p, unsigned int p_max_size) {
|
||||
if ((t == nullptr) || (p_max_size == 0)) { return; }
|
||||
|
||||
s = new_special(p, TAB);
|
||||
s->width = xft_dpi_scale(t->width);
|
||||
s->arg = xft_dpi_scale(t->arg);
|
||||
s->width = dpi_scale(t->width);
|
||||
s->arg = dpi_scale(t->arg);
|
||||
}
|
||||
|
||||
void clear_stored_graphs() {
|
||||
|
Loading…
Reference in New Issue
Block a user