/*- * kvm.cpp - The Vm screensaver for KDE * Copyright (c) 2000 by Artur Rataj * This file is distributed under the terms of the GNU General Public License * * This file is partially based on kmatrix screen saver -- original copyright follows: * kmatrix.c - The Matrix screensaver for KDE * by Eric Plante Copyright (c) 1999 * Distributed under the Gnu Public License * * Much of this code taken from xmatrix.c from xscreensaver; * original copyright follows: * xscreensaver, Copyright (c) 1999 Jamie Zawinski * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation. No representations are made about the suitability of this * software for any purpose. It is provided "as is" without express or * implied warranty. * */ // layout management added 1998/04/19 by Mario Weilguni #ifdef HAVE_CONFIG_H #include #endif #include #include /* for AIX at least */ #include #include #include #include #include #include #include #include #include #include #include #include #ifdef DEBUG_MEM #include #endif #include "kvm.h" #include "vm.xpm" #include "vm.xbm" #define CHAR_HEIGHT 22 // libkscreensaver interface extern "C" { KDE_EXPORT const char *kss_applicationName = "kvm.kss"; KDE_EXPORT const char *kss_description = I18N_NOOP( "Virtual Machine" ); KDE_EXPORT const char *kss_version = "2.2.0"; KDE_EXPORT KScreenSaver *kss_create( WId id ) { return new kVmSaver( id ); } KDE_EXPORT TQDialog *kss_setup() { return new kVmSetup(); } } static void load_images (m_state *state) { if ( TQPixmap::defaultDepth() > 1 ) { state->images = TQPixmap( vm ); } else { state->images = TQBitmap( vm_width, vm_height, vm_bits ); } state->image_width = state->images.width(); state->image_height = state->images.height(); state->nglyphs = state->image_height / CHAR_HEIGHT; } static m_state * init_pool ( TQWidget *w ) { m_state *state = new m_state; state->w = w; load_images (state); state->char_width = state->image_width / 4; state->char_height = CHAR_HEIGHT; state->grid_width = w->width() / state->char_width; state->grid_height = w->height() / state->char_height; state->grid_margin_x = w->width()%state->char_width/2; state->grid_margin_y = w->height()%state->char_height/2; state->show_threads = 1; vm_init_pool( &(state->pool), state->grid_width*state->grid_height, THREAD_MAX_STACK_SIZE, MAX_THREADS_NUM ); //vm_enable_reverse( state->pool, 1 ); state->modified = new char[state->grid_height*state->grid_width]; for( int x = 0; x < state->grid_width*state->grid_height; ++x ) state->modified[x] = 1; return state; } static void draw_pool (m_state *state) { int x, y; struct tvm_process* curr_thread; if( state->show_threads ) { curr_thread = state->pool->processes; while( curr_thread ) { state->modified[curr_thread->position] = 2; curr_thread = curr_thread->next; } } for (y = 0; y < state->grid_height; y++) for (x = 0; x < state->grid_width; x++) { int index = state->grid_width * y + x; if( state->modified[index] ) { int op = state->pool->area[index]; int pos_y; int pos_x = 0; switch( op ) { case VM_OP_STOP: pos_y = 14; break; case VM_OP_EXEC: pos_y = 15; break; case VM_OP_COPY: pos_y = 12; break; default: pos_y = op - VM_OP_PUSH; if( pos_y < 0 ) { pos_y = -pos_y; pos_x = 1; } break; } if( state->show_threads ) if( state->modified[index] == 1 ) pos_x += 2; TQPainter p(state->w); p.setPen( TQt::green ); p.setBrush( TQt::black ); p.drawPixmap( state->grid_margin_x + x*state->char_width, state->grid_margin_y + y*state->char_height, state->images, pos_x*state->char_width, pos_y*state->char_height, state->char_width, state->char_height ); --state->modified[index]; } } } //----------------------------------------------------------------------------- kVmSaver::kVmSaver( WId id ) : KScreenSaver( id ) { readSettings(); colorContext = TQColor::enterAllocContext(); blank(); setSpeed( speed ); setRefreshTimeout( refreshTimeout ); refreshStep = 0; pool_state = init_pool( this ); vm_default_initstate( time(0), &(pool_state->pool->vm_random_data) ); connect( &timer, TQT_SIGNAL( timeout() ), TQT_SLOT( slotTimeout() ) ); timer.start( 100 - speed ); } kVmSaver::~kVmSaver() { timer.stop(); vm_done_pool( pool_state->pool ); delete[] pool_state->modified; TQColor::leaveAllocContext(); TQColor::destroyAllocContext( colorContext ); } void kVmSaver::blank() { setBackgroundColor( black ); erase(); } void kVmSaver::setSpeed( int spd ) { speed = spd; // timer.changeInterval( (100 - speed)*(100 - speed)*(100 - speed)/10000 ); timer.changeInterval( (100 - speed) ); } void kVmSaver::setRefreshTimeout( const int refreshTimeout ) { this->refreshTimeout = refreshTimeout; } void kVmSaver::readSettings() { KConfig *config = TDEGlobal::config(); config->setGroup( "Settings" ); speed = config->readNumEntry( "Speed", 50 ); refreshTimeout = config->readNumEntry( "DisplayRefreshTimeout", 0 ); } int kVmSaver::getRandom( const int max_value ) { return (int)( vm_random(&(pool_state->pool->vm_random_data))*1.0*(max_value + 1.0)/ (VM_RAND_MAX + 1.0) ); // return (int)( rand()*1.0*(max_value + 1.0)/ // (RAND_MAX + 1.0) ); } void kVmSaver::modifyArea( const int op ) { int position; vm_modify( pool_state->pool, position = getRandom(pool_state->pool->area_size - 1), op ); pool_state->modified[position] = 1; } void kVmSaver::slotTimeout() { for( int i = 0; i < 1; ++i ) { if( getRandom(2) == 0 ) modifyArea( VM_OP_PUSH + getRandom(11) - getRandom(11) ); if( getRandom(8) == 0 ) modifyArea( VM_OP_STOP ); if( getRandom(8) == 0 ) modifyArea( VM_OP_COPY ); if( getRandom(8) == 0 ) modifyArea( VM_OP_EXEC ); // if( getRandom(5) == 0 ) // modifyArea( VM_OP_WAIT ); } if( getRandom(0) == 0 ) vm_exec( pool_state->pool, getRandom(pool_state->pool->area_size - 1), 0, vm_get_reverse( pool_state->pool ) ); vm_iterate( pool_state->pool, pool_state->modified ); // if( refreshStep++ >= refreshTimeout*refreshTimeout*refreshTimeout ) { if( refreshStep++ >= refreshTimeout ) { draw_pool( pool_state ); refreshStep = 0; } } //----------------------------------------------------------------------------- kVmSetup::kVmSetup( TQWidget *parent, const char *name ) : KDialogBase( parent, name, true, i18n( "Setup Virtual Machine" ), Ok|Cancel|Help, Ok, true ) { readSettings(); setButtonText( Help, i18n( "A&bout" ) ); TQWidget *main = makeMainWidget(); TQHBoxLayout *tl = new TQHBoxLayout( main, 0, spacingHint() ); TQVBoxLayout *tl1 = new TQVBoxLayout(); tl->addLayout(tl1); TQLabel *label = new TQLabel( i18n("Virtual machine speed:"), main ); tl1->addWidget(label); TQSlider *slider = new TQSlider( Qt::Horizontal, main ); slider->setMinimumSize( 120, 20 ); slider->setRange( 0, 100 ); slider->setSteps( 10, 20 ); slider->setTickmarks( TQSlider::Below ); slider->setTickInterval( 10 ); slider->setValue( speed ); connect( slider, TQT_SIGNAL( valueChanged( int ) ), TQT_SLOT( slotSpeed( int ) ) ); tl1->addWidget(slider); label = new TQLabel( i18n("Display update speed:"), main ); tl1->addWidget(label); slider = new TQSlider( Qt::Horizontal, main ); slider->setMinimumSize( 120, 20 ); slider->setRange( 0, MAX_REFRESH_TIMEOUT ); slider->setSteps( MAX_REFRESH_TIMEOUT/10, MAX_REFRESH_TIMEOUT/5 ); slider->setTickmarks( TQSlider::Below ); slider->setTickInterval( MAX_REFRESH_TIMEOUT/10 ); slider->setValue( MAX_REFRESH_TIMEOUT - refreshTimeout ); connect( slider, TQT_SIGNAL( valueChanged( int ) ), TQT_SLOT( slotRefreshTimeout( int ) ) ); tl1->addWidget(slider); tl1->addStretch(); preview = new TQWidget( main ); preview->setFixedSize( 220, 165 ); preview->show(); // otherwise saver does not get correct size saver = new kVmSaver( preview->winId() ); tl->addWidget(preview); } kVmSetup::~kVmSetup() { delete saver; } void kVmSetup::readSettings() { KConfig *config = TDEGlobal::config(); config->setGroup( "Settings" ); speed = config->readNumEntry( "Speed", 50 ); if ( speed > 100 ) speed = 100; else if ( speed < 0 ) speed = 0; refreshTimeout = config->readNumEntry( "DisplayRefreshTimeout", 0 ); if ( refreshTimeout > MAX_REFRESH_TIMEOUT ) refreshTimeout = MAX_REFRESH_TIMEOUT; else if ( refreshTimeout < 0 ) refreshTimeout = 0; } void kVmSetup::slotSpeed( int num ) { speed = num; if ( saver ) saver->setSpeed( num ); } void kVmSetup::slotRefreshTimeout( int num ) { refreshTimeout = MAX_REFRESH_TIMEOUT - num; if ( saver ) saver->setRefreshTimeout( refreshTimeout ); } void kVmSetup::slotOk() { KConfig *config = TDEGlobal::config(); config->setGroup( "Settings" ); TQString sspeed; sspeed.setNum( speed ); config->writeEntry( "Speed", sspeed ); sspeed.setNum( refreshTimeout ); config->writeEntry( "DisplayRefreshTimeout", sspeed ); config->sync(); accept(); } void kVmSetup::slotHelp() { KMessageBox::about(this, i18n("Virtual Machine Version 0.1\n\nCopyright (c) 2000 Artur Rataj \n"), i18n("About Virtual Machine") ); } #include "kvm.moc"