1 /*---------------------------------------------------------------------\
3 | __ __ ____ _____ ____ |
4 | \ \ / /_ _/ ___|_ _|___ \ |
5 | \ V / _` \___ \ | | __) | |
6 | | | (_| |___) || | / __/ |
7 | |_|\__,_|____/ |_| |_____| |
11 \----------------------------------------------------------------------/
15 Author: Stefan Hundhammer <sh@suse.de>
16 Stanislav Visnovsky <visnov@suse.cz>
20 #include <rpc/types.h> // MAXHOSTNAMELEN
23 #include <ycp/YCPTerm.h>
24 #include <ycp/YCPCode.h>
26 #include <yui/Y2UINamespace.h>
28 #define y2log_component "web-ui"
29 #include <ycp/y2log.h>
31 #include <WApplication>
34 #include "YWebApplication.h"
35 #include "YWebWidgetFactory.h"
36 #include "YWebOptionalWidgetFactory.h"
37 #include "YWebDialog.h"
41 YWebUI * YWebUI::_ui = 0;
42 int YWebUI::_argc = 0;
43 char ** YWebUI::_argv = 0;
45 WApplication* _wApp = 0;
47 YWebUI::YWebUI( const Wt::WEnvironment& env, const char * macro_file )
49 YUI( true /* with_threads */ )
51 , _do_exit_loop( false )
56 _builtinCallData.function = 0;
57 // processCommandLineArgs( argc, argv );
59 topmostConstructorHasFinished();
63 void YWebUI::processCommandLineArgs( int argc, char **argv )
67 for( int i=0; i < argc; i++ )
71 y2milestone ("Web argument: %s", argv[i]);
81 y2debug("Closing down Web UI.");
87 YWebUI::createWidgetFactory()
89 YWebWidgetFactory * factory = new YWebWidgetFactory();
90 YUI_CHECK_NEW( factory );
97 YOptionalWidgetFactory *
98 YWebUI::createOptionalWidgetFactory()
100 YWebOptionalWidgetFactory * factory = new YWebOptionalWidgetFactory();
101 YUI_CHECK_NEW( factory );
108 YWebUI::createApplication()
110 YWebApplication * app = new YWebApplication();
111 YUI_CHECK_NEW( app );
117 void YWebUI::internalError( const char * msg )
124 void YWebUI::idleLoop( int fd_ycp )
128 sleep(1); // idleLoop ( pipe_to_ui[0] );
130 // The pipe is non-blocking, so we have to check if we really read a
131 // signal byte. Although idleLoop already makes a select, this seems to
132 // be necessary. Anyway: Why do we set the pipe to non-blocking if we
133 // wait in idleLoop for it to become readable? It is needed in
134 // YUIQt::idleLoop for QSocketNotifier.
136 y2milestone( "Waiting for work from YCP" );
138 if ( ! waitForYCPThread () )
141 if ( terminate_ui_thread )
146 y2security( "%s", _builtinCallData.function->name().c_str());
148 while( _wtimer_work )
152 // _builtinCallData.result = _builtinCallData.function->evaluateCall_int();
160 void YWebUI::leaveIdleLoop( int )
163 _leave_idle_loop = true;
167 void YWebUI::sendEvent( YEvent * event )
171 _event_handler.sendEvent( event );
173 if ( _do_exit_loop ) {
180 YEvent * YWebUI::userInput( unsigned long timeout_millisec )
184 YQDialog * dialog = dynamic_cast<YQDialog *> ( YDialog::currentDialog( false ) );
186 if ( _user_input_timer.isActive() )
187 _user_input_timer.stop();
191 if ( timeout_millisec > 0 )
192 _user_input_timer.start( timeout_millisec, true ); // single shot
194 dialog->activate( true );
196 if ( qApp->focusWidget() )
197 qApp->focusWidget()->setFocus();
200 _do_exit_loop = true; // should exit_loop() be called in sendEvent()?
202 while ( ! pendingEvent() )
207 _do_exit_loop = false;
208 event = _event_handler.consumePendingEvent();
209 dialog->activate( false );
211 // Display a busy cursor, but only if there is no other activity within
212 // BUSY_CURSOR_TIMEOUT milliseconds (avoid cursor flicker)
214 _busy_cursor_timer.start( BUSY_CURSOR_TIMEOUT, true ); // single shot
217 if ( _user_input_timer.isActive() )
218 _user_input_timer.stop();
225 YEvent * YWebUI::pollInput()
230 if ( _user_input_timer.isActive() )
231 _user_input_timer.stop();
233 if ( ! pendingEvent() )
235 YQDialog * dialog = dynamic_cast<YQDialog *> ( YDialog::currentDialog( false ) );
239 dialog->activate( true );
240 qApp->processEvents();
241 event = _event_handler.consumePendingEvent();
242 dialog->activate( false );
246 if ( pendingEvent() )
247 event = _event_handler.consumePendingEvent();
253 YDialog * YWebUI::createDialog( YWidgetOpt & opt )
255 return new YWebDialog( opt );
259 void YWebUI::showDialog( YDialog * dialog )
262 // event loop in Qt is here
266 void YWebUI::closeDialog( YDialog * dialog )
271 extern pid_t gettid();
273 WApplication *createApplication(const WEnvironment& env)
275 // Instantiate the Wt application.
276 YWebUI *appl = new YWebUI( env, 0 );
278 // HACK!!!! - not a singleton
281 y2security( "Application: %p, thread %d", _wApp, gettid());
285 std::string title( "YaST2" );
286 char hostname[ MAXHOSTNAMELEN+1 ];
288 if ( gethostname( hostname, sizeof( hostname )-1 ) == 0 )
290 hostname[ sizeof( hostname ) -1 ] = '\0'; // make sure it's terminated
292 if ( strlen( hostname ) > 0 )
294 if ( ( strcmp( hostname, "(none)" ) != 0 &&
295 strcmp( hostname, "linux" ) != 0 )
304 y2milestone( "Created WApplication (%p)", appl );
306 // Set application title
307 appl->setTitle(title);
309 // Set up a timer for handling YaST requests
315 void *start_webserver_thread( void * yui )
317 // FIXME: do the work
318 YWebUI* ui = (YWebUI*)yui;
320 WRun(ui->_argc, ui->_argv, &createApplication);
325 void YWebUI::createTimer()
327 _timer = new WTimer();
328 _timer->setInterval( 1000 ); // 1 sec
330 _timer->timeout.connect( SLOT(this, YWebUI::triggeredTimer ) );
335 void YWebUI::triggeredTimer()
337 y2debug ("Timer triggered");
338 if( _wtimer_work && _builtinCallData.function )
341 y2milestone("Work to do in %p, function '%s'", this, _builtinCallData.function->name().c_str());
343 // callFunction() checks for NULL function pointers
344 // (dynamic_cast<WTimer*>(WObject::sender()))->stop ();
346 _builtinCallData.result = _builtinCallData.function->evaluateCall_int();
348 _builtinCallData.function = 0;
350 _wtimer_work = false;