nux-1.14.0
WindowCompositor.cpp
00001 // -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
00002 /*
00003  * Copyright 2010,2011 Inalogic® Inc.
00004  *
00005  * This program is free software: you can redistribute it and/or modify it
00006  * under the terms of the GNU Lesser General Public License, as
00007  * published by the  Free Software Foundation; either version 2.1 or 3.0
00008  * of the License.
00009  *
00010  * This program is distributed in the hope that it will be useful, but
00011  * WITHOUT ANY WARRANTY; without even the implied warranties of
00012  * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
00013  * PURPOSE.  See the applicable version of the GNU Lesser General Public
00014  * License for more details.
00015  *
00016  * You should have received a copy of both the GNU Lesser General Public
00017  * License along with this program. If not, see <http://www.gnu.org/licenses/>
00018  *
00019  * Authored by: Jay Taoko <jaytaoko@inalogic.com>
00020  *
00021  */
00022 
00023 
00024 #include "Nux.h"
00025 #include "WindowCompositor.h"
00026 #include "NuxCore/Logger.h"
00027 #include "NuxGraphics/GLError.h"
00028 #include "WindowThread.h"
00029 #include "BaseWindow.h"
00030 #include "MenuPage.h"
00031 #include "PaintLayer.h"
00032 #include "Painter.h"
00033 
00034 #include "NuxGraphics/FontTexture.h"
00035 namespace nux
00036 {
00037 namespace
00038 {
00039 logging::Logger logger("nux.window");
00040 }
00041 
00042   WindowCompositor::WindowCompositor()
00043   {
00044     m_FocusAreaWindow           = NULL;
00045     m_MenuWindow                = NULL;
00046     m_OverlayWindow             = NULL;
00047     _tooltip_window             = NULL;
00048     m_TooltipArea               = NULL;
00049     m_ModalWindow               = NULL;
00050     m_SelectedWindow            = NULL;
00051     _menu_chain                 = NULL;
00052     m_Background                = NULL;
00053     _tooltip_window             = NULL;
00054     m_OverlayWindow             = NULL;
00055     OverlayDrawingCommand       = NULL;
00056     m_CurrentWindow             = NULL;
00057     m_MenuWindow                = NULL;
00058     _mouse_over_area            = NULL;
00059     key_focus_area_             = NULL;
00060     _always_on_front_window     = NULL;
00061     inside_event_cycle_         = false;
00062     inside_rendering_cycle_     = false;
00063     _exclusive_input_area       = NULL;
00064     _in_exclusive_input_mode    = false;
00065     _pending_exclusive_input_mode_action = false;
00066 
00067     _dnd_area                   = NULL;
00068     mouse_over_area_            = NULL;
00069     mouse_owner_area_           = NULL;
00070     _mouse_over_menu_page       = NULL;
00071     _mouse_owner_menu_page      = NULL;
00072     mouse_owner_base_window_    = NULL;
00073     _starting_menu_event_cycle  = false;
00074     _menu_is_active             = false;
00075     _enable_nux_new_event_architecture   = true;
00076     on_menu_closure_continue_with_event_ = false;
00077 
00078     m_FrameBufferObject = GetGraphicsDisplay()->GetGpuDevice()->CreateFrameBufferObject ();
00079     // Do not leave the Fbo binded. Deactivate it.
00080     m_FrameBufferObject->Deactivate ();
00081 
00082     // At this stage, the size of the window may not be known yet.
00083     // FormatRenderTargets will be called the first time runtime gets into WindowThread::ExecutionLoop
00084     m_MainColorRT = GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableDeviceTexture (2, 2, 1, BITFMT_R8G8B8A8);
00085     m_MainDepthRT = GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableDeviceTexture (2, 2, 1, BITFMT_D24S8);
00086 
00087     _menu_chain = new std::list<MenuPage*>;
00088     m_PopupRemoved = false;
00089     m_MenuRemoved = false;
00090     m_ModalWindow = NULL;
00091     m_Background = new ColorLayer (Color (0xFF4D4D4D));
00092   }
00093 
00094   WindowCompositor::~WindowCompositor ()
00095   {
00096     _window_to_texture_map.clear ();
00097     m_FrameBufferObject.Release ();
00098     m_MainColorRT.Release ();
00099     m_MainDepthRT.Release ();
00100     _menu_chain->clear();
00101     _view_window_list.clear ();
00102     _modal_view_window_list.clear ();
00103 
00104     NUX_SAFE_DELETE (_menu_chain);
00105     NUX_SAFE_DELETE (m_Background);
00106   }
00107 
00108 
00109   BaseWindow* WindowCompositor::GetSelectedWindow()
00110   {
00111     return m_SelectedWindow.GetPointer ();
00112   }
00113 
00114   WindowCompositor::RenderTargetTextures &WindowCompositor::GetWindowBuffer (BaseWindow *window)
00115   {
00116     static RenderTargetTextures invalid;
00117     std::map< BaseWindow*, RenderTargetTextures >::iterator it = _window_to_texture_map.find (window);
00118 
00119     if (it != _window_to_texture_map.end())
00120     {
00121       return it->second;
00122     }
00123     LOG_WARN(logger) << "No RenderTargetTextures for window.";
00124     return invalid;
00125   }
00126 
00127   void WindowCompositor::RegisterWindow (BaseWindow *window)
00128   {
00129     LOG_DEBUG_BLOCK(logger);
00130     if (!window)
00131       return;
00132 
00133     WindowList::iterator it = find(_view_window_list.begin(),
00134                                    _view_window_list.end(), window);
00135     if (it == _view_window_list.end())
00136     {
00137       _view_window_list.push_front(ObjectWeakPtr<BaseWindow>(window));
00138       m_SelectedWindow = window;
00139 
00140       RenderTargetTextures rt;
00141 
00142       // Don't size the texture to the dimension of the window yet. this will be done later.
00143       auto device = GetGraphicsDisplay()->GetGpuDevice();
00144       rt.color_rt = device->CreateSystemCapableDeviceTexture (2, 2, 1, BITFMT_R8G8B8A8);
00145       rt.depth_rt = device->CreateSystemCapableDeviceTexture (2, 2, 1, BITFMT_D24S8);
00146 
00147       _window_to_texture_map[window] = rt;
00148 
00149       window->object_destroyed.connect(sigc::mem_fun(this, &WindowCompositor::UnRegisterWindow));
00150     }
00151   }
00152 
00153   void WindowCompositor::UnRegisterWindow(Object* obj)
00154   {
00155     LOG_DEBUG_BLOCK(logger);
00156     WeakBaseWindowPtr window(obj);
00157     if (window.IsNull())
00158       return;
00159 
00160     WindowList::iterator it = find(_view_window_list.begin(),
00161                                    _view_window_list.end(), window);
00162     if (it == _view_window_list.end())
00163     {
00164       // look for a weak pointer that has been cleared out.
00165       it = find(_view_window_list.begin(),
00166                 _view_window_list.end(), WeakBaseWindowPtr());
00167     }
00168 
00169     if (it != _view_window_list.end())
00170     {
00171       _view_window_list.erase(it);
00172 
00173       if (_view_window_list.size())
00174         m_SelectedWindow = _view_window_list.front();
00175     }
00176     _window_to_texture_map.erase(window.GetPointer());
00177   }
00178 
00179   Area* WindowCompositor::GetMouseOwnerArea()
00180   {
00181     return mouse_owner_area_;
00182   }
00183 
00185   Point WindowCompositor::GetMousePosition()
00186   {
00187     return _mouse_position;
00188   }
00189 
00190   void WindowCompositor::ResetMousePointerAreas()
00191   {
00192     SetMouseOverArea(NULL);
00193     SetMouseOwnerArea(NULL);
00194     _mouse_over_menu_page   = NULL;
00195     _mouse_owner_menu_page  = NULL;
00196   }
00197 
00198   void WindowCompositor::GetAreaUnderMouse(const Point& mouse_position,
00199                                            NuxEventType event_type,
00200                                            InputArea** area_under_mouse_pointer,
00201                                            BaseWindow** window)
00202   {
00203     *area_under_mouse_pointer = NULL;
00204 
00205     // Go through the list of BaseWindo and find the first area over which the
00206     // mouse pointer is.
00207     WindowList::iterator window_it;
00208 
00209     for (window_it = _view_window_list.begin(); window_it != _view_window_list.end(); ++window_it)
00210     {
00211       if ((*window_it).IsValid() && (*window_it)->IsVisible())
00212       {
00213         InputArea *area = static_cast<InputArea*>((*window_it)->FindAreaUnderMouse(mouse_position, event_type));
00214         if (area)
00215         {
00216           *area_under_mouse_pointer = area;
00217           *window = (*window_it).GetPointer();
00218           return;
00219         }
00220       }
00221     }
00222 
00223     // If area_under_mouse_pointer is NULL, then the mouse pointer is not over
00224     // any of the BaseWindow. Try the main window layout.
00225     if (*area_under_mouse_pointer == NULL)
00226     {
00227       Layout* main_window_layout = GetWindowThread()->GetMainLayout();
00228       if (main_window_layout)
00229         *area_under_mouse_pointer = static_cast<InputArea*>(main_window_layout->FindAreaUnderMouse(mouse_position, event_type));
00230     }
00231   }
00232 
00233   void WindowCompositor::OnMouseOverViewDestroyed(Object* object)
00234   {
00235     if (mouse_over_area_ == object)
00236     {
00237       mouse_over_area_ = NULL;
00238     }
00239   }
00240 
00241   void WindowCompositor::SetMouseOverArea(Area* area)
00242   {
00243     mouse_over_area_ = static_cast<InputArea*>(area);
00244 
00245     mouse_over_view_connection_.disconnect();
00246 
00247     if (mouse_over_area_)
00248     {
00249       mouse_over_view_connection_ = mouse_over_area_->object_destroyed.connect(sigc::mem_fun (this, &WindowCompositor::OnMouseOverViewDestroyed));
00250     }
00251   }
00252 
00253   void WindowCompositor::OnMouseOwnerViewDestroyed(Object* object)
00254   {
00255     if (mouse_owner_area_ == object)
00256     {
00257       mouse_owner_area_ = NULL;
00258     }
00259   }
00260 
00261   void WindowCompositor::SetMouseOwnerArea(Area* area)
00262   {
00263     if (mouse_owner_area_ == area)
00264       return;
00265 
00266     mouse_owner_area_ = static_cast<InputArea*>(area);
00267     dnd_safety_x_ = 0;
00268     dnd_safety_y_ = 0;
00269 
00270     mouse_owner_view_connection_.disconnect();
00271 
00272     if (mouse_owner_area_)
00273     {
00274       mouse_owner_view_connection_ = mouse_owner_area_->object_destroyed.connect(sigc::mem_fun (this, &WindowCompositor::OnMouseOwnerViewDestroyed));
00275     }
00276   }
00277 
00278   void WindowCompositor::OnMouseOwnerBaseWindowDestroyed(Object* object)
00279   {
00280     if (mouse_owner_base_window_ == object)
00281     {
00282       mouse_owner_base_window_ = NULL;
00283     }
00284   }
00285 
00286   void WindowCompositor::SetMouseOwnerBaseWindow(BaseWindow* base_window)
00287   {
00288     mouse_owner_base_window_ = base_window;
00289 
00290     mouse_owner_basewindow_connection_.disconnect();
00291 
00292     if (mouse_owner_base_window_)
00293     {
00294       mouse_owner_basewindow_connection_ = mouse_owner_base_window_->object_destroyed.connect (sigc::mem_fun (this, &WindowCompositor::OnMouseOwnerBaseWindowDestroyed));
00295     }
00296   }
00297 
00298   void WindowCompositor::DndEventCycle (Event &event)
00299   {
00300     if (event.e_event == NUX_DND_MOVE)
00301     {
00302       InputArea *hit_area = NULL;
00303       BaseWindow *hit_base_window = NULL;
00304 
00305       GetAreaUnderMouse(Point(event.e_x, event.e_y), event.e_event, &hit_area, &hit_base_window);
00306 
00307       if (hit_area)
00308       {
00309         SetDnDArea (hit_area);
00310         hit_area->HandleDndMove(event);
00311       }
00312       else
00313       {
00314         ResetDnDArea ();
00315       }
00316     }
00317     else if (event.e_event == NUX_DND_ENTER_WINDOW)
00318     {
00319       // do nothing for now
00320     }
00321     else if (event.e_event == NUX_DND_LEAVE_WINDOW)
00322     {
00323       ResetDnDArea ();
00324     }
00325     else if (event.e_event == NUX_DND_DROP)
00326     {
00327       InputArea *current_dnd_area = GetWindowCompositor().GetDnDArea();
00328       if (current_dnd_area->GetGeometry().IsPointInside (event.e_x - event.e_x_root, event.e_y - event.e_y_root))
00329         current_dnd_area->HandleDndDrop(event);
00330     }
00331   }
00332 
00333   void WindowCompositor::MouseEventCycle(Event &event)
00334   {
00335     // mouse_owner_area_: the view that has the mouse down
00336     // mouse_over_area_: the view that is directly below the mouse pointer
00337 
00338     int dx = event.e_x - _mouse_position.x;
00339     int dy = event.e_y - _mouse_position.y;
00340 
00341     _mouse_position = Point(event.e_x, event.e_y);
00342 
00343     if (mouse_owner_area_ == NULL)
00344     {
00345       // Context: The left mouse button is not down over an area.
00346       // We look for the area where the mouse pointer is located.
00347 
00348       // We should never get here for a NUX_MOUSE_RELEASED event
00349       if ((event.e_event == NUX_MOUSE_PRESSED) ||
00350         (event.e_event == NUX_MOUSE_MOVE) ||
00351         (event.e_event == NUX_MOUSE_DOUBLECLICK) ||
00352         (event.e_event == NUX_MOUSE_WHEEL) ||
00353         (event.e_event == NUX_WINDOW_MOUSELEAVE))
00354       {
00355         InputArea* hit_view = NULL;         // The view under the mouse
00356         BaseWindow* hit_base_window = NULL; // The BaseWindow below the mouse pointer.
00357 
00358         // Look for the area below the mouse pointer in the BaseWindow.
00359         Area *pointer_grab_area = GetPointerGrabArea ();
00360         if (pointer_grab_area)
00361         {
00362           // If there is a pending mouse pointer grab, test that area only
00363           hit_view = NUX_STATIC_CAST(InputArea*, pointer_grab_area->FindAreaUnderMouse(Point(event.e_x, event.e_y), event.e_event));
00364           if ((hit_view == NULL) && (event.e_event == NUX_MOUSE_PRESSED))
00365           {
00366             Geometry geo = pointer_grab_area->GetAbsoluteGeometry();
00367             int x = event.e_x - geo.x;
00368             int y = event.e_y - geo.y;
00369 
00370             NUX_STATIC_CAST(InputArea*, pointer_grab_area)->EmitMouseDownOutsideArea(x, y, event.GetMouseState(), event.GetKeyState());
00371           }
00372         }
00373         else
00374         {
00375           GetAreaUnderMouse(Point(event.e_x, event.e_y), event.e_event, &hit_view, &hit_base_window);
00376           SetMouseOwnerBaseWindow(hit_base_window);
00377         }
00378 
00379         Geometry hit_view_geo;
00380         int hit_view_x = 0;
00381         int hit_view_y = 0;
00382 
00383         if (hit_view)
00384         {
00385           hit_view_geo = hit_view->GetAbsoluteGeometry();
00386           hit_view_x = event.e_x - hit_view_geo.x;
00387           hit_view_y = event.e_y - hit_view_geo.y;
00388         }
00389 
00390         if(event.e_event == NUX_WINDOW_MOUSELEAVE)
00391         {
00392           if (mouse_over_area_ != NULL)
00393           {
00394             // The area where the mouse was in the previous cycle and the area returned by GetAreaUnderMouse are different.
00395             // The area from the previous cycle receive a "mouse leave signal".
00396             Geometry geo = mouse_over_area_->GetAbsoluteGeometry();
00397             int x = event.e_x - geo.x;
00398             int y = event.e_y - geo.y;
00399 
00400             mouse_over_area_->EmitMouseLeaveSignal(x, y, event.GetMouseState(), event.GetKeyState());
00401             SetMouseOverArea(NULL);
00402           }
00403         }
00404         else if (hit_view && (event.e_event == NUX_MOUSE_MOVE))
00405         {
00406           if (hit_view != mouse_over_area_)
00407           {
00408             if (mouse_over_area_ != NULL)
00409             {
00410               // The area where the mouse was in the previous cycle and the area returned by GetAreaUnderMouse are different.
00411               // The area from the previous cycle receive a "mouse leave signal".
00412               Geometry geo = mouse_over_area_->GetAbsoluteGeometry();
00413               int x = event.e_x - geo.x;
00414               int y = event.e_y - geo.y;
00415 
00416               mouse_over_area_->EmitMouseLeaveSignal(x, y, event.GetMouseState(), event.GetKeyState());
00417             }
00418 
00419             // The area we found under the mouse pointer receives a "mouse enter signal".
00420             SetMouseOverArea(hit_view);
00421             mouse_over_area_->EmitMouseEnterSignal(hit_view_x, hit_view_y, event.GetMouseState(), event.GetKeyState());
00422           }
00423 
00424           // Send a "mouse mouse signal".
00425           mouse_over_area_->EmitMouseMoveSignal(hit_view_x, hit_view_y, dx, dy, event.GetMouseState(), event.GetKeyState());
00426         }
00427         else if (hit_view && ((event.e_event == NUX_MOUSE_PRESSED) || (event.e_event == NUX_MOUSE_DOUBLECLICK)))
00428         {
00429           if ((event.e_event == NUX_MOUSE_DOUBLECLICK) && (!hit_view->DoubleClickEnabled()))
00430           {
00431             // If the area does not accept double click events, transform the event into a mouse pressed.
00432             event.e_event = NUX_MOUSE_PRESSED;
00433           }
00434 
00435           bool emit_double_click_signal = false;
00436           if (mouse_over_area_ && (hit_view != mouse_over_area_))
00437           {
00438             // The area where the mouse was in the previous cycle and the area returned by GetAreaUnderMouse are different.
00439             // The area from the previous cycle receive a "mouse leave signal".
00440             // This case should be rare. I would happen if the mouse is over an area and that area is removed and reveals
00441             // a new area. If the next mouse event is a NUX_MOUSE_PRESSED, then the revealed area will be the one 
00442             // that is returned by GetAreaUnderMouse.
00443             Geometry geo = mouse_over_area_->GetAbsoluteGeometry();
00444             int x = event.e_x - geo.x;
00445             int y = event.e_y - geo.y;
00446 
00447             mouse_over_area_->EmitMouseLeaveSignal(x, y, event.GetMouseState(), event.GetKeyState());
00448           }
00449           else if (mouse_over_area_ && (hit_view == mouse_over_area_) && (event.e_event == NUX_MOUSE_DOUBLECLICK))
00450           {
00451             emit_double_click_signal = true;
00452           }
00453 
00454           SetMouseOverArea(hit_view);
00455           SetMouseOwnerArea(hit_view);
00456           _mouse_position_on_owner = Point(hit_view_x, hit_view_y);
00457 
00458           // In the case of a mouse down event, if there is currently a keyboard event receiver and it is different
00459           // from the area returned by GetAreaUnderMouse, then stop that receiver from receiving anymore keyboard events and switch
00460           // make the found area the new receiver (if it accept keyboard events).
00461           if (mouse_over_area_ != GetKeyFocusArea())
00462           {
00463             InputArea* grab_area = GetKeyboardGrabArea();
00464             if (grab_area)
00465             {
00466               if (mouse_over_area_->IsChildOf(grab_area) /*&& mouse_over_area_->AcceptKeyboardEvent()*/)
00467               {
00468                 SetKeyFocusArea(mouse_over_area_);
00469               }
00470               else
00471               {
00472                 SetKeyFocusArea(grab_area);
00473               }
00474             }
00475             else
00476             {
00477               SetKeyFocusArea(mouse_over_area_);
00478             }
00479           }
00480 
00481           if (emit_double_click_signal)
00482           {
00483             mouse_over_area_->EmitMouseDoubleClickSignal(hit_view_x, hit_view_y, event.GetMouseState(), event.GetKeyState());
00484           }
00485           else
00486           {
00487             mouse_over_area_->EmitMouseDownSignal(hit_view_x, hit_view_y, event.GetMouseState(), event.GetKeyState());
00488           }
00489         }
00490         else if (hit_view && (event.e_event == NUX_MOUSE_WHEEL))
00491         {
00492           hit_view->EmitMouseWheelSignal(hit_view_x, hit_view_y, event.e_wheeldelta, event.GetMouseState(), event.GetKeyState());
00493         }
00494         else if (hit_view == NULL)
00495         {
00496           if (mouse_over_area_)
00497           {
00498             Geometry geo = mouse_over_area_->GetAbsoluteGeometry();
00499             int x = event.e_x - geo.x;
00500             int y = event.e_y - geo.y;
00501 
00502             mouse_over_area_->EmitMouseLeaveSignal(x, y, event.GetMouseState(), event.GetKeyState());
00503           }
00504 
00505 //           if(GetKeyFocusArea() && (event.e_event == NUX_MOUSE_PRESSED))
00506 //           {
00507 //             InputArea* grab_area = GetKeyFocusArea();
00508 // 
00509 //             if(grab_area)
00510 //             {
00511 //               SetKeyFocusArea(grab_area);
00512 //             }
00513 //             else
00514 //             {
00515 //               SetKeyFocusArea(NULL);
00516 //             }
00517 //           }
00518           SetMouseOverArea(NULL);
00519         }
00520       }
00521     }
00522     else
00523     {
00524       // Context: The left mouse button down over an area. All events goes to that area.
00525       // But we still need to know where the mouse is.
00526 
00527       InputArea* hit_view = NULL;         // The view under the mouse
00528       BaseWindow* hit_base_window = NULL; // The BaseWindow below the mouse pointer.
00529 
00530       GetAreaUnderMouse(Point(event.e_x, event.e_y), event.e_event, &hit_view, &hit_base_window);
00531 
00532       Geometry mouse_owner_geo = mouse_owner_area_->GetAbsoluteGeometry();
00533       int mouse_owner_x = event.e_x - mouse_owner_geo.x;
00534       int mouse_owner_y = event.e_y - mouse_owner_geo.y;
00535 
00536       // the mouse is down over a view
00537       if(event.e_event == NUX_MOUSE_MOVE)
00538       {
00539         int dx = mouse_owner_x - _mouse_position_on_owner.x;
00540         int dy = mouse_owner_y - _mouse_position_on_owner.y;
00541 
00542         if (mouse_owner_area_->_dnd_enabled_as_source)
00543         {
00544           dnd_safety_x_ += dx;
00545           dnd_safety_y_ += dy;
00546 
00547           if (abs (dnd_safety_y_) > 30 || abs (dnd_safety_x_) > 30)
00548           {
00549 #ifdef NUX_OS_LINUX
00550             mouse_owner_area_->StartDragAsSource ();
00551 #endif
00552             ResetMousePointerAreas ();
00553             return;
00554           }
00555         }
00556         else
00557         {
00558           mouse_owner_area_->EmitMouseDragSignal(mouse_owner_x, mouse_owner_y, dx, dy, event.GetMouseState(), event.GetKeyState());
00559         }
00560 
00561         if((mouse_over_area_ == mouse_owner_area_) && (hit_view != mouse_owner_area_))
00562         {
00563           mouse_owner_area_->EmitMouseLeaveSignal(mouse_owner_x, mouse_owner_y, event.GetMouseState(), event.GetKeyState());
00564           SetMouseOverArea(hit_view);
00565         }
00566         else if((mouse_over_area_ != mouse_owner_area_) && (hit_view == mouse_owner_area_))
00567         {
00568           mouse_owner_area_->EmitMouseEnterSignal(mouse_owner_x, mouse_owner_y, event.GetMouseState(), event.GetKeyState());
00569           SetMouseOverArea(mouse_owner_area_);
00570         }
00571 
00572         _mouse_position_on_owner = Point(mouse_owner_x, mouse_owner_y);
00573       }
00574       else if(event.e_event == NUX_MOUSE_RELEASED)
00575       {
00576         mouse_owner_area_->EmitMouseUpSignal(mouse_owner_x, mouse_owner_y, event.GetMouseState(), event.GetKeyState());
00577 
00578         if(hit_view == mouse_owner_area_)
00579         {
00580           mouse_owner_area_->EmitMouseClickSignal(mouse_owner_x, mouse_owner_y, event.GetMouseState(), event.GetKeyState());
00581           SetMouseOverArea(mouse_owner_area_);
00582         }
00583         else
00584         {
00585           SetMouseOverArea(hit_view);
00586         }
00587 
00588         SetMouseOwnerArea(NULL);
00589         _mouse_position_on_owner = Point(0, 0);
00590       }
00591     }
00592   }
00593 
00594   void WindowCompositor::MenuEventCycle(Event& event)
00595   {
00596     // _mouse_owner_menu_page: the menu page that has the mouse down
00597     // _mouse_over_menu_page: the menu page that is directly below the mouse pointer
00598 
00599     _mouse_position = Point(event.e_x, event.e_y);
00600 
00601     if(_mouse_owner_menu_page == NULL)
00602     {
00603       if((event.e_event == NUX_MOUSE_PRESSED) ||
00604         (event.e_event == NUX_MOUSE_RELEASED) ||
00605         (event.e_event == NUX_MOUSE_MOVE) ||
00606         (event.e_event == NUX_MOUSE_DOUBLECLICK) ||
00607         (event.e_event == NUX_MOUSE_WHEEL))
00608       {
00609         // Find the MenuPage under the mouse
00610         MenuPage* hit_menu_page = NULL;
00611         std::list<MenuPage*>::iterator menu_it;
00612         for(menu_it = _menu_chain->begin (); menu_it != _menu_chain->end (); menu_it++)
00613         {
00614           // The leaf of the menu chain is in the front of the list.
00615           hit_menu_page = NUX_STATIC_CAST(MenuPage*, (*menu_it)->FindAreaUnderMouse(Point(event.e_x, event.e_y), event.e_event));
00616           if(hit_menu_page)
00617           {
00618             break;
00619           }
00620         }
00621 
00622         Geometry hit_menu_page_geo;
00623         int hit_menu_page_x = 0;
00624         int hit_menu_page_y = 0;
00625 
00626         if(hit_menu_page)
00627         {
00628           hit_menu_page_geo = hit_menu_page->GetAbsoluteGeometry();
00629           hit_menu_page_x = event.e_x - hit_menu_page_geo.x;
00630           hit_menu_page_y = event.e_y - hit_menu_page_geo.y;
00631         }
00632 
00633         if(hit_menu_page && (event.e_event == NUX_MOUSE_RELEASED))
00634         {
00635           hit_menu_page->EmitMouseUpSignal(hit_menu_page_x, hit_menu_page_y, event.GetMouseState(), event.GetKeyState());
00636 
00637           (*_menu_chain->begin())->sigClosingMenu(*_menu_chain->begin());
00638           (*_menu_chain->begin())->StopMenu();
00639         }
00640         else if(hit_menu_page && (event.e_event == NUX_MOUSE_MOVE))
00641         {
00642           if(hit_menu_page != _mouse_over_menu_page)
00643           {
00644             if(_mouse_over_menu_page != 0)
00645             {
00646               Geometry geo = _mouse_over_menu_page->GetAbsoluteGeometry();
00647               int x = event.e_x - geo.x;
00648               int y = event.e_y - geo.y;
00649 
00650               _mouse_over_menu_page->EmitMouseLeaveSignal(x, y, event.GetMouseState(), event.GetKeyState());
00651             }
00652 
00653             _mouse_over_menu_page = hit_menu_page;
00654             _mouse_over_menu_page->EmitMouseEnterSignal(hit_menu_page_x, hit_menu_page_y, event.GetMouseState(), event.GetKeyState());
00655           }
00656 
00657           _mouse_over_menu_page->EmitMouseMoveSignal(hit_menu_page_x, hit_menu_page_y, event.e_dx, event.e_dy, event.GetMouseState(), event.GetKeyState());
00658         }
00659         else if(hit_menu_page && ((event.e_event == NUX_MOUSE_PRESSED) || (event.e_event == NUX_MOUSE_DOUBLECLICK)))
00660         {
00661           if(!hit_menu_page->DoubleClickEnabled())
00662           {
00663 
00664           }
00665 
00666           if(_mouse_over_menu_page && (hit_menu_page != _mouse_over_menu_page))
00667           {
00668             Geometry geo = _mouse_over_menu_page->GetAbsoluteGeometry();
00669             int x = event.e_x - geo.x;
00670             int y = event.e_y - geo.y;
00671 
00672             _mouse_over_menu_page->EmitMouseLeaveSignal(x, y, event.GetMouseState(), event.GetKeyState());
00673           }
00674 
00675           _mouse_over_menu_page = hit_menu_page;
00676           _mouse_owner_menu_page = hit_menu_page;
00677           _mouse_position_on_owner = Point(hit_menu_page_x, hit_menu_page_y);
00678 
00679           if(_mouse_over_menu_page != GetKeyFocusArea())
00680           {
00681             if(_mouse_over_menu_page->AcceptKeyboardEvent())
00682               SetKeyFocusArea(_mouse_over_menu_page);
00683           }
00684 
00685           _mouse_over_menu_page->EmitMouseDownSignal(hit_menu_page_x, hit_menu_page_y, event.GetMouseState(), event.GetKeyState());
00686         }
00687         else if(hit_menu_page && (event.e_event == NUX_MOUSE_WHEEL))
00688         {
00689           hit_menu_page->EmitMouseWheelSignal(hit_menu_page_x, hit_menu_page_y, event.e_wheeldelta, event.GetMouseState(), event.GetKeyState());
00690         }
00691         else if(hit_menu_page == NULL)
00692         {
00693           if(_mouse_over_menu_page)
00694           {
00695             Geometry geo = _mouse_over_menu_page->GetAbsoluteGeometry();
00696             int x = event.e_x - geo.x;
00697             int y = event.e_y - geo.y;
00698 
00699             _mouse_over_menu_page->EmitMouseLeaveSignal(x, y, event.GetMouseState(), event.GetKeyState());
00700           }
00701 
00702           if(event.e_event == NUX_MOUSE_PRESSED || event.e_event == NUX_MOUSE_DOUBLECLICK)
00703           {
00704             (*_menu_chain->begin())->sigClosingMenu(*_menu_chain->begin());
00705             (*_menu_chain->begin())->StopMenu();
00706 
00707             on_menu_closure_continue_with_event_ = (*_menu_chain->begin())->OnClosureContinueEventCycle();
00708           }
00709           _mouse_over_menu_page = 0;
00710         }
00711       }
00712     }
00713     else
00714     {
00715       // We should never get here for a NUX_MOUSE_PRESSED event.
00716       MenuPage* hit_menu_page = NULL;
00717       std::list<MenuPage*>::iterator menu_it;
00718       for(menu_it = _menu_chain->begin (); menu_it != _menu_chain->end (); menu_it++)
00719       {
00720         // The leaf of the menu chain is in the front of the list.
00721         hit_menu_page = NUX_STATIC_CAST(MenuPage*, (*menu_it)->FindAreaUnderMouse(Point(event.e_x, event.e_y), event.e_event));
00722         if(hit_menu_page)
00723         {
00724           break;
00725         }
00726       }
00727 
00728       Geometry mouse_owner_geo = _mouse_owner_menu_page->GetAbsoluteGeometry();
00729       int mouse_owner_x = event.e_x - mouse_owner_geo.x;
00730       int mouse_owner_y = event.e_y - mouse_owner_geo.y;
00731 
00732       // the mouse is down over a view
00733       if(event.e_event == NUX_MOUSE_MOVE)
00734       {
00735         int dx = mouse_owner_x - _mouse_position_on_owner.x;
00736         int dy = mouse_owner_y - _mouse_position_on_owner.y;
00737 
00738         _mouse_owner_menu_page->EmitMouseDragSignal(mouse_owner_x, mouse_owner_y, dx, dy, event.GetMouseState(), event.GetKeyState());
00739 
00740         if((_mouse_over_menu_page == _mouse_owner_menu_page) && (hit_menu_page != _mouse_owner_menu_page))
00741         {
00742           _mouse_owner_menu_page->EmitMouseLeaveSignal(mouse_owner_x, mouse_owner_y, event.GetMouseState(), event.GetKeyState());
00743           _mouse_over_menu_page = hit_menu_page;
00744         }
00745         else if((_mouse_over_menu_page != _mouse_owner_menu_page) && (hit_menu_page == _mouse_owner_menu_page))
00746         {
00747           _mouse_owner_menu_page->EmitMouseEnterSignal(mouse_owner_x, mouse_owner_y, event.GetMouseState(), event.GetKeyState());
00748           _mouse_over_menu_page = _mouse_owner_menu_page;
00749         }
00750 
00751         _mouse_position_on_owner = Point(mouse_owner_x, mouse_owner_y);
00752       }
00753       else if(event.e_event == NUX_MOUSE_RELEASED)
00754       {
00755         _mouse_owner_menu_page->EmitMouseUpSignal(mouse_owner_x, mouse_owner_y, event.GetMouseState(), event.GetKeyState());
00756 
00757         if(hit_menu_page == _mouse_owner_menu_page)
00758         {
00759           _mouse_owner_menu_page->EmitMouseClickSignal(mouse_owner_x, mouse_owner_y, event.GetMouseState(), event.GetKeyState());
00760           _mouse_over_menu_page = _mouse_owner_menu_page;
00761         }
00762         else
00763         {
00764           _mouse_over_menu_page = hit_menu_page;
00765         }
00766 
00767         (*_menu_chain->begin())->sigClosingMenu(*_menu_chain->begin());
00768         (*_menu_chain->begin())->StopMenu();
00769 
00770         _mouse_owner_menu_page = NULL;
00771         _mouse_position_on_owner = Point(0, 0);
00772       }
00773     }
00774   }
00775 
00776   void WindowCompositor::FindKeyFocusArea(NuxEventType event_type,
00777     unsigned int key_symbol,
00778     unsigned int special_keys_state,
00779     InputArea** key_focus_area,
00780     BaseWindow** window)
00781   {
00782     *key_focus_area = NULL;
00783     *window = NULL;
00784 
00785     // Go through the list of BaseWindos and find the first area over which the mouse pointer is.
00786     WindowList::iterator window_it;
00787     window_it = _view_window_list.begin();
00788     while((*key_focus_area == NULL) && (window_it != _view_window_list.end()))
00789     {
00790       if((*window_it).IsValid() && (*window_it)->IsVisible())
00791       {
00792         *key_focus_area = NUX_STATIC_CAST(InputArea*, (*window_it)->FindKeyFocusArea(event_type, key_symbol, special_keys_state));
00793         if(key_focus_area)
00794         {
00795           // We have found an area. We are going to exit the while loop.
00796           *window = (*window_it).GetPointer();
00797         }
00798       }
00799       ++window_it;
00800     }
00801 
00802     // If key_focus_area is NULL, then try the main window layout.
00803     if(*key_focus_area == NULL)
00804     {
00805       Layout* main_window_layout = GetWindowThread()->GetMainLayout();
00806       if(main_window_layout)
00807       {
00808         *key_focus_area = NUX_STATIC_CAST(InputArea*, main_window_layout->FindKeyFocusArea(event_type, key_symbol, special_keys_state));
00809       }
00810     }
00811   }
00812 
00813   void WindowCompositor::FindKeyFocusAreaFrom(NuxEventType event_type,
00814     unsigned int key_symbol,
00815     unsigned int special_keys_state,
00816     InputArea* root_search_area,
00817     InputArea** key_focus_area,
00818     BaseWindow** window)
00819   {
00820     *key_focus_area = NULL;
00821     *window = NULL;
00822 
00823     if (root_search_area == NULL)
00824     {
00825       return;
00826     }
00827 
00828     *key_focus_area = NUX_STATIC_CAST(InputArea*, root_search_area->FindKeyFocusArea(event_type, key_symbol, special_keys_state));
00829     if (key_focus_area)
00830     {
00831       *window = NUX_STATIC_CAST(BaseWindow*, root_search_area->GetTopLevelViewWindow());
00832     }
00833   }
00834 
00835   void WindowCompositor::SendKeyEvent(InputArea* input_area,
00836     NuxEventType event_type,
00837     unsigned int key_sym,
00838     unsigned long x11_key_code,
00839     unsigned long special_keys_state,
00840     const char* text,
00841     int key_repeat_count)
00842   {
00843     if (input_area == NULL)
00844       return;
00845 
00846     if (event_type == NUX_KEYDOWN)
00847     {
00848       input_area->EmitKeyEventSignal(event_type,
00849         key_sym,
00850         special_keys_state,
00851         text,
00852         key_repeat_count);
00853     }
00854     else if (event_type == NUX_KEYUP)
00855     {
00856       input_area->EmitKeyUpSignal(key_sym, x11_key_code, special_keys_state);
00857     }
00858   }
00859 
00860   void WindowCompositor::KeyboardEventCycle(Event &event)
00861   {
00862     InputArea* keyboard_event_grab_view = GetKeyboardGrabArea();
00863 
00864     InputArea* focus_area = NULL;   // The view under the mouse
00865     BaseWindow* base_window = NULL; // The BaseWindow below the mouse pointer.
00866 
00867     if(keyboard_event_grab_view)
00868     {
00869       // There is a keyboard grab.
00870       // Find the key focus area, under the keyboard grab area. That is to say, the key focus area is in the widget tree 
00871       // whose root is the keyboard grab area. This phase is known as the capture phase.
00872       
00873       FindKeyFocusAreaFrom(event.e_event, event.GetKeySym(), event.GetKeyState(),
00874         keyboard_event_grab_view,
00875         &focus_area,
00876         &base_window);
00877     }
00878     else
00879     {
00880       FindKeyFocusArea(event.e_event, event.GetKeySym(), event.GetKeyState(),
00881         &focus_area,
00882         &base_window);
00883     }
00884 
00885     if (focus_area)
00886       SetKeyFocusArea(focus_area);
00887     else
00888       SetKeyFocusArea(NULL);
00889 
00890     KeyNavDirection direction = KEY_NAV_NONE;
00891 
00892     switch (event.GetKeySym())
00893     {
00894     case NUX_VK_UP:
00895       direction = KEY_NAV_UP;
00896       break;
00897     case NUX_VK_DOWN:
00898       direction = KEY_NAV_DOWN;
00899       break;
00900     case NUX_VK_LEFT:
00901       direction = KEY_NAV_LEFT;
00902       break;
00903     case NUX_VK_RIGHT:
00904       direction = KEY_NAV_RIGHT;
00905       break;
00906     case NUX_VK_LEFT_TAB:
00907       direction = KEY_NAV_TAB_PREVIOUS;
00908       break;
00909     case NUX_VK_TAB:
00910       direction = KEY_NAV_TAB_NEXT;
00911       break;
00912     case NUX_VK_ENTER:
00913     case NUX_KP_ENTER:
00914       // Not sure if Enter should be a navigation key
00915       direction = KEY_NAV_ENTER;
00916       break;
00917     default:
00918       direction = KEY_NAV_NONE;
00919       break;
00920     }
00921 
00922     if (key_focus_area_)
00923     {
00924       if (key_focus_area_->InspectKeyEvent(event.e_event, event.GetKeySym(), event.GetText()))
00925       {
00926         SendKeyEvent(key_focus_area_,
00927                     event.e_event,
00928                     event.GetKeySym(),
00929                     event.e_x11_keycode,
00930                     event.GetKeyState(),
00931                     event.GetText(),
00932                     event.GetKeyRepeatCount());
00933       }
00934       else if (direction == KEY_NAV_NONE)
00935       {
00936         Area* parent = key_focus_area_->GetParentObject();
00937 
00938         while (parent && !parent->InspectKeyEvent(event.e_event, event.GetKeySym(), event.GetText()))
00939         {
00940           parent = parent->GetParentObject();
00941         }
00942 
00943         if (parent)
00944         {
00945           SendKeyEvent(static_cast<InputArea*>(parent),
00946             event.e_event,
00947             event.GetKeySym(),
00948             event.e_x11_keycode,
00949             event.GetKeyState(),
00950             event.GetText(),
00951             event.GetKeyRepeatCount());
00952         }
00953       }
00954       else if (event.e_event == NUX_KEYDOWN)
00955       {        
00956         if (direction == KEY_NAV_ENTER)
00957         {
00958           if (key_focus_area_ && key_focus_area_->Type().IsDerivedFromType(InputArea::StaticObjectType))
00959           {
00960             static_cast<InputArea*>(key_focus_area_)->OnKeyNavFocusActivate.emit(key_focus_area_);
00961           }
00962         }
00963         else
00964         {
00965           InputArea* key_nav_focus = NULL;
00966           Area* parent = key_focus_area_->GetParentObject();
00967           
00968           if (parent)
00969             key_nav_focus = NUX_STATIC_CAST(InputArea*, parent->KeyNavIteration(direction));
00970           
00971           while (key_nav_focus == NULL && parent != NULL)
00972           {
00973             parent = parent->GetParentObject();
00974             if (parent)
00975               key_nav_focus = NUX_STATIC_CAST(InputArea*, parent->KeyNavIteration(direction));
00976           }
00977 
00978           if (key_nav_focus)
00979           {
00980             SetKeyFocusArea(key_nav_focus);
00981           }
00982         }
00983       }
00984     }
00985     else
00986     {
00987       // The event is for the Application itself
00988     }
00989   }
00990 
00991   // NUXTODO: rename as EventCycle
00992   void WindowCompositor::ProcessEvent (Event &event)
00993   {
00994     inside_event_cycle_ = true;
00995     if (_enable_nux_new_event_architecture)
00996     {
00997       if (((event.e_event >= NUX_MOUSE_PRESSED) && (event.e_event <= NUX_MOUSE_WHEEL)) ||
00998       (event.e_event == NUX_WINDOW_MOUSELEAVE))
00999       {
01000         bool menu_active = false;
01001         if (_menu_chain->size())
01002         {
01003           menu_active = true;
01004           MenuEventCycle(event);
01005           CleanMenu();
01006         }
01007 
01008         if((menu_active && on_menu_closure_continue_with_event_) || !(menu_active))
01009         {
01010           MouseEventCycle(event);
01011         }
01012 
01013         on_menu_closure_continue_with_event_ = false;
01014 
01015         if (_starting_menu_event_cycle)
01016         {
01017           _starting_menu_event_cycle = false;
01018         }
01019       }
01020       else if ((event.e_event >= NUX_KEYDOWN) && (event.e_event <= NUX_KEYUP))
01021       {
01022         KeyboardEventCycle(event);
01023       }
01024       else if ((event.e_event >= NUX_DND_MOVE) && (event.e_event <= NUX_DND_LEAVE_WINDOW))
01025       {
01026         DndEventCycle(event);
01027       }
01028     }
01029     inside_event_cycle_ = false;
01030   }
01031 
01032   long WindowCompositor::MenuEventCycle(Event &event, long TraverseInfo, long ProcessEventInfo)
01033   {
01034     long ret = TraverseInfo;
01035     std::list<MenuPage*>::iterator menu_it;
01036 
01037     if (m_MenuWindow.IsValid())
01038     {
01039       event.e_x_root = m_MenuWindow->GetBaseX ();
01040       event.e_y_root = m_MenuWindow->GetBaseY ();
01041     }
01042 
01043     // Let all the menu area check the event first. Beside, they are on top of everything else.
01044     for (menu_it = _menu_chain->begin (); menu_it != _menu_chain->end (); menu_it++)
01045     {
01046       // The deepest menu in the menu cascade is in the front of the list.
01047       ret = (*menu_it)->ProcessEvent (event, ret, ProcessEventInfo);
01048     }
01049 
01050     if ((event.e_event == NUX_MOUSE_PRESSED) && _menu_chain->size ())
01051     {
01052       bool inside = false;
01053 
01054       for (menu_it = _menu_chain->begin (); menu_it != _menu_chain->end (); menu_it++)
01055       {
01056         Geometry geo = (*menu_it)->GetGeometry ();
01057 
01058         if (PT_IN_BOX (event.e_x - event.e_x_root, event.e_y - event.e_y_root,
01059                         geo.x, geo.x + geo.width, geo.y, geo.y + geo.height))
01060         {
01061           inside = true;
01062           break;
01063         }
01064       }
01065 
01066       if (inside == false)
01067       {
01068         (*_menu_chain->begin ())->NotifyMouseDownOutsideMenuCascade (event.e_x - event.e_x_root, event.e_y - event.e_y_root);
01069       }
01070     }
01071 
01072     if (m_MenuWindow.IsValid ())
01073     {
01074       event.e_x_root = 0;
01075       event.e_y_root = 0;
01076     }
01077 
01078     if ( (event.e_event == NUX_MOUSE_RELEASED) )
01079     {
01080       SetWidgetDrawingOverlay (NULL, NULL);
01081     }
01082 
01083     if ( (event.e_event == NUX_SIZE_CONFIGURATION) && _menu_chain->size() )
01084     {
01085       (*_menu_chain->begin() )->NotifyTerminateMenuCascade();
01086     }
01087 
01088     return ret;
01089   }
01090 
01091   void WindowCompositor::StartModalWindow (ObjectWeakPtr<BaseWindow> window)
01092   {
01093     if (window == 0)
01094       return;
01095 
01096     WindowList::iterator it = find (_modal_view_window_list.begin(), _modal_view_window_list.end(), window);
01097 
01098     if (it == _modal_view_window_list.end() )
01099     {
01100       _modal_view_window_list.push_front (window);
01101     }
01102   }
01103 
01104   void WindowCompositor::StopModalWindow (ObjectWeakPtr<BaseWindow> window)
01105   {
01106     if (_modal_view_window_list.size () > 0)
01107     {
01108       if (*_modal_view_window_list.begin () == window)
01109         _modal_view_window_list.pop_front ();
01110     }
01111   }
01112 
01114   void WindowCompositor::PushToFront (BaseWindow *window)
01115   {
01116     if (window == 0)
01117       return;
01118 
01119     WindowList::iterator it = find (_view_window_list.begin(), _view_window_list.end (), window);
01120 
01121     if (it != _view_window_list.end () )
01122     {
01123       _view_window_list.erase (it);
01124       _view_window_list.push_front (ObjectWeakPtr<BaseWindow> (window));
01125     }
01126 
01127     EnsureAlwaysOnFrontWindow ();
01128   }
01129 
01131   void WindowCompositor::PushToBack (BaseWindow *window)
01132   {
01133     if (window == 0)
01134       return;
01135 
01136     if (window == _always_on_front_window)
01137       return;
01138 
01139     WindowList::iterator it = find (_view_window_list.begin (), _view_window_list.end (), window);
01140 
01141     if (it != _view_window_list.end() )
01142     {
01143       _view_window_list.erase (it);
01144       _view_window_list.push_back (ObjectWeakPtr<BaseWindow> (window));
01145     }
01146 
01147     EnsureAlwaysOnFrontWindow ();
01148   }
01149 
01151   void WindowCompositor::PushHigher (BaseWindow *top_floating_view, BaseWindow *bottom_floating_view, bool strict)
01152   {
01153     NUX_RETURN_IF_NULL (bottom_floating_view);
01154     NUX_RETURN_IF_NULL (top_floating_view);
01155     NUX_RETURN_IF_FALSE (bottom_floating_view != top_floating_view)
01156 
01157     WindowList::iterator it;
01158     WindowList::iterator it_top;
01159     WindowList::iterator it_bot;
01160 
01161     int i = 0;
01162     int top_pos = -1;
01163     int bot_pos = -1;
01164 
01165     for (it_top = _view_window_list.begin (), i = 0; it_top != _view_window_list.end (); it_top++, i++)
01166     {
01167       if(*it == bottom_floating_view)
01168       {
01169         it_bot = it;
01170         bot_pos = i;
01171       }
01172 
01173       if(*it == top_floating_view)
01174       {
01175         it_top = it;
01176         top_pos = i;
01177       }
01178 
01179       if ((top_pos >= 0) && (bot_pos >= 0))
01180         break;
01181     }
01182 
01183     if ((it_top == _view_window_list.end ()) || (it_bot == _view_window_list.end ()))
01184     {
01185       return;
01186     }
01187 
01188     if ((top_pos < bot_pos) && (strict == false))
01189     {
01190       _view_window_list.erase (it_top);
01191       _view_window_list.insert (it_bot, ObjectWeakPtr<BaseWindow> (top_floating_view));
01192     }
01193 
01194     EnsureAlwaysOnFrontWindow ();
01195   }
01196 
01197   void WindowCompositor::SetAlwaysOnFrontWindow (BaseWindow *window)
01198   {
01199     _always_on_front_window = ObjectWeakPtr<BaseWindow> (window);
01200 
01201     EnsureAlwaysOnFrontWindow ();
01202   }
01203 
01204   void WindowCompositor::EnsureAlwaysOnFrontWindow ()
01205   {
01206     // Do not re-order while we are traversing the list of BaseWindow.
01207     if (inside_event_cycle_)
01208       return;
01209 
01210     if (_always_on_front_window == NULL)
01211       return;
01212 
01213     WindowList::iterator always_top_it = find (_view_window_list.begin(), _view_window_list.end(), _always_on_front_window);
01214     if ((always_top_it != _view_window_list.end ()) &&
01215         (always_top_it != _view_window_list.begin ()) &&
01216         _always_on_front_window.IsValid())
01217     {
01218       _view_window_list.erase (always_top_it);
01219       _view_window_list.push_front (_always_on_front_window);
01220     }
01221   }
01222 
01223   InputArea *WindowCompositor::GetExclusiveInputArea ()
01224   {
01225     return _exclusive_input_area;
01226   }
01227 
01228   bool WindowCompositor::InExclusiveInputMode ()
01229   {
01230     return _in_exclusive_input_mode;
01231   }
01232 
01233   void WindowCompositor::Draw (bool SizeConfigurationEvent, bool force_draw)
01234   {
01235     inside_rendering_cycle_ = true;
01236     if (!GetWindowThread ()->GetWindow().isWindowMinimized())
01237     {
01238       //int w, h;
01239       GetWindowThread ()->GetGraphicsEngine().GetContextSize (m_Width, m_Height);
01240       GetWindowThread ()->GetGraphicsEngine().SetViewport (0, 0, m_Width, m_Height);
01241       
01242       // Reset the Model view Matrix and the projection matrix
01243       GetWindowThread ()->GetGraphicsEngine().ResetProjectionMatrix ();
01244       
01245       GetWindowThread ()->GetGraphicsEngine().ResetModelViewMatrixStack ();
01246       GetWindowThread ()->GetGraphicsEngine().Push2DTranslationModelViewMatrix (0.375f, 0.375f, 0.0f);
01247 
01248 
01249       if (force_draw || SizeConfigurationEvent)
01250       {
01251         // We fall here after something dramatic has happen to the window such as a resizing. In this case
01252         // everything must be rendered. This is very costly and should happen rarely.
01253         if (!GetWindowThread()->IsEmbeddedWindow())
01254           RenderMainWindowComposition(true);
01255 
01256         {
01257           RenderTopViews(true, _view_window_list, false);
01258           RenderTopViews(true, _modal_view_window_list, true);
01259 
01260           DrawMenu(true);
01261           DrawTooltip(true);
01262           DrawOverlay(true);
01263         }
01264       }
01265       else if (m_PopupRemoved || m_MenuRemoved)
01266       {
01267         // A popup removed cause the whole window to be dirty (at least some part of it).
01268         // So exchange DrawList with a real Draw.
01269         if (!GetWindowThread()->IsEmbeddedWindow())
01270           RenderMainWindowComposition(false);
01271 
01272         {
01273           RenderTopViews(false, _view_window_list, false);
01274           RenderTopViews(false, _modal_view_window_list, true);
01275 
01276           DrawMenu(true);
01277           DrawTooltip(true);
01278           DrawOverlay(true);
01279         }
01280       }
01281       else
01282       {
01283         if (!GetWindowThread()->IsEmbeddedWindow())
01284           RenderMainWindowComposition(false);
01285 
01286         {
01287           RenderTopViews(false, _view_window_list, false);
01288           RenderTopViews(false, _modal_view_window_list, true);
01289 
01290           DrawMenu(true);
01291           DrawTooltip(true);
01292           DrawOverlay(true);
01293         }
01294       }
01295 
01296       m_PopupRemoved = false;
01297       m_MenuRemoved = false;
01298 
01299       GetWindowThread ()->GetGraphicsEngine().Pop2DWindow();
01300     }
01301     inside_rendering_cycle_ = false;
01302   }
01303 
01304   void WindowCompositor::DrawMenu (bool force_draw)
01305   {
01306     ObjectWeakPtr<BaseWindow> window = m_MenuWindow;
01307 
01308     if (window.IsValid ())
01309     {
01310       //GetWindowThread ()->GetGraphicsEngine().SetContext (x, y, buffer_width, buffer_height);
01311       GetWindowThread ()->GetGraphicsEngine().SetOrthographicProjectionMatrix (GetWindowThread ()->GetGraphicsEngine().GetWindowWidth(),
01312           GetWindowThread ()->GetGraphicsEngine().GetWindowHeight() );
01313       GetWindowThread ()->GetGraphicsEngine().EmptyClippingRegion();
01314     }
01315     else
01316     {
01317       GetWindowThread ()->GetGraphicsEngine().SetOrthographicProjectionMatrix (GetWindowThread ()->GetGraphicsEngine().GetWindowWidth(),
01318           GetWindowThread ()->GetGraphicsEngine().GetWindowHeight() );
01319       GetWindowThread ()->GetGraphicsEngine().EmptyClippingRegion();
01320     }
01321 
01322     std::list<MenuPage *>::reverse_iterator rev_it_menu;
01323 
01324     for (rev_it_menu = _menu_chain->rbegin(); rev_it_menu != _menu_chain->rend( ); rev_it_menu++)
01325     {
01326       SetProcessingTopView (m_MenuWindow.GetPointer ());
01327       (*rev_it_menu)->ProcessDraw (GetWindowThread ()->GetGraphicsEngine(), force_draw);
01328       SetProcessingTopView (NULL);
01329     }
01330 
01331 //     GetGraphicsDisplay()->GetGraphicsEngine()->SetContext (0, 0,
01332 //                                             GetWindowThread ()->GetGraphicsEngine().GetWindowWidth(),
01333 //                                             GetWindowThread ()->GetGraphicsEngine().GetWindowHeight() );
01334   }
01335 
01336   void WindowCompositor::DrawOverlay (bool force_draw)
01337   {
01338     ObjectWeakPtr<BaseWindow> window = m_OverlayWindow;
01339     int buffer_width = GetWindowThread ()->GetGraphicsEngine().GetWindowWidth();
01340     int buffer_height = GetWindowThread ()->GetGraphicsEngine().GetWindowHeight();
01341 
01342     if (window.IsValid ())
01343     {
01344       //GetWindowThread ()->GetGraphicsEngine().SetContext (x, y, buffer_width, buffer_height);
01345       GetWindowThread ()->GetGraphicsEngine().SetOrthographicProjectionMatrix (buffer_width, buffer_height);
01346       GetWindowThread ()->GetGraphicsEngine().EmptyClippingRegion();
01347     }
01348     else
01349       GetWindowThread ()->GetGraphicsEngine().SetOpenGLClippingRectangle (0, 0, buffer_width, buffer_height);
01350 
01351     if (OverlayDrawingCommand)
01352     {
01353       SetProcessingTopView (m_OverlayWindow.GetPointer ());
01354       OverlayDrawingCommand->OverlayDrawing (GetWindowThread ()->GetGraphicsEngine() );
01355       SetProcessingTopView (NULL);
01356     }
01357 
01358     //GetGraphicsDisplay()->GetGraphicsEngine()->SetContext (0, 0, buffer_width, buffer_height);
01359   }
01360 
01361   void WindowCompositor::DrawTooltip (bool force_draw)
01362   {
01363     ObjectWeakPtr<BaseWindow> window = _tooltip_window;
01364     int buffer_width = GetWindowThread ()->GetGraphicsEngine().GetWindowWidth();
01365     int buffer_height = GetWindowThread ()->GetGraphicsEngine().GetWindowHeight();
01366 
01367     if (window.IsValid ())
01368     {
01369       //GetWindowThread ()->GetGraphicsEngine().SetContext (x, y, buffer_width, buffer_height);
01370       GetWindowThread ()->GetGraphicsEngine().SetOrthographicProjectionMatrix (buffer_width, buffer_height);
01371       GetWindowThread ()->GetGraphicsEngine().EmptyClippingRegion();
01372     }
01373     else
01374       GetWindowThread ()->GetGraphicsEngine().SetOpenGLClippingRectangle (0, 0, buffer_width, buffer_height);
01375 
01376     if(m_TooltipText.Size())
01377     {
01378         //SetProcessingTopView(_tooltip_window);
01379         GetPainter().PaintShape(GetWindowThread ()->GetGraphicsEngine(), _tooltip_geometry, Color(0xA0000000), eSHAPE_CORNER_ROUND10, true);
01380         GetPainter().PaintTextLineStatic(GetWindowThread ()->GetGraphicsEngine(), GetSysBoldFont(), _tooltip_text_geometry, m_TooltipText, Color(0xFFFFFFFF));
01381         //SetProcessingTopView(NULL);
01382     }
01383 
01384     //GetGraphicsDisplay()->GetGraphicsEngine()->SetContext (0, 0, buffer_width, buffer_height);
01385   }
01386 
01387   void WindowCompositor::RenderTopViewContent (BaseWindow *window, bool force_draw)
01388   {
01389     GetPainter().EmptyBackgroundStack();
01390     SetProcessingTopView (window);
01391     window->ProcessDraw (GetWindowThread ()->GetGraphicsEngine(), force_draw || window->IsRedrawNeeded() );
01392     SetProcessingTopView (NULL);
01393     GetPainter().EmptyBackgroundStack();
01394   }
01395 
01396   void WindowCompositor::RenderTopViews(bool force_draw,
01397                                         WindowList& windows_to_render,
01398                                         bool drawModal)
01399   {
01400     // Before anything, deactivate the current frame buffer, set the viewport 
01401     // to the size of the display and call EmptyClippingRegion().
01402     // Then call GetScissorRect() to get the size of the global clipping area.
01403     // This is is hack until we implement SetGlobalClippingRectangle() (the opposite of SetGlobalClippingRectangle).
01404     GraphicsEngine& graphics_engine = GetWindowThread()->GetGraphicsEngine();
01405     unsigned int window_width = graphics_engine.GetWindowWidth();
01406     unsigned int window_height = graphics_engine.GetWindowHeight();
01407     GetGraphicsDisplay()->GetGpuDevice()->DeactivateFrameBuffer();
01408     graphics_engine.SetViewport(0, 0, window_width, window_height);
01409     graphics_engine.EmptyClippingRegion();
01410 
01411     Geometry global_clip_rect = graphics_engine.GetScissorRect();
01412     global_clip_rect.y = window_height - global_clip_rect.y - global_clip_rect.height;
01413 
01414     // Always make a copy of the windows to render.  We have no control over
01415     // the windows we are actually drawing.  It has been observed that some
01416     // windows modify the windows stack during the draw process.
01417     //
01418     // So... we take a copy of the window list.  As much as I'd love to just
01419     // have BaseWindow* in the container, again, we have no control over the
01420     // windows we are drawing and one may just decide to unregister or destroy
01421     // another window mid-render.  Since we are contructing a copy of the
01422     // list, lets reverse it as we are constructing, as we want to draw the
01423     // windows from back to front.
01424     WindowList windows(windows_to_render.rbegin(), windows_to_render.rend());
01425     for (WindowList::iterator it = windows.begin(), end = windows.end(); it != end; ++it)
01426     {
01427       WeakBaseWindowPtr& window_ptr = *it;
01428       if (window_ptr.IsNull())
01429         continue;
01430 
01431       BaseWindow* window = window_ptr.GetPointer();
01432       if (!drawModal && window->IsModal())
01433         continue;
01434 
01435       if (window->IsVisible())
01436       {
01437         if (global_clip_rect.Intersect(window->GetGeometry()).IsNull())
01438         {
01439           // The global clipping area can be seen as a per monitor clipping
01440           // region. It is mostly used in embedded mode with compiz.  If we
01441           // get here, it means that the BaseWindow we want to render is not
01442           // in area of the monitor that compiz is currently rendering. So
01443           // skip it.
01444           continue;
01445         }
01446 
01447         RenderTargetTextures& rt = GetWindowBuffer(window);
01448 
01449         // Based on the areas that requested a rendering inside the
01450         // BaseWindow, render the BaseWindow or just use its cache.
01451         if (force_draw || window->IsRedrawNeeded() || window->ChildNeedsRedraw())
01452         {
01453           if (rt.color_rt.IsValid() /*&& rt.depth_rt.IsValid()*/)
01454           {
01455             t_s32 buffer_width = window->GetBaseWidth();
01456             t_s32 buffer_height = window->GetBaseHeight();
01457 
01458             if ((rt.color_rt->GetWidth() != buffer_width) ||
01459                 (rt.color_rt->GetHeight() != buffer_height))
01460             {
01461               rt.color_rt = GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableDeviceTexture (buffer_width, buffer_height, 1, BITFMT_R8G8B8A8);
01462               rt.depth_rt = GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableDeviceTexture (buffer_width, buffer_height, 1, BITFMT_D24S8);
01463             }
01464 
01465             m_FrameBufferObject->FormatFrameBufferObject (buffer_width, buffer_height, BITFMT_R8G8B8A8);
01466             m_FrameBufferObject->SetRenderTarget ( 0, rt.color_rt->GetSurfaceLevel (0) );
01467             m_FrameBufferObject->SetDepthSurface ( rt.depth_rt->GetSurfaceLevel (0) );
01468             m_FrameBufferObject->Activate();
01469             graphics_engine.SetViewport(0, 0, buffer_width, buffer_height);
01470             graphics_engine.SetOrthographicProjectionMatrix(buffer_width, buffer_height);
01471             graphics_engine.EmptyClippingRegion();
01472 
01473             graphics_engine.SetOpenGLClippingRectangle(0, 0, buffer_width, buffer_height);
01474 
01475             CHECKGL ( glClearColor (0, 0, 0, 0) );
01476             GLuint clear_color_buffer_bit = (force_draw || window->IsRedrawNeeded() ) ? GL_COLOR_BUFFER_BIT : 0;
01477             CHECKGL ( glClear (clear_color_buffer_bit | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT) );
01478           }
01479           else
01480           {
01481             int x = window->GetBaseX();
01482             int y = window->GetBaseY();
01483             Matrix4 mat;
01484             mat.Translate (x, y, 0);
01485             graphics_engine.SetOrthographicProjectionMatrix(window_width, window_height);
01486           }
01487 
01488           RenderTopViewContent(window, force_draw);
01489         }
01490 
01491         if (rt.color_rt.IsValid())
01492         {
01493           m_FrameBufferObject->Deactivate();
01494 
01495           // Enable this to render the drop shadow under windows: not perfect yet...
01496           if (0)
01497           {
01498             graphics_engine.EmptyClippingRegion();
01499             graphics_engine.SetOpenGLClippingRectangle(0, 0, window_width, window_height);
01500             graphics_engine.SetViewport(0, 0, window_width, window_height);
01501             graphics_engine.SetOrthographicProjectionMatrix(window_width, window_height);
01502 
01503             Geometry shadow(window->GetBaseX(), window->GetBaseY(),
01504                             window->GetBaseWidth(), window->GetBaseHeight());
01505             //if(window->IsVisibleSizeGrip())
01506             {
01507               shadow.OffsetPosition (4, 4);
01508               GetPainter().PaintShape (graphics_engine, shadow, color::Black,
01509                                        eSHAPE_CORNER_SHADOW);
01510             }
01511 //                    else
01512 //                    {
01513 //                        shadow.OffsetPosition(4, 4);
01514 //                        GetPainter().PaintShape(GetWindowThread ()->GetGraphicsEngine(), shadow, Color(0xFF000000), eSHAPE_CORNER_ROUND10_SHADOW);
01515 //                    }
01516           }
01517 
01518           CHECKGL ( glDepthMask (GL_FALSE) );
01519           {
01520             graphics_engine.ApplyClippingRectangle();
01521             PresentBufferToScreen (rt.color_rt, window->GetBaseX(), window->GetBaseY(), false, false, window->GetOpacity (), window->premultiply());
01522           }
01523           CHECKGL ( glDepthMask (GL_TRUE) );
01524           graphics_engine.GetRenderStates().SetBlend(false);
01525         }
01526 
01527         window->_child_need_redraw = false;
01528       }
01529       else
01530       {
01531         // Invisible window, nothing to draw.
01532         window->_child_need_redraw = false;
01533         window->DoneRedraw();
01534       }
01535     }
01536 
01537     m_FrameBufferObject->Deactivate();
01538   }
01539 
01540 // This function is meant to draw the main window and the small windows but it will not traverse the element.
01541 // It just copies to the backbuffer what it already has in  the framebuffer objects.
01542   void WindowCompositor::PresentRendering()
01543   {
01544     m_FrameBufferObject->Deactivate();
01545     unsigned int window_width, window_height;
01546     window_width = GetWindowThread ()->GetGraphicsEngine().GetWindowWidth();
01547     window_height = GetWindowThread ()->GetGraphicsEngine().GetWindowHeight();
01548     GetWindowThread ()->GetGraphicsEngine().EmptyClippingRegion();
01549     //GetWindowThread ()->GetGraphicsEngine().SetOpenGLClippingRectangle(0, 0, window_width, window_height);
01550     GetWindowThread ()->GetGraphicsEngine().SetViewport (0, 0, window_width, window_height);
01551     GetWindowThread ()->GetGraphicsEngine().SetOrthographicProjectionMatrix (window_width, window_height);
01552 
01553     PresentBufferToScreen (m_MainColorRT, 0, 0, false);
01554 
01555     PageBBox page;
01556     page.xmin = 0;
01557     page.xmax = 100;
01558     page.ymin = 700;
01559     page.ymax = 730;
01560     page.x_margin = 0;
01561     page.y_margin = 0;
01562 
01563     NString FPS = NString::Printf (TEXT ("FPS: %3.2f"), GetWindowThread ()->GetFrameRate() );
01564 
01565     GetWindowThread ()->GetGraphicsEngine().RenderColorTextLineStatic (GetSysBoldFont(), page, FPS, Color (0xffff0000), true, eAlignTextLeft);
01566 
01567     GetWindowThread ()->GetGraphicsEngine().Pop2DWindow();
01568   }
01569 
01570   void WindowCompositor::RenderMainWindowComposition(bool force_draw)
01571   {
01572     t_s32 buffer_width, buffer_height;
01573 
01574     buffer_width = GetWindowThread()->GetGraphicsEngine().GetWindowWidth();
01575     buffer_height = GetWindowThread()->GetGraphicsEngine().GetWindowHeight();
01576 
01577     if ((!m_MainColorRT.IsValid()) || (!m_MainDepthRT.IsValid()) || (m_MainColorRT->GetWidth() != buffer_width) || (m_MainColorRT->GetHeight() != buffer_height))
01578     {
01579       m_MainColorRT = GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableDeviceTexture (buffer_width, buffer_height, 1, BITFMT_R8G8B8A8);
01580       m_MainDepthRT = GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableDeviceTexture (buffer_width, buffer_height, 1, BITFMT_D24S8);
01581     }
01582 
01583     m_FrameBufferObject->FormatFrameBufferObject(buffer_width, buffer_height, BITFMT_R8G8B8A8);
01584     m_FrameBufferObject->SetRenderTarget(0, m_MainColorRT->GetSurfaceLevel(0));
01585     m_FrameBufferObject->SetDepthSurface(m_MainDepthRT->GetSurfaceLevel(0));
01586     m_FrameBufferObject->Activate();
01587 
01588     GetWindowThread()->GetGraphicsEngine().EmptyClippingRegion();
01589     GetWindowThread()->GetGraphicsEngine().SetOpenGLClippingRectangle (0, 0, buffer_width, buffer_height);
01590     GetWindowThread()->GetGraphicsEngine().SetViewport (0, 0, buffer_width, buffer_height);
01591     GetWindowThread()->GetGraphicsEngine().SetOrthographicProjectionMatrix (buffer_width, buffer_height);
01592     {
01593       CHECKGL(glClear(/*GL_COLOR_BUFFER_BIT |*/ GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT));
01594       //Begin 2D Drawing
01595       {
01596         if (force_draw)
01597         {
01598           GetPainter().PushDrawLayer(GetWindowThread()->GetGraphicsEngine(), Geometry (0, 0, buffer_width, buffer_height), m_Background);
01599           //GetPainter().PushBackground(GetWindowThread()->GetGraphicsEngine(), Geometry(0, 0, buffer_width, buffer_height), m_Background, true);
01600 
01601           GetWindowThread()->ProcessDraw(GetWindowThread()->GetGraphicsEngine(), true);
01602 
01603           nuxAssert(GetWindowThread()->GetGraphicsEngine().GetNumberOfClippingRegions() == 0);
01604           GetPainter().PopBackground();
01605           GetPainter().EmptyBackgroundStack();
01606         }
01607         else
01608         {
01609           GetPainter().PushLayer (GetWindowThread()->GetGraphicsEngine(), Geometry (0, 0, buffer_width, buffer_height), m_Background);
01610           //GetPainter().PushBackground(GetWindowThread()->GetGraphicsEngine(), Geometry(0, 0, buffer_width, buffer_height), m_Background, false);
01611 
01612           GetWindowThread()->ProcessDraw(GetWindowThread()->GetGraphicsEngine(), false);
01613 
01614           nuxAssert(GetWindowThread()->GetGraphicsEngine().GetNumberOfClippingRegions() == 0);
01615           GetPainter().PopBackground();
01616           GetPainter().EmptyBackgroundStack();
01617         }
01618       }
01619       // End 2D Drawing
01620     }
01621 
01622     if (key_focus_area_)
01623     {
01624       // key focus test
01625       Geometry geo= key_focus_area_->GetRootGeometry();
01626       //GetGraphicsDisplay()->GetGraphicsEngine()->QRP_Color(geo.x, geo.y, geo.width, geo.height, color::Blue);
01627     }
01628 
01629     GetWindowThread ()->GetGraphicsEngine().SetOrthographicProjectionMatrix (buffer_width, buffer_height);
01630     m_FrameBufferObject->Deactivate();
01631 
01632     unsigned int window_width, window_height;
01633     window_width = GetWindowThread ()->GetGraphicsEngine().GetWindowWidth();
01634     window_height = GetWindowThread ()->GetGraphicsEngine().GetWindowHeight();
01635     GetWindowThread ()->GetGraphicsEngine().EmptyClippingRegion();
01636     GetWindowThread ()->GetGraphicsEngine().SetOpenGLClippingRectangle (0, 0, window_width, window_height);
01637     GetWindowThread ()->GetGraphicsEngine().SetViewport (0, 0, window_width, window_height);
01638     GetWindowThread ()->GetGraphicsEngine().SetOrthographicProjectionMatrix (window_width, window_height);
01639 
01640     PresentBufferToScreen (m_MainColorRT, 0, 0, false);
01641 
01642   }
01643 
01644   void WindowCompositor::PresentBufferToScreen (ObjectPtr<IOpenGLBaseTexture> HWTexture, int x, int y, bool RenderToMainTexture, bool BluredBackground, float opacity, bool premultiply)
01645   {
01646     nuxAssert (HWTexture.IsValid() );
01647 
01648     if (HWTexture.IsNull() )
01649       return;
01650 
01651     t_s32 window_width, window_height;
01652     window_width = GetWindowThread ()->GetGraphicsEngine().GetWindowWidth();
01653     window_height = GetWindowThread ()->GetGraphicsEngine().GetWindowHeight();
01654 
01655 
01656     if (RenderToMainTexture && (HWTexture != m_MainColorRT) )
01657     {
01658       nuxAssert (m_MainColorRT->GetWidth() == window_width);
01659       nuxAssert (m_MainColorRT->GetHeight() == window_height);
01660       m_FrameBufferObject->FormatFrameBufferObject (window_width, window_height, BITFMT_R8G8B8A8);
01661       m_FrameBufferObject->SetRenderTarget ( 0, m_MainColorRT->GetSurfaceLevel (0) );
01662       m_FrameBufferObject->SetDepthSurface ( m_MainDepthRT->GetSurfaceLevel (0) );
01663       m_FrameBufferObject->Activate();
01664     }
01665     else
01666     {
01667       GetGraphicsDisplay()->GetGpuDevice()->DeactivateFrameBuffer();
01668     }
01669 
01670     GetWindowThread()->GetGraphicsEngine().EmptyClippingRegion();
01671     GetWindowThread()->GetGraphicsEngine().SetOpenGLClippingRectangle (0, 0, window_width, window_height);
01672     GetWindowThread()->GetGraphicsEngine().SetViewport (0, 0, window_width, window_height);
01673     GetWindowThread()->GetGraphicsEngine().SetOrthographicProjectionMatrix (window_width, window_height);
01674 
01675     // Render the MAINFBO
01676     {
01677       int src_width, src_height;
01678       src_width = HWTexture->GetWidth();
01679       src_height = HWTexture->GetHeight();
01680 
01681       TexCoordXForm texxform0;
01682       texxform0.FlipVCoord (true);
01683 
01684       if (premultiply)
01685       {
01686         GetWindowThread ()->GetGraphicsEngine().GetRenderStates().SetBlend (true, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
01687         GetGraphicsDisplay()->GetGraphicsEngine()->QRP_1Tex (x, y, src_width, src_height, HWTexture, texxform0, Color (opacity, opacity, opacity, opacity));
01688       }
01689       else
01690       {
01691         GetWindowThread ()->GetGraphicsEngine().GetRenderStates().SetBlend (true, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
01692         GetGraphicsDisplay()->GetGraphicsEngine()->QRP_1Tex (x, y, src_width, src_height, HWTexture, texxform0, Color (1.0f, 1.0f, 1.0f, opacity));
01693       }
01694       GetWindowThread ()->GetGraphicsEngine().GetRenderStates().SetBlend (false);
01695     }
01696   }
01697 
01698   void WindowCompositor::AddMenu(MenuPage *menu, BaseWindow *window, bool OverrideCurrentMenuChain)
01699   {
01700     if(_menu_chain->size() == 0)
01701     {
01702       // A menu is opening.
01703       _starting_menu_event_cycle = true;
01704       _menu_is_active = true;
01705     }
01706 
01707     std::list<MenuPage*>::iterator it = find(_menu_chain->begin(), _menu_chain->end(), menu);
01708     if(it == _menu_chain->end())
01709     {
01710       // When adding a MenuPage, make sure that it is a child of the MenuPage in _menu_chain->begin().
01711       if (_menu_chain->size() )
01712       {
01713         if (menu->GetParentMenu() != (*_menu_chain->begin() ) )
01714         {
01715           if (OverrideCurrentMenuChain)
01716           {
01717             // Remove the current menu chain
01718             for (it = _menu_chain->begin(); it != _menu_chain->end(); it++)
01719             {
01720               // Stop all pages
01721               (*it)->StopMenu();
01722             }
01723 
01724             _menu_chain->clear();
01725           }
01726           else
01727           {
01728             // The MenuPage argument is not a descendent of the current menu chain.
01729             return;
01730           }
01731         }
01732       }
01733 
01734       m_MenuWindow = window;
01735       // The deepest menu is added in front of the list and tested first for events.
01736       _menu_chain->push_front (menu);
01737     }
01738   }
01739 
01740   // Be careful never call this function while you are iterating through the elements of _menu_chain.
01741   void WindowCompositor::RemoveMenu (MenuPage *menu)
01742   {
01743     std::list<MenuPage *>::iterator it = find(_menu_chain->begin(), _menu_chain->end(), menu);
01744 
01745     if(it == _menu_chain->end())
01746     {
01747       return;
01748     }
01749 
01750     _menu_chain->erase (it);
01751     m_MenuRemoved = true;
01752 
01753     if(_menu_is_active && (_menu_chain->size() == 0))
01754     {
01755       // The menu is closed
01756       _menu_is_active         = false;
01757       ResetMousePointerAreas();
01758       m_MenuWindow            = NULL;
01759     }
01760   }
01761 
01762   void WindowCompositor::CleanMenu()
01763   {
01764     if (_menu_chain->size() == 0)
01765       return;
01766 
01767     std::list<MenuPage *>::iterator menu_it = _menu_chain->begin();
01768 
01769     while (menu_it != _menu_chain->end() )
01770     {
01771       if ( (*menu_it)->IsActive() == false)
01772       {
01773         menu_it = _menu_chain->erase (menu_it);
01774         m_MenuRemoved = true;
01775       }
01776       else
01777       {
01778         menu_it++;
01779       }
01780     }
01781 
01782     if (_menu_is_active && (_menu_chain->size() == 0))
01783     {
01784       _menu_is_active         = false;
01785       ResetMousePointerAreas();
01786       m_MenuWindow            = NULL;
01787     }
01788   }
01789 
01790   void WindowCompositor::SetWidgetDrawingOverlay (InputArea *ic, BaseWindow* OverlayWindow)
01791   {
01792     OverlayDrawingCommand = ic;
01793     m_OverlayWindow = OverlayWindow;
01794   }
01795 
01796   InputArea *WindowCompositor::GetWidgetDrawingOverlay()
01797   {
01798     return OverlayDrawingCommand;
01799   }
01800 
01801   void WindowCompositor::SetTooltip(InputArea* TooltipArea, const TCHAR *TooltipText, int x, int y)
01802   {
01803     _tooltip_window = GetProcessingTopView();
01804     m_TooltipArea = TooltipArea;
01805     m_TooltipText = TooltipText;
01806     m_TooltipX = x;
01807     m_TooltipY = y;
01808 
01809     if(m_TooltipText.Size())
01810     {
01811       int w = GetSysBoldFont()->GetCharStringWidth(m_TooltipText.GetTCharPtr());
01812       int h = GetSysBoldFont()->GetFontHeight();
01813 
01814       _tooltip_text_geometry = Geometry(
01815           m_TooltipX + 10,
01816           m_TooltipY - h/2 - 2,
01817           w,
01818           h + 4);
01819 
01820       _tooltip_geometry = _tooltip_text_geometry;
01821       _tooltip_geometry.OffsetSize(20, 8);
01822       _tooltip_geometry.OffsetPosition(-10, -4);
01823 
01824       _tooltip_mainwindow_geometry = _tooltip_geometry;
01825 
01826       if(_tooltip_window.IsValid())
01827       {
01828         _tooltip_mainwindow_geometry.OffsetPosition(_tooltip_window->GetBaseX(), _tooltip_window->GetBaseY());
01829       }
01830     }
01831     else
01832     {
01833       _tooltip_mainwindow_geometry = _tooltip_geometry = _tooltip_text_geometry = Geometry(0, 0, 0, 0);
01834     }
01835   }
01836 
01837   Geometry WindowCompositor::GetTooltipGeometry() const
01838   {
01839     return _tooltip_geometry;
01840   }
01841 
01842   Geometry WindowCompositor::GetTooltipMainWindowGeometry() const
01843   {
01844       return _tooltip_mainwindow_geometry;
01845   }
01846 
01847   void WindowCompositor::CancelTooltip()
01848   {
01849     _tooltip_window = NULL;
01850     m_TooltipArea = NULL;
01851     m_TooltipText = TEXT ("");
01852   }
01853 
01854   bool WindowCompositor::ValidateMouseInsideTooltipArea(int x, int y)
01855   {
01856     NUX_RETURN_VALUE_IF_FALSE(m_TooltipArea, false);
01857     NUX_RETURN_VALUE_IF_FALSE(_tooltip_window.IsValid(), false);
01858 
01859     Geometry geo = m_TooltipArea->GetGeometry();
01860     geo.OffsetPosition(_tooltip_window->GetBaseX(), _tooltip_window->GetBaseY());
01861 
01862     return geo.IsPointInside(x, y);
01863   }
01864 
01865   bool WindowCompositor::IsTooltipActive()
01866   {
01867     NUX_RETURN_VALUE_IF_FALSE(m_TooltipArea, false);
01868     return true;
01869   }
01870 
01871   void WindowCompositor::OnKeyNavFocusDestroyed(Object* area)
01872   {
01873     if (key_focus_area_ == area)
01874     {
01875       key_focus_area_ = NULL;
01876     }
01877   }
01878   
01879   void WindowCompositor::SetKeyFocusArea(InputArea *area)
01880   {
01881     InputArea* keyboard_grab_area = GetKeyboardGrabArea();
01882 
01883     if (keyboard_grab_area  && area && (area != keyboard_grab_area) && (!area->IsChildOf(keyboard_grab_area)))
01884     {
01885       // There is a keyboard grab pending. Only an area that is a child of the area that has
01886       // the keyboard grab can be set to receive keyboard events.
01887       nuxDebugMsg("[WindowCompositor::SetKeyFocusArea] There is a keyboard grab pending. Cannot change the keyboard event receiver.");
01888       return;
01889     }
01890 
01891     if (key_focus_area_ == area)
01892     {
01893       return;
01894     }
01895 
01896     if (area && (area->AcceptKeyNavFocus() == false))
01897       return;
01898 
01899     if (key_focus_area_)
01900     {
01901       key_focus_area_->EmitEndKeyboardFocus();
01902       key_focus_area_->ResetUpwardPathToKeyFocusArea();
01903 
01904       if (key_focus_area_->Type().IsDerivedFromType(InputArea::StaticObjectType))
01905       {
01906         static_cast<InputArea*>(key_focus_area_)->OnKeyNavFocusChange.emit(key_focus_area_);
01907       }
01908 
01909       if (key_focus_area_->Type().IsDerivedFromType(View::StaticObjectType))
01910       {
01911         static_cast<View*>(key_focus_area_)->QueueDraw();
01912       }
01913     }
01914 
01915     if (area)
01916     {
01917       key_focus_area_ = area;
01918 
01919       key_focus_area_->SetPathToKeyFocusArea();
01920       key_focus_area_->EmitStartKeyboardFocus();
01921 
01922       if (key_focus_area_->Type().IsDerivedFromType(InputArea::StaticObjectType))
01923       {
01924         static_cast<InputArea*>(key_focus_area_)->OnKeyNavFocusChange.emit(key_focus_area_);
01925       }
01926 
01927       if (key_focus_area_->Type().IsDerivedFromType(View::StaticObjectType))
01928       {
01929         static_cast<View*>(key_focus_area_)->QueueDraw();
01930       }
01931 
01932       key_focus_area_->ChildFocusChanged.emit(key_focus_area_);
01933 
01934     }
01935     else
01936     {
01937       key_focus_area_ = NULL;
01938     }
01939 
01940     // Even if the the area parameter cannot receive keyboard events, it will get the
01941     // keyboard navigatiuon focus.
01942 
01943     if (key_focus_area_)
01944     {
01945       key_focus_area_->begin_key_focus.emit();
01946     }
01947 
01948 
01949     key_focus_area_connection_.disconnect();
01950     if (area)
01951     {
01952       key_focus_area_connection_ = area->object_destroyed.connect (sigc::mem_fun (this, &WindowCompositor::OnKeyNavFocusDestroyed));
01953     }
01954   }
01955 
01956   InputArea* WindowCompositor::GetKeyFocusArea()
01957   {
01958     return key_focus_area_;
01959   }
01960 
01961   void WindowCompositor::SetBackgroundPaintLayer(AbstractPaintLayer *bkg)
01962   {
01963     NUX_SAFE_DELETE (m_Background);
01964     m_Background = bkg->Clone();
01965   }
01966 
01967   void WindowCompositor::FloatingAreaConfigureNotify(int Width, int Height)
01968   {
01969     WindowList::iterator it;
01970 
01971     for (it = _view_window_list.begin(); it != _view_window_list.end(); it++)
01972     {
01973       if (!(*it).IsValid())
01974         continue;
01975       if ((*it)->IsVisible())
01976       {
01977         (*it)->NotifyConfigurationChange (Width, Height);
01978       }
01979     }
01980   }
01981 
01982   void WindowCompositor::FormatRenderTargets (int width, int height)
01983   {
01984     int buffer_width = GetWindowThread()->GetGraphicsEngine().GetWindowWidth();
01985     int buffer_height = GetWindowThread()->GetGraphicsEngine().GetWindowHeight();
01986 
01987     nuxAssert(buffer_width >= 1);
01988     nuxAssert(buffer_height >= 1);
01989 
01990     m_MainColorRT = GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableDeviceTexture (buffer_width, buffer_height, 1, BITFMT_R8G8B8A8);
01991     m_MainDepthRT = GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableDeviceTexture (buffer_width, buffer_height, 1, BITFMT_D24S8);
01992 
01993     // Clear the buffer the first time...
01994     m_FrameBufferObject->FormatFrameBufferObject (buffer_width, buffer_height, BITFMT_R8G8B8A8);
01995     m_FrameBufferObject->SetRenderTarget(0, m_MainColorRT->GetSurfaceLevel(0));
01996     m_FrameBufferObject->SetDepthSurface(m_MainDepthRT->GetSurfaceLevel(0));
01997     m_FrameBufferObject->Activate();
01998 
01999     CHECKGL(glClearColor(0.0f, 0.0f, 0.0f, 0.0f) );
02000     CHECKGL(glClearDepth(1.0f) );
02001     CHECKGL(glClearStencil(0) );
02002     CHECKGL(glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT));
02003     m_FrameBufferObject->Deactivate();
02004     CHECKGL(glClearColor(0.0f, 0.0f, 0.0f, 0.0f));
02005     CHECKGL(glClearDepth(1.0f));
02006     CHECKGL(glClearStencil(0));
02007     CHECKGL(glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT));
02008 
02009 //     m_BlurTexture   = GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableDeviceTexture (Max (buffer_width, 1), Max (buffer_height, 1), 1, BITFMT_R8G8B8A8);
02010 //     m_FullSceneMip0 = GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableDeviceTexture (Max (buffer_width / 2, 1), Max (buffer_height / 2, 1), 1, BITFMT_R8G8B8A8);
02011 //     m_FullSceneMip1 = GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableDeviceTexture (Max (buffer_width / 4, 1), Max (buffer_height / 4, 1), 1, BITFMT_R8G8B8A8);
02012 //     m_FullSceneMip2 = GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableDeviceTexture (Max (buffer_width / 8, 1), Max (buffer_height / 8, 1), 1, BITFMT_R8G8B8A8);
02013   }
02014 
02015   void WindowCompositor::RestoreRenderingSurface()
02016   {
02017     BaseWindow *top_view = GetProcessingTopView();
02018 
02019     if (top_view && inside_rendering_cycle_)
02020     {
02021       nuxAssert(top_view->Type().IsDerivedFromType (BaseWindow::StaticObjectType));
02022 
02023       RenderTargetTextures rt = GetWindowBuffer(top_view);
02024 
02025       int buffer_width = top_view->GetBaseWidth();
02026       int buffer_height = top_view->GetBaseHeight();
02027 
02028       nuxAssert(buffer_width >= 1);
02029       nuxAssert(buffer_height >= 1);
02030 
02031       if ((rt.color_rt->GetWidth() != buffer_width) || (rt.color_rt->GetHeight() != buffer_height))
02032       {
02033         rt.color_rt = GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableDeviceTexture(buffer_width, buffer_height, 1, BITFMT_R8G8B8A8);
02034         rt.depth_rt = GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableDeviceTexture(buffer_width, buffer_height, 1, BITFMT_D24S8);
02035       }
02036 
02037       m_FrameBufferObject->FormatFrameBufferObject(buffer_width, buffer_height, BITFMT_R8G8B8A8);
02038       m_FrameBufferObject->SetRenderTarget(0, rt.color_rt->GetSurfaceLevel(0));
02039       m_FrameBufferObject->SetDepthSurface(rt.depth_rt->GetSurfaceLevel(0));
02040       m_FrameBufferObject->Activate();
02041 
02042       GetWindowThread()->GetGraphicsEngine().SetViewport(0, 0, buffer_width, buffer_height);
02043       GetWindowThread()->GetGraphicsEngine().SetOrthographicProjectionMatrix(buffer_width, buffer_height);
02044       GetWindowThread()->GetGraphicsEngine().ApplyClippingRectangle();
02045       //GetWindowThread()->GetGraphicsEngine().ApplyModelViewMatrix(); ???
02046     }
02047     else
02048     {
02049       int buffer_width = GetWindowThread()->GetGraphicsEngine().GetWindowWidth();
02050       int buffer_height = GetWindowThread()->GetGraphicsEngine().GetWindowHeight();
02051 
02052       nuxAssert(buffer_width >= 1);
02053       nuxAssert(buffer_height >= 1);
02054       // Restore Main Frame Buffer
02055       m_FrameBufferObject->FormatFrameBufferObject(buffer_width, buffer_height, BITFMT_R8G8B8A8);
02056       m_FrameBufferObject->SetRenderTarget(0, m_MainColorRT->GetSurfaceLevel(0));
02057       m_FrameBufferObject->SetDepthSurface(m_MainDepthRT->GetSurfaceLevel(0));
02058       m_FrameBufferObject->Activate();
02059 
02060       GetWindowThread()->GetGraphicsEngine().SetViewport(0, 0, buffer_width, buffer_height);
02061       GetWindowThread()->GetGraphicsEngine().SetOrthographicProjectionMatrix(buffer_width, buffer_height);
02062       GetWindowThread()->GetGraphicsEngine().ApplyClippingRectangle();
02063       //GetWindowThread()->GetGraphicsEngine().ApplyModelViewMatrix(); ???
02064     }
02065   }
02066 
02067   void* WindowCompositor::GetBackupTextureData(BaseWindow *base_window, int &width, int &height, int &format)
02068   {
02069     width = height = format = 0;
02070 
02071     NUX_RETURN_VALUE_IF_NULL(base_window, 0);
02072 
02073     std::map<BaseWindow*, struct RenderTargetTextures>::iterator it;
02074 
02075     it = _window_to_texture_map.find(base_window);
02076 
02077     if (it == _window_to_texture_map.end())
02078     {
02079       return 0;
02080     }
02081 
02082     if ((*it).second.color_rt.IsNull())
02083     {
02084       return 0;
02085     }
02086 
02087     return (*it).second.color_rt->GetSurfaceData(0, width, height, format);
02088   }
02089 
02090 
02091   void WindowCompositor::ResetDnDArea()
02092   {
02093     SetDnDArea(NULL);
02094   }
02095 
02096   void WindowCompositor::SetDnDArea(InputArea* area)
02097   {
02098 #if defined (NUX_OS_LINUX)
02099     if (_dnd_area == area)
02100       return;
02101 
02102     if (_dnd_area)
02103     {
02104       _dnd_area->HandleDndLeave ();
02105       _dnd_area->UnReference ();
02106     }
02107     _dnd_area = area;
02108     
02109     if (_dnd_area)
02110     {
02111       _dnd_area->Reference ();
02112       _dnd_area->HandleDndEnter ();
02113     }
02114 #endif
02115   }
02116 
02117   InputArea* WindowCompositor::GetDnDArea()
02118   {
02119     return _dnd_area;
02120   }
02121 
02122   bool WindowCompositor::GrabPointerAdd(InputArea* area)
02123   {
02124     NUX_RETURN_VALUE_IF_NULL(area, false);
02125     bool result = true;
02126 
02127     if (GetPointerGrabArea() == area)
02128     {
02129       nuxDebugMsg (TEXT ("[WindowCompositor::GrabPointerAdd] The area already has the grab"));
02130       return result;
02131     }
02132     
02133     if (GetWindow().PointerGrabData() != this)
02134       result = GetWindow().GrabPointer(NULL, this, true);
02135 
02136     if (result)
02137       pointer_grab_stack_.push_front(area);
02138 
02139     // reset the mouse pointers areas.
02140     ResetMousePointerAreas();
02141 
02142     return result;
02143   }
02144 
02145   bool WindowCompositor::GrabPointerRemove(InputArea* area)
02146   {
02147     NUX_RETURN_VALUE_IF_NULL(area, false);
02148 
02149     std::list<InputArea*>::iterator it;
02150 
02151     // find the first instance of the area pointer in the stack
02152     it = find(pointer_grab_stack_.begin(), pointer_grab_stack_.end(), area);
02153 
02154     if (it == pointer_grab_stack_.end())
02155       return false;
02156 
02157     pointer_grab_stack_.erase(it);
02158     
02159     if (pointer_grab_stack_.empty())
02160       GetWindow().UngrabPointer(this);
02161     
02162     // reset the mouse pointers areas.
02163     ResetMousePointerAreas();
02164 
02165     return true;
02166   }
02167 
02168   bool WindowCompositor::IsInPointerGrabStack(InputArea* area)
02169   {
02170     NUX_RETURN_VALUE_IF_NULL(area, false);
02171 
02172     std::list<InputArea*>::iterator it;
02173     it = find (pointer_grab_stack_.begin(), pointer_grab_stack_.end(), area);
02174 
02175     if (it == pointer_grab_stack_.end())
02176       return false;
02177 
02178     return true;
02179   }
02180 
02181   InputArea* WindowCompositor::GetPointerGrabArea()
02182   {
02183     if (pointer_grab_stack_.empty())
02184       return NULL;
02185 
02186     return (*pointer_grab_stack_.begin());
02187   }
02188 
02189   bool WindowCompositor::GrabKeyboardAdd(InputArea* area)
02190   {
02191     NUX_RETURN_VALUE_IF_NULL(area, false);
02192     bool result = true;
02193 
02194     if (GetKeyboardGrabArea() == area)
02195     {
02196       nuxDebugMsg(TEXT ("[WindowCompositor::GrabKeyboardAdd] The area already has the grab"));
02197       return result;
02198     }
02199 
02200     if (GetWindow().KeyboardGrabData() != this)
02201     {
02202       result = GetWindow().GrabKeyboard(NULL, this, true);
02203     }
02204     
02205     if (result)
02206     {
02207       InputArea* current_keyboard_grab = GetKeyboardGrabArea();
02208       if (current_keyboard_grab)
02209         current_keyboard_grab->end_keyboard_grab.emit(current_keyboard_grab);
02210 
02211       keyboard_grab_stack_.push_front(area);
02212       
02213       // If there is any area with the key focus, cancel it.
02214       if (key_focus_area_)
02215       {
02216         key_focus_area_->EmitEndKeyboardFocus();
02217         key_focus_area_->ResetUpwardPathToKeyFocusArea();
02218 
02219         if (key_focus_area_->Type().IsDerivedFromType(InputArea::StaticObjectType))
02220         {
02221           static_cast<InputArea*>(key_focus_area_)->OnKeyNavFocusChange.emit(key_focus_area_);
02222         }
02223 
02224         if (key_focus_area_->Type().IsDerivedFromType(View::StaticObjectType))
02225         {
02226           static_cast<View*>(key_focus_area_)->QueueDraw();
02227         }
02228         key_focus_area_ = NULL;
02229       }
02230       // Must be called only after the area has been added to the front of keyboard_grab_stack_.
02231       SetKeyFocusArea(area);
02232 
02233       area->start_keyboard_grab.emit(area);
02234     }
02235     
02236     return result;
02237   }
02238 
02239   bool WindowCompositor::GrabKeyboardRemove(InputArea* area)
02240   {
02241     NUX_RETURN_VALUE_IF_NULL(area, false);
02242 
02243     std::list<InputArea*>::iterator it;
02244 
02245     // find the first instance of the area keyboard in the stack
02246     it = find(keyboard_grab_stack_.begin(), keyboard_grab_stack_.end(), area);
02247 
02248     if (it == keyboard_grab_stack_.end())
02249       return false;
02250 
02251     InputArea* current_keyboard_grab = (*it);
02252     bool has_grab = false;
02253     
02254     if (it == keyboard_grab_stack_.begin())
02255     {
02256       // At the top of the keyboard_grab_stack_. Means it has the keyboard grab.
02257       has_grab = true;
02258     }
02259 
02260     // First remove the area from the grab list
02261     keyboard_grab_stack_.erase(it);
02262 
02263     // Then emit end_keyboard_grab if the area had the keyboard grab
02264     if (has_grab && current_keyboard_grab)
02265     {
02266       current_keyboard_grab->end_keyboard_grab.emit(current_keyboard_grab);
02267     }
02268 
02269     if (keyboard_grab_stack_.empty())
02270     {
02271       GetWindow().UngrabKeyboard(this);
02272     }
02273 
02274     // Must be called only after the area has been added to the front of keyboard_grab_stack_.
02275     if (keyboard_grab_stack_.empty())
02276     {
02277       SetKeyFocusArea(NULL);
02278     }
02279     else
02280     {
02281       // If there is any area with the key focus, cancel it.
02282       if (key_focus_area_)
02283       {
02284         key_focus_area_->EmitEndKeyboardFocus();
02285         key_focus_area_->ResetUpwardPathToKeyFocusArea();
02286 
02287         if (key_focus_area_->Type().IsDerivedFromType(InputArea::StaticObjectType))
02288         {
02289           static_cast<InputArea*>(key_focus_area_)->OnKeyNavFocusChange.emit(key_focus_area_);
02290         }
02291 
02292         if (key_focus_area_->Type().IsDerivedFromType(View::StaticObjectType))
02293         {
02294           static_cast<View*>(key_focus_area_)->QueueDraw();
02295         }
02296         key_focus_area_ = NULL;
02297       }
02298             
02299       it = keyboard_grab_stack_.begin();
02300       SetKeyFocusArea(*it);
02301 
02302       InputArea* new_keyboard_grab = (*it);
02303       new_keyboard_grab->start_keyboard_grab.emit(new_keyboard_grab);
02304     }
02305     
02306     return true;
02307   }
02308 
02309   bool WindowCompositor::IsInKeyboardGrabStack(InputArea* area)
02310   {
02311     NUX_RETURN_VALUE_IF_NULL (area, false);
02312 
02313     std::list<InputArea*>::iterator it;
02314     it = find(keyboard_grab_stack_.begin(), keyboard_grab_stack_.end(), area);
02315 
02316     if (it == keyboard_grab_stack_.end())
02317       return false;
02318 
02319     return true;
02320   }
02321 
02322   InputArea* WindowCompositor::GetKeyboardGrabArea()
02323   {
02324     if (keyboard_grab_stack_.size() == 0)
02325       return NULL;
02326 
02327     return (*keyboard_grab_stack_.begin());
02328   }
02329 }
02330 
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends