nux-0.9.46

Nux/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 
00057   class WindowThread: public AbstractThread
00058   {
00059     NUX_DECLARE_OBJECT_TYPE (WindowThread, AbstractThread);
00060   public:
00061     WindowThread (const TCHAR *WindowTitle, unsigned int width, unsigned int height, AbstractThread *Parent, bool Modal);
00062     ~WindowThread();
00063 
00065 
00068     void SetLayout (Layout *layout);
00069 
00070     void TerminateThread();
00071 
00073     void RunUserInterface();
00074 
00075     // Event, Drawing
00076     virtual long ProcessEvent (IEvent &event, long TraverseInfo, long ProcessEventInfo);
00077 
00078     void ProcessDraw (GraphicsEngine &GfxContext, bool force_draw);
00079 
00080     void SetWindowTitle (const TCHAR *WindowTitle)
00081     {
00082       m_WindowTitle = WindowTitle;
00083     }
00084 
00085     GraphicsDisplay &GetWindow() const
00086     {
00087       return *_graphics_display;
00088     }
00089 
00090     GraphicsEngine &GetGraphicsEngine() const
00091     {
00092       return *_graphics_display->GetGraphicsEngine();
00093     }
00094     
00095     BasePainter &GetPainter() const
00096     {
00097       return *m_Painter;
00098     }
00099     
00100     TimerHandler &GetTimerHandler() const
00101     {
00102       return *m_TimerHandler;
00103     }
00104     
00105     UXTheme &GetTheme() const
00106     {
00107       return *m_Theme;
00108     }
00109 
00110     void SetWindowSize (int width, int height);
00111 
00112     void SetWindowBackgroundPaintLayer (AbstractPaintLayer *bkg);
00113 
00114     void RequestRedraw();
00115 
00116     void ClearRedrawFlag();
00117 
00118     bool IsRedrawNeeded() const;
00119 
00120     void AddToDrawList (View *view);
00121 
00122     void ClearDrawList ();
00123 
00124     std::vector<Geometry> GetDrawList ();
00125 
00126     // Layout
00127 
00129 
00132     void QueueMainLayout ();
00133 
00135 
00140     bool QueueObjectLayout (Area *area);
00141     void AddObjectToRefreshList (Area *area); 
00142 
00144 
00149     bool RemoveObjectFromLayoutQueue (Area *area);
00150 
00152     bool RemoveObjectFromRefreshList (Area *area);
00153 
00155 
00158     void RemoveQueuedLayout ();
00159 
00161 
00164     void ComputeElementLayout(Area* bo, bool recurse_to_top_level_layout = false);
00165 
00167 
00170     bool IsInsideLayoutCycle () const;
00171 
00173     bool IsComputingLayout() const
00174     {
00175       return IsInsideLayoutCycle ();
00176     }
00177 
00178     bool IsWaitingforModalWindow()
00179     {
00180       return m_bWaitForModalWindow;
00181     }
00182 
00183     bool IsModalWindow()
00184     {
00185       return m_bWaitForModalWindow;
00186     }
00187 
00188     void SetWindowStyle(WindowStyle wstyle)
00189     {
00190       m_WindowStyle = wstyle;
00191     }
00192 
00193     WindowStyle GetWindowStyle() const
00194     {
00195       return m_WindowStyle;
00196     }
00197 
00198     virtual ThreadState Start( void* arg = NULL );
00199 
00200     WindowCompositor& GetWindowCompositor()
00201     {
00202       return *m_window_compositor;
00203     }
00204     // should be private
00205 
00206     float GetFrameRate() const;
00207     t_u32 GetFrameCounter() const;
00208     t_u32 GetFramePeriodeCounter() const;
00209 
00210     bool IsEmbeddedWindow();
00211 
00212 #if defined(NUX_OS_WINDOWS)
00213     bool ProcessForeignEvent (HWND hWnd, MSG msg, WPARAM wParam, LPARAM lParam, void *data);
00214 #elif defined(NUX_OS_LINUX)
00215     bool ProcessForeignEvent (XEvent *event, void *data);
00216 #endif
00217 
00218     void RenderInterfaceFromForeignCmd(nux::Geometry *clip);
00219 
00220     virtual unsigned int Run (void *);
00221 
00234     virtual bool ThreadCtor();
00235 
00236 #if defined(NUX_OS_WINDOWS)
00237 
00251     virtual bool ThreadCtor (HWND WindowHandle, HDC WindowDCHandle, HGLRC OpenGLRenderingContext);
00252 #elif defined(NUX_OS_LINUX)
00253 
00267     virtual bool ThreadCtor (Display *X11Display, Window X11Window, GLXContext OpenGLContext);
00268 #endif
00269 
00277     virtual bool ThreadDtor();
00278 
00280 
00283     Layout* GetMainLayout();
00284 
00288     void AddTimeline (Timeline* timeline);
00289     void RemoveTimeline (Timeline* timeline);
00290     bool ProcessTimelines (GTimeVal *frame_time);
00291     long _last_timeline_frame_time_sec;
00292     long _last_timeline_frame_time_usec;
00293 
00294     void StartMasterClock ();
00295     void StopMasterClock ();
00299     void *m_InitData;
00300     void *m_ExitData;
00301 
00302     sigc::signal<void> RedrawRequested;
00303 
00304     bool _inside_main_loop;
00305     bool _inside_timer_loop;
00306     bool _pending_wake_up_timer;
00307 
00308     TimerFunctor *_async_wake_up_functor;
00309     TimerHandle _async_wake_up_timer;
00310 
00311     // quits the main loop.
00312     void NuxMainLoopQuit ();
00313 
00314     // Automation
00315 
00316 #if defined (NUX_OS_WINDOWS)
00317 
00324     bool PumpFakeEventIntoPipe (WindowThread* window_thread, INPUT *win_event);
00325     
00326     INPUT _fake_event;
00327 #elif defined (NUX_OS_LINUX)
00328 
00335     bool PumpFakeEventIntoPipe (WindowThread* window_thread, XEvent *xevent);
00336     
00337     XEvent _fake_event;
00338 #endif
00339     
00348     void SetFakeEventMode (bool enable);
00349     
00356     bool InFakeEventMode () const;
00357 
00362     void ReadyFakeEventProcessing (void*);
00363     
00368     bool ReadyForNextFakeEvent () const;
00369 
00370     bool _ready_for_next_fake_event;
00371     bool _processing_fake_event;
00372     bool _fake_event_mode;
00373     TimerFunctor *_fake_event_call_back;
00374     TimerHandle _fake_event_timer;
00375 
00377 
00387     int InstallEventInspector (EventInspector function, void* data);
00388 
00390 
00396     bool RemoveEventInspector (int event_inspector_id);
00397 
00399 
00405     bool RemoveEventInspector (EventInspector function);
00406 
00408 
00413     bool CallEventInspectors (Event* event);
00414 
00419     void SetFocusedArea (Area *focused_area);
00420     
00421   protected:
00423 
00428     void ReconfigureLayout();
00429 
00430     void AsyncWakeUpCallback (void*);
00431 
00432     //void SetModalWindow(bool b) {m_bIsModal = b;}
00433 
00437     void EnableMouseKeyboardInput();
00438 
00442     void DisableMouseKeyboardInput();
00443 
00444 #if (defined(NUX_OS_LINUX) || defined(NUX_USE_GLIB_LOOP_ON_WINDOWS)) && (!defined(NUX_DISABLE_GLIB_LOOP))
00445     t_u32 ExecutionLoop (t_u32 timer_id);
00446 #else
00447     t_u32 ExecutionLoop();
00448 #endif
00449 
00450     virtual ThreadState StartChildThread (NThread *thread, bool Modal);
00451     virtual void AddChildThread (NThread *);
00452     virtual void RemoveChildThread (NThread *);
00453     virtual void ChildHasFinished (NThread *app);
00454     virtual void TerminateAllChildThread();
00455     virtual ThreadState SuspendChildGraphics (WindowThread *app);
00456 
00457     bool m_bWaitForModalWindow;
00458     WindowThread *m_ModalWindowThread;
00459 
00460     //typedef Loki::Functor< void, LOKI_TYPELIST_1(void*)   > ChildThreadExitCallback;
00461 
00462     typedef struct
00463     {
00464       NThread *thread;
00465       std::list< sigc::signal<void, void *> > ChildThreadExitCallback;
00466     } ThreadInfo;
00467 
00468     //std::list<NThread*> m_ChildThread;
00469     std::list< ThreadInfo * > m_ChildThreadInfo;
00470 
00471   private:
00472     void OnFocusedAreaDestroyed (Object *object);
00473     Area *_focused_area;
00474     sigc::connection _focused_area_destroyed_con;
00476 
00480     void StartLayoutCycle ();
00481 
00483 
00487     void StopLayoutCycle ();
00488 
00490     /*
00491         The objects whose size is to be computed are added to a list with a call to AddObjectToRefreshList.
00492         Size computation is performed just before the rendering cycle.
00493         \sa AddObjectToRefreshList
00494     */
00495     void ComputeQueuedLayout ();
00496     void RefreshLayout ();  
00497 
00498     GSource *_MasterClock;
00499 
00500     WindowThread (const WindowThread &);
00501     // Does not make sense for a singleton. This is a self assignment.
00502     WindowThread &operator= (const WindowThread &);
00503     // Declare operator address-of as private
00504     WindowThread *operator &();
00505 
00507 
00510     std::list<Area *> _queued_layout_list;
00511     std::vector<Geometry> m_dirty_areas;
00512 
00514     bool _inside_layout_cycle;
00515 
00517     bool _queue_main_layout;
00518 
00519     float m_FrameRate;
00520     t_u32 m_FrameCounter;
00521     t_u32 m_FramePeriodeCounter;
00522     float m_PeriodeTime;
00523 
00524     std::list<Timeline*> *_Timelines;
00525 
00526     bool m_bFirstDrawPass;
00527     unsigned int m_StartupWidth;
00528     unsigned int m_StartupHeight;
00529     NString m_WindowTitle;
00530 
00531     bool _draw_requested_to_host_wm;  
00532     Layout *_main_layout;
00533 
00534     UXTheme         *m_Theme;
00535     BasePainter     *m_Painter;
00536     TimerHandler    *m_TimerHandler;
00537 
00538     GraphicsDisplay *_graphics_display;
00539     GraphicsEngine *m_GraphicsContext;
00540     WindowCompositor *m_window_compositor;
00541     std::list<NThread *> m_ThreadList;
00542     bool m_WidgetInitialized;
00543     WindowStyle m_WindowStyle;
00544     bool m_bIsModal;
00545 
00546     bool m_ThreadCtorCalled;    
00547 
00548     bool m_ThreadDtorCalled;    
00549 
00550     bool m_embedded_window;             
00551 
00556     bool m_size_configuration_event;
00557 
00558     bool m_force_redraw;
00559 
00560     typedef struct _EventInspectorStorage
00561     {
00562       _EventInspectorStorage ()
00563       {
00564         _function = 0;
00565         _data = 0;
00566         _uid = 0;
00567       }
00568       EventInspector  _function;
00569       void*           _data;
00570       int             _uid;
00571     } EventInspectorStorage;
00572     
00574 
00578     std::map<int, EventInspectorStorage> _event_inspectors_map; 
00579 
00580     friend class BasePainter;
00581     friend class SystemThread;
00582 
00583 #if (defined(NUX_OS_LINUX) || defined(NUX_USE_GLIB_LOOP_ON_WINDOWS)) && (!defined(NUX_DISABLE_GLIB_LOOP))
00584     GMainLoop *m_GLibLoop;
00585     GMainContext *m_GLibContext;
00586     friend gboolean nux_event_dispatch (GSource *source, GSourceFunc callback, gpointer user_data);
00587     friend gboolean nux_timeout_dispatch (gpointer user_data);
00588 
00589     void InitGlibLoop();
00590     t_u32 AddGLibTimeout (t_u32 duration);
00591 #endif
00592     friend class TimerHandler;
00593 
00594     friend WindowThread *CreateGUIThread (const TCHAR *WindowTitle,
00595                                           t_u32 width,
00596                                           t_u32 height,
00597                                           WindowThread *Parent,
00598                                           ThreadUserInitFunc UserInitFunc,
00599                                           void *InitData);
00600 
00601     friend WindowThread *CreateWindowThread (WindowStyle WndStyle,
00602         const TCHAR *WindowTitle,
00603         t_u32 width,
00604         t_u32 height,
00605         WindowThread *Parent,
00606         ThreadUserInitFunc UserInitFunc,
00607         void *InitData);
00608 
00609     friend WindowThread *CreateModalWindowThread (WindowStyle WndStyle,
00610         const TCHAR *WindowTitle,
00611         t_u32 width,
00612         t_u32 height,
00613         WindowThread *Parent,
00614         ThreadUserInitFunc UserInitFunc,
00615         void *InitData);
00616 
00617 #if defined(NUX_OS_WINDOWS)
00618     friend WindowThread *CreateFromForeignWindow (HWND WindowHandle, HDC WindowDCHandle, HGLRC OpenGLRenderingContext,
00619         ThreadUserInitFunc UserInitFunc,
00620         void *InitData);
00621 #elif defined(NUX_OS_LINUX)
00622     friend WindowThread *CreateFromForeignWindow (Window X11Window, GLXContext OpenGLContext,
00623         ThreadUserInitFunc UserInitFunc,
00624         void *InitData);
00625 #endif
00626 
00627     friend SystemThread *CreateSystemThread (AbstractThread *Parent, ThreadUserInitFunc UserInitFunc, void *InitData);
00628 
00629   };
00630 
00631 }
00632 
00633 #endif // WINDOWTHREAD_H