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