Rapicorn - Experimental UI Toolkit - Source Code
13.07.0
|
00001 // Licensed GNU LGPL v3 or later: http://www.gnu.org/licenses/lgpl.html 00002 #ifndef __RAPICORN_SCREEN_WINDOW_HH__ 00003 #define __RAPICORN_SCREEN_WINDOW_HH__ 00004 00005 #include <ui/events.hh> 00006 #include <ui/region.hh> 00007 00008 namespace Rapicorn { 00009 class ScreenDriver; 00010 class ScreenCommand; 00011 00013 class ScreenWindow : public virtual Deletable, public virtual std::enable_shared_from_this<ScreenWindow> { 00014 RAPICORN_CLASS_NON_COPYABLE (ScreenWindow); 00015 public: 00017 enum Flags { 00018 MODAL = 1 << 0, 00019 STICKY = 1 << 1, 00020 VMAXIMIZED = 1 << 2, 00021 HMAXIMIZED = 1 << 3, 00022 SHADED = 1 << 4, 00023 SKIP_TASKBAR = 1 << 5, 00024 SKIP_PAGER = 1 << 6, 00025 HIDDEN = 1 << 7, 00026 FULLSCREEN = 1 << 8, 00027 ABOVE_ALL = 1 << 9, 00028 BELOW_ALL = 1 << 10, 00029 ATTENTION = 1 << 11, 00030 FOCUS_DECO = 1 << 12, 00031 _WM_STATE_MASK = 0x00003fff, 00032 DECORATED = 1 << 24, 00033 MINIMIZABLE = 1 << 25, 00034 MAXIMIZABLE = 1 << 26, 00035 DELETABLE = 1 << 27, 00036 _DECO_MASK = 0x0f000000, 00037 ACCEPT_FOCUS = 1 << 28, 00038 UNFOCUSED = 1 << 29, 00039 ICONIFY = 1 << 30, 00040 }; 00041 static String flags_name (uint64 flags, String combo = ","); 00042 00043 struct Setup { 00044 WindowType window_type; 00045 Flags request_flags; 00046 String session_role; 00047 Color bg_average; 00048 inline Setup(); 00049 }; 00051 struct Config { 00052 String title; 00053 String alias; 00054 int root_x, root_y; 00055 int request_width, request_height; 00056 int width_inc, height_inc; 00057 inline Config(); 00058 }; 00060 struct State { 00061 WindowType window_type; 00062 Flags window_flags; 00063 String visible_title; 00064 String visible_alias; 00065 int width, height; 00066 int root_x, root_y; 00067 int deco_x, deco_y; 00068 bool visible; 00069 bool active; 00070 inline State(); 00071 inline bool operator== (const State &o) const; 00072 inline bool operator!= (const State &o) const { return !operator== (o); } 00073 }; 00074 // == public API == 00075 State get_state (); 00076 void beep (); 00077 void show (); 00078 void present (); 00079 bool viewable (); 00080 void destroy (); 00081 void configure (const Config &config, bool sizeevent); 00082 void blit_surface (cairo_surface_t *surface, const Rapicorn::Region ®ion); 00083 void start_user_move (uint button, double root_x, double root_y); 00084 void start_user_resize (uint button, double root_x, double root_y, AnchorType edge); 00085 Event* pop_event (); 00086 void push_event (Event *event); 00087 bool has_event (); 00088 void set_event_wakeup (const std::function<void()> &wakeup); 00089 bool peek_events (const std::function<bool (Event*)> &pred); 00090 protected: 00091 explicit ScreenWindow (); 00092 virtual ~ScreenWindow (); 00093 virtual ScreenDriver& screen_driver_async () const = 0; 00094 void enqueue_event (Event *event); 00095 bool update_state (const State &state); 00096 void queue_command (ScreenCommand *command); 00097 private: 00098 State async_state_; 00099 bool async_state_accessed_; 00100 Spinlock async_spin_; 00101 std::list<Event*> async_event_queue_; 00102 std::function<void()> async_wakeup_; 00103 }; 00104 typedef std::shared_ptr<ScreenWindow> ScreenWindowP; 00105 00106 struct ScreenCommand 00107 { 00108 enum Type { CREATE = 1, CONFIGURE, BEEP, SHOW, PRESENT, BLIT, UMOVE, URESIZE, DESTROY, SHUTDOWN, OK, ERROR, }; 00109 Type type; 00110 ScreenWindow *screen_window; 00111 union { 00112 struct { ScreenWindow::Config *config; ScreenWindow::Setup *setup; }; 00113 struct { ScreenWindow::Config *dconfig; bool dresize; }; 00114 struct { cairo_surface_t *surface; Rapicorn::Region *region; }; 00115 struct { int button, root_x, root_y; }; 00116 struct { String *result_msg; }; 00117 }; 00118 ScreenCommand (Type type, ScreenWindow *window); 00119 ScreenCommand (Type type, ScreenWindow *window, const ScreenWindow::Config &cfg, bool sizeevent); 00120 ScreenCommand (Type type, ScreenWindow *window, const ScreenWindow::Setup &cs, const ScreenWindow::Config &cfg); 00121 ScreenCommand (Type type, ScreenWindow *window, cairo_surface_t *surface, const Rapicorn::Region ®ion); 00122 ScreenCommand (Type type, ScreenWindow *window, int button, int root_x, int root_y); 00123 ScreenCommand (Type type, ScreenWindow *window, const String &result); 00124 ~ScreenCommand(); 00125 static bool reply_type (Type type); 00126 }; 00127 00129 class ScreenDriver { 00130 AsyncNotifyingQueue<ScreenCommand*> command_queue_; 00131 AsyncBlockingQueue<ScreenCommand*> reply_queue_; 00132 std::thread thread_handle_; 00133 RAPICORN_CLASS_NON_COPYABLE (ScreenDriver); 00134 protected: 00135 ScreenDriver *sibling_; 00136 String name_; 00137 int priority_; 00138 virtual void run (AsyncNotifyingQueue<ScreenCommand*> &command_queue, AsyncBlockingQueue<ScreenCommand*> &reply_queue) = 0; 00140 explicit ScreenDriver (const String &name, int priority = 0); 00141 virtual ~ScreenDriver (); 00142 void queue_command (ScreenCommand *screen_command); 00143 bool open_L (); 00144 void close_L (); 00145 public: 00147 ScreenWindow* create_screen_window (const ScreenWindow::Setup &setup, const ScreenWindow::Config &config); 00149 static ScreenDriver* retrieve_screen_driver (const String &backend_name); 00151 static bool driver_priority_lesser (const ScreenDriver *d1, const ScreenDriver *d2); 00153 static void forcefully_close_all (); 00154 class Friends { friend class ScreenWindow; static void queue_command (ScreenDriver &d, ScreenCommand *c) { d.queue_command (c); } }; 00156 }; 00157 00159 template<class DriverImpl> 00160 struct ScreenDriverFactory : public ScreenDriver { 00161 Atomic<int> running; 00162 ScreenDriverFactory (const String &name, int priority = 0) : 00163 ScreenDriver (name, priority), running (false) 00164 {} 00165 virtual void 00166 run (AsyncNotifyingQueue<ScreenCommand*> &command_queue, AsyncBlockingQueue<ScreenCommand*> &reply_queue) 00167 { 00168 running = true; 00169 DriverImpl driver (*this, command_queue, reply_queue); 00170 if (driver.connect()) 00171 { 00172 reply_queue.push (new ScreenCommand (ScreenCommand::OK, NULL)); 00173 driver.run(); 00174 } 00175 else 00176 reply_queue.push (new ScreenCommand (ScreenCommand::ERROR, NULL, "")); 00177 running = false; 00178 } 00179 virtual 00180 ~ScreenDriverFactory() 00181 { 00182 assert (running == false); 00183 } 00184 }; 00185 00186 // == Implementations == 00187 ScreenWindow::Setup::Setup() : 00188 window_type (WindowType (0)), request_flags (ScreenWindow::Flags (0)) 00189 {} 00190 00191 ScreenWindow::Config::Config() : 00192 root_x (INT_MIN), root_y (INT_MIN), request_width (0), request_height (0), width_inc (0), height_inc (0) 00193 {} 00194 00195 ScreenWindow::State::State() : 00196 window_flags (ScreenWindow::Flags (0)), 00197 width (0), height (0), root_x (INT_MIN), root_y (INT_MIN), deco_x (INT_MIN), deco_y (INT_MIN), 00198 visible (0), active (0) 00199 {} 00200 00201 bool 00202 ScreenWindow::State::operator== (const State &o) const 00203 { 00204 return window_type == o.window_type && window_flags == o.window_flags && width == o.width && height == o.height && 00205 root_x == o.root_x && root_y == o.root_y && deco_x == o.deco_x && deco_y == o.deco_y && 00206 visible == o.visible && active == o.active && visible_title == o.visible_title && visible_alias == o.visible_alias; 00207 } 00208 00209 } // Rapicorn 00210 00211 #endif /* __RAPICORN_SCREEN_WINDOW_HH__ */