home *** CD-ROM | disk | FTP | other *** search
- /*----------------------------------
- SysInfo.c - summary of system statistics
-
- Largest free memory block, updated every .75 seconds
- Displays Free CPU cycles, updated every .75 seconds
- Time of day, updated every .75 seconds
- swap file size, updated every 3 seconds
- free disk space on 1 drv, updated every 3 seconds
-
- Automatically positions itself at the top of the screen in a box 2.5
- system characters high. Double clicking anywhere in the client window
- will cause the the frame controls to be hidden, or restored if already
- hidden. Keyboard accelerators will still work while the frame is hidden.
-
- Program can also be minimized.
-
- ----------------------------------*/
-
- #define INCL_WIN
- #define INCL_GPI
- #define INCL_DOS
-
- #include <os2.h>
- #include <string.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <ctype.h>
- #include <time.h>
- #include <process.h>
-
- #define ID_TIMER 1
- #define MAX_CHILDREN 10
- #define CH_MEMTEXT 1
- #define CH_MEMVAL 0
- #define CH_SWAPTEXT 3
-
- #define CH_SWAPVAL 2
- #define CH_CLOCKTEXT 5
- #define CH_CLOCKVAL 4
- #define CH_CPUTEXT 7
- #define CH_CPUVAL 6
- #define CH_DISKTEXT 9
- #define CH_DISKVAL 8
-
- #define SWAPFILE "c:\\os2\\system\\swapper.dat"
-
- MRESULT EXPENTRY ClientWndProc (HWND, USHORT, MPARAM, MPARAM) ;
- MRESULT EXPENTRY ChildProc (HWND, USHORT, MPARAM, MPARAM) ;
- VOID SizeTheWindow( HWND );
- void SwitchList( HWND hwndFrame, HPOINTER hptrIcon );
- void far cdecl CountCyc( PVOID nl );
- void GetFontInfo(HWND hwnd, PUSHORT cyChar, PUSHORT cxChar, PUSHORT cyDesc);
- int ComputeFree(short DriveNum, float *fAvail );
- SHORT CreateChildren( HWND hwndParent );
- VOID ToggleFrameControls( HWND hwndFrame );
- VOID UpdateLong( PHWND ahwndChild );
- VOID UpdateShort( PHWND ahwndChild );
-
- // window handles for hiding frame controls and creating children
- HWND hwndFrame, hwndSys, hwndMin, hwndTitle;
- HWND hwndChild[ MAX_CHILDREN ];
- SHORT fHidden = 0;
-
- // font info for sizing windows
- SHORT cyChar, cxChar, cyDesc;
-
- // raw data from CPU cycles count
- ULONG uCalibVal = 0, uCurVal = 0, ulLast = 1;
-
- // params for free disk space
- USHORT usDriveNum = 3, fIsRed;
- float fFreeSpace = 0.0;
-
- // size of the swap file
- ULONG ulSwapSize = 0;
-
- // largest free block
- ULONG ulFrSize = 0;
-
-
- /*
- Function: main
-
- Description:
- Entry point for system info program. Creates the client window and
- starts the thread for the CPU monitor. Takes two command line params.
- First param is the drive letter. If not present it defaults to C. This
- is the drive on which the free space will be monitored.
-
- If a second param is present and equal to /cal, the cpu counter will
- be recalibrated. This should be done with no other programs running
- to get a better idea of a true idle system.
-
- Values Returned:
- None.
-
- Notes:
-
- */
-
- int main ( int argc, char **argv )
-
- {
- static PSZ pszClientClass = "System Info" ;
- static ULONG flFrameFlags = FCF_TITLEBAR | FCF_SYSMENU | FCF_ICON |
- FCF_MINBUTTON | FCF_BORDER;
- CHAR achBuf[12];
- HPOINTER hwndIcon; /* handle to our programs icon */
- HAB hab;
- HMQ hmq;
- HWND hwndClient;
- QMSG qmsg;
-
- usDriveNum = 3;
-
- PrfQueryProfileString( HINI_USERPROFILE, "System Info",
- "Calibration Value", "0", achBuf, 12L );
- uCalibVal = atol( achBuf );
-
- if ( argc >= 2 )
- usDriveNum = toupper( *argv[1] ) - 'A' + 1; // pick up a drive letter.
- if ( argc == 3 && !stricmp( argv[2], "/cal" ) )
- uCalibVal = 0; // mark for recal
-
- _beginthread( CountCyc, NULL, 8000, NULL );
-
- hab = WinInitialize( 0 );
- hmq = WinCreateMsgQueue( hab, 0 );
-
- WinRegisterClass(hab, pszClientClass, ClientWndProc, CS_MOVENOTIFY, 0 );
- WinRegisterClass(hab, "InfoChild", ChildProc, 0, 6 );
-
- hwndFrame = WinCreateStdWindow( HWND_DESKTOP, WS_VISIBLE,
- &flFrameFlags, pszClientClass, pszClientClass,
- 0L, 0, 1, &hwndClient );
-
- /* Add our title to the task list maintained by Task Manager */
- hwndIcon = WinLoadPointer( HWND_DESKTOP, 0, 1 );
- SwitchList( hwndFrame, hwndIcon );
-
- SizeTheWindow( hwndFrame );
-
- CreateChildren( hwndClient );
- ToggleFrameControls( hwndFrame );
-
- WinStartTimer (hab, hwndClient, ID_TIMER, 750 );
-
- while (WinGetMsg (hab, &qmsg, NULL, 0, 0 ) )
- WinDispatchMsg (hab, &qmsg) ;
-
- WinStopTimer (hab, hwndClient, ID_TIMER) ;
-
- // store the calibration value on exit
- sprintf( achBuf, "%lu", uCalibVal );
- PrfWriteProfileString( HINI_USERPROFILE, "System Info",
- "Calibration Value", achBuf );
-
- WinDestroyWindow( hwndFrame );
- WinDestroyMsgQueue( hmq );
- WinDestroyPointer( hwndIcon );
- WinTerminate( hab );
- DosExit( EXIT_PROCESS, 0 );
- }
-
- /*
- Function: SizeTheWindow
-
- Description:
- Set the initial size of the window at 2.5 character heights and for the
- entire width of the display. Positions it at the top of the screen.
-
- Values Returned:
- None
-
- Notes:
- I stole this code from a petzold sample.
-
- */
-
-
- VOID SizeTheWindow (HWND hwndFrame)
-
- {
- USHORT usCxScreen, usCyScreen, usCyBorder;
- RECTL rcl;
-
- usCxScreen = (USHORT)WinQuerySysValue( HWND_DESKTOP, SV_CXSCREEN );
- usCyScreen = (USHORT)WinQuerySysValue( HWND_DESKTOP, SV_CYSCREEN );
- usCyBorder = (USHORT)WinQuerySysValue( HWND_DESKTOP, SV_CYBORDER );
-
- rcl.yBottom = 0 ;
- rcl.yTop = 2 * cyChar;
- rcl.xLeft = 0 ;
- rcl.xRight = usCyScreen - 2 * usCyBorder;
-
- /* now figure out the size of the frame rectangle */
- WinCalcFrameRect( hwndFrame, &rcl, FALSE );
-
- /* ... and shift to the top line of the screen */
- rcl.yBottom = usCyScreen - (rcl.yTop - rcl.yBottom);
- rcl.yTop = usCyScreen;
- rcl.xRight = usCxScreen;
- rcl.xLeft = 0;
-
- WinSetWindowPos (hwndFrame, NULL, (SHORT) rcl.xLeft, (SHORT) rcl.yBottom,
- (SHORT) (rcl.xRight - rcl.xLeft),
- (SHORT) (rcl.yTop - rcl.yBottom), SWP_SIZE | SWP_MOVE) ;
- }
-
- /*
- Function: ClientWndProc
-
- Description:
- Window procedure for the main window. Really does very little except
- call other functions to do something useful.
-
- Values Returned:
- MRESULTS
-
- Notes:
-
- */
-
- MRESULT EXPENTRY ClientWndProc(HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2)
- {
- static SHORT sTicks = 0;
-
- switch (msg)
- {
- case WM_CREATE:
- GetFontInfo( hwnd, &cyChar, &cxChar, &cyDesc );
- return 0;
-
- case WM_BUTTON1DOWN:
- if ( fHidden )
- return WinSendMsg( hwndFrame, WM_TRACKFRAME,
- (MPARAM)( SHORT1FROMMP(mp2) | TF_MOVE ), NULL );
- return 0;
-
- case WM_BUTTON1DBLCLK:
- ToggleFrameControls( hwndFrame );
- return 0;
-
- case WM_TIMER:
- if ( (sTicks % 4) == 0 ) // every three seconds do the disk parms
- UpdateLong( hwndChild );
- UpdateShort( hwndChild );
- sTicks++;
- return 0;
-
- case WM_ERASEBACKGROUND:
- return MRFROMSHORT(TRUE);
- }
-
- return WinDefWindowProc (hwnd, msg, mp1, mp2) ;
- }
-
-
-
- /*
- Function: SwitchList
-
- Description:
- Add our program name to the switch list maintained by the system.
-
- Values Returned:
- None
-
- Notes:
-
- */
-
- void SwitchList( HWND hwndFrame, HPOINTER hptrIcon )
-
- {
- SWCNTRL swctl; /* switch list entry structure */
-
- WinQueryWindowProcess( hwndFrame, &swctl.idProcess, NULL );
- swctl.idSession = 0;
- swctl.fReserved = 0;
- swctl.hprog = NULL;
- swctl.hwnd = hwndFrame;
- swctl.hwndIcon = hptrIcon;
- swctl.uchVisibility = SWL_VISIBLE;
- swctl.fbJump = SWL_JUMPABLE;
- strcpy( swctl.szSwtitle, "System Information" );
-
- WinAddSwitchEntry( &swctl );
-
- return;
- }
-
- /*
- Function: CountCyc
-
- Description:
- Separate thread that runs at idle class, priority one. Since the system
- provides an idle class, priority zero thread, setting it to one gives
- a better value for idle time.
-
- Simply counts iterations of a loop every 750 milliseconds. That value
- is then compared to the number of iterations we were able to do when
- the system was idle.
-
- Values Returned:
- None
-
- Notes:
-
- */
-
-
- void far cdecl CountCyc( PVOID nl )
-
- {
- SEL selGlobalSeg, /* selector num for global info seg */
- selLocalSeg; /* selector num for local info seg */
- GINFOSEG FAR *pgis; /* pointer to the global info seg */
- ULONG lMils;
- ULONG uBldVal;
-
- DosGetInfoSeg(&selGlobalSeg, &selLocalSeg); /* get local & global info segs */
- pgis = MAKEPGINFOSEG( selGlobalSeg ); /* get a pointer to the global */
-
- if ( uCalibVal == 0L )
- {
- DosEnterCritSec();
- DosSetPrty( PRTYS_THREAD, PRTYC_TIMECRITICAL, PRTYD_MAXIMUM, 0 );
-
- lMils = pgis->msecs + 3750;
- while( pgis->msecs < lMils )
- uCalibVal++;
-
- DosExitCritSec();
- uCalibVal /= 5;
- }
-
- // set priority to idle, 1 so that we avoid conflict with system idle thread.
- DosSetPrty( PRTYS_THREAD, PRTYC_IDLETIME, PRTYD_MINIMUM, 0 );
- DosSetPrty( PRTYS_THREAD, PRTYC_IDLETIME, 1, 0 );
- while( 1 )
- {
- lMils = pgis->msecs + 750;
- uBldVal = 0L;
- while( pgis->msecs < lMils )
- uBldVal++;
-
- uCurVal = uBldVal;
- }
-
- }
-
-
- /*
- Function: ComputeFree
-
- Description:
- Compute free space on the specified drive. Set the free space as
- a float point value representing free MB.
-
- Values Returned:
- 0 - drive has more the 10% free
- 1 - drive is within 10% of being full
-
- Notes:
-
- */
-
- int ComputeFree( short DriveNum, float *fAvail )
-
- {
- FSALLOCATE fsaBuf;
- float fTotFree;
-
- DosQFSInfo( DriveNum, 1, (PCHAR)&fsaBuf, sizeof( fsaBuf ) );
- fTotFree = (float)fsaBuf.cbSector * (float)fsaBuf.cSectorUnit *
- (float)fsaBuf.cUnitAvail;
- fTotFree /= (float)0x100000;
-
- *fAvail = fTotFree;
-
- if ( fsaBuf.cUnitAvail * 10 < fsaBuf.cUnit )
- return( 1 ); /* less than 10% space free */
- else
- return( 0 );
- }
-
-
- /*
- Function: GetFontInfo
-
- Description:
-
- Call WinQueryFontMetrics to determine information about the system font
-
- Values Returned:
- None.
-
- Notes:
-
- */
-
- void GetFontInfo( HWND hwnd, USHORT *cy, USHORT *cx, USHORT *cd )
-
- {
- HPS hps; /* need a ps before calling font metrics */
- FONTMETRICS fm; /* info about the current font */
-
-
- hps = WinGetPS( hwnd ); /* need a PS for query Font */
- GpiQueryFontMetrics( hps, (LONG)sizeof(fm), &fm );
- WinReleasePS( hps ); /* done with the ps now */
-
- *cy = (SHORT)fm.lMaxBaselineExt; /* max height of one character */
- *cx = (SHORT)fm.lAveCharWidth; /* average width of a character */
- *cd = (SHORT)fm.lMaxDescender; /* max descender of a char */
-
- return;
- }
-
-
- /*
- Function: CreateChildren
-
- Description:
- Create the ten child windows in a double row. All windows are static
- text. The leftmost windows are aligned on the left, the rightmost on the
- right, all others are centered.
-
- Values Returned:
- 0 - no error
- 1 - error
-
- Notes:
-
- */
-
-
- SHORT CreateChildren( HWND hwndParent )
-
- {
- short i, x, y, cx, cy;
- SWP swp;
-
- WinQueryWindowPos( hwndParent, &swp );
-
- for( i = 0; i < 10; i+= 2 )
- {
- x = (swp.cx / 5) * (i/2);
- y = 0;
- cx = swp.cx / 5;
- cy = swp.cy / 2;
-
- hwndChild[i] = WinCreateWindow( hwndParent, "InfoChild", NULL,
- WS_VISIBLE, x, y, cx, cy, NULL, HWND_TOP, i, NULL, NULL );
- WinSetWindowPtr( hwndChild[i], 2, malloc( 100 ) );
-
- y = swp.cy / 2;
- hwndChild[i + 1] = WinCreateWindow( hwndParent, "InfoChild", NULL,
- WS_VISIBLE, x, y, cx, cy, NULL, HWND_TOP, i + 1, NULL, NULL );
- WinSetWindowPtr( hwndChild[i + 1], 2, malloc( 100 ) );
- if ( hwndChild[ i ] == NULL || hwndChild[ i + 1 ] == NULL )
- return 1;
- }
-
- strcpy( WinQueryWindowPtr( hwndChild[ CH_CPUTEXT ], 2 ), "CPU Usage" );
- strcpy( WinQueryWindowPtr( hwndChild[ CH_MEMTEXT ], 2 ), "Free Memory" );
- strcpy( WinQueryWindowPtr( hwndChild[ CH_SWAPTEXT ], 2 ), "Swap File Size" );
- strcpy( WinQueryWindowPtr( hwndChild[ CH_DISKTEXT ], 2 ), "Free Disk Space" );
- strcpy( WinQueryWindowPtr( hwndChild[ CH_CLOCKTEXT ], 2 ), "Time of day" );
- strcpy( WinQueryWindowPtr( hwndChild[ CH_CPUVAL ], 2 ), "" );
- strcpy( WinQueryWindowPtr( hwndChild[ CH_MEMVAL ], 2 ), "" );
- strcpy( WinQueryWindowPtr( hwndChild[ CH_SWAPVAL ], 2 ), "" );
- strcpy( WinQueryWindowPtr( hwndChild[ CH_DISKVAL ], 2 ), "" );
- strcpy( WinQueryWindowPtr( hwndChild[ CH_CLOCKVAL ], 2 ), "" );
-
- UpdateShort( hwndChild );
- UpdateLong( hwndChild );
- return 0;
- }
-
-
-
- /*
- Function: ToggleFrameControls
-
- Description:
- if frame controls are hidden, restore them, if visible hide them.
-
-
- Values Returned:
- None
-
- Notes:
- I stole this code from an MS sample
- */
-
-
-
- VOID ToggleFrameControls( HWND hwndFrame )
-
- {
-
- if ( !fHidden ) // hide the controls
- {
- hwndTitle = WinWindowFromID( hwndFrame, FID_TITLEBAR );
- hwndSys = WinWindowFromID( hwndFrame, FID_SYSMENU );
- hwndMin = WinWindowFromID( hwndFrame, FID_MINMAX );
-
- WinSetParent( hwndTitle, HWND_OBJECT, FALSE );
- WinSetParent( hwndSys, HWND_OBJECT, FALSE );
- WinSetParent( hwndMin, HWND_OBJECT, FALSE );
-
- WinSendMsg( hwndFrame, WM_UPDATEFRAME, (MPARAM)(FCF_TITLEBAR | FCF_SYSMENU | FCF_MINBUTTON),
- NULL ) ;
- fHidden = TRUE;
-
- SizeTheWindow( hwndFrame );
- }
- else
- {
- WinSetParent( hwndTitle, hwndFrame, FALSE );
- WinSetParent( hwndSys, hwndFrame, FALSE );
- WinSetParent( hwndMin, hwndFrame, FALSE );
-
- WinSendMsg( hwndFrame, WM_UPDATEFRAME, (MPARAM)(FCF_TITLEBAR | FCF_SYSMENU | FCF_MINBUTTON),
- NULL );
- fHidden = FALSE;
- SizeTheWindow( hwndFrame );
- }
-
- return;
- }
-
- /*
- Function: UpdateLong
-
- Description:
- Update the parameters that are done every three seconds -- swap file,
- disk space.
-
- Values Returned:
- None
-
- Notes:
-
- */
-
-
-
-
- VOID UpdateLong( PHWND ahwndChild )
-
- {
- float fTmp;
- CHAR achSpace[20];
- FILESTATUS fs;
-
- fTmp = fFreeSpace;
- fIsRed = ComputeFree( usDriveNum, &fFreeSpace );
- if ( fFreeSpace != fTmp ) // drive space has changed
- {
- if ( fIsRed )
- WinSetWindowUShort( ahwndChild[ CH_DISKVAL ], 0, 1 );
- else
- WinSetWindowUShort( ahwndChild[ CH_DISKVAL ], 0, 0 );
- sprintf( achSpace, "%c: %3.1f MB", usDriveNum + 'A' - 1, fFreeSpace );
- strcpy( WinQueryWindowPtr( ahwndChild[ CH_DISKVAL ], 2 ), achSpace );
- WinInvalidateRect( ahwndChild[ CH_DISKVAL ], NULL, 0 );
- }
-
- DosQPathInfo( SWAPFILE, FIL_STANDARD, (PBYTE)&fs, sizeof(fs), 0L );
- if ( ulSwapSize != fs.cbFile )
- {
- ulSwapSize = fs.cbFile;
- sprintf( achSpace, "%4.0f KB", (float)ulSwapSize / 1024.0 );
- strcpy( WinQueryWindowPtr( ahwndChild[ CH_SWAPVAL ], 2 ), achSpace );
- WinInvalidateRect( ahwndChild[ CH_SWAPVAL ], NULL, 0 );
- }
-
- return;
- }
-
- /*
- Function: UpdateShort
-
- Description:
- Updates the parameters that are done on a .75 second basis - free memory,
- time of day, CPU usage
-
- Values Returned:
- None
-
- Notes:
-
- */
-
- VOID UpdateShort( PHWND ahwndChild )
-
- {
- ULONG ulCur;
- CHAR achFmt[25];
- struct tm *tml;
- time_t timer;
-
- while ( uCalibVal == 0L )
- DosSleep( 100L );
-
- ulCur = (uCurVal * 100L) / uCalibVal;
- if ( ulLast != ulCur )
- {
- sprintf( achFmt, "%ld%%", 100L - ulCur );
- strcpy( WinQueryWindowPtr( ahwndChild[ CH_CPUVAL ], 2 ), achFmt );
- WinInvalidateRect( ahwndChild[ CH_CPUVAL ], NULL, 0 );
- ulLast = ulCur;
- }
-
- time( &timer );
- tml = localtime( &timer );
- ctime( &timer );
- if ( tml->tm_hour == 0 )
- sprintf( achFmt, "12:%02d:%02d AM", tml->tm_min, tml->tm_sec );
- else if ( tml->tm_hour < 12 )
- sprintf( achFmt, "%02d:%02d:%02d AM", tml->tm_hour, tml->tm_min, tml->tm_sec );
- else if ( tml->tm_hour == 12 )
- sprintf( achFmt, "12:%02d:%02d PM", tml->tm_min, tml->tm_sec );
- else
- sprintf( achFmt, "%02d:%02d:%02d PM", tml->tm_hour - 12, tml->tm_min, tml->tm_sec );
- strcpy( WinQueryWindowPtr( ahwndChild[ CH_CLOCKVAL ], 2 ), achFmt );
- WinInvalidateRect( ahwndChild[ CH_CLOCKVAL ], NULL, 0 );
-
- DosMemAvail( &ulCur );
- if ( ulCur != ulFrSize )
- {
- sprintf( achFmt, "%4ld KB", (ulCur + 512) / 1024 );
- strcpy( WinQueryWindowPtr( ahwndChild[ CH_MEMVAL ], 2 ), achFmt );
- WinInvalidateRect( ahwndChild[ CH_MEMVAL ], NULL, 0 );
- ulFrSize = ulCur;
- }
- return;
- }
-
-
-
- /*
- Function: ChildProc
-
- Description:
- Child window that is extremely stupid -- knows how to display centered
- text in its window
-
- Values Returned:
- MRESULTS
-
- Notes:
-
- */
-
- MRESULT EXPENTRY ChildProc( HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2 )
-
- {
- HPS hps;
- RECTL rcl;
- LONG lCol;
- PCHAR pch;
-
- switch( msg )
- {
- case WM_CREATE:
- WinSetWindowUShort( hwnd, 0, 0 );
- return 0;
-
- case WM_BUTTON1DBLCLK:
- case WM_BUTTON1DOWN:
- WinSendMsg( WinQueryWindow( hwnd, QW_PARENT, 0 ), msg, mp1, mp2 );
- return 0;
-
- case WM_DESTROY:
- free( WinQueryWindowPtr( hwnd, 2 ) );
- return 0;
-
- case WM_PAINT:
- pch = WinQueryWindowPtr( hwnd, 2 );
- WinQueryWindowRect( hwnd, &rcl );
- hps = WinBeginPaint( hwnd, NULL, NULL );
- if ( WinQueryWindowUShort( hwnd, 0 ) == 0 )
- lCol = CLR_NEUTRAL;
- else
- lCol = CLR_RED;
- WinDrawText( hps, -1, pch, &rcl, lCol, CLR_BACKGROUND,
- DT_VCENTER | DT_CENTER | DT_ERASERECT );
- WinEndPaint( hps );
- return 0;
- }
-
- return WinDefWindowProc( hwnd, msg, mp1, mp2 );
- }
-