[comp.sys.apollo] Screen Savers

MARCUS@STOAT.PCL.AC.UK (03/15/89)

>From: mcdonald < (louis mcdonald)mcdonald%loki.edsg@com.hac.hac2arpa>
>Subject: Screen saver

>We have some Sun (ugh) users here who have some interesting screen savers
 running.
>Has anyone played with the Apollo screen saver?

>Louis McDonald

Here's a screen saver that will save  a part of the screen. Holding down M1 and
moving the mouse will grow/shrink a 'rubberband' box defining the area to
be saved. Press EXIT to save the image.

I was investigating pixel orientated bitmaps at the time so this program
uses them - not very useful for sending to a Xerox 4020 or the like! I suggest
you modify it to save a colour map an plane orientated bitmap (as I have
been meaning to do for some time now...)

                            - m a r c u s -

-------------------------------- cut here &< ----------------------------------

/***************************************************************************/
/*                                                                         */
/*    Sgrab - Grabs any rectangular area of the screen and stores it in    */
/*            a pixel oriented external file bitmap                        */
/*                                                                         */
/*    Usage: sgrab filename                                                */
/*                                                                         */
/*    Author: Marcus Harvey 1988                                           */
/*                                                                         */
/***************************************************************************/


#include <stdio.h>
#include <math.h>
#include "/sys/ins/base.ins.c"
#include "/sys/ins/gpr.ins.c"
#include "/sys/ins/error.ins.c"
#include "/sys/ins/kbd.ins.c"
#include "/sys/ins/pgm.ins.c"

#define XOR             6
#define BLT             3
#define line_prim_set   (short int)(1 << (short)gpr_$rop_line)
#define blit_prim_set   (short int)(1 << (short)gpr_$rop_blt)

status_$t                       status;
gpr_$bitmap_desc_t              disp_bmap, mem_bmap, disk_bmap, cursor_bmap;
gpr_$offset_t                   disp_bmap_size, mem_bmap_size, disk_bmap_size;
gpr_$attribute_desc_t           mem_bmap_attr, disk_bmap_attr;
gpr_$bmf_group_header_array_t   disk_bmap_hdr;
gpr_$rgb_plane_t                hi_plane;
gpr_$color_vector_t             color_map;
gpr_$window_t                   whole_screen;
gpr_$position_t                 dest_origin = $0,0;
gpr_$disp_char_t                disp_char;
gpr_$window_t                   blit_window;
char                            fname[32];
short                           fname_len;
short                           ix;


check(message)

char *message;
$
    if(status.all != status_$ok)
    $
        fprintf(stderr,"%s : ",message);
        error_$print(status);
    

 /* end check(message) */


void init_cursor()

$
    static gpr_$offset_t            cursor_bmap_size = $16,16;
    static gpr_$position_t          cursor_orig = $0,0;
    static gpr_$coordinate_array_t  x_coords = $15,8,8, y_coords = $8,8,15;
    gpr_$attribute_desc_t           cursor_bmap_attr;

    gpr_$allocate_attribute_block(cursor_bmap_attr,status);

    gpr_$allocate_bitmap  ( cursor_bmap_size,
                            hi_plane,
                            cursor_bmap_attr,
                            cursor_bmap,
                            status);

    gpr_$set_bitmap(cursor_bmap,status);

    gpr_$start_pgon(0,0,status);
    check("gpr_$start_pgon");
    gpr_$pgon_polyline(x_coords,y_coords,(short)3,status);
    check("gpr_$pgon_polyline");
    gpr_$close_fill_pgon(status);
    check("gpr_$close_fill_pgon");

    gpr_$set_cursor_active(false,status);
    gpr_$set_cursor_origin(cursor_orig,status);
    gpr_$set_cursor_pattern(cursor_bmap,status);

 /* end init_cursor() */


void enable_events()

$
    gpr_$keyset_t       key_set, button_set;

    lib_$init_set(key_set,(short)256);
    lib_$add_to_set(key_set,(short)256,KBD_$SAVE);
    lib_$add_to_set(key_set,(short)256,KBD_$EXIT);
    lib_$add_to_set(key_set,(short)256,KBD_$ABORT);

    gpr_$enable_input(gpr_$keystroke,key_set,status);
    gpr_$enable_input(gpr_$locator,key_set,status);

    lib_$init_set(button_set,(short)256);
    lib_$add_to_set(button_set,(short)256,KBD_$M1D);
    lib_$add_to_set(button_set,(short)256,KBD_$M1U);
    lib_$add_to_set(button_set,(short)256,KBD_$M2D);
    lib_$add_to_set(button_set,(short)256,KBD_$M2U);
    lib_$add_to_set(button_set,(short)256,KBD_$M3D);
    lib_$add_to_set(button_set,(short)256,KBD_$M3U);

    gpr_$enable_input(gpr_$buttons,button_set,status);

 /* end enable_events() */


void create_bitmap_file()
$
    static gpr_$version_t  version = $1,1;
    unsigned char          created;

    gpr_$allocate_attribute_block(disk_bmap_attr,status);

    disk_bmap_hdr[0].n_sects = 1;
    disk_bmap_hdr[0].pixel_size = hi_plane + 1;
    disk_bmap_hdr[0].allocated_size = 8;
    disk_bmap_hdr[0].bytes_per_line = 0;
    disk_bmap_hdr[0].bytes_per_sect = 0;
    disk_bmap_hdr[0].storage_offset = 0;

    disk_bmap_size = blit_window.window_size;

    gpr_$open_bitmap_file ( gpr_$create,
                            fname,
                            fname_len,
                            version,
                            disk_bmap_size,
                            (short)1,
                            disk_bmap_hdr,
                            disk_bmap_attr,
                            disk_bmap,
                            created,
                            status);

    check("gpr_$open_bitmap_file");

    gpr_$set_bitmap(disk_bmap,status);
    gpr_$pixel_blt(disp_bmap,blit_window,dest_origin,status);

    gpr_$set_bitmap_file_color_map( disk_bmap,
                                    (long)0,
                                    (short)16,
                                    color_map,
                                    status);

    check("gpr_$set_bitmap_file_color_map");


 /* end of create_bitmap_file() */


