]> icculus.org git repositories - duncan/yast2-web-wt.git/blob - src/YWebUI_core.cc
- removed bad experiment
[duncan/yast2-web-wt.git] / src / YWebUI_core.cc
1 /*---------------------------------------------------------------------\
2 |                                                                      |
3 |                      __   __    ____ _____ ____                      |
4 |                      \ \ / /_ _/ ___|_   _|___ \                     |
5 |                       \ V / _` \___ \ | |   __) |                    |
6 |                        | | (_| |___) || |  / __/                     |
7 |                        |_|\__,_|____/ |_| |_____|                    |
8 |                                                                      |
9 |                               core system                            |
10 |                                                        (C) SuSE GmbH |
11 \----------------------------------------------------------------------/
12
13   File:         YWebUI_core.cc
14
15   Author:       Stefan Hundhammer <sh@suse.de>
16                 Stanislav Visnovsky <visnov@suse.cz>
17
18 /-*/
19
20 #include <rpc/types.h>          // MAXHOSTNAMELEN
21 #include <dlfcn.h>
22
23 #include <ycp/YCPTerm.h>
24 #include <ycp/YCPCode.h>
25
26 #include <yui/Y2UINamespace.h>
27
28 #define y2log_component "web-ui"
29 #include <ycp/y2log.h>
30
31 #include <WApplication>
32
33 #include "YWebUI.h"
34 #include "YWebApplication.h"
35 #include "YWebWidgetFactory.h"
36 #include "YWebOptionalWidgetFactory.h"
37 #include "YWebDialog.h"
38
39 using namespace Wt;
40
41 YWebUI * YWebUI::_ui = 0;
42 int YWebUI::_argc = 0;
43 char ** YWebUI::_argv = 0;
44
45 WApplication* _wApp = 0;
46
47 YWebUI::YWebUI( const Wt::WEnvironment& env, const char * macro_file )
48     : WApplication(env),
49     YUI( true /* with_threads */ )
50     , _main_dialog_id(0)
51     , _do_exit_loop( false )
52 {
53     _ui                         = this;
54     _fatal_error                = false;
55
56     _builtinCallData.function = 0;
57 //    processCommandLineArgs( argc, argv );
58
59     topmostConstructorHasFinished();
60 }
61
62
63 void YWebUI::processCommandLineArgs( int argc, char **argv )
64 {
65     if ( argv )
66     {
67         for( int i=0; i < argc; i++ )
68         {
69             string opt = argv[i];
70
71             y2milestone ("Web argument: %s", argv[i]);
72
73         }
74     }
75 }
76
77
78
79 YWebUI::~YWebUI()
80 {
81     y2debug("Closing down Web UI.");
82 }
83
84
85
86 YWidgetFactory *
87 YWebUI::createWidgetFactory()
88 {
89     YWebWidgetFactory * factory = new YWebWidgetFactory();
90     YUI_CHECK_NEW( factory );
91
92     return factory;
93 }
94
95
96
97 YOptionalWidgetFactory *
98 YWebUI::createOptionalWidgetFactory()
99 {
100     YWebOptionalWidgetFactory * factory = new YWebOptionalWidgetFactory();
101     YUI_CHECK_NEW( factory );
102
103     return factory;
104 }
105
106
107 YApplication *
108 YWebUI::createApplication()
109 {
110     YWebApplication * app = new YWebApplication();
111                 YUI_CHECK_NEW( app );
112                 return app;
113 }
114
115
116
117 void YWebUI::internalError( const char * msg )
118 {
119     raiseFatalError();
120     abort();
121 }
122
123
124 void YWebUI::idleLoop( int fd_ycp )
125 {
126     while ( true )
127     {
128         sleep(1);       // idleLoop ( pipe_to_ui[0] );
129
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.
135
136         y2milestone( "Waiting for work from YCP" );
137         
138         if ( ! waitForYCPThread () )
139             continue;
140
141         if ( terminate_ui_thread )
142             return;
143
144         _wtimer_work = true;
145         
146         y2security( "%s", _builtinCallData.function->name().c_str());
147         
148         while( _wtimer_work )
149         {
150             sleep(1);
151         }
152         // _builtinCallData.result = _builtinCallData.function->evaluateCall_int();
153
154         signalYCPThread();
155     }
156
157 }
158
159
160 void YWebUI::leaveIdleLoop( int )
161 {
162     // FIXME
163     _leave_idle_loop = true;
164 }
165
166
167 void YWebUI::sendEvent( YEvent * event )
168 {
169     if ( event )
170     {
171         _event_handler.sendEvent( event );
172
173         if ( _do_exit_loop ) {
174         // FIXME:
175         }
176     }
177 }
178
179
180 YEvent * YWebUI::userInput( unsigned long timeout_millisec )
181 {
182     YEvent *    event  = 0;
183 #if 0
184     YQDialog *  dialog = dynamic_cast<YQDialog *> ( YDialog::currentDialog( false ) );
185
186     if ( _user_input_timer.isActive() )
187         _user_input_timer.stop();
188
189     if ( dialog )
190     {
191         if ( timeout_millisec > 0 )
192             _user_input_timer.start( timeout_millisec, true ); // single shot
193
194         dialog->activate( true );
195
196         if ( qApp->focusWidget() )
197             qApp->focusWidget()->setFocus();
198
199         normalCursor();
200         _do_exit_loop = true; // should exit_loop() be called in sendEvent()?
201
202         while ( ! pendingEvent() )
203         {
204             qApp->enter_loop();
205         }
206
207         _do_exit_loop = false;
208         event = _event_handler.consumePendingEvent();
209         dialog->activate( false );
210
211         // Display a busy cursor, but only if there is no other activity within
212         // BUSY_CURSOR_TIMEOUT milliseconds (avoid cursor flicker)
213
214         _busy_cursor_timer.start( BUSY_CURSOR_TIMEOUT, true ); // single shot
215     }
216
217     if ( _user_input_timer.isActive() )
218         _user_input_timer.stop();
219
220 #endif
221     return event;
222 }
223
224
225 YEvent * YWebUI::pollInput()
226 {
227     YEvent * event = 0;
228
229 #if 0
230     if ( _user_input_timer.isActive() )
231         _user_input_timer.stop();
232
233     if ( ! pendingEvent() )
234     {
235         YQDialog * dialog = dynamic_cast<YQDialog *> ( YDialog::currentDialog( false ) );
236
237         if ( dialog )
238         {
239             dialog->activate( true );
240             qApp->processEvents();
241             event = _event_handler.consumePendingEvent();
242             dialog->activate( false );
243         }
244     }
245
246     if ( pendingEvent() )
247         event = _event_handler.consumePendingEvent();
248 #endif
249     return event;
250 }
251
252
253 YDialog * YWebUI::createDialog( YWidgetOpt & opt )
254 {
255     return new YWebDialog( opt );
256 }
257
258
259 void YWebUI::showDialog( YDialog * dialog )
260 {
261     // FIXME
262     // event loop in Qt is here
263 }
264
265
266 void YWebUI::closeDialog( YDialog * dialog )
267 {
268     // FIXME
269 }
270
271 extern pid_t gettid();
272
273 WApplication *createApplication(const WEnvironment& env)
274 {
275   // Instantiate the Wt application.
276   YWebUI *appl = new YWebUI( env, 0 );
277
278   // HACK!!!! - not a singleton
279   _wApp = appl;
280   
281   y2security( "Application: %p, thread %d", _wApp, gettid());
282
283     // Set window title
284
285     std::string title( "YaST2" );
286     char hostname[ MAXHOSTNAMELEN+1 ];
287
288     if ( gethostname( hostname, sizeof( hostname )-1 ) == 0 )
289     {
290         hostname[ sizeof( hostname ) -1 ] = '\0'; // make sure it's terminated
291
292         if ( strlen( hostname ) > 0 )
293         {
294             if ( ( strcmp( hostname, "(none)" ) != 0 &&
295                    strcmp( hostname, "linux"  ) != 0 )
296                   )
297             {
298                 title += "@";
299                 title += hostname;
300             }
301         }
302     }
303
304   y2milestone( "Created WApplication (%p)", appl );
305
306   // Set application title
307   appl->setTitle(title);
308
309   // Set up a timer for handling YaST requests
310   appl->createTimer();
311
312   return appl;
313 }
314
315 void *start_webserver_thread( void * yui )
316 {
317     // FIXME: do the work
318     YWebUI* ui = (YWebUI*)yui;
319
320     WRun(ui->_argc, ui->_argv, &createApplication);
321
322     return 0;
323 }
324
325 void YWebUI::createTimer()
326 {
327     _timer = new WTimer();
328     _timer->setInterval( 1000 ); // 1 sec
329
330     _timer->timeout.connect( SLOT(this, YWebUI::triggeredTimer ) );
331
332     _timer->start();
333 }
334
335 void YWebUI::triggeredTimer()
336 {
337     y2debug ("Timer triggered, work %d, function %p", (int)_wtimer_work, _builtinCallData.function);
338     if( _wtimer_work && _builtinCallData.function )
339     {
340
341         y2milestone("Work to do in %p, function '%s'", this, _builtinCallData.function->name().c_str());
342
343         // callFunction() checks for NULL function pointers
344         //      (dynamic_cast<WTimer*>(WObject::sender()))->stop ();
345
346         _builtinCallData.result = _builtinCallData.function->evaluateCall_int();
347         
348         _builtinCallData.function = 0;
349         
350         _wtimer_work = false;
351         
352         signalYCPThread();
353     }
354 }
355