summaryrefslogtreecommitdiff
path: root/src/main.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.cc')
-rw-r--r--src/main.cc344
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());