nux-1.16.0
WindowThread.h
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     void SetWindowSize (int width, int height);
00108 
00109     void SetWindowBackgroundPaintLayer (AbstractPaintLayer *bkg);
00110 
00111     void RequestRedraw();
00112 
00113     void ClearRedrawFlag();
00114 
00115     bool IsRedrawNeeded() const;
00116 
00117     void AddToDrawList (View *view);
00118 
00119     void ClearDrawList ();
00120 
00121     std::vector<Geometry> GetDrawList ();
00122 
00123     // Layout
00124 
00126 
00129     void QueueMainLayout ();
00130 
00132 
00137     bool QueueObjectLayout (Area *area);
00138     void AddObjectToRefreshList (Area *area); 
00139 
00141 
00146     bool RemoveObjectFromLayoutQueue (Area *area);
00147 
00149     bool RemoveObjectFromRefreshList (Area *area);
00150 
00152 
00155     void RemoveQueuedLayout ();
00156 
00158 
00161     void ComputeElementLayout(Area* bo, bool recurse_to_top_level_layout = false);
00162 
00164 
00167     bool IsInsideLayoutCycle () const;
00168 
00170     bool IsComputingLayout() const
00171     {
00172       return IsInsideLayoutCycle ();
00173     }
00174 
00175     bool IsWaitingforModalWindow()
00176     {
00177       return m_bWaitForModalWindow;
00178     }
00179 
00180     bool IsModalWindow()
00181     {
00182       return m_bWaitForModalWindow;
00183     }
00184 
00185     void SetWindowStyle(WindowStyle wstyle)
00186     {
00187       m_WindowStyle = wstyle;
00188     }
00189 
00190     WindowStyle GetWindowStyle() const
00191     {
00192       return m_WindowStyle;
00193     }
00194 
00195     virtual ThreadState Start( void* arg = NULL );
00196 
00197     WindowCompositor& GetWindowCompositor()
00198     {
00199       return *m_window_compositor;
00200     }
00201     // should be private
00202 
00203     float GetFrameRate() const;
00204     t_u32 GetFrameCounter() const;
00205     t_u32 GetFramePeriodeCounter() const;
00206 
00207     bool IsEmbeddedWindow();
00208 
00209 #if defined(NUX_OS_WINDOWS)
00210     bool ProcessForeignEvent (HWND hWnd, MSG msg, WPARAM wParam, LPARAM lParam, void *data);
00211 #elif defined(NUX_OS_LINUX)
00212     bool ProcessForeignEvent (XEvent *event, void *data);
00213 #endif
00214 
00215     void RenderInterfaceFromForeignCmd(nux::Geometry *clip);
00216 
00217     virtual unsigned int Run (void *);
00218 
00231     virtual bool ThreadCtor();
00232 
00233 #if defined(NUX_OS_WINDOWS)
00234 
00248     virtual bool ThreadCtor (HWND WindowHandle, HDC WindowDCHandle, HGLRC OpenGLRenderingContext);
00249 #elif defined(NUX_OS_LINUX)
00250 
00264     virtual bool ThreadCtor (Display *X11Display, Window X11Window, GLXContext OpenGLContext);
00265     Display *_x11display;
00266     bool     _ownx11display;
00267 #endif
00268 
00276     virtual bool ThreadDtor();
00277 
00279 
00282     Layout* GetMainLayout();
00283 
00287     void AddTimeline (Timeline* timeline);
00288     void RemoveTimeline (Timeline* timeline);
00289     bool ProcessTimelines (GTimeVal *frame_time);
00290     long _last_timeline_frame_time_sec;
00291     long _last_timeline_frame_time_usec;
00292 
00293     void StartMasterClock ();
00294     void StopMasterClock ();
00298     void *m_InitData;
00299     void *m_ExitData;
00300 
00301     sigc::signal<void> RedrawRequested;
00302 
00303     bool _inside_main_loop;
00304     bool _inside_timer_loop;
00305     bool _pending_wake_up_timer;
00306 
00307     TimerFunctor *_async_wake_up_functor;
00308     TimerHandle _async_wake_up_timer;
00309 
00310     // quits the main loop.
00311     void NuxMainLoopQuit ();
00312 
00313     // Automation
00314 
00315 #if defined (NUX_OS_WINDOWS)
00316 
00323     bool PumpFakeEventIntoPipe (WindowThread* window_thread, INPUT *win_event);
00324     
00325     INPUT _fake_event;
00326 #elif defined (NUX_OS_LINUX)
00327 
00334     bool PumpFakeEventIntoPipe (WindowThread* window_thread, XEvent *xevent);
00335     
00336     XEvent _fake_event;
00337 #endif
00338     
00347     void SetFakeEventMode (bool enable);
00348     
00355     bool InFakeEventMode () const;
00356 
00361     void ReadyFakeEventProcessing (void*);
00362     
00367     bool ReadyForNextFakeEvent () const;
00368 
00369     bool _ready_for_next_fake_event;
00370     bool _processing_fake_event;
00371     bool _fake_event_mode;
00372     TimerFunctor *_fake_event_call_back;
00373     TimerHandle _fake_event_timer;
00374 
00376 
00386     int InstallEventInspector (EventInspector function, void* data);
00387 
00389 
00395     bool RemoveEventInspector (int event_inspector_id);
00396 
00398 
00404     bool RemoveEventInspector (EventInspector function);
00405 
00407 
00412     bool CallEventInspectors (Event* event);
00413 
00418     void SetFocusedArea (Area *focused_area);
00419     
00420   protected:
00422 
00427     void ReconfigureLayout();
00428 
00429     void AsyncWakeUpCallback (void*);
00430 
00431     //void SetModalWindow(bool b) {m_bIsModal = b;}
00432 
00436     void EnableMouseKeyboardInput();
00437 
00441     void DisableMouseKeyboardInput();
00442 
00443 #if (defined(NUX_OS_LINUX) || defined(NUX_USE_GLIB_LOOP_ON_WINDOWS)) && (!defined(NUX_DISABLE_GLIB_LOOP))
00444     t_u32 ExecutionLoop (t_u32 timer_id);
00445 #else
00446     t_u32 ExecutionLoop();
00447 #endif
00448 
00449     virtual ThreadState StartChildThread (NThread *thread, bool Modal);
00450     virtual void AddChildThread (NThread *);
00451     virtual void RemoveChildThread (NThread *);
00452     virtual void ChildHasFinished (NThread *app);
00453     virtual void TerminateAllChildThread();
00454     virtual ThreadState SuspendChildGraphics (WindowThread *app);
00455 
00456     bool m_bWaitForModalWindow;
00457     WindowThread *m_ModalWindowThread;
00458 
00459     //typedef Loki::Functor< void, LOKI_TYPELIST_1(void*)   > ChildThreadExitCallback;
00460 
00461     typedef struct
00462     {
00463       NThread *thread;
00464       std::list< sigc::signal<void, void *> > ChildThreadExitCallback;
00465     } ThreadInfo;
00466 
00467     //std::list<NThread*> m_ChildThread;
00468     std::list< ThreadInfo * > m_ChildThreadInfo;
00469 
00470   private:
00471     void OnFocusedAreaDestroyed (Object *object);
00472     Area *_focused_area;
00473     sigc::connection _focused_area_destroyed_con;
00475 
00479     void StartLayoutCycle ();
00480 
00482 
00486     void StopLayoutCycle ();
00487 
00489     /*
00490         The objects whose size is to be computed are added to a list with a call to AddObjectToRefreshList.
00491         Size computation is performed just before the rendering cycle.
00492         \sa AddObjectToRefreshList
00493     */
00494     void ComputeQueuedLayout ();
00495     void RefreshLayout ();  
00496 
00497     GSource *_MasterClock;
00498 
00499     WindowThread (const WindowThread &);
00500     // Does not make sense for a singleton. This is a self assignment.
00501     WindowThread &operator= (const WindowThread &);
00502     // Declare operator address-of as private
00503     WindowThread *operator &();
00504 
00506 
00509     std::list<Area *> _queued_layout_list;
00510     std::vector<Geometry> m_dirty_areas;
00511 
00513     bool _inside_layout_cycle;
00514 
00516     bool _queue_main_layout;
00517 
00518     float m_FrameRate;
00519     t_u32 m_FrameCounter;
00520     t_u32 m_FramePeriodeCounter;
00521     float m_PeriodeTime;
00522 
00523     std::list<Timeline*> *_Timelines;
00524 
00525     bool m_bFirstDrawPass;
00526     unsigned int m_StartupWidth;
00527     unsigned int m_StartupHeight;
00528     NString m_WindowTitle;
00529 
00530     bool _draw_requested_to_host_wm;  
00531     Layout *_main_layout;
00532 
00533     UXTheme         *m_Theme;
00534     BasePainter     *m_Painter;
00535     TimerHandler    *m_TimerHandler;
00536 
00537     GraphicsDisplay *_graphics_display;
00538     GraphicsEngine *m_GraphicsContext;
00539     WindowCompositor *m_window_compositor;
00540     std::list<NThread *> m_ThreadList;
00541     bool m_WidgetInitialized;
00542     WindowStyle m_WindowStyle;
00543     bool m_bIsModal;
00544 
00545     bool m_ThreadCtorCalled;    
00546 
00547     bool m_ThreadDtorCalled;    
00548 
00549     bool m_embedded_window;             
00550 
00555     bool m_size_configuration_event;
00556 
00557     bool m_force_redraw;
00558 
00559     typedef struct _EventInspectorStorage
00560     {
00561       _EventInspectorStorage ()
00562       {
00563         _function = 0;
00564         _data = 0;
00565         _uid = 0;
00566       }
00567       EventInspector  _function;
00568       void*           _data;
00569       int             _uid;
00570     } EventInspectorStorage;
00571     
00573 
00577     std::map<int, EventInspectorStorage> _event_inspectors_map; 
00578 
00579     friend class BasePainter;
00580     friend class SystemThread;
00581 
00582 #if (defined(NUX_OS_LINUX) || defined(NUX_USE_GLIB_LOOP_ON_WINDOWS)) && (!defined(NUX_DISABLE_GLIB_LOOP))
00583     GMainLoop *m_GLibLoop;
00584     GMainContext *m_GLibContext;
00585     friend gboolean nux_event_dispatch (GSource *source, GSourceFunc callback, gpointer user_data);
00586     friend gboolean nux_timeout_dispatch (gpointer user_data);
00587 
00588     void InitGlibLoop();
00589     t_u32 AddGLibTimeout (t_u32 duration);
00590 #endif
00591     friend class TimerHandler;
00592 
00593     friend WindowThread *CreateGUIThread (const TCHAR *WindowTitle,
00594                                           t_u32 width,
00595                                           t_u32 height,
00596                                           WindowThread *Parent,
00597                                           ThreadUserInitFunc UserInitFunc,
00598                                           void *InitData);
00599 
00600     friend WindowThread *CreateWindowThread (WindowStyle WndStyle,
00601         const TCHAR *WindowTitle,
00602         t_u32 width,
00603         t_u32 height,
00604         WindowThread *Parent,
00605         ThreadUserInitFunc UserInitFunc,
00606         void *InitData);
00607 
00608     friend WindowThread *CreateModalWindowThread (WindowStyle WndStyle,
00609         const TCHAR *WindowTitle,
00610         t_u32 width,
00611         t_u32 height,
00612         WindowThread *Parent,
00613         ThreadUserInitFunc UserInitFunc,
00614         void *InitData);
00615 
00616 #if defined(NUX_OS_WINDOWS)
00617     friend WindowThread *CreateFromForeignWindow (HWND WindowHandle, HDC WindowDCHandle, HGLRC OpenGLRenderingContext,
00618         ThreadUserInitFunc UserInitFunc,
00619         void *InitData);
00620 #elif defined(NUX_OS_LINUX)
00621     friend WindowThread *CreateFromForeignWindow (Window X11Window, GLXContext OpenGLContext,
00622         ThreadUserInitFunc UserInitFunc,
00623         void *InitData);
00624 #endif
00625 
00626     friend SystemThread *CreateSystemThread (AbstractThread *Parent, ThreadUserInitFunc UserInitFunc, void *InitData);
00627 
00628   };
00629 
00630 }
00631 
00632 #endif // WINDOWTHREAD_H
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends