nux-0.9.48
|
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