Back to index

nux  3.0.0
Nux.cpp
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 #include "Nux.h"
00024 #include "NuxGraphics/NuxGraphics.h"
00025 
00026 namespace nux
00027 {
00028 
00029   static NCriticalSection ThreadArrayLock;
00030   std::vector<NThread *> ThreadArray;
00031 
00032   void NuxInitialize(const char *CommandLine)
00033   {
00034     nux::NuxCoreInitialize(0);
00035     nux::NuxGraphicsInitialize();
00036 
00037     // Register a thread local store for the WindowThreads. Each window thread will be able to access its own WindowThread pointer.
00038     inlRegisterThreadLocalIndex(0, ThreadLocal_InalogicAppImpl, NULL);
00039   }
00040 
00041   static WindowThread *_CreateModalWindowThread(const char *window_title,
00042       int width,
00043       int height,
00044       WindowThread *parent,
00045       ThreadUserInitFunc user_init_func,
00046       void *data,
00047       bool Modal)
00048   {
00049     // check that Parent exist
00050     WindowThread *w = new WindowThread(window_title, width, height, parent, Modal);
00051 
00052     if (w == 0)
00053     {
00054       nuxDebugMsg("[_CreateModalWindowThread] WindowThread creation failed.");
00055       return NULL;
00056     }
00057 
00058     return w;
00059   }
00060 
00061   WindowThread *CreateGUIThread(const char *window_title,
00062                                 int width,
00063                                 int height,
00064                                 WindowThread *parent,
00065                                 ThreadUserInitFunc user_init_func,
00066                                 void *data)
00067   {
00068     return CreateNuxWindow(window_title, width, height, WINDOWSTYLE_NORMAL, parent, false, user_init_func, data);
00069   }
00070 
00071   WindowThread *CreateNuxWindow(const char *window_title,
00072     int width,
00073     int height,
00074     WindowStyle window_border_style,
00075     AbstractThread *parent,
00076     bool modal,
00077     ThreadUserInitFunc user_init_func,
00078     void *data)
00079   {
00080     if (GetWindowThread())
00081     {
00082       // An WindowThread already exist for this thread.
00083       nuxDebugMsg("[CreateGUIThread] You may have only one Nux window per system thread.");
00084       return NULL;
00085     }
00086 
00087     modal = (modal && parent && parent->Type().IsObjectType(WindowThread::StaticObjectType));
00088 
00089     if (width <= WindowThread::MINIMUM_WINDOW_WIDTH)
00090     {
00091       width = WindowThread::MINIMUM_WINDOW_WIDTH;
00092     }
00093     
00094     if (height <= WindowThread::MINIMUM_WINDOW_HEIGHT)
00095     {
00096       height = WindowThread::MINIMUM_WINDOW_HEIGHT;
00097     }
00098 
00099     WindowThread *w = new WindowThread(window_title, width, height, parent, modal);
00100 
00101     if (w == NULL)
00102     {
00103       nuxDebugMsg("[CreateGUIThread] WindowThread creation failed.");
00104       return NULL;
00105     }
00106 
00107     w->user_init_func_ = user_init_func;
00108     w->user_exit_func_ = 0;
00109     w->initialization_data_ = data;
00110     w->window_style_ = window_border_style;
00111     w->ThreadCtor();
00112     return w;
00113   }
00114 
00115   WindowThread *CreateNuxWindowNewThread(const char *window_title,
00116     int width,
00117     int height,
00118     WindowStyle window_border_style,
00119     AbstractThread *parent,
00120     bool modal,
00121     ThreadUserInitFunc user_init_func,
00122     void *data)
00123   {
00124     modal = (modal && parent && parent->Type().IsObjectType(WindowThread::StaticObjectType));
00125 
00126     if (width <= WindowThread::MINIMUM_WINDOW_WIDTH)
00127     {
00128       width = WindowThread::MINIMUM_WINDOW_WIDTH;
00129     }
00130 
00131     if (height <= WindowThread::MINIMUM_WINDOW_HEIGHT)
00132     {
00133       height = WindowThread::MINIMUM_WINDOW_HEIGHT;
00134     }
00135 
00136     WindowThread *w = new WindowThread(window_title, width, height, parent, modal);
00137     if (w == NULL)
00138     {
00139       nuxDebugMsg("[CreateNuxWindowNewThread] WindowThread creation failed.");
00140       return NULL;
00141     }
00142 
00143     w->user_init_func_ = user_init_func;
00144     w->user_exit_func_ = 0;
00145     w->initialization_data_ = data;
00146     w->window_style_ = window_border_style;
00147     // Do not call WindowThread::ThreadCtor();
00148     return w;
00149   }
00150 
00151 #if defined(NUX_OS_WINDOWS)
00152   WindowThread* CreateFromForeignWindow(HWND WindowHandle, HDC WindowDCHandle, HGLRC OpenGLRenderingContext,
00153                                         ThreadUserInitFunc user_init_func,
00154                                         void *data)
00155   {
00156     if (GetWindowThread())
00157     {
00158       // An WindowThread already exist for this thread.
00159       nuxDebugMsg("[CreateGUIThread] You may have only one Nux window per system thread.");
00160       return NULL;
00161     }
00162 
00163     WindowThread *w = new WindowThread("WindowTitle", 400, 300, 0, true);
00164 
00165     if (w == 0)
00166     {
00167       nuxDebugMsg("[CreateGUIThread] WindowThread creation failed.");
00168       return NULL;
00169     }
00170 
00171     w->user_init_func_ = user_init_func;
00172     w->user_exit_func_ = 0;
00173     w->initialization_data_ = data;
00174     w->window_style_ = WINDOWSTYLE_NORMAL;
00175     w->ThreadCtor(WindowHandle, WindowDCHandle, OpenGLRenderingContext);
00176     return w;
00177   }
00178 
00179 #elif defined(NUX_OS_LINUX)
00180 #ifdef NUX_OPENGLES_20
00181   WindowThread *CreateFromForeignWindow (Window X11Window, EGLContext OpenGLContext,
00182                                          ThreadUserInitFunc user_init_func,
00183                                          void *data)
00184 #else
00185   WindowThread *CreateFromForeignWindow (Window X11Window, GLXContext OpenGLContext,
00186                                          ThreadUserInitFunc user_init_func,
00187                                          void *data)
00188 #endif
00189   {
00190     if (GetWindowThread())
00191     {
00192       // An WindowThread already exist for this thread.
00193       nuxDebugMsg("[CreateGUIThread] You may have only one Nux window per system thread.");
00194       return 0;
00195     }
00196 
00197     WindowThread *w = new WindowThread("WindowTitle", 400, 300, 0, true);
00198 
00199     if (w == 0)
00200     {
00201       nuxDebugMsg("[CreateGUIThread] WindowThread creation failed.");
00202       return NULL;
00203     }
00204 
00205     w->user_init_func_ = user_init_func;
00206     w->user_exit_func_ = 0;
00207     w->initialization_data_ = data;
00208     w->window_style_ = WINDOWSTYLE_NORMAL;
00209     w->embedded_window_ = true;
00210     w->ThreadCtor(NULL, X11Window, OpenGLContext);
00211     return w;
00212   }
00213 #endif
00214 
00215 // Create a window thread that is a child of the Parent. This thread has a window.
00216   WindowThread *CreateWindowThread(WindowStyle WndStyle,
00217                                    const char *window_title,
00218                                    int width,
00219                                    int height,
00220                                    WindowThread *parent,
00221                                    ThreadUserInitFunc user_init_func,
00222                                    void *data)
00223   {
00224     if (width <= WindowThread::MINIMUM_WINDOW_WIDTH)
00225     {
00226       width = WindowThread::MINIMUM_WINDOW_WIDTH;
00227     }
00228 
00229     if (height <= WindowThread::MINIMUM_WINDOW_HEIGHT)
00230     {
00231       height = WindowThread::MINIMUM_WINDOW_HEIGHT;
00232     }
00233 
00234     WindowThread *w = _CreateModalWindowThread(window_title, width, height, parent, user_init_func, data, false);
00235 
00236     if (w == 0)
00237     {
00238       nuxDebugMsg("[CreateWindowThread] WindowThread creation failed.");
00239       return NULL;
00240     }
00241 
00242     w->user_init_func_ = user_init_func;
00243     w->user_exit_func_ = 0;
00244     w->initialization_data_ = data;
00245     w->window_style_ = WndStyle;
00246 
00247     return w;
00248   }
00249 
00250 // Create modal graphics thread that is a child of the Parent. This thread has a window.
00251   WindowThread *CreateModalWindowThread(WindowStyle WndStyle,
00252                                         const char *window_title,
00253                                         int width,
00254                                         int height,
00255                                         WindowThread *parent,
00256                                         ThreadUserInitFunc user_init_func,
00257                                         void *data)
00258   {
00259     if (width <= WindowThread::MINIMUM_WINDOW_WIDTH)
00260     {
00261       width = WindowThread::MINIMUM_WINDOW_WIDTH;
00262     }
00263 
00264     if (height <= WindowThread::MINIMUM_WINDOW_HEIGHT)
00265     {
00266       height = WindowThread::MINIMUM_WINDOW_HEIGHT;
00267     }
00268 
00269     WindowThread *w = _CreateModalWindowThread(window_title, width, height, parent, user_init_func, data, true);
00270 
00271     if (w == 0)
00272     {
00273       nuxDebugMsg("[CreateWindowThread] WindowThread creation failed.");
00274       return NULL;
00275     }
00276 
00277     w->user_init_func_ = user_init_func;
00278     w->user_exit_func_ = 0;
00279     w->initialization_data_ = data;
00280     w->window_style_ = WndStyle;
00281 
00282     return w;
00283   }
00284 
00285   SystemThread *CreateSystemThread(AbstractThread *parent, ThreadUserInitFunc user_init_func, void *data)
00286   {
00287     SystemThread *system_thread = new SystemThread(parent);
00288     
00289     if (system_thread == 0)
00290     {
00291       nuxDebugMsg("[CreateSimpleThread] SystemThread creation failed.");
00292       return NULL;
00293     }
00294     system_thread->user_init_func_ = user_init_func;
00295     system_thread->user_exit_func_ = 0;
00296     system_thread->initialization_data_ = data;
00297     return system_thread;
00298   }
00299 
00300   bool RegisterNuxThread(NThread *ThreadPtr)
00301   {
00302     nuxAssert(ThreadPtr);
00303     NUX_RETURN_VALUE_IF_NULL(ThreadPtr, false);
00304 
00305     NScopeLock Scope(&ThreadArrayLock);
00306     std::vector<NThread *>::iterator it = find(ThreadArray.begin(), ThreadArray.end(), ThreadPtr);
00307 
00308     if (it == ThreadArray.end())
00309     {
00310       ThreadArray.push_back(ThreadPtr);
00311     }
00312 
00313     return true;
00314   }
00315 
00316   void UnregisterNuxThread(NThread *ThreadPtr)
00317   {
00318     nuxAssert(ThreadPtr);
00319     NUX_RETURN_IF_NULL(ThreadPtr);
00320 
00321     NScopeLock Scope(&ThreadArrayLock);
00322     std::vector<NThread *>::iterator it = find(ThreadArray.begin(), ThreadArray.end(), ThreadPtr);
00323 
00324     if (it != ThreadArray.end())
00325     {
00326       ThreadArray.erase(it);
00327     }
00328   }
00329 
00330   ObjectPtr<FontTexture> GetSysFont()
00331   {
00332     return GetWindowThread()->GetGraphicsEngine().GetFont();
00333   }
00334 
00335   ObjectPtr<FontTexture> GetSysBoldFont()
00336   {
00337     return GetWindowThread()->GetGraphicsEngine().GetBoldFont();
00338   }
00339 
00340   WindowCompositor &GetWindowCompositor()
00341   {
00342     NThread *thread = GetWindowThread();
00343 
00344     if (thread && !thread->Type().IsObjectType(WindowThread::StaticObjectType))
00345     {
00346       nuxDebugMsg("[GetWindowCompositor] You can't call GetWindowCompositor on this type of thread: s", thread->Type().name );
00347       PrintOutputDebugString("[GetWindowCompositor] You can't call GetWindowCompositor on this type of thread: s", thread->Type().name );
00348       NUX_HARDWARE_BREAK;
00349     }
00350 
00351     return (static_cast<WindowThread *> (thread))->GetWindowCompositor();
00352   }
00353 
00354   WindowThread *GetWindowThread()
00355   {
00356     return GetThreadNuxWindow();
00357   }
00358 
00359   WindowThread *GetThreadNuxWindow()
00360   {
00361     NThread *thread = static_cast<NThread *> (inlGetThreadLocalStorage(ThreadLocal_InalogicAppImpl));
00362     return NUX_STATIC_CAST(WindowThread *, thread);
00363   }
00364 
00365   BasePainter& GetPainter()
00366   {
00367     NThread *thread = GetWindowThread();
00368     return NUX_STATIC_CAST(WindowThread *, thread)->GetPainter();
00369   }
00370 
00371   UXTheme& GetTheme() 
00372   {
00373     NThread *thread = GetWindowThread();
00374     return NUX_STATIC_CAST(WindowThread *, thread)->GetTheme();
00375   }
00376 
00377   TimerHandler& GetTimer()
00378   {
00379     NThread *thread = GetWindowThread();
00380     return NUX_STATIC_CAST(WindowThread *, thread)->GetTimerHandler();
00381   }
00382 }