/***************************************************************************/
/*                                                                         */
/*                                                                         */
/*                             M  A  I  N                                  */
/*                                                                         */
/*                                                                         */
/***************************************************************************/


main(argc,argv)

int     argc;
char    *argv[];

$
    gpr_$event_t        event_type;
    gpr_$position_t     mouse_position, cursor_position;
    gpr_$position_t     handle, anchor;
    gpr_$rgb_plane_t    plane;
    unsigned char       event_data;
    boolean             grab, exit;
    short               disp_len_ret, Ax, Ay, Hx, Hy;


/* Determine display characteristics and initialise various
   parameters  */

    if (argc < 2)
    $
        fprintf(stderr,"Sgrab  : a screen image capture utility\n");
        fprintf(stderr,"Usage  : sgrab filename\n");
        fprintf(stderr,"Author : Marcus Harvey\n");
        pgm_$exit(false);
    
    else
    $
        strcpy(fname,argv[1]);
        fname_len = strlen(fname);
    

    gpr_$inq_disp_characteristics ( gpr_$borrow,
                                    (short)1,
                                    sizeof(disp_char),
                                    disp_char,
                                    disp_len_ret,
                                    status);

    exit = grab = false;
    hi_plane = disp_char.n_planes - 1;

    disp_bmap_size.x_size = disp_char.x_window_size;
    disp_bmap_size.y_size = disp_char.y_window_size;

    mem_bmap_size = disp_bmap_size;

    whole_screen.window_base = dest_origin;
    whole_screen.window_size = disp_bmap_size;

    blit_window.window_base.x_coord = 0;
    blit_window.window_base.y_coord = 0;
    blit_window.window_size.x_size  = 0;
    blit_window.window_size.y_size  = 0;

/* Initialise graphics primitives in borrow_nc mode */

    gpr_$init ( gpr_$borrow_nc,
                (short)1,
                disp_bmap_size,
                hi_plane,
                disp_bmap,
                status);

    check("gpr_$init");

/* Initialise custom cursor and events we want to see */

    init_cursor();
    enable_events();

/* Allocate main memory bitmap and blit whole screen to it */

    gpr_$allocate_attribute_block(mem_bmap_attr, status);

    gpr_$allocate_bitmap(mem_bmap_size,
                         hi_plane,
                         mem_bmap_attr,
                         mem_bmap,
                         status);

    check("gpr_$allocate_bitmap");

    gpr_$set_bitmap(mem_bmap,status);
    gpr_$pixel_blt(disp_bmap,whole_screen,dest_origin,status);

    gpr_$set_bitmap(disp_bmap,status);
    gpr_$set_cursor_active(true,status);
    gpr_$set_draw_width(2,status);

    gpr_$inq_color_map((long)0,(short)16,color_map,status);
    check("gpr_$inq_color_map");

    gpr_$raster_op_prim_set(line_prim_set,status);
    for (plane = 0 ; plane <= hi_plane ; plane++)
        gpr_$set_raster_op(plane,XOR,status);

    gpr_$raster_op_prim_set(blit_prim_set,status);
    for (plane = 0 ; plane <= hi_plane ; plane++)
        gpr_$set_raster_op(plane,BLT,status);

/* Wait for user input and act accordingly */

    while(!exit)
    $
        gpr_$event_wait(event_type, event_data, mouse_position, status);

        if (event_type == gpr_$buttons)
        $
            if (event_data == KBD_$M1D)
            $
                grab = true;

                gpr_$set_cursor_active(false,status);
                gpr_$pixel_blt(mem_bmap,whole_screen,dest_origin,status);
                gpr_$set_cursor_active(true,status);

                anchor = handle = mouse_position;
            
            else if (event_data == KBD_$M1U)
            $
                grab = false;

                Ax = anchor.x_coord;
                Ay = anchor.y_coord;
                Hx = handle.x_coord;
                Hy = handle.y_coord;

                blit_window.window_size.x_size = (short) abs(Ax - Hx);
                blit_window.window_size.y_size = (short) abs(Ay - Hy);

                if (Ax < Hx)
                    blit_window.window_base.x_coord = Ax;
                else
                    blit_window.window_base.x_coord = Hx;

                if (Ay < Hy)
                    blit_window.window_base.y_coord = Ay;
                else
                    blit_window.window_base.y_coord = Hy;
            
        

        if (event_type == gpr_$locator)
        $
            cursor_position = mouse_position;
            gpr_$set_cursor_position(cursor_position, status);

            if (grab)
            $
                gpr_$set_cursor_active(false,status);

                gpr_$draw_box ( anchor.x_coord,anchor.y_coord,
                                handle.x_coord,handle.y_coord,
                                status);

                handle = cursor_position;

                gpr_$draw_box ( anchor.x_coord,anchor.y_coord,
                                handle.x_coord,handle.y_coord,
                                status);

                gpr_$set_cursor_active(true,status);
            
        

        if (event_type == gpr_$keystroke)
        $

            if (event_data == KBD_$ABORT)
                exit = true;

            else if (event_data == KBD_$EXIT)
            $
                gpr_$pixel_blt(mem_bmap,whole_screen,dest_origin,status);
                create_bitmap_file();
                exit = true;
            
        
    

    gpr_$terminate(false, status);

 /* end main() */

-------------------------------- cut here &< ----------------------------------