2 * kvm.cpp - The Vm screensaver for KDE
3 * Copyright (c) 2000 by Artur Rataj
4 * This file is distributed under the terms of the GNU General Public License
6 * This file is partially based on kmatrix screen saver -- original copyright follows:
7 * kmatrix.c - The Matrix screensaver for KDE
8 * by Eric Plante Copyright (c) 1999
9 * Distributed under the Gnu Public License
11 * Much of this code taken from xmatrix.c from xscreensaver;
12 * original copyright follows:
13 * xscreensaver, Copyright (c) 1999 Jamie Zawinski <jwz@jwz.org>
15 * Permission to use, copy, modify, distribute, and sell this software and its
16 * documentation for any purpose is hereby granted without fee, provided that
17 * the above copyright notice appear in all copies and that both that
18 * copyright notice and this permission notice appear in supporting
19 * documentation. No representations are made about the suitability of this
20 * software for any purpose. It is provided "as is" without express or
24 // layout management added 1998/04/19 by Mario Weilguni <mweilguni@kde.org>
33 /* for AIX at least */
44 #include <QVBoxLayout>
45 #include <QHBoxLayout>
47 #include <kapplication.h>
51 #include <kmessagebox.h>
62 #define CHAR_HEIGHT 22
65 // libkscreensaver interface
68 KDE_EXPORT
const char *kss_applicationName
= "kvm.kss";
69 KDE_EXPORT
const char *kss_description
= I18N_NOOP( "Virtual Machine" );
70 KDE_EXPORT
const char *kss_version
= "2.2.0";
72 KDE_EXPORT KScreenSaver
*kss_create( WId id
)
74 return new kVmSaver( id
);
77 KDE_EXPORT QDialog
*kss_setup()
79 return new kVmSetup();
86 load_images (m_state
*state
)
88 if ( QPixmap::defaultDepth() > 1 )
90 state
->images
= QPixmap( vm
);
94 state
->images
= QBitmap( vm_width
, vm_height
, vm_bits
);
96 state
->image_width
= state
->images
.width();
97 state
->image_height
= state
->images
.height();
98 state
->nglyphs
= state
->image_height
/ CHAR_HEIGHT
;
103 init_pool ( QWidget
*w
)
105 m_state
*state
= new m_state
;
110 state
->char_width
= state
->image_width
/ 4;
111 state
->char_height
= CHAR_HEIGHT
;
113 state
->grid_width
= w
->width() / state
->char_width
;
114 state
->grid_height
= w
->height() / state
->char_height
;
115 state
->grid_margin_x
= w
->width()%state
->char_width
/2;
116 state
->grid_margin_y
= w
->height()%state
->char_height
/2;
117 state
->show_threads
= 1;
118 vm_init_pool( &(state
->pool
), state
->grid_width
*state
->grid_height
,
119 THREAD_MAX_STACK_SIZE
, MAX_THREADS_NUM
);
120 //vm_enable_reverse( state->pool, 1 );
121 state
->modified
= new char[state
->grid_height
*state
->grid_width
];
122 for( int x
= 0; x
< state
->grid_width
*state
->grid_height
; ++x
)
123 state
->modified
[x
] = 1;
128 draw_pool (m_state
*state
)
131 struct tvm_process
* curr_thread
;
133 if( state
->show_threads
) {
134 curr_thread
= state
->pool
->processes
;
135 while( curr_thread
) {
136 state
->modified
[curr_thread
->position
] = 2;
137 curr_thread
= curr_thread
->next
;
140 for (y
= 0; y
< state
->grid_height
; y
++)
141 for (x
= 0; x
< state
->grid_width
; x
++) {
142 int index
= state
->grid_width
* y
+ x
;
143 if( state
->modified
[index
] )
145 int op
= state
->pool
->area
[index
];
162 pos_y
= op
- VM_OP_PUSH
;
169 if( state
->show_threads
)
170 if( state
->modified
[index
] == 1 )
172 QPainter
p(state
->w
);
173 p
.setPen( Qt::green
);
174 p
.setBrush( Qt::black
);
175 p
.drawPixmap( state
->grid_margin_x
+ x
*state
->char_width
,
176 state
->grid_margin_y
+ y
*state
->char_height
,
177 state
->images
, pos_x
*state
->char_width
,
178 pos_y
*state
->char_height
,
179 state
->char_width
, state
->char_height
);
180 --state
->modified
[index
];
185 //-----------------------------------------------------------------------------
187 kVmSaver::kVmSaver( WId id
) : KScreenSaver( id
)
191 colorContext
= QColor::enterAllocContext();
195 setRefreshTimeout( refreshTimeout
);
199 pool_state
= init_pool( this );
200 vm_default_initstate( time(0), &(pool_state
->pool
->vm_random_data
) );
201 connect( &timer
, SIGNAL( timeout() ), SLOT( slotTimeout() ) );
202 timer
.start( 100 - speed
);
205 kVmSaver::~kVmSaver()
208 vm_done_pool( pool_state
->pool
);
209 delete[] pool_state
->modified
;
210 QColor::leaveAllocContext();
211 QColor::destroyAllocContext( colorContext
);
214 void kVmSaver::blank()
216 setBackgroundColor( black
);
220 void kVmSaver::setSpeed( int spd
)
223 // timer.changeInterval( (100 - speed)*(100 - speed)*(100 - speed)/10000 );
224 timer
.changeInterval( (100 - speed
) );
226 void kVmSaver::setRefreshTimeout( const int refreshTimeout
)
228 this->refreshTimeout
= refreshTimeout
;
231 void kVmSaver::readSettings()
233 KConfig
*config
= KGlobal::config();
234 config
->setGroup( "Settings" );
236 speed
= config
->readNumEntry( "Speed", 50 );
237 refreshTimeout
= config
->readNumEntry( "DisplayRefreshTimeout", 0 );
239 int kVmSaver::getRandom( const int max_value
) {
240 return (int)( vm_random(&(pool_state
->pool
->vm_random_data
))*1.0*(max_value
+ 1.0)/
241 (VM_RAND_MAX
+ 1.0) );
242 // return (int)( rand()*1.0*(max_value + 1.0)/
243 // (RAND_MAX + 1.0) );
245 void kVmSaver::modifyArea( const int op
) {
248 vm_modify( pool_state
->pool
, position
=
249 getRandom(pool_state
->pool
->area_size
- 1), op
);
250 pool_state
->modified
[position
] = 1;
253 void kVmSaver::slotTimeout()
255 for( int i
= 0; i
< 1; ++i
) {
256 if( getRandom(2) == 0 )
257 modifyArea( VM_OP_PUSH
+ getRandom(11) - getRandom(11) );
258 if( getRandom(8) == 0 )
259 modifyArea( VM_OP_STOP
);
260 if( getRandom(8) == 0 )
261 modifyArea( VM_OP_COPY
);
262 if( getRandom(8) == 0 )
263 modifyArea( VM_OP_EXEC
);
264 // if( getRandom(5) == 0 )
265 // modifyArea( VM_OP_WAIT );
267 if( getRandom(0) == 0 )
268 vm_exec( pool_state
->pool
, getRandom(pool_state
->pool
->area_size
- 1), 0,
269 vm_get_reverse( pool_state
->pool
) );
270 vm_iterate( pool_state
->pool
, pool_state
->modified
);
271 // if( refreshStep++ >= refreshTimeout*refreshTimeout*refreshTimeout ) {
272 if( refreshStep
++ >= refreshTimeout
) {
273 draw_pool( pool_state
);
278 //-----------------------------------------------------------------------------
280 kVmSetup::kVmSetup( QWidget
*parent
, const char *name
)
281 : KDialogBase( parent
, name
, true, i18n( "Setup Virtual Machine" ),
282 Ok
|Cancel
|Help
, Ok
, true )
286 setButtonText( Help
, i18n( "A&bout" ) );
287 QWidget
*main
= makeMainWidget();
289 QHBoxLayout
*tl
= new QHBoxLayout( main
, 0, spacingHint() );
290 QVBoxLayout
*tl1
= new QVBoxLayout();
293 QLabel
*label
= new QLabel( i18n("Virtual machine speed:"), main
);
294 tl1
->addWidget(label
);
296 QSlider
*slider
= new QSlider( QSlider::Horizontal
, main
);
297 slider
->setMinimumSize( 120, 20 );
298 slider
->setRange( 0, 100 );
299 slider
->setSteps( 10, 20 );
300 slider
->setTickmarks( QSlider::Below
);
301 slider
->setTickInterval( 10 );
302 slider
->setValue( speed
);
303 connect( slider
, SIGNAL( valueChanged( int ) ),
304 SLOT( slotSpeed( int ) ) );
305 tl1
->addWidget(slider
);
307 label
= new QLabel( i18n("Display update speed:"), main
);
308 tl1
->addWidget(label
);
310 slider
= new QSlider( QSlider::Horizontal
, main
);
311 slider
->setMinimumSize( 120, 20 );
312 slider
->setRange( 0, MAX_REFRESH_TIMEOUT
);
313 slider
->setSteps( MAX_REFRESH_TIMEOUT
/10, MAX_REFRESH_TIMEOUT
/5 );
314 slider
->setTickmarks( QSlider::Below
);
315 slider
->setTickInterval( MAX_REFRESH_TIMEOUT
/10 );
316 slider
->setValue( MAX_REFRESH_TIMEOUT
- refreshTimeout
);
317 connect( slider
, SIGNAL( valueChanged( int ) ),
318 SLOT( slotRefreshTimeout( int ) ) );
319 tl1
->addWidget(slider
);
322 preview
= new QWidget( main
);
323 preview
->setFixedSize( 220, 165 );
324 preview
->show(); // otherwise saver does not get correct size
325 saver
= new kVmSaver( preview
->winId() );
326 tl
->addWidget(preview
);
329 kVmSetup::~kVmSetup()
334 void kVmSetup::readSettings()
336 KConfig
*config
= KGlobal::config();
337 config
->setGroup( "Settings" );
339 speed
= config
->readNumEntry( "Speed", 50 );
342 else if ( speed
< 0 )
344 refreshTimeout
= config
->readNumEntry( "DisplayRefreshTimeout", 0 );
345 if ( refreshTimeout
> MAX_REFRESH_TIMEOUT
)
346 refreshTimeout
= MAX_REFRESH_TIMEOUT
;
347 else if ( refreshTimeout
< 0 )
351 void kVmSetup::slotSpeed( int num
)
355 saver
->setSpeed( num
);
357 void kVmSetup::slotRefreshTimeout( int num
)
359 refreshTimeout
= MAX_REFRESH_TIMEOUT
- num
;
361 saver
->setRefreshTimeout( refreshTimeout
);
364 void kVmSetup::slotOk()
366 KConfig
*config
= KGlobal::config();
367 config
->setGroup( "Settings" );
370 sspeed
.setNum( speed
);
371 config
->writeEntry( "Speed", sspeed
);
372 sspeed
.setNum( refreshTimeout
);
373 config
->writeEntry( "DisplayRefreshTimeout", sspeed
);
379 void kVmSetup::slotHelp()
381 KMessageBox::about(this,
382 i18n("Virtual Machine Version 0.1\n\nCopyright (c) 2000 Artur Rataj <art@zeus.polsl.gliwice.pl>\n"),
383 i18n("About Virtual Machine")