libyui
3.0.10
|
00001 /* 00002 Copyright (C) 2000-2012 Novell, Inc 00003 This library is free software; you can redistribute it and/or modify 00004 it under the terms of the GNU Lesser General Public License as 00005 published by the Free Software Foundation; either version 2.1 of the 00006 License, or (at your option) version 3.0 of the License. This library 00007 is distributed in the hope that it will be useful, but WITHOUT ANY 00008 WARRANTY; without even the implied warranty of MERCHANTABILITY or 00009 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 00010 License for more details. You should have received a copy of the GNU 00011 Lesser General Public License along with this library; if not, write 00012 to the Free Software Foundation, Inc., 51 Franklin Street, Fifth 00013 Floor, Boston, MA 02110-1301 USA 00014 */ 00015 00016 00017 /*-/ 00018 00019 File: YUI.h 00020 00021 Author: Stefan Hundhammer <sh@suse.de> 00022 00023 /-*/ 00024 00025 #ifndef YUI_h 00026 #define YUI_h 00027 00028 #include <pthread.h> 00029 #include <string> 00030 00031 #include "YTypes.h" 00032 #include "YSettings.h" 00033 00034 class YApplication; 00035 class YWidget; 00036 class YWidgetFactory; 00037 class YOptionalWidgetFactory; 00038 class YEvent; 00039 class YBuiltinCaller; 00040 class YDialog; 00041 class YMacroPlayer; 00042 class YMacroRecorder; 00043 00044 00045 /** 00046 * Abstract base class of a libYUI user interface. 00047 **/ 00048 class YUI 00049 { 00050 friend class YUIFunction; 00051 friend class YUITerminator; 00052 00053 protected: 00054 /** 00055 * Constructor. 00056 **/ 00057 YUI( bool withThreads ); 00058 00059 public: 00060 00061 /** 00062 * Destructor. 00063 **/ 00064 virtual ~YUI(); 00065 00066 /** 00067 * Shut down multithreading. This needs to be called before the destructor 00068 * if the UI was created with threads. If the UI was created without 00069 * threads, this does nothing. 00070 **/ 00071 void shutdownThreads(); 00072 00073 /** 00074 * Access the global UI. 00075 **/ 00076 static YUI * ui(); 00077 00078 /** 00079 * Return the widget factory that provides all the createXY() methods for 00080 * standard (mandatory, i.e. non-optional) widgets. 00081 * 00082 * This will create the factory upon the first call and return a pointer to 00083 * the one and only (singleton) factory upon each subsequent call. 00084 * This may throw exceptions if the factory cannot be created. 00085 **/ 00086 static YWidgetFactory * widgetFactory(); 00087 00088 /** 00089 * Return the widget factory that provides all the createXY() methods for 00090 * optional ("special") widgets and the corresponding hasXYWidget() 00091 * methods. 00092 * 00093 * This will create the factory upon the first call and return a pointer to 00094 * the one and only (singleton) factory upon each subsequent call. 00095 * This may throw exceptions if the factory cannot be created. 00096 **/ 00097 static YOptionalWidgetFactory * optionalWidgetFactory(); 00098 00099 /** 00100 * Return the global YApplication object. 00101 * 00102 * This will create the YApplication upon the first call and return a 00103 * pointer to the one and only (singleton) YApplication upon each 00104 * subsequent call. This may throw exceptions if the YApplication cannot 00105 * be created. 00106 **/ 00107 static YApplication * app(); 00108 00109 /** 00110 * Aliases for YUI::app() 00111 **/ 00112 static YApplication * application() { return app(); } 00113 static YApplication * yApp() { return app(); } 00114 00115 /** 00116 * Make sure there is a UI (with a UI plug-in) created. 00117 * 00118 * If there is none yet, this will use all-default parameters to load a UI 00119 * plug-in and create a UI (without threads). 00120 **/ 00121 static void ensureUICreated(); 00122 00123 00124 protected: 00125 00126 /** 00127 * Create the widget factory that provides all the createXY() methods for 00128 * standard (mandatory, i.e. non-optional) widgets. 00129 * 00130 * Derived classes are required to implement this. 00131 **/ 00132 virtual YWidgetFactory * createWidgetFactory() = 0; 00133 00134 /** 00135 * Create the widget factory that provides all the createXY() methods for 00136 * optional ("special") widgets and the corresponding hasXYWidget() 00137 * methods. 00138 * 00139 * Derived classes are required to implement this. 00140 **/ 00141 virtual YOptionalWidgetFactory * createOptionalWidgetFactory() = 0; 00142 00143 /** 00144 * Create the YApplication object that provides global methods. 00145 * 00146 * Derived classes are required to implement this. 00147 **/ 00148 virtual YApplication * createApplication() = 0; 00149 00150 00151 public: 00152 00153 /** 00154 * Block (or unblock) events. If events are blocked, any event sent 00155 * should be ignored until events are unblocked again. 00156 * 00157 * This default implementation keeps track of a simple internal flag that 00158 * can be queried with eventsBlocked(), so if you reimplement 00159 * blockEvents(), be sure to reimplement eventsBlocked() as well. 00160 **/ 00161 virtual void blockEvents( bool block = true ) { _eventsBlocked = block; } 00162 00163 /** 00164 * Unblock events previously blocked. This is just an alias for 00165 * blockEvents( false) for better readability. 00166 * 00167 * Note: This method is intentionally not virtual. 00168 **/ 00169 void unblockEvents() { blockEvents( false ); } 00170 00171 /** 00172 * Returns 'true' if events are currently blocked. 00173 * 00174 * Reimplement this if you reimplement blockEvents(). 00175 **/ 00176 virtual bool eventsBlocked() const { return _eventsBlocked; } 00177 00178 /** 00179 * Notification that a widget is being deleted. 00180 * This is called from the YWidget destructor. 00181 * 00182 * Derived classes can implement this for any clean-up actions such as 00183 * deleting any events that might be pending for that widget. 00184 **/ 00185 virtual void deleteNotify( YWidget * widget ) {} 00186 00187 /** 00188 * Must be called after the constructor of the Qt/NCurses ui 00189 * is ready. Starts the ui thread. 00190 **/ 00191 void topmostConstructorHasFinished(); 00192 00193 /** 00194 * Running with threads? 00195 **/ 00196 bool runningWithThreads() const { return _withThreads; } 00197 00198 /** 00199 * This method implements the UI thread in case it is existing. 00200 * The loop consists of calling idleLoop, getting the next 00201 * command from the @ref YCPUIComponent, evaluating it, which 00202 * possibly invovles calling userInput() or pollInput() 00203 * and writes the answer back to the other thread where the request 00204 * came from. 00205 **/ 00206 void uiThreadMainLoop(); 00207 00208 /** 00209 * Return the transparent inter-thread communication. 00210 * This will return 0 until set from the outside. 00211 **/ 00212 YBuiltinCaller * builtinCaller() const { return _builtinCaller; } 00213 00214 /** 00215 * Set the transparent inter-thread communication. 00216 * Built-ins are only really called if there is a valid YBuiltinCaller set. 00217 **/ 00218 void setBuiltinCaller( YBuiltinCaller * caller ) 00219 { _builtinCaller = caller; } 00220 00221 /** 00222 * UI-specific runPkgSelection method. 00223 * 00224 * Derived classes are required to implement this. 00225 * 00226 * The packageSelector's dialog will take care of the event and delete it 00227 * when appropriate. The returned pointer is valid until the next call to 00228 * YDialog::userInput(), YDialog::pollInput(), or YUI::runPkgSelection() or 00229 * until the dialog with the packageSelector is destroyed. 00230 **/ 00231 virtual YEvent * runPkgSelection( YWidget * packageSelector ) = 0; 00232 00233 00234 protected: 00235 00236 /** 00237 * This virtual method is called when threads are activated in case the 00238 * execution control is currently on the side of the module. This means 00239 * that no UserInput() or PollInput() is pending. The module just does some 00240 * work. The UI <-> module protocol is in the "UI waits for the next 00241 * command" state. The UI can override this method when it wants to react 00242 * to user input or other external events such as repaint requests from the 00243 * X server. 00244 * 00245 * 'fd_ycp' file descriptor that should be used to determine when 00246 * to leave the idle loop. As soon as it is readable, the loop must 00247 * be left. In order to avoid polling you can combine it with other 00248 * ui-specific fds and do a common select() call. 00249 **/ 00250 virtual void idleLoop( int fd_ycp ) = 0; 00251 00252 /** 00253 * Tells the ui thread that it should terminate and waits 00254 * until it does so. 00255 **/ 00256 void terminateUIThread(); 00257 00258 /** 00259 * Creates and launches the ui thread. 00260 **/ 00261 void createUIThread(); 00262 friend void *start_ui_thread( void *ui_int ); 00263 00264 /** 00265 * Destructor for the UI thread. This will be called as the last thing the 00266 * UI thread does. 00267 * 00268 * Derived classes can overwrite this. In most cases it makes sense to call 00269 * this base class method in the new implementation. 00270 **/ 00271 virtual void uiThreadDestructor(); 00272 00273 /** 00274 * Signals the ui thread by sending one byte through the pipe 00275 * to it. 00276 **/ 00277 void signalUIThread(); 00278 00279 /** 00280 * Waits for the ui thread to send one byte through the pipe 00281 * to the ycp thread and reads this byte from the pipe. 00282 **/ 00283 bool waitForUIThread(); 00284 00285 /** 00286 * Signals the ycp thread by sending one byte through the pipe 00287 * to it. 00288 **/ 00289 void signalYCPThread(); 00290 00291 /** 00292 * Waits for the ycp thread to send one byte through the pipe 00293 * to the ycp thread and reads this byte from the pipe. 00294 **/ 00295 bool waitForYCPThread(); 00296 00297 /** 00298 * Set the button order (in YButtonBox widgets) from environment 00299 * variables: 00300 * 00301 * $Y2_BUTTON_ORDER="KDE" 00302 * $Y2_BUTTON_ORDER="Gnome" 00303 * 00304 * (all case insensitive) 00305 **/ 00306 void setButtonOrderFromEnvironment(); 00307 00308 00309 // 00310 // Data members 00311 // 00312 00313 /** 00314 * true if a seperate UI thread is created 00315 **/ 00316 bool _withThreads; 00317 00318 /** 00319 * Handle to the ui thread. 00320 **/ 00321 pthread_t _uiThread; 00322 00323 /** 00324 * Inter-thread communication between the YCP thread and the UI thread: 00325 * The YCP thread supplies data here and signals the UI thread, 00326 * the UI thread picks up the data, executes the function, puts 00327 * the result here and signals the YCP thread that waits until 00328 * the result is available. 00329 **/ 00330 YBuiltinCaller * _builtinCaller; 00331 00332 /** 00333 * Used to synchronize data transfer with the ui thread. 00334 * It stores a pair of file descriptors of a pipe. For each YCP value 00335 * we send to the ui thread, we write one aribrary byte here. 00336 **/ 00337 int pipe_to_ui[2]; 00338 00339 /** 00340 * Used to synchronize data transfer with the ui thread. 00341 * It stores a pair of file descriptors of a pipe. For each YCP value 00342 * we get from the ui thread, we read one aribrary byte from here. 00343 **/ 00344 int pipe_from_ui[2]; 00345 00346 /** 00347 * This is a flag that signals the ui thread that it should 00348 * terminate. This is done by setting the flag to true. The ui 00349 * thread replies by setting the flag back to false directly 00350 * after terminating itself. 00351 **/ 00352 bool _terminate_ui_thread; 00353 00354 /** 00355 * Flag that keeps track of blocked events. 00356 * Never query this directly, use eventsBlocked() instead. 00357 **/ 00358 bool _eventsBlocked; 00359 00360 private: 00361 00362 static YUI * _ui; 00363 }; 00364 00365 00366 00367 #endif // YUI_h