home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 11 Util / 11-Util.zip / GETSCRN.EXE / SOURCE / CAPTURE.C < prev    next >
Text File  |  1990-06-24  |  9KB  |  270 lines

  1. /*
  2.  
  3.  
  4.  
  5.                                 CAPTURE.c
  6.  
  7.         Copyright (c) 1990 by:  Arthur Kevin McGrath
  8.                                 Contract Engineers
  9.                                 P. O. Box 128
  10.                                 Barboursville, VA  22923
  11.  
  12.                                 703/832-7025
  13.  
  14.  
  15.   ALL RIGHTS ARE RESERVED.  You may not copy this program in any way
  16.   except to make back-up copies FOR YOUR OWN USE.  If you copy this
  17.   program for any reason without WRITTEN PERMISSION from the above
  18.   named copyright owner (except to make back-up copies FOR YOUR OWN USE),
  19.   you are breaking the Copyright Laws of the United States.  You will go
  20.   to jail for one year and pay a $50,000 fine.
  21.  
  22.  
  23.  
  24.  
  25. */
  26.  
  27.  
  28.  
  29. #include        <stdio.h>
  30. #include        <stdlib.h>
  31. #include        <ctype.h>
  32.  
  33.  
  34. #define INCL_BASE
  35. #define INCL_VIO
  36. #include <os2.h>
  37.  
  38. #include "capture.h"
  39. #include "extern.h"
  40.  
  41.  
  42.  
  43.  
  44.  
  45.  
  46. /*  CAPTURE_THE_SCREEN() takes ASCII characters from the PHYSICAL VIDEO
  47.     BUFFER and transfers copies of them to a text buffer of the user's
  48.     choice.   The user has the option of capturing all 256 ASCII
  49.     characters or just the printable ASCII characters (from SPACE
  50.     through 'z').
  51.  
  52.     This function requires the following parameters:
  53.         NOTHING   ( VOID )
  54.  
  55.     This function returns the following values:
  56.         NOTHING   ( VOID )                      */
  57.  
  58. PFNTHREAD capture_the_screen( void )
  59. {
  60.     HQUEUE              q;
  61.     char                file[ LONGEST_PATH_NAME + LONGEST_FILE_NAME ];
  62.     char                *screen_text;
  63.     unsigned            end_of_screen;
  64.     unsigned            source, destination, column;
  65.     VIOMODEINFO         mode;
  66.     VIOPHYSBUF          physical_screen;
  67.     struct screen_text  *display;
  68.     UCHAR               status;
  69.     HFILE               FileHandle;
  70.     USHORT              error, ActionTaken, attributes = ARCHIVE;
  71.     USHORT              OpenFlag = 0x0011, OpenMode = 0x0122;
  72.     USHORT              BytesWritten, owner;
  73.     SEL                 selector;
  74.     struct stack_selector   *thread;
  75.     PIDINFO             this_thread;
  76.  
  77.  
  78.     /*  Where is our video buffer and how big is it.    */
  79.     mode.cb = ( USHORT )sizeof( mode );
  80.     error = VioGetMode( &mode, DEFAULT_SCREEN_HANDLE );
  81.  
  82.     physical_screen.pBuf = ( PBYTE )mode.buf_addr;
  83.     physical_screen.cb = mode.buf_length;
  84.  
  85.     /*  The text portion of any screen takes up only half of
  86.         the actual video buffer.  The other half, of course,
  87.         is made up of attribute bytes.  We will grab enough
  88.         memory to hold the text we are about to extract from
  89.         the screen PLUS one NEWLINE character for each
  90.         line on the screen.     */
  91.     end_of_screen = ( int )
  92.                 ( mode.buf_length / ( long )sizeof( struct screen_text )        );
  93.     error = DosAllocSeg(        ( end_of_screen + mode.row ),
  94.                     &selector,
  95.                     NOSHARE_NODISCARD   );
  96.     screen_text = ( char *)MAKEP( selector, 0 );
  97.  
  98.  
  99.     /*  If SCREEN_TEXT is not a NULL, then MALLOC() was successful.
  100.         Otherwise, we have a problem and the user must be informed. */
  101.     if( !error )
  102.     {
  103.         /*  Lock the screen so that nobody changes sessions while we
  104.             are playing with the Physical Video Buffer. */
  105.         error = VioScrLock( LOCKIO_WAIT, &status, DEFAULT_SCREEN_HANDLE );
  106.  
  107.  
  108.         /*  Don't do any of this stuff if we cannot lock the screen. */
  109.         if(  ( error == NO_ERROR )      && ( status == LOCK_SUCCESS )   )
  110.         {
  111.             error = VioGetPhysBuf( &physical_screen, RESERVED );
  112.  
  113.  
  114.  
  115.             /*  Now that we have a selector that we can use to address the
  116.                 Physical Video Buffer, let us convert that selector into
  117.                 a Pointer.      We will then pretend that an array of
  118.                 SCREEN_TEXT structures lives at that address.       */
  119.                 display = ( struct screen_text *)MAKEP( physical_screen.asel[0], 0 );
  120.  
  121.  
  122.             /*  Let us copy the characters from the screen to our text buffer.  */
  123.             for( source = destination = column = 0;
  124.                             source < end_of_screen;
  125.                             source++, destination++ )
  126.             {
  127.                 /*      Here we will insert code that:
  128.                         1.  Checks to see if we have reached the end of
  129.                             a line,
  130.                         2.  If we have reached the end of a line:
  131.                             a.  strip off any trailing spaces,
  132.                             b.  append a newline character.     */
  133.                 if( column < mode.col )
  134.                 {
  135.                     column++;
  136.  
  137.                 }
  138.                 else
  139.                 {
  140.                     do
  141.                     {
  142.                         destination--;
  143.                         column--;
  144.  
  145.                     }while(     ( column > 0 )
  146.                                 &&
  147.                           ( screen_text[ destination ] == ' ' )    );
  148.  
  149.  
  150.                     /*  Our array index can go no lower than ZERO.
  151.                         Hence, we have a special case when one or more
  152.                         lines are filled with blanks.  If the a line is
  153.                         filled with SPACES all the way back to the first
  154.                         column, then we put a NEWLINE character in the
  155.                         first column.  Otherwise, we preserve the
  156.                         NON-BLANK character that lives there.   */
  157.                     if( screen_text[ destination ] != ' ' )
  158.                     {
  159.                         destination++;
  160.  
  161.                     }
  162.  
  163.                     screen_text[ destination ] = '\n';
  164.                     destination++;
  165.  
  166.                     column = 1; /* Because we are going to move one character
  167.                                    on this trip. */
  168.  
  169.                 }
  170.  
  171.  
  172.                 if( printable_only )
  173.                 {
  174.                     screen_text[ destination ] = ( char )(isprint( display[ source ].letter ) ? display[ source ].letter : '.' );
  175.  
  176.                 }
  177.                 else
  178.                 {
  179.                     screen_text[ destination ] = display[ source ].letter;
  180.  
  181.                 }
  182.  
  183.             }
  184.  
  185.  
  186.             /*  Now that we have finished playing with the screen, we
  187.                 can release our lock on the PHYSICAL VIDEO BUFFER.      */
  188.             error = VioScrUnLock( DEFAULT_SCREEN_HANDLE );
  189.  
  190.  
  191.             error = pop_up(GET_FILE_NAME, file, error );
  192.  
  193.             /*  Now, let us write the text to a file.   */
  194.             error = DosOpen(    file,
  195.                 &FileHandle,
  196.                 &ActionTaken,
  197.                 ( ULONG )destination,
  198.                 attributes,
  199.                 OpenFlag,
  200.                 OpenMode,
  201.                 ( ULONG )RESERVED   );
  202.  
  203.             if( error == NO_ERROR )
  204.             {
  205.                 error = DosWrite(       FileHandle,
  206.                                 screen_text,
  207.                                 destination,
  208.                                 &BytesWritten   );
  209.  
  210.             }
  211.  
  212.             if( error == NO_ERROR )
  213.             {
  214.                 error = DosClose( FileHandle );
  215.  
  216.  
  217.             }
  218.  
  219.             error = pop_up( RESULTS, file, error );
  220.             DosFreeSeg( selector );
  221.         }
  222.  
  223.     }
  224.     else
  225.     {
  226.         /*  We can only get here if MALLOC() fails. */
  227.         pop_up( RESULTS, file, MALLOC_ERROR );
  228.  
  229.     }
  230.  
  231.  
  232.  
  233.     /*  Get some information we have to pass back to the
  234.                 FREE_THE_STACK() thread so it can release
  235.                 our stack segment.              */
  236.     error = DosAllocSeg( sizeof( struct stack_selector ),
  237.                                 &selector,
  238.                                 SEG_NONSHARED   );
  239.  
  240.     thread = ( struct stack_selector *)MAKEP( selector, 0 );
  241.  
  242.  
  243.     thread -> stack = stack_segment();
  244.     error = DosGetPID( &this_thread );
  245.     thread -> id = this_thread.tid;
  246.  
  247.  
  248.     /*  Let the program know we are ready to release
  249.                 our stack segment.                      */
  250.     error = DosOpenQueue( &owner,
  251.                         &q,
  252.                         STACK_KILLER_QUEUE      );
  253.  
  254.     error = DosWriteQueue( q,
  255.                         ( USHORT )NULL,
  256.                         sizeof( thread ),
  257.                         ( BYTE *)thread,
  258.                         ( UCHAR )10     );
  259.  
  260.  
  261.  
  262.     /*  Let the monitor function know that it is OK to start
  263.         another CAPTURE thread. */
  264.     capturing = FALSE;
  265.  
  266.     DosExit( EXIT_THREAD, NO_ERROR );
  267.  
  268.  
  269. }
  270.