#ifndef MONMON_HH #define MONMON_HH #include #include #include "animator.hh" #include "cairo.hh" #include "io.hh" #include "pango.hh" #include "poll_looper.hh" #include "x.hh" class MonMon : protected virtual Animator::Observer { public: virtual ~MonMon(); void init(x::shared_connection const& conn, xcb_screen_t const* screen, x::Format format, std::shared_ptr const& atoms, std::shared_ptr const& ewmh, uint16_t width, uint16_t height, bool normal, bool black); void quit_from_xcb(); #if FAKE_MONITOR void toggle_fakes(); #endif void expose(int16_t x, int16_t y, uint16_t w, uint16_t h); bool match(xcb_window_t wnd) const { return wnd == wnd_.get(); } void configure(int16_t x, int16_t y, uint16_t w, uint16_t h); void update_desktop_window(); void update_desktop_window(xcb_window_t window, xcb_atom_t property); static void preload(x::Atoms* atoms); protected: MonMon(std::shared_ptr const& looper); virtual void width_changed() { } #if FAKE_MONITOR virtual void do_toggle_fakes() { } #endif virtual void stop_all_animations() { } virtual void internal_quit() { } virtual void draw_content(cairo_t* cairo, PangoLayout* layout, uint16_t w, uint16_t h) = 0; static void rounded_path(cairo_t* cr, double x, double y, double width, double height); void draw(); std::shared_ptr looper_; std::unique_ptr animator_; x::unique_window wnd_; double box_height_; private: void unset_desktop_window(); void update_desktop_pixmap(); void close_pipe(); void pipe(Looper*, int, uint8_t event); void internal_draw(); void force_draw(); void tick(Animator*) override; io::pipe pipe_; std::shared_ptr atoms_; x::unique_gcontext gcontext_; x::unique_colormap cmap_; uint8_t depth_; uint32_t black_pixel_; xcb_screen_t const* screen_; std::mutex mutex_; cairo::unique_surface surface_; cairo::unique cairo_; pango::unique_layout layout_; x::unique_pixmap pixmap_; int16_t x_, y_; uint16_t w_, h_; xcb_atom_t rootpmap_; xcb_window_t desktop_window_; xcb_pixmap_t desktop_pixmap_; cairo::unique_surface desktop_surface_; }; #endif // MONMON_HH