ccsmm@bath.ac.uk (Martin Maclaren) (04/12/90)
Here's my attempt at converting Tim Lambert's Pascal bgc to C -
It lets you set up an Apollo GPR bitmap file as background.
The easiest way to get a GPR file is to take a screendump, using
cpo /com/cpscr <pathname> (-gpr_bitmap if it's mono).
However, this means that you can create a 'wanted' background picture
on your Apollo in the first place. Therefore, a more common approach
would be to convert one of the many available GIF files to GPR -
This can be done using the gif2gpr routine recently made available
by Roque Oliveira (oliveria@caen.engin.umich.edu)
NOTES: As we have no SR10.? machines at the mo, I haven't been able to
verify my attempts at SR9.7/SR10.? dual environment programming.
(Thanks to GELINASJ@CMR001.BITNET for the pointers)
I'll get together a patch if there's any response.
(Modify the Makefile if you don't like -O -M3000)
Have fun,
Martin
--------------------------------------------------------------------------------
#! /bin/sh
# This is a shell archive. Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file". To overwrite existing
# files, type "sh file -c". You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g.. If this archive is complete, you
# will see the following message at the end:
# "End of shell archive."
# Contents: Makefile bgc.c
# Wrapped by ccsmm@gdt on Thu Apr 12 10:18:00 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'Makefile' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'Makefile'\"
else
echo shar: Extracting \"'Makefile'\" \(215 characters\)
sed "s/^X//" >'Makefile' <<'END_OF_FILE'
XCFLAGS = -O -M3000
XLFLAGS = -s
X#CFLAGS = -g -DDEBUG
X#LFLAGS = -g
X
XOBJS = bgc.o
Xbgc : $(OBJS)
X $(CC) $(LFLAGS) $(OBJS) -o bgc
X
Xbgc.o : bgc.c
X
Xclean:
X rm -f *.o *.bak
X
Xrealclean: clean
X rm -f *.bin bgc
END_OF_FILE
if test 215 -ne `wc -c <'Makefile'`; then
echo shar: \"'Makefile'\" unpacked with wrong size!
fi
# end of 'Makefile'
fi
if test -f 'bgc.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'bgc.c'\"
else
echo shar: Extracting \"'bgc.c'\" \(14695 characters\)
sed "s/^X//" >'bgc.c' <<'END_OF_FILE'
X/* Name : bgc
X/*
X/* Syntax : bgc filename ...
X/*
X/* Description : "bgc" lets you use a bitmap as a background pattern.
X/* If you give bgc more than one bitmap (e.g. "bgc *.bmf") it
X/* picks one at random to use as background. If you don't
X/* like that one the AGAIN key makes bgc pick another at
X/* random, and the EXIT key terminates "bgc".
X/*
X/* Authors : Tim Lambert <lambert@spectrum.cs.unsw.oz.au>
X/* Original version in Pascal. bgc.pas+bgc_rtn.pas+bgc.ins.pas
X/* Martin Maclaren <ccsmm@uk.ac.bath>
X/* Translation to C, one bgc.c, attempt at SR10 mods
X/*
X/* Bugs/Fixes : If you make any improvements/bug fixes to this program,
X/* please send them to the ccsmm@uk.ac.bath
X/*
X/* History...
X/*
X/* 10/04/89 : Add SR10 bits - untested
X/* 08/04/89 : Change from .pas to .c
X/* ??/??/?? : Oringinal Creation bgc.pas...
X/* */
X
X#include <stdio.h>
X#include <string.h>
X#ifdef __STDC__
X#include <apollo/base.h>
X#include <apollo/pgm.h>
X#include <apollo/pfm.h>
X#include <apollo/gpr.h>
X#include <apollo/pad.h>
X#include <apollo/ios.h>
X#define OUTA &
X#define OUTP
X#else
X#include "/sys/ins/base.ins.c" /* common include file for all system routines */
X#include "/sys/ins/pgm.ins.c" /* declarations for pgm routines (for getting file arguments) */
X#include "/sys/ins/pfm.ins.c" /* for faults */
X#include "/sys/ins/gpr.ins.c" /* contains the declarations for gpr routines */
X#include "/sys/ins/pad.ins.c" /* contains the declarations for pad routines (for creating windows) */
X#include "/sys/ins/ios.ins.c" /* i/o streams */
X#define OUTA
X#define OUTP *
X#endif
X
X#define name_len 128
Xtypedef char name_t[name_len];
X
X status_$t status; /* all gpr calls return a status value indicating whether they've succeeded or failed */
X gpr_$bitmap_desc_t display_bitmap; /* this is the bitmap corresponding to the screen */
X gpr_$offset_t display_size = {gpr_$max_x_size,gpr_$max_y_size}; /* size of display bitmap */
X gpr_$plane_t display_hi_plane = gpr_$highest_plane; /* number of highest plane on screen - 7 for 8 plane nodes
X 1 for monochrome nodes. we ask for maximum no of planes - gpr reduces this to fit */
X ios_$id_t pad; /* handle to the window we create for drawing in */
X int no_of_args; /* no of arguments to bg (counting argument 0) */
X char ** arg_pointer; /* pointer to the arguments */
X
X extern void refresh();
X extern void check(); /* if last system call was unsuccesful prints an error message */
X extern int randno(); /* returns a number in range 1..n */
X extern void drawit(); /* read in the bitmap in file_name and display it */
X extern pfm_$fh_func_val_t again_pressed(); /* this function is called when program gets a dq -c 1 signal */
X
Xmain(argc, argv)
Xint argc;
Xchar *argv[];
X{
X short unit = 1;
X name_t cmd;
X static name_t window_name = "/tmp/bgc";
X pad_$window_desc_t window;
X gpr_$disp_char_t disp_chars; /* display characteristics */
X short disp_len = sizeof(gpr_$disp_char_t);
X short disp_len_ret;
X gpr_$event_t event_type; /* type of event returned by gpr_$event_wait - not used */
X char event_char; /* character user typed in window - not used */
X gpr_$position_t event_pos; /* position where he/she typed it - not used */
X
X int dummy;
X
X no_of_args=argc; arg_pointer=argv;
X
X if (no_of_args<=1) {
X fprintf(stderr, "Usage: bgc bitmap-names\n");
X pgm_$exit();
X }
X if ((dummy=fork()) != 0) {
X if (dummy == -1)
X perror("bgc: main: fault forking");
X pgm_$exit();
X }
X
X /* kill previous bg, if any */
X sprintf(cmd, "dq %s;msg ' '", window_name); /* hide error message if window does not exist */
X pad_$dm_cmd(stream_$stdout,cmd,(short)strlen(cmd),OUTA status);
X /* check("dm command"); */
X
X /* initialize random number generator */
X srand((unsigned) time((long *) 0));
X
X gpr_$inq_disp_characteristics(gpr_$borrow,stream_$stdout,disp_len,OUTA disp_chars,OUTA disp_len_ret,OUTA status);
X check("main: gpr_$inq_disp_characteristics");
X
X /* create a window and initialise it for graphics */
X window.left = disp_chars.x_window_origin;
X window.top = disp_chars.y_window_origin;
X window.width = disp_chars.x_window_size;
X window.height = disp_chars.y_window_size;
X
X pad_$create_window(window_name,(short)strlen(window_name),pad_$transcript,unit,window,OUTA pad,OUTA status);
X check("main: creating window");
X if (unlink(window_name) != 0) {
X perror("bgc: main: unable to unlink");
X pgm_$exit();
X }
X if (window.width != 0) {
X pad_$set_full_window(pad,(short) 1,window,OUTA status);
X check("main: set full window");
X }
X pad_$set_auto_close(pad,(short) 1,true,OUTA status);
X check("main: pad_$set_auto_close");
X pad_$set_border(pad,(short) 1,false,OUTA status);
X check("main: pad_$set_border");
X#ifdef __STDC__
X pad_$set_erase(pad,(short) 1,false,OUTA status);
X#endif
X gpr_$init(gpr_$direct, pad, display_size, display_hi_plane,OUTA display_bitmap,OUTA status);
X check("main: gpr_init");
X gpr_$inq_bitmap_dimensions(display_bitmap,OUTA display_size,OUTA display_hi_plane,OUTA status);
X check("main: gpr_$inq_bitmap_dimensions");
X gpr_$set_obscured_opt(gpr_$ok_if_obs,OUTA status);
X check("main: gpr_$set_obscured_opt");
X gpr_$set_cursor_active(true,OUTA status);
X check("main: gpr_$set_cursor_active");
X
X drawit(argv[randno(no_of_args-1)]);
X
X/* establish the refresh procedure. if window needs to be refreshed as */
X/* the result of a pop, the draw procedure will automatically be called. */
X gpr_$set_refresh_entry (refresh, (long)0,OUTA status);
X check("main: setting the refresh entry procedure.");
X
X/* establish the again_pressed procedure. if window gets a dq -c 1 signal again_pressed will be called */
X pfm_$establish_fault_handler ((long) 1,pfm_$fh_multi_level,again_pressed,OUTA status);
X check("main: establishing fault handler");
X pad_$def_pfk(pad,"R2 ","dq -c 1",(short) 7,status);
X check("main: defining AGAIN");
X pad_$def_pfk(pad,"R5 ","dq",(short) 2,status);
X check("main: defining EXIT");
X
X gpr_$event_wait (OUTA event_type,OUTA event_char,OUTA event_pos,OUTA status);
X/* We would have liked to have waited for a keystroke, but we can't do input */
X/* into partly obscured windows we resort to evil thing with signals instead */
X
X} /* end of main */
X
X/* MODULE view; - originally bgc_rtn.pas, now all one thingy */
X
X#define max_no_windows (short)50
X
X boolean pattern = false;
X
X gpr_$offset_t fill_size; /* x and y size of our fill bitmap */
X gpr_$rgb_plane_t fill_hi_plane; /* number of highest plane in fill bitmap */
X gpr_$bitmap_desc_t fill_bitmap; /* this is the bitmap to fill with */
X boolean first = true; /* first time for getbitmap()? */
X
Xvoid check(messagex)
Xchar *messagex;
X{
X/* if last system call was unsuccesful prints an error message */
X
X if ( status.all != status_$ok) {
X error_$print(status);
X fprintf(stderr,"bgc: error occurred with %s\n",messagex);
X pgm_$exit();
X }
X#ifdef DEBUG
X fprintf(stdout,"check: %s\n", messagex);
X#endif
X}
X
Xint randno(n)
Xint n;
X{
X/* returns a number in range 1..n */
X return(1 + (rand() % n));
X} /* randno */
X
Xvoid draw_image(clip)
Xgpr_$window_t clip;
X{
X static gpr_$window_t window = {{0,0},{0,0}};
X gpr_$position_t dest; /* destinition point for our bit-blts */
X int i,j;
X
X gpr_$set_clip_window (clip,OUTA status);
X check("draw_image: gpr_$set_clip_window");
X gpr_$acquire_display(OUTA status);
X check("draw_image: gpr_$acquire_display");
X window.window_size.x_size = display_size.x_size;
X window.window_size.y_size = display_size.y_size;
X if (pattern==true) {
X gpr_$set_fill_pattern(fill_bitmap,(short) 1,OUTA status);
X check("draw_image: gpr_$set_fill_pattern");
X gpr_$rectangle(window,OUTA status);
X check("draw_image: rectangle");
X } else {
X for (i=clip.window_base.x_coord / fill_size.x_size;
X i<=(clip.window_base.x_coord+clip.window_size.x_size) / fill_size.x_size; i++) {
X dest.x_coord = i*fill_size.x_size;
X for (j=clip.window_base.y_coord / fill_size.y_size;
X j<=(clip.window_base.y_coord+clip.window_size.y_size) / fill_size.y_size; j++) {
X dest.y_coord = j*fill_size.y_size;
X gpr_$pixel_blt(fill_bitmap,window,dest,OUTA status ); /* does a bit_blt from bitmap file to fill */
X check("draw_image: pixel_blt");
X }
X }
X };
X gpr_$release_display(OUTA status);
X check("draw_image: gpr_$release_display");
X} /* draw_image */
X
Xvoid refresh(unobscured, position_change)
Xboolean unobscured;
Xboolean position_change;
X{
X gpr_$window_t vis_list[max_no_windows];
X short i, slots_total;
X
X gpr_$release_display(OUTA status);
X check("refresh: gpr_$release_display");
X pad_$pop_push_window(pad,(short)1,false,OUTA status);
X check("refresh: push");
X gpr_$acquire_display(OUTA status);
X check("refresh: gpr_$acquire_display");
X gpr_$set_cursor_active(false,OUTA status);
X check("refresh: gpr_$set_cursor_active");
X gpr_$inq_vis_list (max_no_windows,OUTA slots_total,OUTA vis_list,OUTA status);
X check("refresh: gpr_$inq_vis_list");
X slots_total = (slots_total<max_no_windows) ? slots_total : max_no_windows;
X for(i=0; i<slots_total; i++)
X draw_image(vis_list[i]);
X gpr_$set_cursor_active(true,OUTA status);
X check("refresh: gpr_$set_cursor_active");
X}
X
X
Xvoid getbitmap(file_name)
Xchar *file_name;
X{
X/* gets bitmap from file_name */
X gpr_$position_t dest; /* destinition point for our bit-blts */
X gpr_$rgb_plane_t file_hi_plane; /* number of highest plane in file bitmap */
X gpr_$color_vector_t color_map;
X gpr_$version_t version; /* some useless information returned by gpr_$open_bitmap_file */
X gpr_$offset_t file_size; /* x and y size of our file bitmap */
X short groups; /* more of the same */
X gpr_$bmf_group_header_array_t group_hs; /* field pixel_size * field n_sects should give # of planes in bitmap */
X gpr_$attribute_desc_t attribs; /* the attribute block for the bitmap file */
X gpr_$bitmap_desc_t file_bitmap; /* this is the bitmap to fill with */
X boolean created; /* tells us if the bitmap file was created - should be false */
X static gpr_$window_t window = {{0,0},{0,0}};
X int i,j;
X
X gpr_$allocate_attribute_block(OUTA attribs,OUTA status ); /* our window */
X check("getbitmap: gpr_$allocate_attribute_block");
X
X /* open the bitmap file */
X gpr_$open_bitmap_file(gpr_$readonly,OUTP file_name,(short)strlen(file_name),OUTA version,
X OUTA file_size,OUTA groups,OUTA group_hs,
X attribs,OUTA file_bitmap,OUTA created,OUTA status );
X check("getbitmap: gpr_$open_bitmap_file");
X file_hi_plane = group_hs[0].pixel_size * group_hs[0].n_sects - 1; /* calculates # of planes in file bitmap */
X fill_hi_plane = (display_hi_plane<file_hi_plane) ? display_hi_plane : file_hi_plane;
X if (fill_hi_plane == 7) {
X gpr_$inq_bitmap_file_color_map(file_bitmap,(short) 0,(short) 256,OUTA color_map,OUTA status);
X check("getbitmap: gpr_$inq_bitmap_file_color_map");
X gpr_$acquire_display(status);
X check("getbitmap: gpr_$acquire_display");
X gpr_$set_color_map((short) 16,(short) 240, color_map[16],OUTA status);
X check("getbitmap: gpr_$set_color_map");
X gpr_$release_display(OUTA status);
X check("getbitmap: gpr_$release_display");
X }
X if ((file_size.x_size == 32) && (file_size.y_size == 32)) {
X fill_size = file_size;
X pattern = true;
X } else {
X /* make sure fill bitmap is at least 200x200 */
X fill_size.x_size = file_size.x_size*(1+ 200 / file_size.x_size);
X fill_size.y_size = file_size.y_size*(1+ 200 / file_size.y_size);
X pattern = false;
X }
X if (first==false) { /* deallocate fill_bitmap if this isn't the first time we've been called */
X gpr_$deallocate_bitmap(fill_bitmap,OUTA status);
X check("getbitmap: gpr_$deallocate_bitmap");
X } else first=false;
X/* allocate a memory bitmap for bit-blting to */
X gpr_$allocate_bitmap(fill_size,fill_hi_plane,attribs,OUTA fill_bitmap,OUTA status);
X check("getbitmap: gpr_$allocate_bitmap");
X window.window_size.x_size = file_size.x_size; /* bitmap file */
X window.window_size.y_size = file_size.y_size;
X gpr_$set_bitmap(fill_bitmap,OUTA status);
X check("getbitmap: gpr_$set_bitmap");
X for(i=0; i<=((fill_size.x_size-1) / file_size.x_size); i++) {
X dest.x_coord = i*file_size.x_size;
X for(j=0; j<=((fill_size.y_size-1) / file_size.y_size); j++) {
X dest.y_coord = j*file_size.y_size;
X gpr_$pixel_blt(file_bitmap,window,dest,OUTA status); /* does a bit_blt from bitmap file to fill */
X check("getbitmap: pixel_blt");
X }
X }
X gpr_$deallocate_bitmap(file_bitmap,OUTA status);
X check("getbitmap: gpr_$deallocate_bitmap");
X}
X
Xvoid drawit(file_name)
Xchar *file_name;
X{
X/* read in the bitmap in file_name and display it */
X getbitmap(file_name);
X
X /* draw the picture. */
X gpr_$acquire_display(OUTA status);
X check("drawit: gpr_$acquire_display");
X gpr_$set_bitmap(display_bitmap,OUTA status );
X check("drawit: gpr_$set_bitmap");
X refresh(true,false);
X gpr_$release_display(OUTA status);
X check("drawit: gpr_$release_display");
X} /* drawit */
X
X
Xpfm_$fh_func_val_t again_pressed(f_status)
Xpfm_$fault_rec_t f_status;
X{
X/* this function is called when program gets a dq -c 1 signal,
X this should happen when AGAIN is pressed */
X
X static boolean lock=false; /* we ignore further interupts till we're finished */
X#ifdef DEBUG
X fprintf(stdout,"again_pressed:\n");
X#endif
X if ( lock==false ) {
X lock = true;
X drawit(arg_pointer[randno(no_of_args-1)]);
X lock = false;
X }
X return(pfm_$return_to_faulting_code);
X} /* again_pressed */
END_OF_FILE
if test 14695 -ne `wc -c <'bgc.c'`; then
echo shar: \"'bgc.c'\" unpacked with wrong size!
fi
# end of 'bgc.c'
fi
echo shar: End of shell archive.
exit 0