diff options
Diffstat (limited to 'src/main.cc')
| -rw-r--r-- | src/main.cc | 344 |
1 files changed, 2 insertions, 342 deletions
diff --git a/src/main.cc b/src/main.cc index c8be11c..53e9a7f 100644 --- a/src/main.cc +++ b/src/main.cc @@ -1,361 +1,21 @@ #include "common.hh" -#include <algorithm> #include <iostream> -#include <math.h> #include <string.h> #include <thread> #include <xcb/xcb_event.h> -#include <xcb/xcb_icccm.h> #include <xcb/xcb_keysyms.h> -#include "animation.hh" #include "animator.hh" #include "args.hh" -#include "blissful_monitor.hh" -#include "cairo.hh" -#include "fake_monitor.hh" #include "io.hh" -#include "monitor.hh" +#include "icecc.hh" #include "monmon.hh" -#include "pango.hh" #include "poll_looper.hh" #include "x.hh" namespace { -class IceccMonMon : public MonMon, virtual Monitor::Observer { -public: - IceccMonMon(std::shared_ptr<PollLooper> const& looper, unsigned columns) - : MonMon(looper), connected_(false), max_jobs_(0), jobs_(0), requests_(0), - force_columns_(columns) { - } - - void connect(Args const* args) { - std::unique_ptr<Monitor> monitor; -#if FAKE_MONITOR - monitor = FakeMonitor::create(looper_); -#else - monitor = Monitor::create(looper_); -#endif - monitor_ = BlissfulMonitor::create(looper_, std::move(monitor)); - monitor_->add_observer(this); - monitor_->connect(args->arg("network", ""), - args->arg("scheduler", "")); - } - -protected: - void width_changed() override { - job_pattern_.reset(); - } - -#if FAKE_MONITOR - void do_toggle_fakes() override { - monitor_->toggle_fakes(); - } -#endif - -private: - class MachineAnimation; - - struct Machine : virtual Animator::AnimationObserver { - uint32_t id; - Monitor::Machine data; - unsigned jobs; - unsigned requests; - double x; - std::shared_ptr<MachineAnimation> animation; - - explicit Machine(uint32_t id) - : id(id), jobs(0), requests(0), x(0.0) { - } - - Machine(Machine const&) = delete; - Machine& operator=(Machine const&) = delete; - - ~Machine() override { - assert(!animation); - } - - bool operator<(Machine const& machine) const { - if (data.name < machine.data.name) return true; - if (data.name > machine.data.name) return false; - return id < machine.id; - } - - void ticked(Animator*, Animation*, double value) override { - x = value; - } - - void stopped(Animator*, Animation*) override { - x = static_cast<double>(jobs) / data.max_jobs; - animation.reset(); - } - }; - - class MachineAnimation : public Animation { - public: - explicit MachineAnimation(Machine* machine) - : machine_(machine), last_(0.0) { - } - - bool tick(double duration, double* value) override { - auto target = static_cast<double>(machine_->jobs) - / machine_->data.max_jobs; - if (duration == 0.0) { - last_ = duration; - *value = machine_->x; - return machine_->x != target; - } else { - double diff = target - machine_->x; - double max = (duration - last_) * .5; - last_ = duration; - if (fabs(diff) > max) { - diff = diff < 0.0 ? -max : max; - *value = machine_->x + diff; - return true; - } else { - *value = target; - return false; - } - } - } - - private: - Machine* machine_; - double last_; - }; - - - void state(Monitor*, Monitor::State state) override { - switch (state) { - case Monitor::SEARCHING: - connected_ = false; - stop_all_animations(); - machines_.clear(); - max_jobs_ = 0; - jobs_ = 0; - requests_ = 0; - if (!wnd_) return; - draw(); - break; - case Monitor::CONNECTED: - connected_ = true; - draw(); - break; - } - } - - void stop_all_animations() override { - if (!animator_) return; - for (auto& machine : machines_) { - if (machine->animation) animator_->stop(machine->animation.get()); - } - } - - void internal_quit() override { - monitor_->disconnect(); - } - - void update(Machine* machine) { - auto old = machine->data.max_jobs; - machine->data = monitor_->machine(machine->id); - if (old < machine->data.max_jobs) { - max_jobs_ += machine->data.max_jobs - old; - if (machine->jobs) animate(machine); - } else if (old > machine->data.max_jobs) { - max_jobs_ -= old - machine->data.max_jobs; - if (machine->jobs) animate(machine); - } - } - - void draw_content(cairo_t* cairo, PangoLayout* layout, uint16_t w, uint16_t h) - override { - auto const pad_x = std::min(9.0, w / 20.0), pad_y = pad_x; - auto const margin_x = std::min(7.5, w / 20.0), margin_y = margin_x; - auto y = pad_y; - auto const columns = force_columns_ ? force_columns_ : std::max(1, w / h); - auto const box_width = (w - pad_x) / columns - pad_x; - auto const box_height = box_height_ + margin_y * 2; - if (!job_pattern_) { - job_pattern_.reset(cairo_pattern_create_linear(0.0, 0.0, box_width, 0.0)); - cairo_pattern_add_color_stop_rgb(job_pattern_.get(), 0.000000, - 0.000000, 0.000000, 0.000000); - cairo_pattern_add_color_stop_rgb(job_pattern_.get(), 0.594324, - 0.729412, 0.000000, 0.000000); - cairo_pattern_add_color_stop_rgb(job_pattern_.get(), 0.809683, - 1.000000, 0.545098, 0.196078); - cairo_pattern_add_color_stop_rgb(job_pattern_.get(), 0.899833, - 0.972549, 0.937255, 0.074510); - cairo_pattern_add_color_stop_rgb(job_pattern_.get(), 1.000000, - 0.976471, 0.968627, 0.831373); - } - pango_layout_set_width(layout, - (box_width - margin_x * 2) * PANGO_SCALE); - unsigned col = 0; - for (auto const& machine : machines_) { - pango_layout_set_text(layout, machine->data.name.data(), - machine->data.name.size()); - auto x = pad_x + col * (box_width + pad_x); - rounded_path(cairo, x, y, box_width, box_height); - cairo_set_source_rgba(cairo, 0.1, 0.1, 0.1, 0.7); - - if (machine->x > 0.0) { - cairo_fill_preserve(cairo); - auto old = cairo::unique_path(cairo_copy_path(cairo)); - cairo_new_path(cairo); - cairo_rectangle(cairo, x, y, machine->x * box_width, box_height); - cairo_clip(cairo); - cairo_append_path(cairo, old.get()); - cairo_matrix_t matrix; - cairo_matrix_init_translate(&matrix, -x, 0); - cairo_pattern_set_matrix(job_pattern_.get(), &matrix); - cairo_set_source(cairo, job_pattern_.get()); - cairo_fill(cairo); - cairo_reset_clip(cairo); - } else { - cairo_fill(cairo); - } - if (machine->requests > 0) { - auto radius = box_height / 10.0; - cairo_set_line_width(cairo, 1.5); - cairo_new_path(cairo); - cairo_move_to(cairo, x + box_width - radius, y); - cairo_rel_line_to(cairo, - -(machine->requests * (box_width - radius * 2)) - / requests_, 0); - cairo_set_source_rgb(cairo, 0, 0.6, 0); - cairo_stroke(cairo); - } - - cairo_move_to(cairo, x + margin_x, y + margin_y); - pango_cairo_layout_path(cairo, layout); - cairo_set_source_rgb(cairo, 0.0, 0.0, 0.0); - cairo_set_line_cap(cairo, CAIRO_LINE_CAP_ROUND); - cairo_set_line_width(cairo, 2.0); - cairo_stroke(cairo); - cairo_set_source_rgb(cairo, 1.0, 1.0, 1.0); - cairo_move_to(cairo, x + margin_x, y + margin_y); - pango_cairo_show_layout(cairo, layout); - if (++col == columns) { - col = 0; - y += box_height + pad_y * 2; - if (y >= h) break; - } - } - } - - void added_machine(Monitor*, uint32_t id) override { - auto machine = std::make_unique<Machine>(id); - update(machine.get()); - machines_.emplace( - std::lower_bound(machines_.begin(), machines_.end(), machine, - compare_machine), - std::move(machine)); - draw(); - } - - static bool compare_machine(std::unique_ptr<Machine> const& m1, - std::unique_ptr<Machine> const& m2) { - return *m1 < *m2; - } - - void updated_machine(Monitor*, uint32_t id) override { - for (auto& machine : machines_) { - if (machine->id == id) { - auto old = machine->data.name; - update(machine.get()); - if (machine->data.name != old) { - // TODO: Perhaps remove and insert instead? - std::sort(machines_.begin(), machines_.end(), compare_machine); - } - draw(); - return; - } - } - assert(false); - } - - void removed_machine(Monitor*, uint32_t id) override { - for (auto it = machines_.begin(); it != machines_.end(); ++it) { - if ((*it)->id == id) { - max_jobs_ -= (*it)->data.max_jobs; - requests_ -= (*it)->requests; - jobs_ -= (*it)->jobs; - if (animator_) animator_->stop((*it)->animation.get()); - machines_.erase(it); - draw(); - return; - } - } - assert(false); - } - - void added_job(Monitor*, uint32_t source, uint32_t target) override { - if (source == target) { - for (auto& machine : machines_) { - if (machine->id == source) { - ++machine->jobs; - animate(machine.get()); - } - } - } else { - for (auto& machine : machines_) { - if (machine->id == source) { - ++machine->requests; - } - if (machine->id == target) { - ++machine->jobs; - animate(machine.get()); - } - } - ++requests_; - } - ++jobs_; - draw(); - } - - void removed_job(Monitor*, uint32_t source, uint32_t target) override { - if (source == target) { - for (auto& machine : machines_) { - if (machine->id == source) { - --machine->jobs; - animate(machine.get()); - } - } - } else { - for (auto& machine : machines_) { - if (machine->id == source) { - --machine->requests; - } - if (machine->id == target) { - --machine->jobs; - animate(machine.get()); - } - } - --requests_; - } - --jobs_; - draw(); - } - - void animate(Machine* machine) { - if (!animator_) return; - if (machine->animation) return; - machine->animation = std::make_unique<MachineAnimation>(machine); - animator_->start(machine->animation, machine); - } - - std::unique_ptr<Monitor> monitor_; - bool connected_; - std::vector<std::unique_ptr<Machine>> machines_; - unsigned max_jobs_; - unsigned jobs_; - unsigned requests_; - cairo::unique_pattern job_pattern_; - unsigned force_columns_; -}; - struct XcbKeySymbolsDelete { void operator()(xcb_key_symbols_t* ptr) const { if (ptr) xcb_key_symbols_free(ptr); @@ -540,7 +200,7 @@ int main(int argc, char** argv) { atoms->preload("__MONMON_QUIT"); MonMon::preload(atoms.get()); std::shared_ptr<x::Ewmh> ewmh(x::Ewmh::create(conn, screen_index)); - auto monmon = std::make_shared<IceccMonMon>(looper, columns); + std::shared_ptr<IceccMonMon> monmon(create_icecc_monmon(looper, columns)); monmon->init(conn, screen, format, atoms, ewmh, 400, 400, args->is_set("titlebar"), args->is_set("black")); monmon->connect(args.get()); |
