00001 /*!@file GUI/XWinManaged.H A window class with active window management */ 00002 00003 // //////////////////////////////////////////////////////////////////// // 00004 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2001 by the // 00005 // University of Southern California (USC) and the iLab at USC. // 00006 // See http://iLab.usc.edu for information about this project. // 00007 // //////////////////////////////////////////////////////////////////// // 00008 // Major portions of the iLab Neuromorphic Vision Toolkit are protected // 00009 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency // 00010 // in Visual Environments, and Applications'' by Christof Koch and // 00011 // Laurent Itti, California Institute of Technology, 2001 (patent // 00012 // pending; application number 09/912,225 filed July 23, 2001; see // 00013 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status). // 00014 // //////////////////////////////////////////////////////////////////// // 00015 // This file is part of the iLab Neuromorphic Vision C++ Toolkit. // 00016 // // 00017 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can // 00018 // redistribute it and/or modify it under the terms of the GNU General // 00019 // Public License as published by the Free Software Foundation; either // 00020 // version 2 of the License, or (at your option) any later version. // 00021 // // 00022 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope // 00023 // that it will be useful, but WITHOUT ANY WARRANTY; without even the // 00024 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // 00025 // PURPOSE. See the GNU General Public License for more details. // 00026 // // 00027 // You should have received a copy of the GNU General Public License // 00028 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write // 00029 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, // 00030 // Boston, MA 02111-1307 USA. // 00031 // //////////////////////////////////////////////////////////////////// // 00032 // 00033 // Primary maintainer for this file: Laurent Itti <itti@usc.edu> 00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/GUI/XWinManaged.H $ 00035 // $Id: XWinManaged.H 9412 2008-03-10 23:10:15Z farhan $ 00036 // 00037 00038 #ifndef XWINMANAGED_H_DEFINED 00039 #define XWINMANAGED_H_DEFINED 00040 00041 #include "GUI/XWindow.H" 00042 #include "rutz/atomic.h" // for rutz::atomic_int_t 00043 00044 #include <X11/Xlib.h> 00045 #include <algorithm> 00046 #include <deque> 00047 #include <pthread.h> 00048 #include <unistd.h> 00049 #include <string> 00050 #include <vector> 00051 00052 #define WRITEIMG(img) { \ 00053 inplaceNormalize(img, 0.0f, 255.0f); \ 00054 Raster::WriteFloat(img, 0, "/tmp/img.ppm"); } 00055 00056 00057 template <class T> class PixRGB; 00058 template <class T> class Image; 00059 00060 //! A window class with active window management 00061 /*! This class is an extension of the XWindow class to allow event 00062 handling. In the current implementation, <I>exposure</I> and 00063 <I>resize</I> events are handled. Instead of destroying the 00064 window, clicking the <I>close</I> button will set a flag that can 00065 be accessed by calling pressedCloseButton(). 00066 */ 00067 class XWinManaged : public XWindow 00068 { 00069 public: 00070 00071 //! Constructor: create, display and map the window, start the event handling. 00072 /*! The call of to the constructor is identical to the parent class 00073 XWindow. In addition to creating the window, the event handling 00074 is started. 00075 @param w Width of usable image area. 00076 @param h height of usable image area. 00077 @param x Horizontal position hint for window placement; use -1 00078 for automatic placement. 00079 @param y Vertical position hint for window placement; use -1 00080 for automatic placement. 00081 @param title String that will appear in the window title. */ 00082 XWinManaged(const Dims& dims, 00083 const int x = -1, const int y = -1, 00084 const char* title = "USC Neuromorphic Vision"); 00085 00086 00087 //! Constructor: create a window as large as img and display img 00088 XWinManaged(const Image< PixRGB<byte> >& img, 00089 const char* title = "USC Neuromorphic Vision"); 00090 00091 00092 //! Constructor: create a window as large as img and display img 00093 XWinManaged(const Image<byte>& img, 00094 const char* title = "USC Neuromorphic Vision"); 00095 00096 //! Constructor: create a window as large as img and display img 00097 XWinManaged(const Image<float>& img, 00098 const char* title = "USC Neuromorphic Vision", 00099 bool normalize = true); 00100 00101 //! Destructor: destroy the window and stop the event handling 00102 virtual ~XWinManaged(); 00103 00104 //! returns whether the user has clicked the <I>close</I> button. 00105 bool pressedCloseButton() 00106 { return toBeClosed; } 00107 00108 //! request that event tracing be turned on or off 00109 void setTraceEvents(bool on); 00110 00111 00112 //! returns the key press at the front of the keyboard buffer 00113 /*! returns -1 if no key press has occured since the last call */ 00114 int getLastKeyPress(); 00115 00116 //! get the decoded string of the last key press 00117 /*! returns an empty string if no key press has occured since the 00118 last call */ 00119 std::string getLastKeyString(); 00120 00121 //! get the decoded keysym of the last key press 00122 /*! Returns NoSymbol if no key press has occured since the last 00123 call. Also return the corresponding string through s if s is 00124 non-null. */ 00125 KeySym getLastKeySym(std::string* s = 0); 00126 00127 //! copy the last key event into ev, and pop that event from the queue 00128 /*! @return false if there is no queued key event */ 00129 bool getLastKeyEvent(XKeyEvent* ev); 00130 00131 //! returns the last mouse click at the front of the click buffer 00132 /*! does not distinguish between right and left buttons; returns 00133 (-1,-1) if no mouse clicks have occured since the last call */ 00134 Point2D<int> getLastMouseClick(); 00135 00136 //! copy the last button press event into ev, and pop that event from the queue 00137 /*! @return false if there is no queued button event */ 00138 bool getLastButtonEvent(XButtonEvent* ev); 00139 00140 std::string describeKeyEvent(const XKeyEvent* ev) const; 00141 00142 std::string describeButtonEvent(const XButtonEvent* ev) const; 00143 00144 std::string describeEvent(const XEvent* ev) const; 00145 00146 00147 private: 00148 00149 //! Common initialization code used by the constructors 00150 void init(); 00151 00152 //! thread function that handles X events 00153 static void* cEventLoop(void* self); 00154 00155 //! deal with the events coming in 00156 /*! NOTE: before you consider turning this into a virtual function 00157 and overriding it, be sure to consider the multi-threading 00158 issues involved; currently, eventHandler() must be called with 00159 itsDisplayMutex locked, so if you override the function, you'll 00160 need to be sure */ 00161 void eventHandler(XEvent* event); 00162 00163 Atom deleteAtom; // XServer atom for window closing action 00164 pthread_t eventLoopThread; // thread for the event handler loop 00165 rutz::atomic_int_t windowPresent;// flag whether event handling whould keep running 00166 bool toBeClosed; // flag whether the user hashit the close button 00167 pthread_mutex_t itsEventsMutex; 00168 std::deque<XKeyEvent> itsKeyEvents; 00169 std::deque<XButtonEvent> itsButtonEvents; 00170 rutz::atomic_int_t itsTraceEvents; // whether to print info about each event as it is received 00171 }; 00172 00173 00174 // ###################################################################### 00175 // very useful listener for any close button action 00176 00177 //! watch for close button actions with all registered XWinManaged windows 00178 class CloseButtonListener 00179 { 00180 public: 00181 00182 //! add a window to the list by pointer 00183 inline void add(XWinManaged* win); 00184 00185 //! add a window to the list by reference 00186 inline void add(XWinManaged& win); 00187 00188 //! remove a window from the list by pointer 00189 inline void remove(XWinManaged* win); 00190 00191 //! remove a window from the list by reference 00192 inline void remove(XWinManaged& win); 00193 00194 //! has a close button been pressed at any of the windows? 00195 /*! This function will seg fault if the list contains pointers to 00196 windows that don't exist anymore. Make sure that you remove windows 00197 from the CloseButtonListener before you explicitely delete them!*/ 00198 inline bool pressedAnyCloseButton(); 00199 00200 //! wait for a close button to be pressed 00201 /*! run in an idle loop until a close button is pressed */ 00202 inline void waitForClose(); 00203 00204 private: 00205 std::vector<XWinManaged*> windows; 00206 }; 00207 00208 // ###################################################################### 00209 // inlined methods 00210 00211 // ###################################################################### 00212 inline void CloseButtonListener::add(XWinManaged* win) 00213 { windows.push_back(win); } 00214 00215 inline void CloseButtonListener::add(XWinManaged& win) 00216 { add(&win); } 00217 00218 // ###################################################################### 00219 inline void CloseButtonListener::remove(XWinManaged* win) 00220 { 00221 std::vector<XWinManaged*>::iterator it = find(windows.begin(),windows.end(),win); 00222 if (it != windows.end()) 00223 windows.erase(it); 00224 } 00225 00226 inline void CloseButtonListener::remove(XWinManaged& win) 00227 { remove(&win); } 00228 00229 // ###################################################################### 00230 inline bool CloseButtonListener::pressedAnyCloseButton() 00231 { 00232 for (uint i = 0; i < windows.size(); i++) 00233 if (windows[i]->pressedCloseButton()) return true; 00234 return false; 00235 } 00236 00237 // ###################################################################### 00238 inline void CloseButtonListener::waitForClose() 00239 { 00240 while (!(pressedAnyCloseButton())) usleep(30000); 00241 } 00242 00243 #endif 00244 00245 // ###################################################################### 00246 /* So things look consistent in everyone's emacs... */ 00247 /* Local Variables: */ 00248 /* indent-tabs-mode: nil */ 00249 /* End: */