[comp.sources.unix] v17i047: MGR, Bellcore window manager, Part46/61

rsalz@uunet.uu.net (Rich Salz) (01/27/89)

Submitted-by: Stephen A. Uhler <sau@bellcore.com>
Posting-number: Volume 17, Issue 47
Archive-name: mgr/part46




#! /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 archive 46 (of 61)."
# Contents:  demo/icon/zoom.c
# Wrapped by rsalz@papaya.bbn.com on Thu Nov 17 21:05:55 1988
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'demo/icon/zoom.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'demo/icon/zoom.c'\"
else
echo shar: Extracting \"'demo/icon/zoom.c'\" \(28993 characters\)
sed "s/^X//" >'demo/icon/zoom.c' <<'END_OF_FILE'
X/*                        Copyright (c) 1988 Bellcore
X *                            All Rights Reserved
X *       Permission is granted to copy or use this program, EXCEPT that it
X *       may not be sold for profit, the copyright notice must be reproduced
X *       on copies, and credit should be given to Bellcore where it is due.
X *       BELLCORE MAKES NO WARRANTY AND ACCEPTS NO LIABILITY FOR THIS PROGRAM.
X */
X/*	$Header: zoom.c,v 4.4 88/07/11 13:10:39 sau Exp $
X	$Source: /tmp/mgrsrc/demo/icon/RCS/zoom.c,v $
X*/
Xstatic char	RCSid_[] = "$Source: /tmp/mgrsrc/demo/icon/RCS/zoom.c,v $$Revision: 4.4 $";
X
X/* icon edittor -- version I (single window) */
X
X#include <stdio.h>
X#include <signal.h>
X#include <sys/file.h>
X#include "term.h"
X#include "bitmap.h"
X
X/* general defines */
X
X#define GAP	2		/* general purpose gap */
X#define TITLE	20		/* cols needed for title */
X#define MAXMARK	7		/* max # of text items on status line */
X#define MIN	4		/* min number of pixels in a bitmap */
X#define SLEEP	5		/* time it takes for a message to go away */
X#define SETMSG	1		/* set the message */
X#define MAX	100		/* max # of pixels in a bitmap */
X#define FILES	100		/* max # of files to edit at once */
X
X/* bitmap functions */
X
X#define SET	0		/* bit set */
X#define CLEAR	1		/* clear */
X#define TOGGLE	2		/* toggle */
X#define ON	4		/* bit is on */
X#define OFF	0		/* bit is off */
X
X/* zoom options */
X
X#define YANK	1		/* yank a region */
X#define PUT	2		/* put a previously yanked region */
X#define SHRINK	3		/* make icon smaller */
X#define GROW	4		/* make icon bigger */
X#define SHIFT	5
X
X/* title fields */
X
X#define T_FUNC	0		/* raster op functions */
X#define T_OP	1		/* sweep otions */
X#define T_SIZE	2		/* bitmap size */
X#define T_NAME	3		/* file name */
X
X/* menu names */
X
X#define M_MODES		1	/* set/clear/toggle */
X#define M_OPTIONS	2	/* yank/put/shrink/grow/ */
X#define M_SIZE		3	/* none */
X#define M_EDIT		4	/* save/get */
X#define M_PUT		5	/* put functions */
X#define M_FILES		6	/* name of files to edit */
X
X#define dprintf	if(debug)fprintf
X
X#define SET_FUNC(n) \
X	(n!=func ? m_func(func = n) : n);
X#define SWAP(x,y) \
X	(code=x,x=y,y=code)
X#define MARK(i) \
X	((i)>=0 ? marks[i] : 0)
X
X#ifndef Min
X#define Min(x,y)	((x)<(y)?(x):(y))
X#endif
X#ifndef Max
X#define Max(x,y)	((x)>(y)?(x):(y))
X#endif
X
X#define INVERT(i) \
X	m_bitwrite(x0+MARK(i-1),0,MARK(i)-MARK(i-1),font_high);
X
X#define W	BIT_WIDE
X#define H	BIT_HIGH
X
X/* menus */
X
Xstruct menu_entry modes[] = {
X   "set", "s0\r",
X   "clear","s1\r",
X   "toggle","s2\r",
X   "grid","x\r",
X   };
X
Xstruct menu_entry edit[] = {
X   "save","f\r",
X   "get","g\r",
X   "yank","y\r",
X   "quit","Q\r"
X   };
X
Xstruct menu_entry resize[] = {
X   "resize","+\r",
X   };
X
Xstruct menu_entry options[] = {
X   "yank","F1\r",
X   "put","F2\r",
X   "shrink","F3\r",
X   "grow","F4\r",
X   "shift","F5\r",
X   "fix window","w\r",
X   "undo","u\r",
X   };
X
Xstruct menu_entry functions[] = {
X   "copy","P0\r",
X   "paint","P1\r",
X   "mask","P2\r",
X   "xor","P3\r",
X   "grid","x\r",
X   };
X
Xstruct menu_entry sizes[] = {
X   "normal cursor","16,16",
X   "small icon","48,48",
X   "normal icon","64,64",
X   };
X
Xstruct menu_entry files[FILES];
X
Xchar name[80];				/* name of icon */
X
X/* function codings for put */
X
Xint func_put[] = {
X   BIT_SRC, BIT_SRC|BIT_DST, BIT_SRC&BIT_DST, BIT_SRC^BIT_DST
X   };
X
Xint func_zoom[] = {
X   BIT_SRC^BIT_DST, BIT_SRC&BIT_NOT(BIT_DST), BIT_DST&BIT_NOT(BIT_SRC), BIT_SRC
X   };
X   
X
Xint marks[MAXMARK];		/* positions demarcating labels */
Xint win_wide, win_high;		/* window size */
Xint win_x, win_y;		/* window location */
Xint font_wide, font_high;	/* font size */
Xint x0,y0;			/* starting location of icon*/
Xint func;			/* current mgr raster function */
Xint debug=0;
Xchar *title[MAXMARK];		/* title goes here */
Xint xmax,ymax,border;		/* screen parameters */
Xchar *str_save(), *sprintf();
Xchar *prog;
X
Xmain(argc,argv)
Xint argc;
Xchar **argv;
X   {
X
X   register int i, c;
X   int w, h;			/* bitmap size */
X   int x,y;			/* scale factors */
X   int mx,my;			/* mouse position */
X   int bitx, bity;		/* bit position in bitmap */
X   int lastx, lasty;		/* prev. bit position in bitmap */
X   int size;			/* size of bitmap (bytes) */
X   int done=0;			/* exit flag */
X   int code;			/* return codes */
X   int state;			/* bit toggle state */
X 
X   /* state flags */
X
X   int menu = -1;		/* current menu selected */
X   int grid = 0;		/* grid state */
X   int mode = TOGGLE;		/* edit mode */
X   int function = 0;		/* function flag */
X   int put = 0;			/* put mode */
X
X   /* misc */
X
X   int file_count;		/* number of files in file menu */
X   char *pntr;			/* temp char pntr */
X   char dims[12];		/* string buffer for icon dims */
X   char line[512];		/* input buffer */
X
X   char *sprintf(), *malloc(), *rindex(), *get_str(), *strcpy();
X   int clean(), message();
X
X   BITMAP *map;				/* what your editting */
X   BITMAP *new, *temp;			/* temp bitmap */
X   BITMAP *yanked=BIT_NULL;		/* yanked bitmap */
X   BITMAP *last=BIT_NULL;		/* bitmap to undo */
X   BITMAP *read_icon(), *set_undo();
X
X   ckmgrterm( *argv );
X   debug = getenv("DEBUG");
X
X   if (argc <2) {
X      fprintf(stderr,"Usage: %s files...\n",argv[0]);
X      exit(1);
X      }
X   prog = *argv;
X
X   /* setup mgr */
X
X   m_setup(M_MODEOK);
X   m_ttyset();
X   m_push(P_FLAGS|P_MENU|P_EVENT);
X
X   signal(SIGINT,clean);
X   signal(SIGTERM,clean);
X   signal(SIGALRM,message);
X
X   m_setmode(M_ABS);
X   m_setmode(M_NOWRAP);
X   SET_FUNC(B_INVERT);
X   get_font(&font_wide, &font_high);
X   get_size(&win_x,&win_y,&win_wide,&win_high);
X   get_param(0,&xmax,&ymax,&border);
X
X   menu_load(1,MENU_SIZE(modes),modes);
X   menu_load(2,MENU_SIZE(options),options);
X   menu_load(3,MENU_SIZE(resize),resize);
X   menu_load(4,MENU_SIZE(edit),edit);
X   menu_load(5,MENU_SIZE(functions),functions);
X
X   for(i=1;i<argc && i<= FILES-3;i++) {		/* save room for new names */
X      pntr = rindex(argv[i],'/');
X      pntr = pntr ? pntr++ : argv[i];
X      files[i-1].value = str_save(pntr,"");
X      files[i-1].action = str_save(argv[i],"\r");
X      }
X   file_count = i-1;
X
X   m_nomenu();
X
X   /* get mgr events */
X
X   m_setevent(BUTTON_1,"(%r)\r");
X   m_setevent(BUTTON_2,"[%p]\r");
X   m_setevent(BUTTON_2U,"$\r");
X   m_setevent(RESHAPED,"S\r");
X   m_setevent(REDRAW,"R\r");
X   m_setevent(MOVE,"M\r");
X   
X   /* read in icon */ 
X
X   strcpy(name,argv[1]);
X   if ((map = read_icon(argv[1],0))  == BIT_NULL) {
X      pntr=get_str("Enter icon size (xxx,yyy):\n",
X            win_wide/2,win_high/2,sizes,MENU_SIZE(sizes));
X      sscanf(pntr,"%d,%d",&w,&h);
X      if (w>MAX || h>MAX || w<MIN || h<MIN) {
X         fprintf(stderr,"%s: Wrong size, try again\n",prog);
X         clean(1);
X         }
X      map = bit_alloc(w,h,BIT_NULL,1);
X      bit_blit(map,0,0,w,h,BIT_CLR,0,0,0);
X      }
X
X   /* setup & display icon */
X	
X   x0 = 0;
X   y0 = font_high + 2*GAP;
X   get_scale(&x,&y,map);
X
X   m_clear();
X   title[T_FUNC] = modes[mode].value;
X   title[T_OP] = options[function].value;
X   title[T_SIZE] = sprintf(dims,"%d x %d",W(map),H(map));
X   title[T_NAME] = name;
X   title[4] = NULL;
X   Do_title(title);
X
X   zoom(map,x0,y0,x,y,SET);
X
X   /* process menu and mouse hits */
X
X   m_flush();
X   while (!done && m_gets(line) != NULL) {
X     dprintf(stderr,"main loop got: %s",line);
X     menu = -1;
X     m_nomenu();
X     switch(c = *line) {
X        case '[':				/* got button 1 hit */
X           sscanf(line+1,"%d %d]",&mx,&my);
X           dprintf(stderr,"Got %d,%d\n",mx,my);
X
X           menu = -1;
X           if (my < y0) {			/* button 1 hit on menu */
X              for(i=0;i<4;i++)
X                  if (mx<marks[i]) {
X                     menu = i+1;
X                     break;
X                     }
X              }
X
X           else {
X              lastx = -1;
X              last = set_undo(last,map);
X              while (*line != '$') {		/* button 1 hit on bitmap */
X                 bitx = (mx-GAP)/x;
X                 bity = (my-2*GAP-font_high)/y;
X                 dprintf(stderr,"read (%d/%d,%d/%d) was (%d,%d) %s",
X                         bitx,W(map),bity,H(map),lastx,lasty,line);
X
X                 if (lastx == -1)  {
X                    mode = bit_on(map,bitx,bity) ? CLEAR : SET;
X                    title[T_FUNC]=modes[mode].value;
X                    Do_title(title);
X                    }
X   
X                 if (bitx==lastx && bity == lasty) {
X                    dprintf(stderr,"same bit %d,%d\n",bitx,bity);
X                    }
X                 else if (bitx < W(map) && bity < H(map)) {
X                    do_bit(map,x,y,bitx,bity,mode);
X                    }
X                 else {
X                    dprintf(stderr,"? bit %d,%d\n",bitx,bity);
X                    }
X
X                 lastx=bitx; lasty=bity;
X                 m_getinfo(G_MOUSE2);
X                 m_flush();
X                 m_gets(line);
X                 sscanf(line,"%d %d",&mx,&my);
X                 if (debug) sleep(1);
X                 }
X              }
X
X           /* set menu (if any) */
X
X           if (menu>0) {
X              dprintf(stderr,"selecting menu %d ->",menu); fflush(stderr);
X              if (menu==M_MODES && function==PUT)
X                 menu=M_PUT;
X              m_selectmenu(menu);
X              dprintf(stderr," %d [%d]\n",menu,function);
X              }
X           break;
X        case '(':			/* swept area  */
X           {
X           int rx1,ry1,rx2,ry2;		/* rect coords */
X
X           sscanf(line+1,"%d %d %d %d)",&rx1,&ry1,&rx2,&ry2);
X
X           if (rx1>rx2) SWAP(rx1,rx2);
X           if (ry1>ry2) SWAP(ry1,ry2);
X
X           rx1 = Max(rx1,x0);
X           ry1 = Max(ry1,y0);
X
X           rx1 = (rx1-GAP)/x;
X           rx2 = (rx2-GAP)/x;
X           ry1 = (ry1-2*GAP-font_high)/y;
X           ry2 = (ry2-2*GAP-font_high)/y;
X
X           rx2 = Min(rx2,W(map));
X           ry2 = Min(ry2,H(map));
X
X           w = rx2 - rx1;
X           h = ry2 - ry1;
X           new = bit_create(map,rx1,ry1,w,h);
X           dprintf(stderr,"Extract %d,%d %dx%d code: %s\n",
X                           rx1,ry1,w,h,new?"YES":"NO");
X
X           last = set_undo(last,map);
X
X           if (function) {
X              INVERT(T_OP);
X              dprintf(stderr,"Doing function %d\n",function);
X              switch(function) {
X                 case YANK:
X                    if (yanked)
X                       bit_destroy(yanked);
X                    yanked = bit_alloc(W(new),H(new),BIT_NULL,1);
X                    bit_blit(yanked,0,0,
X                            W(new),H(new),BIT_SRC,new,0,0);
X                    dprintf(stderr,"yanked: %s\n",yanked?"YES":"NO");
X                    if (!yanked)
X                       message(SETMSG,"Can't yank bitmap");
X                    else
X                       message(SETMSG,sprintf(line,"Yanked bitmap %d x %d",
X                               W(new),H(new)));
X                    break;
X                 case PUT:
X                    if (!yanked) {
X                       message(SETMSG,"Nothing to PUT");
X                       break;
X                       }
X
X                    w = Min(W(yanked),W(new));
X                    h = Min(H(yanked),H(new));
X
X                    if (w<1 || h < 1) {
X                       message(SETMSG,"Put where??");
X                       break;
X                       }
X
X                    /* setup and zoom bitmap */
X
X                    temp = bit_alloc(w,h,BIT_NULL,1);
X                    bit_blit(temp,0,0,w,h,BIT_SRC,new,0,0);
X                    bit_blit(temp,0,0,w,h,func_zoom[put],yanked,0,0);
X                    zoom(temp,x0+rx1*x,y0+ry1*y,x,y,SET);
X                    bit_destroy(temp);
X
X                    bit_blit(new,0,0,w,h,func_put[put],yanked,0,0);
X                    title[T_FUNC] = modes[mode].value;
X                    Do_title(title);
X                    dprintf(stderr,"put:%dx%d at %d,%d [%d]\n",
X                            w,h,rx1,ry1,put);
X                    break;
X                 case SHRINK:
X                    w = W(new);
X                    h = H(new);
X                    if (w<MIN || h<MIN) {
X                       message(SETMSG,"Icon would be too small");
X                       break;
X                       }
X                    temp = bit_alloc(w,h,BIT_NULL,1);
X                    bit_blit(temp,0,0,w,h,BIT_SRC,new,0,0);
X                    bit_destroy(new);
X                    bit_destroy(map);
X                    new = BIT_NULL;
X                    map = temp;
X                    get_scale(&x,&y,map);
X                    m_clear();
X                    zoom(map,x0,y0,x,y,SET);
X                    if (grid)
X                       draw_grid(map,x0,y0,x,y);
X                    title[T_SIZE] = sprintf(dims,"%d x %d",
X                            W(map),H(map));
X                    Do_title(title);
X                    break;
X                 case GROW:
X                    w = W(map)*W(map)/W(new);
X                    h = H(map)*H(map)/H(new);
X                    if (w>MAX || h>MAX) {
X                       message(SETMSG,"Icon would be too big");
X                       break;
X                       }
X                    temp = bit_alloc(w,h,BIT_NULL,1);
X                    fprintf(stderr,"growing to %d , %d\n",w,h);
X                    bit_blit(temp,0,0, w,h,BIT_CLR,0,0,0);
X                    bit_blit(temp,rx1,ry1,W(map),H(map),BIT_SRC,map,0,0);
X                    bit_destroy(new);
X                    bit_destroy(map);
X                    new = BIT_NULL;
X                    map = temp;
X                    get_scale(&x,&y,map);
X                    m_clear();
X                    zoom(map,x0,y0,x,y,SET);
X                    if (grid)
X                       draw_grid(map,x0,y0,x,y);
X                    title[T_SIZE] = sprintf(dims,"%d x %d",
X                            W(map),H(map));
X                    Do_title(title);
X                    break;
X                 case SHIFT:
X                    bit_blit(map,0,0,W(map),H(map)-1,BIT_SRC,map,0,1);
X                    zoom(map,x0,y0,x,y,SET);
X                    if (grid)
X                       draw_grid(map,x0,y0,x,y);
X                    break;
X                 }
X              function = 0;
X              }
X           else {
X              if (new && mode==TOGGLE) {
X                 bit_blit(new,0,0,W(new),H(new),
X                          BIT_NOT(BIT_DST),0,0,0);
X                 m_bitwrite(x0+rx1*x,y0+ry1*y,x*W(new),
X                            y*H(new));
X                 }
X              else if (new) {
X                 zoom(new,x0+rx1*x,y0+ry1*y,x,y,mode==SET?CLEAR:SET);
X                 bit_blit(new,0,0,W(new),H(new),
X                          mode==SET?BIT_SET:BIT_CLR,0,0,0);
X                 }
X              if (new)
X                 bit_destroy(new);
X              }
X           }
X           break;
X        case '$':			/* button up */
X           dprintf(stderr,"done\n");
X           menu = -1;
X           m_nomenu();
X           break;
X        case 's':			/* set bit mode */
X           c = *(line+1);
X           if (c>='0' && c<='2')
X              code = c - '0';
X           if (mode != code){
X              mode = code;
X              title[T_FUNC]=modes[mode].value;
X              Do_title(title);
X              }
X           break;
X        case '+':			/* specify bitmap size */
X           pntr=get_str("Enter new size (xxx,yyy):\n",
X                     mx,my,sizes,MENU_SIZE(sizes));
X           sscanf(pntr,"%d,%d",&w,&h);
X           if (w>MAX || h>MAX || w<MIN || h<MIN) {
X              message(SETMSG,"Sorry, invalid size");
X              break;
X              }
X           temp = bit_alloc(w,h,BIT_NULL,1);
X           fprintf(stderr,"resizing to %d , %d\n",w,h);
X           mx = w>W(map) ? (w - W(map))/2 : 0;
X           my = h>H(map) ? (h - H(map))/2 : 0;
X           bit_blit(temp,0,0,w,h,BIT_CLR,0,0,0);
X           bit_blit(temp,mx,my,W(map),H(map),BIT_SRC,map,0,0);
X           bit_destroy(map);
X           map = temp;
X           get_scale(&x,&y,map);
X           m_clear();
X           zoom(map,x0,y0,x,y,SET);
X           if (grid)
X              draw_grid(map,x0,y0,x,y);
X           title[T_SIZE] = sprintf(dims,"%d x %d",W(map),H(map));
X           Do_title(title);
X           if (function)
X              INVERT(T_OP);
X           break;
X        case 'f':			/* save file */
X           if ((pntr=get_str("Enter file name:\n",mx,my,files,file_count))
X                                  && *pntr) {
X              if (write_icon(pntr,map) && strcmp(name,pntr)!=0) {
X                 title[T_NAME] = strcpy(name,pntr);
X                 Do_title(title);
X                 if (function) INVERT(T_OP);
X              
X                 /* add new name to menu */
X
X                 for(i=0;i<file_count;i++)
X                    if (strcmp(files[i].value,name)==0)
X                       break;
X                 if (i==file_count && file_count+1 < FILES) {
X                    files[file_count].value = str_save(name,"");
X                    files[file_count].action = str_save(name,"\r");
X                    file_count++;
X                    }
X                 }
X              }
X           else {
X              message(SETMSG,"No file saved");
X              }
X           break;
X        case 'g':			/* get file */
X           {
X           pntr = get_str("Enter file name:\n",mx,my,files,file_count);
X           if (pntr && *pntr && (new = read_icon(pntr,0))  != BIT_NULL) {
X              bit_destroy(map);
X              map=new;
X              m_clear();
X              code = get_scale(&x,&y,map);
X              zoom(map,x0,y0,x,y,SET);
X              title[T_SIZE] = sprintf(dims,"%d x %d",W(map),H(map));
X              title[T_NAME] = strcpy(name,pntr);
X              Do_title(title);
X              if (grid)
X                 draw_grid(map,x0,y0,x,y);
X              }
X           }
X           break;
X        case 'y':			/* yank file to buffer */
X           pntr = get_str("Enter file name:\n",mx,my,files,file_count);
X           if (pntr && *pntr && (new = read_icon(pntr,0))  != BIT_NULL) {
X              if (yanked)
X                 bit_destroy(yanked);
X              yanked = new;
X              new = BIT_NULL;
X              message(SETMSG,sprintf(line,"Yanked %s (%d x %d)",
X                      pntr,W(yanked),H(yanked)));
X              if (function == YANK) {
X                 INVERT(T_OP); 
X                 function = 0;
X                 }
X              }
X           else
X              message(SETMSG,"Can'y yank file");
X           break;
X        case 'w':			/* reshape window to icon size  */
X           code = Min(x,y);
X           m_shapewindow(win_x,win_y,W(map)*code+GAP+2*border,
X                        W(map)*code+2*font_high+GAP*3 + 2*border);
X           m_sendme("S\r");
X           break;
X        case 'P':			/* set put mode  */
X           code = *(line+1) - '0';
X           if (code<0 || code > 9)
X              code = 0;
X           if (put != code) {
X              put = code;
X              title[T_FUNC]=functions[put].value;
X              Do_title(title);
X              INVERT(T_OP);
X              }
X           break;
X        case 'F':			/* set option flags  */
X           code = *(line+1) - '0';
X
X           if (code<0 || code > 9)
X              break;
X           if (code == PUT && !yanked)
X              break;
X
X           if (code == function && function == PUT) {
X              function = 0;
X              title[T_FUNC] = modes[mode].value;
X              }
X           else if (code == function)
X              function = 0;
X           else {
X              function = code;
X              title[T_OP] = options[function-1].value;
X              dprintf(stderr,"setting function =  %d\n",code);
X              if (function == PUT)
X                 title[T_FUNC]=functions[put].value;
X              }
X           Do_title(title);
X           if (function)
X              INVERT(T_OP);
X           break;
X        case 'u':			/* undo */
X           if (!last)
X              break;
X
X           /* get ready to undo the undo */
X
X           temp = map;
X           map = last;
X           last = temp;
X
X           /* make changes in situ */
X
X           if (W(last)==W(map) && H(last)==H(map)) {
X              temp = bit_alloc(W(map),H(map),BIT_NULL,1);
X              bit_blit(temp,0,0,W(map),H(map),BIT_SRC,map,0,0);
X              bit_blit(temp,0,0,W(map),H(map),BIT_SRC^BIT_DST,last,0,0);
X              zoom(temp,x0,y0,x,y,SET);
X              bit_destroy(temp);
X              }
X
X           /* redoit all */
X
X           else {
X              get_scale(&x,&y,map);
X              m_clear();
X              zoom(map,x0,y0,x,y,SET);
X              if (grid)
X                 draw_grid(map,x0,y0,x,y);
X              title[T_SIZE] = sprintf(dims,"%d x %d", W(map),H(map));
X              Do_title(title);
X              }
X           break;
X        case 'M':			/* move */
X           get_size(&win_x,&win_y,0,0);
X           break;
X        case 'R':			/* redraw */
X           m_clear();
X           zoom(map,x0,y0,x,y,SET);
X           Do_title(title);
X           if (grid)
X              draw_grid(map,x0,y0,x,y);
X           if (function)
X              INVERT(T_OP);
X           break;
X        case 'S':			/* reshape */
X              {
X              int lastx = x;
X              int lasty = y;
X
X              get_font(&font_wide, &font_high);
X              code = get_scale(&x,&y,map);
X              if (code>0 || lastx != x || lasty != y) {
X                 m_clear();
X                 zoom(map,x0,y0,x,y,SET);
X                 if (grid)
X                    draw_grid(map,x0,y0,x,y);
X                 }
X              Do_title(title);
X              if (function)
X                 INVERT(T_OP);
X              }
X              break;
X        case 'Q':			/* quit */
X           done++;
X           m_gets(line);		/* eat the "$" */
X           break;
X        case 'x':			/* toggle grid */
X           draw_grid(map,x0,y0,x,y);
X           grid = 1-grid;
X           break;
X        default:
X           break;
X        }
X     m_flush();
X     }
X   clean(0);
X   }
X
X/* grid a bitmap onto the window */
X
Xint
Xdraw_grid(map,x,y,x_scale,y_scale)
Xregister BITMAP *map;		/* bitmap to zoom */
Xint x,y;			/* screen location to start */
Xint x_scale, y_scale;		/* scale factors (>1) */
X   {
X   register int sx,sy,dx,dy;	/* current src, dst coords */
X
X   for(dy=y,sy=0;sy<H(map);sy++,dy+=y_scale)
X            m_bitwrite(x,dy,W(map)*x_scale,1);
X   for(dx=x,sx=0;sx<W(map);sx++,dx+=x_scale)
X            m_bitwrite(dx,y,1,H(map)*y_scale);
X   } 
X
X/* zoom a bitmap onto the window */
X
X#define X_ON(x)	(x != -1)
X
Xint
Xzoom(map,x,y,x_scale,y_scale,how)
Xregister BITMAP *map;		/* bitmap to zoom */
Xint x,y;			/* screen location to start */
Xint x_scale, y_scale;		/* scale factors (>1) */
Xint how;			/* 1==on bits  0==off bits */
X   {
X   register int sx,sy,dx,dy;	/* current src, dst coords */
X   int on, count=0, set_x;
X
X   for(dy=y,sy=0;sy<H(map);sy++,dy+=y_scale) {
X      for(count=0,dx=x,sx=0;sx<W(map);sx++,dx+=x_scale) {
X         on = how==SET ? (bit_on(map,sx,sy)) : !(bit_on(map,sx,sy));
X         if (on && count)
X            count ++;
X         else if (on) {
X            count++;
X            set_x = dx;
X            }
X         else if (count) {
X            m_bitwrite(set_x,dy,count * x_scale,y_scale);
X            count = 0;
X            }
X         }
X      if (count)
X         m_bitwrite(set_x,dy,count * x_scale,y_scale);
X      }
X   } 
X
X
Xint
Xclean(n)
Xint n;
X   {
X   m_moveprint(0,win_high,"done...");
X   m_popall();
X   m_ttyreset();
X   exit(n);
X   }
X
Xmessage(how,s)
Xint how;
Xchar *s;
X   {
X   alarm(0);
X   if (how==SETMSG) {
X      m_moveprint(0,win_high,s);
X      m_flush();
X      dprintf(stderr,"Setting message [%s]\n",s);
X      alarm(SLEEP);
X      }
X   else {
X      m_movecursor(0,win_high);
X      dprintf(stderr,"clearing message\n");
X      }
X   m_cleareol();
X   m_movecursor(win_wide,win_high);
X   m_flush();
X   }
X
Xint Do_title(args)
Xchar **args;
X   {
X   register int i, count;
X   int len[MAXMARK];		/* label sizes */
X   int sum;			/* total label width */
X   int x = 0;			/* starting label position */
X   int y = font_high;		/* starting label position */
X   register char **label=args;
X
X   SET_FUNC(B_SET);
X   m_movecursor(0,y);
X   m_cleareol();
X
X   for(sum=count=0;*label;count++,label++)
X      sum += (len[count] = strlen(*label) * font_wide + GAP);
X   for(i=0;i<count;i++) {
X      marks[i] = MARK(i-1) + len[i] * win_wide / sum;
X      if (i+1 == count)
X         marks[i] = win_wide;		/* fix rounding error */
X      dprintf(stderr,"%s (%d)at %d=>%d ",
X              args[i],len[i],MARK(i-1),MARK(i));
X      if (MARK(i) - MARK(i-1) > len[i])
X         m_moveprint((MARK(i)+MARK(i-1)- len[i])/2,y,args[i]);
X      m_bitwrite(marks[i],0,GAP,y);
X      }
X   dprintf(stderr,"(%d)\n",win_wide);
X
X   m_bitwrite(0,y,win_wide,GAP);
X   m_movecursor(win_wide+font_wide,y);
X   SET_FUNC(B_INVERT);
X   
X   return(count);
X   }
X
X/* get a user string */
X
X
Xchar *
Xget_str(s,x,y,menu,count)
Xchar *s;			/* text to display */
Xint x,y;			/* center of window */
Xstruct menu_entry *menu;	/* menu to down load */
Xint count;			/* # of menu items */
X   {
X   static char input[128];
X   int wide = Max(15,strlen(s)) * font_wide + 2*border;
X   int high = 2*(font_high + border);
X   int x0 = win_x + x - wide/2;
X   int y0 = win_y + y + font_high;
X   int win;
X   char *pntr, *index();
X
X   if (x0<0)
X      x0 = GAP;
X   if (x0+wide > xmax)
X      x0 = xmax-wide-GAP;
X   if (y0+high > ymax)
X      y0 = ymax-high-GAP;
X
X   dprintf(stderr,"Making %d,%d %dx%d\n",x0,y0,wide,high);
X   message(SIGALRM);		/* turn of any pending message */
X
X   m_newwin(x0,y0,wide,high);
X   m_flush();
X   m_gets(input);
X   if (*input == '$') {		/* button already let go */
X      dprintf(stderr,"$ in makewin\n");
X      m_gets(input);
X      }
X
X   dprintf(stderr,"makewin returns %s",input);
X   win = atoi(input);
X   dprintf(stderr,"Created %d\n",win);
X
X   *input = '\0';
X   if (win) {
X      m_selectwin(win);
X      m_setevent(DEACTIVATED,"\r");
X      m_setevent(DESTROY,"\r");
X      m_setevent(RESHAPE,"\r");
X      m_setevent(BUTTON_1,"%n\r");
X      m_setevent(ACCEPT,"%m\r");
X      if (count > 0) {
X         menu_load(1,count,menu);
X         m_selectmenu(1);
X         }
X      m_printstr(s);
X      dprintf(stderr,"prompt: %s ...",s);
X      fflush(stderr);
X      m_flush();
X      m_ttyreset();
X      m_gets(input);
X
X      pntr = input;
X      if (pntr=index(input,' '))
X         *pntr='\0';
X      if (pntr=index(input,'\n'))
X         *pntr='\0';
X
X      m_ttyset();
X      dprintf(stderr,"Got: %s\n",input); fflush(stderr);
X      m_selectwin(0);
X      m_destroywin(win);
X      m_flush();
X      } 
X   else
X      message(SETMSG,"Sorry, Can't make prompt window");
X   return(input);
X   }
X
X/* read in icon */ 
X
XBITMAP *
Xread_icon(name)
Xchar *name;				/* name of icon file */
X   {
X   FILE *fp;				/* fp to read bitmap from */
X   BITMAP *map, *bitmapread();
X   char tmp[100];
X
X   if ((fp = fopen(name,"r")) == NULL ) {
X      message(SETMSG,sprintf(tmp,"Can't find %s",name));
X      return(BIT_NULL);
X      }
X
X   if( !( map = bitmapread(fp) ) ) {
X      fclose(fp);
X      message(SETMSG,sprintf(tmp,"%s is not an icon or is damaged",name));
X      return(BIT_NULL);
X      }
X
X   fclose(fp);
X   return(map);
X   }
X
Xint
Xget_scale(x,y,map)
Xregister int *x, *y;
XBITMAP *map;
X   {
X   char line[256];
X   int w = W(map);
X   int h = H(map);
X   int count;
X
X   for(count=0;;count++) {
X      get_size(&win_x,&win_y,&win_wide,&win_high);
X      *x = (win_wide - x0)/w;
X      *y = (win_high - y0 - font_high)/h;
X      if (*x>=1 && *y>=1) 
X         break;
X      m_clear();
X      m_clearmode(M_NOWRAP);
X      m_printstr("Window is too small\n");
X      m_gets(line); 
X      }
X   if (count)
X      m_setmode(M_NOWRAP);
X   return(count);
X   }
X
X
Xint
Xwrite_icon(name,map)
Xchar *name;
XBITMAP *map;
X   {
X   FILE *fp = fopen(name,"w");
X   char tmp[100];
X
X   if (fp == NULL  ||  !bitmapwrite(fp,map)) {
X      dprintf(stderr,"Can't write file %s\n",name);
X      message(SETMSG,sprintf(tmp,"Can't write file %s",name));
X      return(0);
X      }
X   fclose(fp);
X   return(1);
X   }
X
X/* do mode to bit, fix up display */
X
Xint
Xdo_bit(map,x,y,bitx,bity,mode)
XBITMAP *map;
Xint x,y;		/* scale factors */
Xint bitx,bity;		/* bit to do */
Xint mode;		/* SET, CLEAR, or TOGGLE */
X   {
X   int state = bit_on(map,bitx,bity) ? ON : OFF;
X   switch(mode | state) {
X      case TOGGLE | OFF:
X      case TOGGLE | ON:
X      case SET | OFF:
X      case CLEAR | ON:
X         bit_point(map,bitx,bity,BIT_NOT(BIT_DST));
X         m_bitwrite(x0+bitx*x,y0+bity*y,x,y);
X         dprintf(stderr,"toggle (%d)\n",mode|state);
X         break;
X      }
X   }
X
X/* save map for undo */
X
XBITMAP *
Xset_undo(last,map)
XBITMAP *last, *map;
X   {
X   if (!last)
X      last = bit_alloc(W(map),H(map),BIT_NULL,1);
X   else if (W(last)!=W(map) || H(last)!=H(map)) {
X      bit_destroy(last);
X      last = bit_alloc(W(map),H(map),BIT_NULL,1);
X      }
X   bit_blit(last,0,0,W(last),H(last),BIT_SRC,map,0,0);
X   return(last);
X   }
X
X/* alloc and save space for the concatenation of s1 and s2 */
X
Xchar *str_save(s1,s2)
Xchar *s1, *s2;
X   {
X   char *malloc();
X   char *result;
X
X   if ((result = malloc(strlen(s1) + strlen(s2) + 1)) == NULL) {
X      fprintf(stderr,"Malloc failed\n");
X      clean(1);  
X      }
X
X   strcpy(result,s1);
X   strcat(result,s2);
X   return(result);
X   }
END_OF_FILE
# end of 'demo/icon/zoom.c'
fi
echo shar: End of archive 46 \(of 61\).
cp /dev/null ark46isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 \
	21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 \
	38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 \
	55 56 57 58 59 60 61 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 61 archives.
    rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
-- 
Please send comp.sources.unix-related mail to rsalz@uunet.uu.net.