Rapicorn - Experimental UI Toolkit - Source Code  13.07.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines
screenwindow.hh
Go to the documentation of this file.
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 &region);   
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 &region);
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__ */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines