This is Percentages.m in view mode; [Download] [Up]
/* Percentages.m Implementation file for the Percentage class. Copyright 1991 Scott Hess. Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that this copyright notice appear in all copies. The copyright notice need not appear on binary-only distributions - just in source code. Scott Hess makes no representations about the suitability of this software for any purpose. It is provided "as is" without express or implied warranty. */ #import "Percentages.h" #import <libc.h> #import <dpsclient/wraps.h> #import <appkit/Panel.h> #import <appkit/Application.h> #import <syslog.h> #import <sys/file.h> #import <nlist.h> #import <string.h> #import "TimeMonWraps.h" #define INLINE_MATH #import <appkit/nextstd.h> #import <appkit/defaults.h> #import <appkit/MenuCell.h> #import <mach.h> #import <appkit/NXImage.h> #import <grp.h> /* By default, we'll hope that we don't have to use /dev/kmem. */ #ifndef USEKMEM #define USEKMEM 0 #endif USEKMEM /* Determines how much movement is needed for a display/redisplay. */ #define MINSHOWN 0.01 /* Minimum values for the defaults. */ #define MINPERIOD 0.2 #define MINFACTOR 4 @implementation Percentages static struct nlist nl[]={{{"_cp_time"}, 0, 0, 0, 0}, {{""}, 0, 0, 0, 0}}; #if !USEKMEM #import <sys/table.h> extern int table( int, int, void *, int, int); #endif - initFrame:(NXRect *)r { int i, j; [super initFrame:r]; kmem=-1; for( i=0; i<3; i++) for( j=0; j<3; j++) pcents[ i][ j]=0.0; return self; } - update { static float radii[ 3]={ 23, 17, 11}; int i; BOOL drawn=NO; PSsetlinewidth( 1.0); if( updateFlags[ 0]) { PSsetgray( NX_LTGRAY); NXRectFill( &bounds); } for( i=0; i<3; i++) if( updateFlags[ i]) { drawn=YES; updateFlags[ i]=NO; bcopy( pcents[ i], lpcents[ i], sizeof( lpcents[ i])); if( pcents[ i][ 2]>=MINSHOWN) drawArc2( radii[ i], 90-(pcents[ i][ 0])*360, 90-(pcents[ i][ 0]+pcents[ i][ 1])*360, 90-(pcents[ i][ 0]+pcents[ i][ 1]+pcents[ i][ 2])*360); else drawArc1( radii[ i], 90-(pcents[ i][ 0])*360, 90-(pcents[ i][ 0]+pcents[ i][ 1])*360); } if( drawn) { static float bbox[]={ 0, 0, 48, 48}; static float coords[]={ 47.5, 24, /* moveto */ 24, 24, 23.5, 0, 360, /* arc */ 41.5, 24, /* moveto */ 24, 24, 17.5, 0, 360, /* arc */ 35.5, 24, /* moveto */ 24, 24, 11.5, 0, 360, /* arc */ 24, 24, /* moveto */ 24, 48, /* lineto */ }; static char ops[]={ dps_ucache, dps_moveto, dps_arc, dps_moveto, dps_arc, dps_moveto, dps_arc, dps_moveto, dps_lineto}; PSsetgray( NX_BLACK); DPSDoUserPath( coords, sizeof( coords)/sizeof( coords[ 0]), dps_float, ops, sizeof( ops)/sizeof( ops[ 0]), bbox, dps_ustroke); } return self; } - drawSelf:(NXRect *)r :(int)count { if( !te) { static NXImage *app, *pause; if( !app) { app=[NXImage findImageNamed:"app"]; pause=[NXImage findImageNamed:"TimeMonP.tiff"]; } PSsetgray( NX_LTGRAY); NXRectFill( &bounds); [app composite:NX_SOVER toPoint:&(bounds.origin)]; [pause composite:NX_SOVER toPoint:&(bounds.origin)]; } else { updateFlags[ 0]=updateFlags[ 1]=updateFlags[ 2]=YES; [self update]; } return self; } /* Just a handy shorthand for use below. */ #define LF2 (layerFactor*layerFactor) - step { long cp_time[ CPUSTATES]; int i, j; float total; steps++; #if !USEKMEM if( kmem==-1) /* Use table()? */ { struct tbl_cpuinfo tc; table( TBL_CPUINFO, 0, &tc, 1, sizeof( tc)); bcopy( tc.ci_cptime, cp_time, sizeof( cp_time)); } else /* Nope, use kmem directly. */ { #endif /* Seek to where _cp_time resides. */ if( lseek( kmem, nl[ 0].n_value, L_SET)!=nl[ 0].n_value) { syslog( LOG_WARNING, "TimeMon: Unable to seek in /dev/kmem\n"); return nil; } /* Read in the variable. */ if( read( kmem, cp_time, sizeof( cp_time))!=sizeof( cp_time)) { syslog( LOG_WARNING, "TimeMon: Unable to read from /dev/kmem\n"); return nil; } #if !USEKMEM } #endif total=cp_time[ CP_USER]+cp_time[ CP_NICE] +cp_time[ CP_SYS]+cp_time[ CP_IDLE]; total-=oldTimes[ CP_USER]+oldTimes[ CP_NICE] +oldTimes[ CP_SYS]+oldTimes[ CP_IDLE]; if( total) /* Make sure we divide reasonably. */ { pcents[ 2][ 0]=(cp_time[ CP_SYS]-oldTimes[ CP_SYS])/total; pcents[ 2][ 1]=(cp_time[ CP_USER]-oldTimes[ CP_USER])/total; pcents[ 2][ 2]=(cp_time[ CP_NICE]-oldTimes[ CP_NICE])/total; bcopy( cp_time, oldTimes, sizeof( cp_time)); if( steps<layerFactor) for( i=0; i<3; i++) pcents[ 1][ i]=(pcents[ 1][ i]*(steps-1) +pcents[ 2][ i])/steps; else for( i=0; i<3; i++) pcents[ 1][ i]=(pcents[ 1][ i]*(layerFactor-1) +pcents[ 2][ i])/layerFactor; if( steps<LF2) for( i=0; i<3; i++) pcents[ 0][ i]=(pcents[ 0][ i]*(steps-1) +pcents[ 2][ i])/steps; else for( i=0; i<3; i++) pcents[ 0][ i]=(pcents[ 0][ i]*(LF2-1) +pcents[ 2][ i])/LF2; for( i=0; i<3; i++) for( j=0; j<3; j++) if( rint( pcents[ i][ j]*100)!=rint( lpcents[ i][ j]*100)) { for( ; i<3; i++) updateFlags[ i]=YES; break; } [self lockFocus]; [self update]; [self unlockFocus]; [window flushWindow]; NXPing(); } return self; } - cycle:sender { return [self step]; } static void _step( DPSTimedEntry te, double curTime, id self) { [self step]; } - appWillInit:sender { struct task_basic_info tbi; unsigned ic=TASK_BASIC_INFO_COUNT; if( task_info( task_self(), TASK_BASIC_INFO, (task_info_t)&tbi, &ic)!=KERN_SUCCESS) return nil; task_priority( task_self(), tbi.base_priority-4, TRUE); return self; } - appDidInit:sender { Window *iw; float f=0.5; NXDefaultsVector defs={ { "UpdatePeriod", "0.5"}, { "LayerFactor", "16"}, { NULL, NULL}, }; #if !USEKMEM struct tbl_cpuinfo tc; #endif /* Register the defaults. */ NXRegisterDefaults( [NXApp appName], defs); #if !USEKMEM if( table( TBL_CPUINFO, 0, &tc, 1, sizeof( tc))>=0) bcopy( tc.ci_cptime, oldTimes, sizeof( oldTimes)); else { syslog( LOG_WARNING, "TimeMon: table() call failed.\n"); syslog( LOG_WARNING, "TimeMon: Attempting direct /dev/kmem access.\n"); #endif /* Get nlist. */ if( nlist( "/mach", nl)) { syslog( LOG_WARNING, "TimeMon: Cannot nlist /mach.\n"); NXRunAlertPanel( "nlist", "Cannot nlist /mach. Exitting.", "Ok", NULL, NULL); [NXApp terminate:sender]; } /* Open kmem. */ kmem=open( "/dev/kmem", O_RDONLY); if( kmem<0) { /* Check permissions. */ gid_t gid=getegid(); struct group *kmemgr=getgrnam( "kmem"); syslog( LOG_WARNING, "TimeMon: Cannot open /dev/kmem.\n"); if( kmemgr->gr_gid!=gid) { syslog( LOG_WARNING, "TimeMon: Not installed setgid kmem.\n"); NXRunAlertPanel( "Permissions", "TimeMon must be installed setgid to group kmem. Exitting.", "Ok", NULL, NULL); } else NXRunAlertPanel( "/dev/kmem", "Cannot open /dev/kmem. Exitting.", "Ok", NULL, NULL); [NXApp terminate:sender]; } /* Seek to where _cp_time resides. */ if( lseek( kmem, nl[ 0].n_value, L_SET)!=nl[ 0].n_value) { syslog( LOG_WARNING, "TimeMon: Unable to seek in /dev/kmem\n"); NXRunAlertPanel( "/dev/kmem", "Cannot seek in /dev/kmem. Exitting.", "Ok", NULL, NULL); [NXApp terminate:sender]; } /* Initialize the oldTimes. */ if( read( kmem, oldTimes, sizeof( oldTimes))!=sizeof( oldTimes)) { syslog( LOG_WARNING, "TimeMon: Unable to read from /dev/kmem\n"); NXRunAlertPanel( "/dev/kmem", "Cannot read from /dev/kmem. Exitting.", "Ok", NULL, NULL); [NXApp terminate:sender]; } #if !USEKMEM } #endif /* Load up the needed DPS procedures. */ drawInit(); /* Move ourselves over to the appIcon window. */ iw=[NXApp appIcon]; [[iw contentView] addSubview:self]; /* Get us registered for periodic exec. */ if( NXGetDefaultValue( [NXApp appName], "UpdatePeriod")) { f=atof( NXGetDefaultValue( [NXApp appName], "UpdatePeriod")); f=MAX( f, MINPERIOD); } [periodText setFloatValue:f]; te=DPSAddTimedEntry( f, (void *)_step, self, NX_MODALRESPTHRESHOLD); /* Get the layer factor. */ layerFactor=16; if( NXGetDefaultValue( [NXApp appName], "LayerFactor")) { layerFactor=atoi( NXGetDefaultValue( [NXApp appName], "LayerFactor")); layerFactor=MAX( layerFactor, MINFACTOR); } [factorText setIntValue:layerFactor]; return [self display]; } - appWillTerminate:sender { /* If te is installed, remove it. */ if( te) { DPSRemoveTimedEntry( te); te=(DPSTimedEntry)0; } /* Make sure we close kmem. */ if( kmem>-1) { close( kmem); kmem=-1; } return self; } - togglePause:sender { if( te) { [pauseMenuCell setTitle:"Continue"]; DPSRemoveTimedEntry( te); te=(DPSTimedEntry)0; } else { float f=0.5; [pauseMenuCell setTitle:"Pause"]; if( NXGetDefaultValue( [NXApp appName], "UpdatePeriod")) { f=atof( NXGetDefaultValue( [NXApp appName], "UpdatePeriod")); f=MAX( f, MINPERIOD); } [periodText setFloatValue:f]; te=DPSAddTimedEntry( f, (void *)_step, self, NX_MODALRESPTHRESHOLD); } return [self display]; } - setPeriod:sender { NXWriteDefault( [NXApp appName], "UpdatePeriod", [periodText stringValue]); if( te) { float f=0.5; DPSRemoveTimedEntry( te); if( NXGetDefaultValue( [NXApp appName], "UpdatePeriod")) { f=atof( NXGetDefaultValue( [NXApp appName], "UpdatePeriod")); f=MAX( f, MINPERIOD); } [periodText setFloatValue:f]; te=DPSAddTimedEntry( f, (void *)_step, self, NX_MODALRESPTHRESHOLD); } return self; } - setFactor:sender { NXWriteDefault( [NXApp appName], "LayerFactor", [factorText stringValue]); layerFactor=16; if( NXGetDefaultValue( [NXApp appName], "LayerFactor")) { layerFactor=atoi( NXGetDefaultValue( [NXApp appName], "LayerFactor")); layerFactor=MAX( layerFactor, MINFACTOR); } [factorText setIntValue:layerFactor]; return [self display]; } - windowWillResize:sender toSize:(NXSize *)aSize { static BOOL gotSize=NO; static NXSize minSize={ 0, 0}; if( !gotSize) { NXRect r; [sender getFrame:&r]; minSize=r.size; gotSize=YES; } aSize->width=MAX( aSize->width, minSize.width); aSize->height=MAX( aSize->height, minSize.height); return self; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.