home *** CD-ROM | disk | FTP | other *** search
- /*
-
-
-
- MAIN.c
-
-
- Copyright (c) 1990 by: Arthur Kevin McGrath
- Contract Engineers
- P. O. Box 128
- Barboursville, VA 22923
-
- 703/832-7025
-
-
- ALL RIGHTS ARE RESERVED. You may not copy this program in any way
- except to make back-up copies FOR YOUR OWN USE. If you copy this
- program for any reason without WRITTEN PERMISSION from the above
- named copyright owner (except to make back-up copies FOR YOUR OWN USE),
- you are breaking the Copyright Laws of the United States. You will go
- to jail for one year and pay a $50,000 fine.
-
-
-
-
- */
-
-
-
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- #include <ctype.h>
-
-
- #define INCL_BASE
- #define INCL_VIO
- #include <os2.h>
-
- #include "capture.h"
-
-
-
- /*
- This program will capture the screen from a FULL SCREEN OS/2
- session and store it in a file. To do this, it needs to know:
-
- 1. when to install itself.
- (The program will install itself when the user types
- CAPTURE )
- 2. when to capture the screen
- (This shall happen when the user hits the
- <ALT><Print Screen> key combination.)
- 3. the name of a file to use for the contents of the screen.
- (The user shall enter this information each time a screen
- is captured.)
- 4. when to de-install itself
-
- Internally, this program will:
-
- 1. install itself as a keyboard monitor
- 2. wait for the ALT-PrintScreen key combination
- 3. find the location of the physical screen buffer
- 4. if and only if we are in a text mode transfer
- every other byte in that buffer to a file
-
- Optionally, I might want to consider providing a "PRINTABLE
- CHARACTER ONLY" option for this thing.
- */
-
-
-
-
-
-
- /* GLOBAL VARIABLES !!!!!!!!!!!!!!!!!! */
-
- unsigned char printable_only;
- char get_file_popup_title[ 80 ];
- char drive_prompt[ 80 ];
- char directory_prompt[ 80 ];
- char file_prompt[ 80 ];
- char ok_prompt[ 80 ];
- char pause_prompt[ 80 ];
-
- UCHAR yes, no;
- char ansi_sequence[] = { "\033[46;1;34m" };
-
- char default_drive_name;
- char default_path_name[ LONGEST_PATH_NAME + 1 ];
- char default_file_name[ LONGEST_FILE_NAME + 1 ];
-
- int capturing = FALSE;
-
- char program_name[ LONGEST_FILE_NAME + LONGEST_PATH_NAME + 1 ];
-
- /* !!!!!!!!!!!!!!!! End of GLOBAL VARIABLES */
-
-
-
-
-
- /* CENTER_THE_LINE() compares the length of the string you want to
- display with the width of the pop up window that will be displaying
- that line. It returns the offset from the left margin where that
- string will have to start in order to be centered on this line.
-
- It requires the following parameters:
-
- It returns the folowing values:
- OFFSET this is the number of columns you must add to the
- left margin to make this string appear centered in
- the pop up window. This number is an UNSIGNED
- INTEGER (USHORT in OS/2 terminology).
- If this function returns the number 0xFFFF,
- then either:
- 1. the string you are trying to display
- is larger than the line you are trying
- to display it on, or
- 2. the right margin that you passed this
- function was SMALLER than the left margin. */
- USHORT center_the_line( USHORT left, USHORT right, USHORT string_length )
- {
- USHORT line_length;
-
- /* Protect this function from OBVIOUSLY bad values. */
- if( left > right )
- {
- return( 0xFFFF );
-
- }
-
- line_length = right - left;
-
- /* Protect this function from OBVIOUSLY bad values. */
- if( string_length > line_length )
- {
- return( 0xFFFF );
-
- }
-
- return( (line_length - string_length) / 2 );
-
- }
-
-
-
-
-
-
- /* GET_STRING() will:
- 1. display any default data.
- 2. position the cursor.
- 3. input a string from the keyboard.
- 4. return either the default string or the input string
- to the calling function.
- 5. echo the data it returns to the screen.
-
- It needs the following parameters to do this:
- DEFAULT_DATA a string to display for the user
- STRING holds the data returned to the user
- SIZE how long is STRING?
- ROW positioning information
- COLUMN positioning information
- WIDTH how wide is the space on the screen
- that will display the data?
- KEYBOARD the handle of the logical keyboard
-
- It returns the following error codes:
- NOTHING ( VOID ) */
- void get_string( char *default_data, char *string,
- USHORT size,
- USHORT row,
- USHORT column,
- USHORT width,
- HKBD keyboard )
- {
- USHORT error, string_length;
- UCHAR attribute = NORMAL_TEXT_COLOR;
- KBDINFO current;
- STRINGINBUF data_length;
- char *this_one;
- struct screen_text blank;
-
- /* Initialize... */
- blank.attribute = NORMAL_TEXT_COLOR;
- blank.letter = ' ';
-
-
- /* Copy DEFAULT_DATA to STRING. */
- thread_copy( string, default_data );
-
- /* Make sure we cannot overflow our spot on the screen. */
- string_length = MIN( ( USHORT )thread_strlen( default_data ), width );
-
- /* Display the default data. */
- error = VioWrtCharStrAtt( default_data,
- string_length,
- row, column,
- &attribute,
- DEFAULT_SCREEN_HANDLE );
-
-
- /* Position the cursor for data entry. */
- error = VioSetCurPos( row, column, DEFAULT_SCREEN_HANDLE );
-
-
- /* Get the data. */
- data_length.cb = MIN( size, ( USHORT )255 );
- error = KbdStringIn( string, &data_length, IO_WAIT, keyboard );
-
- /* Did the operator enter nothing more than the
- TURN AROUND character. If so, copy DEFAULT_DATA
- into STRING. */
- error = KbdGetStatus( ¤t, keyboard );
-
- /* Once we have a string we are happy with, make that string
- the new default. That way, if the user comes back to this
- point again, he/she will see the last thing he/she entered. */
- if( ( ( USHORT )string[0] == current.chTurnAround )
- ||
- ( string[0] == '\r' )
- ||
- ( string[0] == '\n' ) )
- {
- thread_copy( string, default_data );
-
- }
- else
- {
- /* Did we get a delete key? */
- if( string[0] == '\xFF' )
- {
- string[0] = '\0';
- default_data[0] = '\0';
-
- }
- else
- {
- /* Make sure the string ends in a NULL character. */
- string[ data_length.cchIn ] = '\0';
-
- /* Strip off any trailing blanks. */
- for( this_one = &string[ data_length.cchIn - 1 ];
- ( ( *this_one < '\"' ) || ( *this_one == '\\' ) ) && ( this_one >= string );
- this_one-- )
- {
- *this_one = '\0';
-
- }
-
- /* Strip off any leading blanks or back slashes. */
- for( this_one = string;
- ( (*this_one < '\"') || (*this_one == '\\' ) ) && *this_one; )
- {
- this_one++;
-
- }
-
- thread_copy( string, this_one );
-
- /* Make this data entry the new default. */
- thread_copy( default_data, string );
-
-
- }
-
- }
-
- /* Echo the data the user entered. We do this so that
- the color of the displayed data will match the rest
- of our screen. */
- string_length = ( USHORT )thread_strlen( default_data );
-
- /* Do we have any old data to erase before we go back
- to our calling function??? */
- if( string_length < width )
- {
- /* Write some blank spaces. */
- error = VioWrtNCell( ( BYTE *)&blank,
- width,
- row,
- column,
- DEFAULT_SCREEN_HANDLE );
-
- }
-
- error = VioWrtCharStrAtt( default_data,
- string_length,
- row, column,
- &attribute,
- DEFAULT_SCREEN_HANDLE );
-
-
-
- return;
-
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
- /* VALIDATE_DRIVE() will tell us if a given drive letter is listed
- on the logical drive map for this computer.
-
- It needs the following parameters to do this:
- DRIVE_NUMBER the NUMBER of the drive we are checking
- (A = 1, B = 2, C = 3, ..., Z = 26)
- DRIVE_MAP the map returned by the DosQCurDisk()
- system call
-
- It returns the following values:
- TRUE the drive is on the list. It is VALID.
- FALSE there is no such drive on this machine. */
-
-
-
-
-
- void command_line_options( void )
- {
- puts( "Valid parameters are:\n" );
- puts( "\t/A\tcapture all ASCII characters whether or not they are printable\n" );
- puts( "\t/X\tcapture only printable ASCII characters. Replace the\n" );
- puts( "\t\tnon-printable ASCII characters with dots.\n\n" );
-
- puts( "The following choices affect the name of the file used\n" );
- puts( "to hold the text captured from the screen.\n" );
-
- puts( "\t/D\tthe letter of the drive to hold the file.\n" );
- puts( "\t/P\tthe PATH to the file (OMIT the leading \\\n" );
- puts( "\t/F\tthe file name (OMIT any drive or path names)\n" );
- puts( "\n\n" );
-
- puts( "You may use either upper or lower case.\n" );
- puts( "You may use these options in any order on the command line\n" );
- puts( "\n\n" );
-
-
-
- return;
-
- }
-
-
-
- main(int argc, char *argv[], char *envp[] )
- {
-
- unsigned char capture_flag;
- USHORT error;
- int x, i;
- char *marker, bad_module[ LONGEST_FILE_NAME + LONGEST_PATH_NAME ];
- char *comspec;
- BYTE *thread_stack;
- TID id;
- SEL selector;
- RESULTCODES result;
-
-
- /* Initialize some global variables. */
- strcpy( program_name, argv[0] );
-
- default_drive_name = '\0';
- default_path_name[0] = default_file_name[0] = '\0';
- strcpy( default_file_name, "screen.dat" );
-
- /* Initialize the various prompts. */
- strcpy( get_file_popup_title, "CAPTURE FILE NAME AND PATH" );
- strcpy( drive_prompt, "Drive letter:" );
- strcpy( directory_prompt, "Directory path: (Do NOT enter the TRAILING \\ ):" );
- strcpy( file_prompt, "File name:" );
- strcpy( ok_prompt, "Are the above entries correct? (Y or N):" );
- strcpy( pause_prompt, "Hit any key to continue..." );
- yes = 'Y';
- no = 'N';
-
-
-
- /* Command line parameters:
- /A capture ALL ASCII characters, both
- printable and non printable , from
- the screen. (This is the DEFAULT
- condition.)
- /X capture ONLY PRONTABLE ASCII characters
- from the screen. Replace non printable
- characters with dots.
-
- /D drive name.
- /P path name.
- /F file name.
-
- /? list the valid command line options. */
-
-
- /* Invent a default capture flag. */
- capture_flag = ALL_ASCII_CHARACTERS;
-
- /* Parse the command line. */
- for( x = 1; x < argc; x++ )
- {
- switch( argv[x][0] )
- {
- case '-':
- case '/':
- switch( argv[x][1] )
- {
- case 'a':
- case 'A':
- capture_flag = ALL_ASCII_CHARACTERS;
- break;
-
-
- case 'd':
- case 'D':
- x++;
-
- if( x < argc )
- {
- default_drive_name = ( char )toupper( argv[x][0] );
-
- }
-
- break;
-
- case 'f':
- case 'F':
- x++;
-
- if( x < argc )
- {
- strcpy( default_file_name, argv[x] );
-
- }
- break;
-
- case 'p':
- case 'P':
- /* Copy the next command line parameter to internal storeage. */
- x++;
-
- if( x < argc )
- {
- strcpy( default_path_name, argv[x] );
-
- /* Strip opff any TRAILING \ */
- i = strlen( default_path_name );
- i--;
-
- if( default_path_name[i] == '\\' )
- {
- default_path_name[i] = '\0';
-
- }
-
- /* Strip off any LEADING \ */
- for( marker = default_path_name;
- *marker == '\\'; marker++ );
-
- if( marker != default_path_name )
- {
- strcpy( default_path_name, marker );
-
- }
-
- }
-
- break;
-
- case 'x':
- case 'X':
- capture_flag = PRINTABLE_ASCII_ONLY;
- break;
-
- case '?':
- command_line_options();
- DosExit( EXIT_PROCESS, NO_ERROR );
- break;
-
-
-
- default:
- printf( "\n\"%s\" is not a valid parameter\n",
- argv[x] );
- command_line_options();
-
-
- }
-
- break;
-
- default:
- printf( "\n\"%s\" is not a valid parameter\n",
- argv[1] );
- command_line_options();
-
- }
-
- }
-
- /* Allocate the stack space needed for our STACK KILLER thread. */
- DosAllocSeg( STACK_KILLER_STACK,
- &selector,
- NOSHARE_NODISCARD );
- thread_stack = ( BYTE *)MAKEP( selector, 0 );
-
- /* Mark the stack we are about to use so that we can
- monitor stack useage. */
- mark_stack( (char *)thread_stack,
- STACK_KILLER_STACK );
-
-
- /* Start the thread that will free the stack of threads
- that have exited. */
- DosCreateThread( free_the_stack,
- &id,
- ( BYTE *)&thread_stack[ STACK_KILLER_STACK - 1 ] );
-
- /* Get the name of our command processor. */
- DosScanEnv( "COMSPEC", &comspec );
-
- /* Generate a new command line. */
- DosExecPgm( bad_module,
- sizeof( bad_module ),
- EXEC_ASYNC,
- ( PSZ )NULL, // Pass NO arguments.
- ( PSZ )NULL, // Pass PARENT's environment to child.
- &result,
- comspec );
-
- /* Start our keyboard monitor. */
- error = monitor_the_keyboard();
-
- /* Let the operator know that this program is ending. */
- pop_up( FAREWELL, comspec, error );
-
- DosExit( EXIT_PROCESS, NO_ERROR );
-
- return( NO_ERROR );
-
- }