Back to index

nux  3.0.0
WindowThread.h
Go to the documentation of this file.
00001 /*
00002  * Copyright 2010 Inalogic® Inc.
00003  *
00004  * This program is free software: you can redistribute it and/or modify it
00005  * under the terms of the GNU Lesser General Public License, as
00006  * published by the  Free Software Foundation; either version 2.1 or 3.0
00007  * of the License.
00008  *
00009  * This program is distributed in the hope that it will be useful, but
00010  * WITHOUT ANY WARRANTY; without even the implied warranties of
00011  * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
00012  * PURPOSE.  See the applicable version of the GNU Lesser General Public
00013  * License for more details.
00014  *
00015  * You should have received a copy of both the GNU Lesser General Public
00016  * License along with this program. If not, see <http://www.gnu.org/licenses/>
00017  *
00018  * Authored by: Jay Taoko <jaytaoko@inalogic.com>
00019  *
00020  */
00021 
00022 
00023 #ifndef WINDOWTHREAD_H
00024 #define WINDOWTHREAD_H
00025 
00026 #include "TimerProc.h"
00027 
00028 namespace nux
00029 {
00030 
00031   class WindowThread;
00032   class Layout;
00033   class HLayout;
00034   class GraphicsDisplay;
00035   class ClientArea;
00036   class WindowCompositor;
00037   class AbstractThread;
00038   class SystemThread;
00039   class UXTheme;
00040   class TimerHandler;
00041   class Timeline;
00042   class Event;
00043   class Area;
00044   struct ClientAreaDraw;
00045 
00046 #if (defined(NUX_OS_LINUX) || defined(NUX_USE_GLIB_LOOP_ON_WINDOWS)) && (!defined(NUX_DISABLE_GLIB_LOOP))
00047   gboolean nux_event_dispatch(GSource *source, GSourceFunc callback, gpointer user_data);
00048   gboolean nux_timeout_dispatch(gpointer user_data);
00049 #endif
00050 
00052 
00055   typedef int(*EventInspector) (Area* area, Event* event, void* data);
00056 
00058 
00061   class WindowThread: public AbstractThread
00062   {
00063     NUX_DECLARE_OBJECT_TYPE(WindowThread, AbstractThread);
00064   public:
00065     WindowThread(const char *WindowTitle, int width, int height, AbstractThread *Parent, bool Modal);
00066     virtual ~WindowThread();
00067 
00069 
00075     virtual int Run(void *ptr = NULL);
00076 
00082     virtual ThreadState Start(void *ptr = NULL);
00083 
00085 
00088     void ExitMainLoop();
00089 
00091 
00097     void SetWindowSize(int width, int height);
00098 
00100 
00105     void SetWindowBackgroundPaintLayer(AbstractPaintLayer *background_layer);
00106 
00111     GraphicsDisplay &GetGraphicsDisplay() const;
00112 
00117     GraphicsEngine &GetGraphicsEngine() const;
00118 
00123     WindowCompositor& GetWindowCompositor() const;
00124 
00129     BasePainter &GetPainter() const;
00130 
00135     TimerHandler &GetTimerHandler() const;
00136 
00141     UXTheme &GetTheme() const;
00142 
00143 
00145 
00148     void SetLayout(Layout *layout);
00149 
00151 
00154     Layout* GetLayout();
00155 
00157 
00160     bool IsInsideLayoutCycle() const;
00161 
00163     bool IsComputingLayout() const
00164     {
00165       return IsInsideLayoutCycle();
00166     }
00167 
00169 
00176     bool QueueObjectLayout(Area *area);
00177 
00179 
00182     void ComputeElementLayout(Area* bo, bool recurse_to_top_level_layout = false);    
00183 
00185 
00190     bool RemoveObjectFromLayoutQueue(Area *area);
00191 
00197     bool IsWaitingforModalWindow() const;
00198 
00204     bool IsModalWindow() const;
00205 
00211     bool IsEmbeddedWindow();
00212 
00213 #if defined(NUX_OS_WINDOWS)
00214     bool ProcessForeignEvent(HWND hWnd, MSG msg, WPARAM wParam, LPARAM lParam, void *data);
00215 #elif defined(NUX_OS_LINUX)
00216     bool ProcessForeignEvent(XEvent *event, void *data);
00217 #endif
00218 
00226     void RenderInterfaceFromForeignCmd(Geometry *clip);
00227 
00231     void AddTimeline(Timeline* timeline);
00232     void RemoveTimeline(Timeline* timeline);
00233     bool ProcessTimelines(GTimeVal *frame_time);
00234     long last_timeline_frame_time_sec_;
00235     long last_timeline_frame_time_usec_;
00236 
00237     void StartMasterClock();
00238     void StopMasterClock();
00239 
00240     sigc::signal<void> RedrawRequested;
00241     sigc::signal<void, int, int, int, int> window_configuration; 
00242 
00244 
00254     int InstallEventInspector(EventInspector function, void* data);
00255 
00257 
00263     bool RemoveEventInspector(int event_inspector_id);
00264 
00266 
00272     bool RemoveEventInspector(EventInspector function);
00273 
00275 
00280     bool CallEventInspectors(Event* event);
00281 
00283 
00293     TimerHandle SetAsyncTimerCallback(int time_ms, TimeOutSignal* timeout_signal, void *user_data);
00294 
00300     std::string GetWindowTitle() const;
00301 
00302     void ProcessDraw(GraphicsEngine &graphics_engine, bool force_draw);
00303 
00304     void RequestRedraw();
00305 
00306     void ClearRedrawFlag();
00307 
00308     bool IsRedrawNeeded() const;
00309 
00310     void AddToDrawList(View *view);
00311 
00312     void ClearDrawList();
00313 
00314     std::vector<Geometry> GetDrawList();
00315 
00316   protected:
00317 
00330     virtual bool ThreadCtor();
00331 
00332 #if defined(NUX_OS_WINDOWS)
00333 
00346     virtual bool ThreadCtor(HWND WindowHandle, HDC WindowDCHandle, HGLRC OpenGLRenderingContext);
00347 #elif defined(NUX_OS_LINUX)
00348 #ifdef NUX_OPENGLES_20
00349 
00362     virtual bool ThreadCtor(Display *X11Display, Window X11Window, EGLContext OpenGLContext);
00363 #else
00364 
00377     virtual bool ThreadCtor(Display *X11Display, Window X11Window, GLXContext OpenGLContext);
00378 #endif
00379     Display *x11display_;
00380     bool     ownx11display_;
00381 #endif
00382 
00390     virtual bool ThreadDtor();
00391     
00393 
00396     void QueueLayout();
00397 
00399 
00402     void RemoveQueuedLayout();
00403 
00405 
00410     void ReconfigureLayout();
00411 
00416     void EnableMouseKeyboardInput();
00417 
00422     void DisableMouseKeyboardInput();
00423 
00424 #if (defined(NUX_OS_LINUX) || defined(NUX_USE_GLIB_LOOP_ON_WINDOWS)) && (!defined(NUX_DISABLE_GLIB_LOOP))
00425 
00436     unsigned int ExecutionLoop(unsigned int timer_id);
00437 #else
00438 
00448     unsigned int ExecutionLoop();
00449 #endif
00450 
00451     virtual ThreadState StartChildThread(AbstractThread *thread, bool Modal);
00452     virtual void AddChildThread(AbstractThread *);
00453     virtual void RemoveChildThread(AbstractThread *);
00454     virtual void ChildHasFinished(AbstractThread *app);
00455     virtual void TerminateChildThreads();
00456 
00457     virtual ThreadState SuspendChildGraphics(WindowThread *app);
00458 
00459     bool is_modal_window_;
00460     bool wait_for_modal_window_;
00461     WindowThread *modal_window_thread_;
00462 
00463   private:
00465 
00470     int MainLoop();
00471 
00473 
00480     void AsyncWakeUpCallback(void *user_ptr);
00481 
00482     TimeOutSignal *async_wake_up_signal_;
00483     TimerHandle async_wake_up_timer_handle_;
00484 
00486 
00490     void StartLayoutCycle();
00491 
00493 
00497     void StopLayoutCycle();
00498 
00500     /*
00501         The objects whose size is to be computed are added to a list with a call to QueueObjectLayout.
00502         Size computation is performed just before the rendering cycle.
00503         \sa QueueObjectLayout
00504     */
00505     void ComputeQueuedLayout();
00506 
00507     GSource *_MasterClock;
00508 
00509     WindowThread(const WindowThread &);
00510     // Does not make sense for a singleton. This is a self assignment.
00511     WindowThread& operator = (const WindowThread &);
00512     // Declare operator address-of as private
00513     WindowThread* operator & ();
00514 
00515     bool _inside_main_loop;
00516     bool _inside_timer_loop;
00517     bool _pending_wake_up_timer;
00518 
00520 
00523     std::list<Area *> _queued_layout_list;
00524     std::vector<Geometry> m_dirty_areas;
00525 
00527     bool _inside_layout_cycle;
00528 
00530     bool queue_main_layout_;
00531 
00532     std::list<Timeline*> *_Timelines;
00533 
00534     bool first_pass_;                     
00535     unsigned int window_initial_width_;   
00536     unsigned int window_initial_height_;  
00537     std::string window_title_;            
00538 
00539     bool _draw_requested_to_host_wm;      
00540     Layout *main_layout_;
00541 
00542     UXTheme         *theme_;
00543     BasePainter     *painter_;
00544     TimerHandler    *timer_manager_;
00545 
00546     //bool created_own_thread_;             //!< If true, create a system thread and run the window in it.
00547     GraphicsDisplay *graphics_display_;
00548     WindowCompositor *window_compositor_;
00549     bool m_WidgetInitialized;
00550     WindowStyle window_style_;
00551     
00556     bool thread_ctor_called_;
00557 
00562     bool thread_dtor_called_;
00563 
00567     bool embedded_window_;
00568 
00573     bool window_size_configuration_event_;
00574 
00575     bool force_rendering_;
00576 
00577     typedef struct _EventInspectorStorage
00578     {
00579       _EventInspectorStorage()
00580       {
00581         _function = 0;
00582         _data = 0;
00583         _uid = 0;
00584       }
00585       EventInspector  _function;
00586       void*           _data;
00587       int             _uid;
00588     } EventInspectorStorage;
00589     
00591 
00595     std::map<int, EventInspectorStorage> _event_inspectors_map; 
00596 
00597 #if (defined(NUX_OS_LINUX) || defined(NUX_USE_GLIB_LOOP_ON_WINDOWS)) && (!defined(NUX_DISABLE_GLIB_LOOP))
00598     GMainLoop *main_loop_glib_;
00599     GMainContext *main_loop_glib_context_;
00600     friend gboolean nux_event_dispatch(GSource *source, GSourceFunc callback, gpointer user_data);
00601     friend gboolean nux_timeout_dispatch(gpointer user_data);
00602     std::list<GSource*> child_window_list_;
00603 
00604     void InitGlibLoop();
00605     void RunGlibLoop();
00606     void StopGLibLoop();
00607     void CleanupGlibLoop();
00608     bool AddChildWindowGlibLoop(WindowThread* wnd_thread);
00609 
00610     unsigned int AddGLibTimeout(unsigned int duration);
00611 #endif
00612 
00620     unsigned int AddTimeout(unsigned int timeout_delay);
00621 
00622     static const int MINIMUM_WINDOW_WIDTH;  
00623     static const int MINIMUM_WINDOW_HEIGHT; 
00624 
00625     friend class TimerHandler;
00626     friend class BasePainter;
00627     friend class SystemThread;
00628 
00629     friend WindowThread *CreateGUIThread(const char *WindowTitle,
00630                                           int width,
00631                                           int height,
00632                                           WindowThread *Parent,
00633                                           ThreadUserInitFunc UserInitFunc,
00634                                           void *InitData);
00635 
00636     friend WindowThread *CreateNuxWindow(const char *WindowTitle,
00637       int width,
00638       int height,
00639       ThreadUserInitFunc UserInitFunc,
00640       void *InitData);
00641     
00642     friend WindowThread *CreateNuxWindow(const char *window_title,
00643       int width,
00644       int height,
00645       WindowStyle window_border_style,
00646       AbstractThread *parent,
00647       bool modal,
00648       ThreadUserInitFunc user_init_func,
00649       void *data);
00650 
00651     friend WindowThread *CreateNuxWindowNewThread(const char *window_title,
00652       int width,
00653       int height,
00654       WindowStyle window_border_style,
00655       AbstractThread *parent,
00656       bool modal,
00657       ThreadUserInitFunc user_init_func,
00658       void *data);
00659 
00660     friend WindowThread *CreateWindowThread(WindowStyle WndStyle,
00661         const char *WindowTitle,
00662         int width,
00663         int height,
00664         WindowThread *Parent,
00665         ThreadUserInitFunc UserInitFunc,
00666         void *InitData);
00667 
00668     friend WindowThread *CreateModalWindowThread(WindowStyle WndStyle,
00669         const char *WindowTitle,
00670         int width,
00671         int height,
00672         WindowThread *Parent,
00673         ThreadUserInitFunc UserInitFunc,
00674         void *InitData);
00675 
00676 #if defined(NUX_OS_WINDOWS)
00677     friend WindowThread *CreateFromForeignWindow(HWND WindowHandle, HDC WindowDCHandle, HGLRC OpenGLRenderingContext,
00678         ThreadUserInitFunc UserInitFunc,
00679         void *InitData);
00680 #elif defined(NUX_OS_LINUX)
00681 #ifdef NUX_OPENGLES_20
00682     friend WindowThread *CreateFromForeignWindow (Window X11Window, EGLContext OpenGLContext,
00683         ThreadUserInitFunc UserInitFunc,
00684         void *InitData);
00685 #else
00686     friend WindowThread *CreateFromForeignWindow (Window X11Window, GLXContext OpenGLContext,
00687         ThreadUserInitFunc UserInitFunc,
00688         void *InitData);
00689 #endif
00690 #endif
00691 
00692     friend SystemThread *CreateSystemThread(AbstractThread *Parent, ThreadUserInitFunc UserInitFunc, void *InitData);
00693 
00694   };
00695 
00696 }
00697 
00698 #endif // WINDOWTHREAD_H