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>
29 /* for AIX at least */
39 #include <kapplication.h>
43 #include <kmessagebox.h>
54 #define CHAR_HEIGHT 22
57 // libkscreensaver interface
58 class kVmSaverInterface
: public KScreenSaverInterface
63 virtual KAboutData
* aboutData() {
64 return new KAboutData( "kvm.kss", 0, ki18n( "Virtual Machine" ), "2.2.0", ki18n( "Virtual Machine" ) );
68 virtual KScreenSaver
* create( WId id
)
70 return new kVmSaver( id
);
73 virtual QDialog
* setup()
75 return new kVmSetup();
79 int main( int argc
, char *argv
[] )
81 kVmSaverInterface kss
;
82 return kScreenSaverMain( argc
, argv
, kss
);
88 load_images (m_state
*state
)
90 if ( QPixmap::defaultDepth() > 1 )
92 state
->images
= QPixmap( vm
);
96 state
->images
= QBitmap::fromData( QSize(vm_width
, vm_height
), vm_bits
);
98 state
->image_width
= state
->images
.width();
99 state
->image_height
= state
->images
.height();
100 state
->nglyphs
= state
->image_height
/ CHAR_HEIGHT
;
105 init_pool ( QWidget
*w
)
107 m_state
*state
= new m_state
;
112 state
->char_width
= state
->image_width
/ 4;
113 state
->char_height
= CHAR_HEIGHT
;
115 state
->grid_width
= w
->width() / state
->char_width
;
116 state
->grid_height
= w
->height() / state
->char_height
;
117 state
->grid_margin_x
= w
->width()%state
->char_width
/2;
118 state
->grid_margin_y
= w
->height()%state
->char_height
/2;
119 state
->show_threads
= 1;
120 vm_init_pool( &(state
->pool
), state
->grid_width
*state
->grid_height
,
121 THREAD_MAX_STACK_SIZE
, MAX_THREADS_NUM
);
122 //vm_enable_reverse( state->pool, 1 );
123 state
->modified
= new char[state
->grid_height
*state
->grid_width
];
124 for( int x
= 0; x
< state
->grid_width
*state
->grid_height
; ++x
)
125 state
->modified
[x
] = 1;
130 draw_pool (m_state
*state
)
133 struct tvm_process
* curr_thread
;
135 if( state
->show_threads
) {
136 curr_thread
= state
->pool
->processes
;
137 while( curr_thread
) {
138 state
->modified
[curr_thread
->position
] = 2;
139 curr_thread
= curr_thread
->next
;
142 for (y
= 0; y
< state
->grid_height
; y
++)
143 for (x
= 0; x
< state
->grid_width
; x
++) {
144 int index
= state
->grid_width
* y
+ x
;
145 if( state
->modified
[index
] )
147 int op
= state
->pool
->area
[index
];
164 pos_y
= op
- VM_OP_PUSH
;
171 if( state
->show_threads
)
172 if( state
->modified
[index
] == 1 )
174 QPainter
p(state
->w
);
175 p
.setPen( Qt::green
);
176 p
.setBrush( Qt::black
);
177 p
.drawPixmap( state
->grid_margin_x
+ x
*state
->char_width
,
178 state
->grid_margin_y
+ y
*state
->char_height
,
179 state
->images
, pos_x
*state
->char_width
,
180 pos_y
*state
->char_height
,
181 state
->char_width
, state
->char_height
);
182 --state
->modified
[index
];
187 //-----------------------------------------------------------------------------
189 kVmSaver::kVmSaver( WId id
) : KScreenSaver( id
)
194 palette
.setColor( backgroundRole(), Qt::black
);
195 setPalette( palette
);
198 setRefreshTimeout( refreshTimeout
);
202 pool_state
= init_pool( this );
203 vm_default_initstate( time(0), &(pool_state
->pool
->vm_random_data
) );
204 connect( &timer
, SIGNAL( timeout() ), SLOT( update() ) );
205 timer
.start( 100 - speed
);
209 kVmSaver::~kVmSaver()
212 vm_done_pool( pool_state
->pool
);
213 delete[] pool_state
->modified
;
216 void kVmSaver::setSpeed( int spd
)
219 // timer.start( (100 - speed)*(100 - speed)*(100 - speed)/10000 );
220 timer
.start( (100 - speed
) );
222 void kVmSaver::setRefreshTimeout( const int refreshTimeout
)
224 this->refreshTimeout
= refreshTimeout
;
227 void kVmSaver::readSettings()
229 KConfigGroup
config(KGlobal::config(), "Settings");
231 speed
= config
.readEntry( "Speed", 50 );
232 refreshTimeout
= config
.readEntry( "DisplayRefreshTimeout", 0 );
234 int kVmSaver::getRandom( const int max_value
) {
235 return (int)( vm_random(&(pool_state
->pool
->vm_random_data
))*1.0*(max_value
+ 1.0)/
236 (VM_RAND_MAX
+ 1.0) );
237 // return (int)( rand()*1.0*(max_value + 1.0)/
238 // (RAND_MAX + 1.0) );
240 void kVmSaver::modifyArea( const int op
) {
243 vm_modify( pool_state
->pool
, position
=
244 getRandom(pool_state
->pool
->area_size
- 1), op
);
245 pool_state
->modified
[position
] = 1;
248 void kVmSaver::paintEvent(QPaintEvent
*)
250 setAttribute( Qt::WA_NoSystemBackground
); // Only after initial clear
252 for( int i
= 0; i
< 1; ++i
) {
253 if( getRandom(2) == 0 )
254 modifyArea( VM_OP_PUSH
+ getRandom(11) - getRandom(11) );
255 if( getRandom(8) == 0 )
256 modifyArea( VM_OP_STOP
);
257 if( getRandom(8) == 0 )
258 modifyArea( VM_OP_COPY
);
259 if( getRandom(8) == 0 )
260 modifyArea( VM_OP_EXEC
);
261 // if( getRandom(5) == 0 )
262 // modifyArea( VM_OP_WAIT );
264 if( getRandom(0) == 0 )
265 vm_exec( pool_state
->pool
, getRandom(pool_state
->pool
->area_size
- 1), 0,
266 vm_get_reverse( pool_state
->pool
) );
267 vm_iterate( pool_state
->pool
, pool_state
->modified
);
268 // if( refreshStep++ >= refreshTimeout*refreshTimeout*refreshTimeout ) {
269 if( refreshStep
++ >= refreshTimeout
) {
270 draw_pool( pool_state
);
275 //-----------------------------------------------------------------------------
277 kVmSetup::kVmSetup( QWidget
*parent
)
280 setCaption(i18n( "Setup Virtual Machine" ));
281 setButtons(Ok
|Cancel
|Help
);
282 setDefaultButton(Ok
);
286 setButtonText( Help
, i18n( "A&bout" ) );
287 QWidget
*main
= new QWidget(this);
290 QHBoxLayout
*tl
= new QHBoxLayout( main
);
291 tl
->setSpacing( spacingHint() );
292 QVBoxLayout
*tl1
= new QVBoxLayout();
295 QLabel
*label
= new QLabel( i18n("Virtual machine speed:"), main
);
296 tl1
->addWidget(label
);
298 QSlider
*slider
= new QSlider( Qt::Horizontal
, main
);
299 slider
->setMinimumSize( 120, 20 );
300 slider
->setRange( 0, 100 );
301 slider
->setSingleStep( 10 );
302 slider
->setPageStep( 20 );
303 slider
->setTickPosition( QSlider::TicksBelow
);
304 slider
->setTickInterval( 10 );
305 slider
->setValue( speed
);
306 connect( slider
, SIGNAL( valueChanged( int ) ),
307 SLOT( slotSpeed( int ) ) );
308 tl1
->addWidget(slider
);
310 label
= new QLabel( i18n("Display update speed:"), main
);
311 tl1
->addWidget(label
);
313 slider
= new QSlider( Qt::Horizontal
, main
);
314 slider
->setMinimumSize( 120, 20 );
315 slider
->setRange( 0, MAX_REFRESH_TIMEOUT
);
316 slider
->setSingleStep( MAX_REFRESH_TIMEOUT
/10 );
317 slider
->setPageStep( MAX_REFRESH_TIMEOUT
/5 );
318 slider
->setTickPosition( QSlider::TicksBelow
);
319 slider
->setTickInterval( MAX_REFRESH_TIMEOUT
/10 );
320 slider
->setValue( MAX_REFRESH_TIMEOUT
- refreshTimeout
);
321 connect( slider
, SIGNAL( valueChanged( int ) ),
322 SLOT( slotRefreshTimeout( int ) ) );
323 tl1
->addWidget(slider
);
326 preview
= new QWidget( main
);
327 preview
->setFixedSize( 220, 165 );
328 preview
->show(); // otherwise saver does not get correct size
329 saver
= new kVmSaver( preview
->winId() );
330 tl
->addWidget(preview
);
331 connect(this,SIGNAL(okClicked()),this,SLOT(slotOk()));
332 connect(this,SIGNAL(helpClicked()),this,SLOT(slotHelp()));
335 kVmSetup::~kVmSetup()
340 void kVmSetup::readSettings()
342 KConfigGroup
config(KGlobal::config(), "Settings");
344 speed
= config
.readEntry( "Speed", 50 );
347 else if ( speed
< 0 )
349 refreshTimeout
= config
.readEntry( "DisplayRefreshTimeout", 0 );
350 if ( refreshTimeout
> MAX_REFRESH_TIMEOUT
)
351 refreshTimeout
= MAX_REFRESH_TIMEOUT
;
352 else if ( refreshTimeout
< 0 )
356 void kVmSetup::slotSpeed( int num
)
360 saver
->setSpeed( num
);
362 void kVmSetup::slotRefreshTimeout( int num
)
364 refreshTimeout
= MAX_REFRESH_TIMEOUT
- num
;
366 saver
->setRefreshTimeout( refreshTimeout
);
369 void kVmSetup::slotOk()
371 KConfigGroup
config(KGlobal::config(), "Settings");
374 sspeed
.setNum( speed
);
375 config
.writeEntry( "Speed", sspeed
);
376 sspeed
.setNum( refreshTimeout
);
377 config
.writeEntry( "DisplayRefreshTimeout", sspeed
);
383 void kVmSetup::slotHelp()
385 KMessageBox::about(this,
386 i18n("Virtual Machine Version 0.1\n\nCopyright (c) 2000 Artur Rataj <art@zeus.polsl.gliwice.pl>\n"),
387 i18n("About Virtual Machine")