home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume17 / mgr / part46 < prev    next >
Text File  |  1989-01-19  |  32KB  |  1,072 lines

  1. Subject:  v17i047:  MGR, Bellcore window manager, Part46/61
  2. Newsgroups: comp.sources.unix
  3. Approved: rsalz@uunet.UU.NET
  4.  
  5. Submitted-by: Stephen A. Uhler <sau@bellcore.com>
  6. Posting-number: Volume 17, Issue 47
  7. Archive-name: mgr/part46
  8.  
  9.  
  10.  
  11.  
  12. #! /bin/sh
  13. # This is a shell archive.  Remove anything before this line, then unpack
  14. # it by saving it into a file and typing "sh file".  To overwrite existing
  15. # files, type "sh file -c".  You can also feed this as standard input via
  16. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  17. # will see the following message at the end:
  18. #        "End of archive 46 (of 61)."
  19. # Contents:  demo/icon/zoom.c
  20. # Wrapped by rsalz@papaya.bbn.com on Thu Nov 17 21:05:55 1988
  21. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  22. if test -f 'demo/icon/zoom.c' -a "${1}" != "-c" ; then 
  23.   echo shar: Will not clobber existing file \"'demo/icon/zoom.c'\"
  24. else
  25. echo shar: Extracting \"'demo/icon/zoom.c'\" \(28993 characters\)
  26. sed "s/^X//" >'demo/icon/zoom.c' <<'END_OF_FILE'
  27. X/*                        Copyright (c) 1988 Bellcore
  28. X *                            All Rights Reserved
  29. X *       Permission is granted to copy or use this program, EXCEPT that it
  30. X *       may not be sold for profit, the copyright notice must be reproduced
  31. X *       on copies, and credit should be given to Bellcore where it is due.
  32. X *       BELLCORE MAKES NO WARRANTY AND ACCEPTS NO LIABILITY FOR THIS PROGRAM.
  33. X */
  34. X/*    $Header: zoom.c,v 4.4 88/07/11 13:10:39 sau Exp $
  35. X    $Source: /tmp/mgrsrc/demo/icon/RCS/zoom.c,v $
  36. X*/
  37. Xstatic char    RCSid_[] = "$Source: /tmp/mgrsrc/demo/icon/RCS/zoom.c,v $$Revision: 4.4 $";
  38. X
  39. X/* icon edittor -- version I (single window) */
  40. X
  41. X#include <stdio.h>
  42. X#include <signal.h>
  43. X#include <sys/file.h>
  44. X#include "term.h"
  45. X#include "bitmap.h"
  46. X
  47. X/* general defines */
  48. X
  49. X#define GAP    2        /* general purpose gap */
  50. X#define TITLE    20        /* cols needed for title */
  51. X#define MAXMARK    7        /* max # of text items on status line */
  52. X#define MIN    4        /* min number of pixels in a bitmap */
  53. X#define SLEEP    5        /* time it takes for a message to go away */
  54. X#define SETMSG    1        /* set the message */
  55. X#define MAX    100        /* max # of pixels in a bitmap */
  56. X#define FILES    100        /* max # of files to edit at once */
  57. X
  58. X/* bitmap functions */
  59. X
  60. X#define SET    0        /* bit set */
  61. X#define CLEAR    1        /* clear */
  62. X#define TOGGLE    2        /* toggle */
  63. X#define ON    4        /* bit is on */
  64. X#define OFF    0        /* bit is off */
  65. X
  66. X/* zoom options */
  67. X
  68. X#define YANK    1        /* yank a region */
  69. X#define PUT    2        /* put a previously yanked region */
  70. X#define SHRINK    3        /* make icon smaller */
  71. X#define GROW    4        /* make icon bigger */
  72. X#define SHIFT    5
  73. X
  74. X/* title fields */
  75. X
  76. X#define T_FUNC    0        /* raster op functions */
  77. X#define T_OP    1        /* sweep otions */
  78. X#define T_SIZE    2        /* bitmap size */
  79. X#define T_NAME    3        /* file name */
  80. X
  81. X/* menu names */
  82. X
  83. X#define M_MODES        1    /* set/clear/toggle */
  84. X#define M_OPTIONS    2    /* yank/put/shrink/grow/ */
  85. X#define M_SIZE        3    /* none */
  86. X#define M_EDIT        4    /* save/get */
  87. X#define M_PUT        5    /* put functions */
  88. X#define M_FILES        6    /* name of files to edit */
  89. X
  90. X#define dprintf    if(debug)fprintf
  91. X
  92. X#define SET_FUNC(n) \
  93. X    (n!=func ? m_func(func = n) : n);
  94. X#define SWAP(x,y) \
  95. X    (code=x,x=y,y=code)
  96. X#define MARK(i) \
  97. X    ((i)>=0 ? marks[i] : 0)
  98. X
  99. X#ifndef Min
  100. X#define Min(x,y)    ((x)<(y)?(x):(y))
  101. X#endif
  102. X#ifndef Max
  103. X#define Max(x,y)    ((x)>(y)?(x):(y))
  104. X#endif
  105. X
  106. X#define INVERT(i) \
  107. X    m_bitwrite(x0+MARK(i-1),0,MARK(i)-MARK(i-1),font_high);
  108. X
  109. X#define W    BIT_WIDE
  110. X#define H    BIT_HIGH
  111. X
  112. X/* menus */
  113. X
  114. Xstruct menu_entry modes[] = {
  115. X   "set", "s0\r",
  116. X   "clear","s1\r",
  117. X   "toggle","s2\r",
  118. X   "grid","x\r",
  119. X   };
  120. X
  121. Xstruct menu_entry edit[] = {
  122. X   "save","f\r",
  123. X   "get","g\r",
  124. X   "yank","y\r",
  125. X   "quit","Q\r"
  126. X   };
  127. X
  128. Xstruct menu_entry resize[] = {
  129. X   "resize","+\r",
  130. X   };
  131. X
  132. Xstruct menu_entry options[] = {
  133. X   "yank","F1\r",
  134. X   "put","F2\r",
  135. X   "shrink","F3\r",
  136. X   "grow","F4\r",
  137. X   "shift","F5\r",
  138. X   "fix window","w\r",
  139. X   "undo","u\r",
  140. X   };
  141. X
  142. Xstruct menu_entry functions[] = {
  143. X   "copy","P0\r",
  144. X   "paint","P1\r",
  145. X   "mask","P2\r",
  146. X   "xor","P3\r",
  147. X   "grid","x\r",
  148. X   };
  149. X
  150. Xstruct menu_entry sizes[] = {
  151. X   "normal cursor","16,16",
  152. X   "small icon","48,48",
  153. X   "normal icon","64,64",
  154. X   };
  155. X
  156. Xstruct menu_entry files[FILES];
  157. X
  158. Xchar name[80];                /* name of icon */
  159. X
  160. X/* function codings for put */
  161. X
  162. Xint func_put[] = {
  163. X   BIT_SRC, BIT_SRC|BIT_DST, BIT_SRC&BIT_DST, BIT_SRC^BIT_DST
  164. X   };
  165. X
  166. Xint func_zoom[] = {
  167. X   BIT_SRC^BIT_DST, BIT_SRC&BIT_NOT(BIT_DST), BIT_DST&BIT_NOT(BIT_SRC), BIT_SRC
  168. X   };
  169. X   
  170. X
  171. Xint marks[MAXMARK];        /* positions demarcating labels */
  172. Xint win_wide, win_high;        /* window size */
  173. Xint win_x, win_y;        /* window location */
  174. Xint font_wide, font_high;    /* font size */
  175. Xint x0,y0;            /* starting location of icon*/
  176. Xint func;            /* current mgr raster function */
  177. Xint debug=0;
  178. Xchar *title[MAXMARK];        /* title goes here */
  179. Xint xmax,ymax,border;        /* screen parameters */
  180. Xchar *str_save(), *sprintf();
  181. Xchar *prog;
  182. X
  183. Xmain(argc,argv)
  184. Xint argc;
  185. Xchar **argv;
  186. X   {
  187. X
  188. X   register int i, c;
  189. X   int w, h;            /* bitmap size */
  190. X   int x,y;            /* scale factors */
  191. X   int mx,my;            /* mouse position */
  192. X   int bitx, bity;        /* bit position in bitmap */
  193. X   int lastx, lasty;        /* prev. bit position in bitmap */
  194. X   int size;            /* size of bitmap (bytes) */
  195. X   int done=0;            /* exit flag */
  196. X   int code;            /* return codes */
  197. X   int state;            /* bit toggle state */
  198. X   /* state flags */
  199. X
  200. X   int menu = -1;        /* current menu selected */
  201. X   int grid = 0;        /* grid state */
  202. X   int mode = TOGGLE;        /* edit mode */
  203. X   int function = 0;        /* function flag */
  204. X   int put = 0;            /* put mode */
  205. X
  206. X   /* misc */
  207. X
  208. X   int file_count;        /* number of files in file menu */
  209. X   char *pntr;            /* temp char pntr */
  210. X   char dims[12];        /* string buffer for icon dims */
  211. X   char line[512];        /* input buffer */
  212. X
  213. X   char *sprintf(), *malloc(), *rindex(), *get_str(), *strcpy();
  214. X   int clean(), message();
  215. X
  216. X   BITMAP *map;                /* what your editting */
  217. X   BITMAP *new, *temp;            /* temp bitmap */
  218. X   BITMAP *yanked=BIT_NULL;        /* yanked bitmap */
  219. X   BITMAP *last=BIT_NULL;        /* bitmap to undo */
  220. X   BITMAP *read_icon(), *set_undo();
  221. X
  222. X   ckmgrterm( *argv );
  223. X   debug = getenv("DEBUG");
  224. X
  225. X   if (argc <2) {
  226. X      fprintf(stderr,"Usage: %s files...\n",argv[0]);
  227. X      exit(1);
  228. X      }
  229. X   prog = *argv;
  230. X
  231. X   /* setup mgr */
  232. X
  233. X   m_setup(M_MODEOK);
  234. X   m_ttyset();
  235. X   m_push(P_FLAGS|P_MENU|P_EVENT);
  236. X
  237. X   signal(SIGINT,clean);
  238. X   signal(SIGTERM,clean);
  239. X   signal(SIGALRM,message);
  240. X
  241. X   m_setmode(M_ABS);
  242. X   m_setmode(M_NOWRAP);
  243. X   SET_FUNC(B_INVERT);
  244. X   get_font(&font_wide, &font_high);
  245. X   get_size(&win_x,&win_y,&win_wide,&win_high);
  246. X   get_param(0,&xmax,&ymax,&border);
  247. X
  248. X   menu_load(1,MENU_SIZE(modes),modes);
  249. X   menu_load(2,MENU_SIZE(options),options);
  250. X   menu_load(3,MENU_SIZE(resize),resize);
  251. X   menu_load(4,MENU_SIZE(edit),edit);
  252. X   menu_load(5,MENU_SIZE(functions),functions);
  253. X
  254. X   for(i=1;i<argc && i<= FILES-3;i++) {        /* save room for new names */
  255. X      pntr = rindex(argv[i],'/');
  256. X      pntr = pntr ? pntr++ : argv[i];
  257. X      files[i-1].value = str_save(pntr,"");
  258. X      files[i-1].action = str_save(argv[i],"\r");
  259. X      }
  260. X   file_count = i-1;
  261. X
  262. X   m_nomenu();
  263. X
  264. X   /* get mgr events */
  265. X
  266. X   m_setevent(BUTTON_1,"(%r)\r");
  267. X   m_setevent(BUTTON_2,"[%p]\r");
  268. X   m_setevent(BUTTON_2U,"$\r");
  269. X   m_setevent(RESHAPED,"S\r");
  270. X   m_setevent(REDRAW,"R\r");
  271. X   m_setevent(MOVE,"M\r");
  272. X   
  273. X   /* read in icon */ 
  274. X
  275. X   strcpy(name,argv[1]);
  276. X   if ((map = read_icon(argv[1],0))  == BIT_NULL) {
  277. X      pntr=get_str("Enter icon size (xxx,yyy):\n",
  278. X            win_wide/2,win_high/2,sizes,MENU_SIZE(sizes));
  279. X      sscanf(pntr,"%d,%d",&w,&h);
  280. X      if (w>MAX || h>MAX || w<MIN || h<MIN) {
  281. X         fprintf(stderr,"%s: Wrong size, try again\n",prog);
  282. X         clean(1);
  283. X         }
  284. X      map = bit_alloc(w,h,BIT_NULL,1);
  285. X      bit_blit(map,0,0,w,h,BIT_CLR,0,0,0);
  286. X      }
  287. X
  288. X   /* setup & display icon */
  289. X    
  290. X   x0 = 0;
  291. X   y0 = font_high + 2*GAP;
  292. X   get_scale(&x,&y,map);
  293. X
  294. X   m_clear();
  295. X   title[T_FUNC] = modes[mode].value;
  296. X   title[T_OP] = options[function].value;
  297. X   title[T_SIZE] = sprintf(dims,"%d x %d",W(map),H(map));
  298. X   title[T_NAME] = name;
  299. X   title[4] = NULL;
  300. X   Do_title(title);
  301. X
  302. X   zoom(map,x0,y0,x,y,SET);
  303. X
  304. X   /* process menu and mouse hits */
  305. X
  306. X   m_flush();
  307. X   while (!done && m_gets(line) != NULL) {
  308. X     dprintf(stderr,"main loop got: %s",line);
  309. X     menu = -1;
  310. X     m_nomenu();
  311. X     switch(c = *line) {
  312. X        case '[':                /* got button 1 hit */
  313. X           sscanf(line+1,"%d %d]",&mx,&my);
  314. X           dprintf(stderr,"Got %d,%d\n",mx,my);
  315. X
  316. X           menu = -1;
  317. X           if (my < y0) {            /* button 1 hit on menu */
  318. X              for(i=0;i<4;i++)
  319. X                  if (mx<marks[i]) {
  320. X                     menu = i+1;
  321. X                     break;
  322. X                     }
  323. X              }
  324. X
  325. X           else {
  326. X              lastx = -1;
  327. X              last = set_undo(last,map);
  328. X              while (*line != '$') {        /* button 1 hit on bitmap */
  329. X                 bitx = (mx-GAP)/x;
  330. X                 bity = (my-2*GAP-font_high)/y;
  331. X                 dprintf(stderr,"read (%d/%d,%d/%d) was (%d,%d) %s",
  332. X                         bitx,W(map),bity,H(map),lastx,lasty,line);
  333. X
  334. X                 if (lastx == -1)  {
  335. X                    mode = bit_on(map,bitx,bity) ? CLEAR : SET;
  336. X                    title[T_FUNC]=modes[mode].value;
  337. X                    Do_title(title);
  338. X                    }
  339. X   
  340. X                 if (bitx==lastx && bity == lasty) {
  341. X                    dprintf(stderr,"same bit %d,%d\n",bitx,bity);
  342. X                    }
  343. X                 else if (bitx < W(map) && bity < H(map)) {
  344. X                    do_bit(map,x,y,bitx,bity,mode);
  345. X                    }
  346. X                 else {
  347. X                    dprintf(stderr,"? bit %d,%d\n",bitx,bity);
  348. X                    }
  349. X
  350. X                 lastx=bitx; lasty=bity;
  351. X                 m_getinfo(G_MOUSE2);
  352. X                 m_flush();
  353. X                 m_gets(line);
  354. X                 sscanf(line,"%d %d",&mx,&my);
  355. X                 if (debug) sleep(1);
  356. X                 }
  357. X              }
  358. X
  359. X           /* set menu (if any) */
  360. X
  361. X           if (menu>0) {
  362. X              dprintf(stderr,"selecting menu %d ->",menu); fflush(stderr);
  363. X              if (menu==M_MODES && function==PUT)
  364. X                 menu=M_PUT;
  365. X              m_selectmenu(menu);
  366. X              dprintf(stderr," %d [%d]\n",menu,function);
  367. X              }
  368. X           break;
  369. X        case '(':            /* swept area  */
  370. X           {
  371. X           int rx1,ry1,rx2,ry2;        /* rect coords */
  372. X
  373. X           sscanf(line+1,"%d %d %d %d)",&rx1,&ry1,&rx2,&ry2);
  374. X
  375. X           if (rx1>rx2) SWAP(rx1,rx2);
  376. X           if (ry1>ry2) SWAP(ry1,ry2);
  377. X
  378. X           rx1 = Max(rx1,x0);
  379. X           ry1 = Max(ry1,y0);
  380. X
  381. X           rx1 = (rx1-GAP)/x;
  382. X           rx2 = (rx2-GAP)/x;
  383. X           ry1 = (ry1-2*GAP-font_high)/y;
  384. X           ry2 = (ry2-2*GAP-font_high)/y;
  385. X
  386. X           rx2 = Min(rx2,W(map));
  387. X           ry2 = Min(ry2,H(map));
  388. X
  389. X           w = rx2 - rx1;
  390. X           h = ry2 - ry1;
  391. X           new = bit_create(map,rx1,ry1,w,h);
  392. X           dprintf(stderr,"Extract %d,%d %dx%d code: %s\n",
  393. X                           rx1,ry1,w,h,new?"YES":"NO");
  394. X
  395. X           last = set_undo(last,map);
  396. X
  397. X           if (function) {
  398. X              INVERT(T_OP);
  399. X              dprintf(stderr,"Doing function %d\n",function);
  400. X              switch(function) {
  401. X                 case YANK:
  402. X                    if (yanked)
  403. X                       bit_destroy(yanked);
  404. X                    yanked = bit_alloc(W(new),H(new),BIT_NULL,1);
  405. X                    bit_blit(yanked,0,0,
  406. X                            W(new),H(new),BIT_SRC,new,0,0);
  407. X                    dprintf(stderr,"yanked: %s\n",yanked?"YES":"NO");
  408. X                    if (!yanked)
  409. X                       message(SETMSG,"Can't yank bitmap");
  410. X                    else
  411. X                       message(SETMSG,sprintf(line,"Yanked bitmap %d x %d",
  412. X                               W(new),H(new)));
  413. X                    break;
  414. X                 case PUT:
  415. X                    if (!yanked) {
  416. X                       message(SETMSG,"Nothing to PUT");
  417. X                       break;
  418. X                       }
  419. X
  420. X                    w = Min(W(yanked),W(new));
  421. X                    h = Min(H(yanked),H(new));
  422. X
  423. X                    if (w<1 || h < 1) {
  424. X                       message(SETMSG,"Put where??");
  425. X                       break;
  426. X                       }
  427. X
  428. X                    /* setup and zoom bitmap */
  429. X
  430. X                    temp = bit_alloc(w,h,BIT_NULL,1);
  431. X                    bit_blit(temp,0,0,w,h,BIT_SRC,new,0,0);
  432. X                    bit_blit(temp,0,0,w,h,func_zoom[put],yanked,0,0);
  433. X                    zoom(temp,x0+rx1*x,y0+ry1*y,x,y,SET);
  434. X                    bit_destroy(temp);
  435. X
  436. X                    bit_blit(new,0,0,w,h,func_put[put],yanked,0,0);
  437. X                    title[T_FUNC] = modes[mode].value;
  438. X                    Do_title(title);
  439. X                    dprintf(stderr,"put:%dx%d at %d,%d [%d]\n",
  440. X                            w,h,rx1,ry1,put);
  441. X                    break;
  442. X                 case SHRINK:
  443. X                    w = W(new);
  444. X                    h = H(new);
  445. X                    if (w<MIN || h<MIN) {
  446. X                       message(SETMSG,"Icon would be too small");
  447. X                       break;
  448. X                       }
  449. X                    temp = bit_alloc(w,h,BIT_NULL,1);
  450. X                    bit_blit(temp,0,0,w,h,BIT_SRC,new,0,0);
  451. X                    bit_destroy(new);
  452. X                    bit_destroy(map);
  453. X                    new = BIT_NULL;
  454. X                    map = temp;
  455. X                    get_scale(&x,&y,map);
  456. X                    m_clear();
  457. X                    zoom(map,x0,y0,x,y,SET);
  458. X                    if (grid)
  459. X                       draw_grid(map,x0,y0,x,y);
  460. X                    title[T_SIZE] = sprintf(dims,"%d x %d",
  461. X                            W(map),H(map));
  462. X                    Do_title(title);
  463. X                    break;
  464. X                 case GROW:
  465. X                    w = W(map)*W(map)/W(new);
  466. X                    h = H(map)*H(map)/H(new);
  467. X                    if (w>MAX || h>MAX) {
  468. X                       message(SETMSG,"Icon would be too big");
  469. X                       break;
  470. X                       }
  471. X                    temp = bit_alloc(w,h,BIT_NULL,1);
  472. X                    fprintf(stderr,"growing to %d , %d\n",w,h);
  473. X                    bit_blit(temp,0,0, w,h,BIT_CLR,0,0,0);
  474. X                    bit_blit(temp,rx1,ry1,W(map),H(map),BIT_SRC,map,0,0);
  475. X                    bit_destroy(new);
  476. X                    bit_destroy(map);
  477. X                    new = BIT_NULL;
  478. X                    map = temp;
  479. X                    get_scale(&x,&y,map);
  480. X                    m_clear();
  481. X                    zoom(map,x0,y0,x,y,SET);
  482. X                    if (grid)
  483. X                       draw_grid(map,x0,y0,x,y);
  484. X                    title[T_SIZE] = sprintf(dims,"%d x %d",
  485. X                            W(map),H(map));
  486. X                    Do_title(title);
  487. X                    break;
  488. X                 case SHIFT:
  489. X                    bit_blit(map,0,0,W(map),H(map)-1,BIT_SRC,map,0,1);
  490. X                    zoom(map,x0,y0,x,y,SET);
  491. X                    if (grid)
  492. X                       draw_grid(map,x0,y0,x,y);
  493. X                    break;
  494. X                 }
  495. X              function = 0;
  496. X              }
  497. X           else {
  498. X              if (new && mode==TOGGLE) {
  499. X                 bit_blit(new,0,0,W(new),H(new),
  500. X                          BIT_NOT(BIT_DST),0,0,0);
  501. X                 m_bitwrite(x0+rx1*x,y0+ry1*y,x*W(new),
  502. X                            y*H(new));
  503. X                 }
  504. X              else if (new) {
  505. X                 zoom(new,x0+rx1*x,y0+ry1*y,x,y,mode==SET?CLEAR:SET);
  506. X                 bit_blit(new,0,0,W(new),H(new),
  507. X                          mode==SET?BIT_SET:BIT_CLR,0,0,0);
  508. X                 }
  509. X              if (new)
  510. X                 bit_destroy(new);
  511. X              }
  512. X           }
  513. X           break;
  514. X        case '$':            /* button up */
  515. X           dprintf(stderr,"done\n");
  516. X           menu = -1;
  517. X           m_nomenu();
  518. X           break;
  519. X        case 's':            /* set bit mode */
  520. X           c = *(line+1);
  521. X           if (c>='0' && c<='2')
  522. X              code = c - '0';
  523. X           if (mode != code){
  524. X              mode = code;
  525. X              title[T_FUNC]=modes[mode].value;
  526. X              Do_title(title);
  527. X              }
  528. X           break;
  529. X        case '+':            /* specify bitmap size */
  530. X           pntr=get_str("Enter new size (xxx,yyy):\n",
  531. X                     mx,my,sizes,MENU_SIZE(sizes));
  532. X           sscanf(pntr,"%d,%d",&w,&h);
  533. X           if (w>MAX || h>MAX || w<MIN || h<MIN) {
  534. X              message(SETMSG,"Sorry, invalid size");
  535. X              break;
  536. X              }
  537. X           temp = bit_alloc(w,h,BIT_NULL,1);
  538. X           fprintf(stderr,"resizing to %d , %d\n",w,h);
  539. X           mx = w>W(map) ? (w - W(map))/2 : 0;
  540. X           my = h>H(map) ? (h - H(map))/2 : 0;
  541. X           bit_blit(temp,0,0,w,h,BIT_CLR,0,0,0);
  542. X           bit_blit(temp,mx,my,W(map),H(map),BIT_SRC,map,0,0);
  543. X           bit_destroy(map);
  544. X           map = temp;
  545. X           get_scale(&x,&y,map);
  546. X           m_clear();
  547. X           zoom(map,x0,y0,x,y,SET);
  548. X           if (grid)
  549. X              draw_grid(map,x0,y0,x,y);
  550. X           title[T_SIZE] = sprintf(dims,"%d x %d",W(map),H(map));
  551. X           Do_title(title);
  552. X           if (function)
  553. X              INVERT(T_OP);
  554. X           break;
  555. X        case 'f':            /* save file */
  556. X           if ((pntr=get_str("Enter file name:\n",mx,my,files,file_count))
  557. X                                  && *pntr) {
  558. X              if (write_icon(pntr,map) && strcmp(name,pntr)!=0) {
  559. X                 title[T_NAME] = strcpy(name,pntr);
  560. X                 Do_title(title);
  561. X                 if (function) INVERT(T_OP);
  562. X              
  563. X                 /* add new name to menu */
  564. X
  565. X                 for(i=0;i<file_count;i++)
  566. X                    if (strcmp(files[i].value,name)==0)
  567. X                       break;
  568. X                 if (i==file_count && file_count+1 < FILES) {
  569. X                    files[file_count].value = str_save(name,"");
  570. X                    files[file_count].action = str_save(name,"\r");
  571. X                    file_count++;
  572. X                    }
  573. X                 }
  574. X              }
  575. X           else {
  576. X              message(SETMSG,"No file saved");
  577. X              }
  578. X           break;
  579. X        case 'g':            /* get file */
  580. X           {
  581. X           pntr = get_str("Enter file name:\n",mx,my,files,file_count);
  582. X           if (pntr && *pntr && (new = read_icon(pntr,0))  != BIT_NULL) {
  583. X              bit_destroy(map);
  584. X              map=new;
  585. X              m_clear();
  586. X              code = get_scale(&x,&y,map);
  587. X              zoom(map,x0,y0,x,y,SET);
  588. X              title[T_SIZE] = sprintf(dims,"%d x %d",W(map),H(map));
  589. X              title[T_NAME] = strcpy(name,pntr);
  590. X              Do_title(title);
  591. X              if (grid)
  592. X                 draw_grid(map,x0,y0,x,y);
  593. X              }
  594. X           }
  595. X           break;
  596. X        case 'y':            /* yank file to buffer */
  597. X           pntr = get_str("Enter file name:\n",mx,my,files,file_count);
  598. X           if (pntr && *pntr && (new = read_icon(pntr,0))  != BIT_NULL) {
  599. X              if (yanked)
  600. X                 bit_destroy(yanked);
  601. X              yanked = new;
  602. X              new = BIT_NULL;
  603. X              message(SETMSG,sprintf(line,"Yanked %s (%d x %d)",
  604. X                      pntr,W(yanked),H(yanked)));
  605. X              if (function == YANK) {
  606. X                 INVERT(T_OP); 
  607. X                 function = 0;
  608. X                 }
  609. X              }
  610. X           else
  611. X              message(SETMSG,"Can'y yank file");
  612. X           break;
  613. X        case 'w':            /* reshape window to icon size  */
  614. X           code = Min(x,y);
  615. X           m_shapewindow(win_x,win_y,W(map)*code+GAP+2*border,
  616. X                        W(map)*code+2*font_high+GAP*3 + 2*border);
  617. X           m_sendme("S\r");
  618. X           break;
  619. X        case 'P':            /* set put mode  */
  620. X           code = *(line+1) - '0';
  621. X           if (code<0 || code > 9)
  622. X              code = 0;
  623. X           if (put != code) {
  624. X              put = code;
  625. X              title[T_FUNC]=functions[put].value;
  626. X              Do_title(title);
  627. X              INVERT(T_OP);
  628. X              }
  629. X           break;
  630. X        case 'F':            /* set option flags  */
  631. X           code = *(line+1) - '0';
  632. X
  633. X           if (code<0 || code > 9)
  634. X              break;
  635. X           if (code == PUT && !yanked)
  636. X              break;
  637. X
  638. X           if (code == function && function == PUT) {
  639. X              function = 0;
  640. X              title[T_FUNC] = modes[mode].value;
  641. X              }
  642. X           else if (code == function)
  643. X              function = 0;
  644. X           else {
  645. X              function = code;
  646. X              title[T_OP] = options[function-1].value;
  647. X              dprintf(stderr,"setting function =  %d\n",code);
  648. X              if (function == PUT)
  649. X                 title[T_FUNC]=functions[put].value;
  650. X              }
  651. X           Do_title(title);
  652. X           if (function)
  653. X              INVERT(T_OP);
  654. X           break;
  655. X        case 'u':            /* undo */
  656. X           if (!last)
  657. X              break;
  658. X
  659. X           /* get ready to undo the undo */
  660. X
  661. X           temp = map;
  662. X           map = last;
  663. X           last = temp;
  664. X
  665. X           /* make changes in situ */
  666. X
  667. X           if (W(last)==W(map) && H(last)==H(map)) {
  668. X              temp = bit_alloc(W(map),H(map),BIT_NULL,1);
  669. X              bit_blit(temp,0,0,W(map),H(map),BIT_SRC,map,0,0);
  670. X              bit_blit(temp,0,0,W(map),H(map),BIT_SRC^BIT_DST,last,0,0);
  671. X              zoom(temp,x0,y0,x,y,SET);
  672. X              bit_destroy(temp);
  673. X              }
  674. X
  675. X           /* redoit all */
  676. X
  677. X           else {
  678. X              get_scale(&x,&y,map);
  679. X              m_clear();
  680. X              zoom(map,x0,y0,x,y,SET);
  681. X              if (grid)
  682. X                 draw_grid(map,x0,y0,x,y);
  683. X              title[T_SIZE] = sprintf(dims,"%d x %d", W(map),H(map));
  684. X              Do_title(title);
  685. X              }
  686. X           break;
  687. X        case 'M':            /* move */
  688. X           get_size(&win_x,&win_y,0,0);
  689. X           break;
  690. X        case 'R':            /* redraw */
  691. X           m_clear();
  692. X           zoom(map,x0,y0,x,y,SET);
  693. X           Do_title(title);
  694. X           if (grid)
  695. X              draw_grid(map,x0,y0,x,y);
  696. X           if (function)
  697. X              INVERT(T_OP);
  698. X           break;
  699. X        case 'S':            /* reshape */
  700. X              {
  701. X              int lastx = x;
  702. X              int lasty = y;
  703. X
  704. X              get_font(&font_wide, &font_high);
  705. X              code = get_scale(&x,&y,map);
  706. X              if (code>0 || lastx != x || lasty != y) {
  707. X                 m_clear();
  708. X                 zoom(map,x0,y0,x,y,SET);
  709. X                 if (grid)
  710. X                    draw_grid(map,x0,y0,x,y);
  711. X                 }
  712. X              Do_title(title);
  713. X              if (function)
  714. X                 INVERT(T_OP);
  715. X              }
  716. X              break;
  717. X        case 'Q':            /* quit */
  718. X           done++;
  719. X           m_gets(line);        /* eat the "$" */
  720. X           break;
  721. X        case 'x':            /* toggle grid */
  722. X           draw_grid(map,x0,y0,x,y);
  723. X           grid = 1-grid;
  724. X           break;
  725. X        default:
  726. X           break;
  727. X        }
  728. X     m_flush();
  729. X     }
  730. X   clean(0);
  731. X   }
  732. X
  733. X/* grid a bitmap onto the window */
  734. X
  735. Xint
  736. Xdraw_grid(map,x,y,x_scale,y_scale)
  737. Xregister BITMAP *map;        /* bitmap to zoom */
  738. Xint x,y;            /* screen location to start */
  739. Xint x_scale, y_scale;        /* scale factors (>1) */
  740. X   {
  741. X   register int sx,sy,dx,dy;    /* current src, dst coords */
  742. X
  743. X   for(dy=y,sy=0;sy<H(map);sy++,dy+=y_scale)
  744. X            m_bitwrite(x,dy,W(map)*x_scale,1);
  745. X   for(dx=x,sx=0;sx<W(map);sx++,dx+=x_scale)
  746. X            m_bitwrite(dx,y,1,H(map)*y_scale);
  747. X   } 
  748. X
  749. X/* zoom a bitmap onto the window */
  750. X
  751. X#define X_ON(x)    (x != -1)
  752. X
  753. Xint
  754. Xzoom(map,x,y,x_scale,y_scale,how)
  755. Xregister BITMAP *map;        /* bitmap to zoom */
  756. Xint x,y;            /* screen location to start */
  757. Xint x_scale, y_scale;        /* scale factors (>1) */
  758. Xint how;            /* 1==on bits  0==off bits */
  759. X   {
  760. X   register int sx,sy,dx,dy;    /* current src, dst coords */
  761. X   int on, count=0, set_x;
  762. X
  763. X   for(dy=y,sy=0;sy<H(map);sy++,dy+=y_scale) {
  764. X      for(count=0,dx=x,sx=0;sx<W(map);sx++,dx+=x_scale) {
  765. X         on = how==SET ? (bit_on(map,sx,sy)) : !(bit_on(map,sx,sy));
  766. X         if (on && count)
  767. X            count ++;
  768. X         else if (on) {
  769. X            count++;
  770. X            set_x = dx;
  771. X            }
  772. X         else if (count) {
  773. X            m_bitwrite(set_x,dy,count * x_scale,y_scale);
  774. X            count = 0;
  775. X            }
  776. X         }
  777. X      if (count)
  778. X         m_bitwrite(set_x,dy,count * x_scale,y_scale);
  779. X      }
  780. X   } 
  781. X
  782. X
  783. Xint
  784. Xclean(n)
  785. Xint n;
  786. X   {
  787. X   m_moveprint(0,win_high,"done...");
  788. X   m_popall();
  789. X   m_ttyreset();
  790. X   exit(n);
  791. X   }
  792. X
  793. Xmessage(how,s)
  794. Xint how;
  795. Xchar *s;
  796. X   {
  797. X   alarm(0);
  798. X   if (how==SETMSG) {
  799. X      m_moveprint(0,win_high,s);
  800. X      m_flush();
  801. X      dprintf(stderr,"Setting message [%s]\n",s);
  802. X      alarm(SLEEP);
  803. X      }
  804. X   else {
  805. X      m_movecursor(0,win_high);
  806. X      dprintf(stderr,"clearing message\n");
  807. X      }
  808. X   m_cleareol();
  809. X   m_movecursor(win_wide,win_high);
  810. X   m_flush();
  811. X   }
  812. X
  813. Xint Do_title(args)
  814. Xchar **args;
  815. X   {
  816. X   register int i, count;
  817. X   int len[MAXMARK];        /* label sizes */
  818. X   int sum;            /* total label width */
  819. X   int x = 0;            /* starting label position */
  820. X   int y = font_high;        /* starting label position */
  821. X   register char **label=args;
  822. X
  823. X   SET_FUNC(B_SET);
  824. X   m_movecursor(0,y);
  825. X   m_cleareol();
  826. X
  827. X   for(sum=count=0;*label;count++,label++)
  828. X      sum += (len[count] = strlen(*label) * font_wide + GAP);
  829. X   for(i=0;i<count;i++) {
  830. X      marks[i] = MARK(i-1) + len[i] * win_wide / sum;
  831. X      if (i+1 == count)
  832. X         marks[i] = win_wide;        /* fix rounding error */
  833. X      dprintf(stderr,"%s (%d)at %d=>%d ",
  834. X              args[i],len[i],MARK(i-1),MARK(i));
  835. X      if (MARK(i) - MARK(i-1) > len[i])
  836. X         m_moveprint((MARK(i)+MARK(i-1)- len[i])/2,y,args[i]);
  837. X      m_bitwrite(marks[i],0,GAP,y);
  838. X      }
  839. X   dprintf(stderr,"(%d)\n",win_wide);
  840. X
  841. X   m_bitwrite(0,y,win_wide,GAP);
  842. X   m_movecursor(win_wide+font_wide,y);
  843. X   SET_FUNC(B_INVERT);
  844. X   
  845. X   return(count);
  846. X   }
  847. X
  848. X/* get a user string */
  849. X
  850. X
  851. Xchar *
  852. Xget_str(s,x,y,menu,count)
  853. Xchar *s;            /* text to display */
  854. Xint x,y;            /* center of window */
  855. Xstruct menu_entry *menu;    /* menu to down load */
  856. Xint count;            /* # of menu items */
  857. X   {
  858. X   static char input[128];
  859. X   int wide = Max(15,strlen(s)) * font_wide + 2*border;
  860. X   int high = 2*(font_high + border);
  861. X   int x0 = win_x + x - wide/2;
  862. X   int y0 = win_y + y + font_high;
  863. X   int win;
  864. X   char *pntr, *index();
  865. X
  866. X   if (x0<0)
  867. X      x0 = GAP;
  868. X   if (x0+wide > xmax)
  869. X      x0 = xmax-wide-GAP;
  870. X   if (y0+high > ymax)
  871. X      y0 = ymax-high-GAP;
  872. X
  873. X   dprintf(stderr,"Making %d,%d %dx%d\n",x0,y0,wide,high);
  874. X   message(SIGALRM);        /* turn of any pending message */
  875. X
  876. X   m_newwin(x0,y0,wide,high);
  877. X   m_flush();
  878. X   m_gets(input);
  879. X   if (*input == '$') {        /* button already let go */
  880. X      dprintf(stderr,"$ in makewin\n");
  881. X      m_gets(input);
  882. X      }
  883. X
  884. X   dprintf(stderr,"makewin returns %s",input);
  885. X   win = atoi(input);
  886. X   dprintf(stderr,"Created %d\n",win);
  887. X
  888. X   *input = '\0';
  889. X   if (win) {
  890. X      m_selectwin(win);
  891. X      m_setevent(DEACTIVATED,"\r");
  892. X      m_setevent(DESTROY,"\r");
  893. X      m_setevent(RESHAPE,"\r");
  894. X      m_setevent(BUTTON_1,"%n\r");
  895. X      m_setevent(ACCEPT,"%m\r");
  896. X      if (count > 0) {
  897. X         menu_load(1,count,menu);
  898. X         m_selectmenu(1);
  899. X         }
  900. X      m_printstr(s);
  901. X      dprintf(stderr,"prompt: %s ...",s);
  902. X      fflush(stderr);
  903. X      m_flush();
  904. X      m_ttyreset();
  905. X      m_gets(input);
  906. X
  907. X      pntr = input;
  908. X      if (pntr=index(input,' '))
  909. X         *pntr='\0';
  910. X      if (pntr=index(input,'\n'))
  911. X         *pntr='\0';
  912. X
  913. X      m_ttyset();
  914. X      dprintf(stderr,"Got: %s\n",input); fflush(stderr);
  915. X      m_selectwin(0);
  916. X      m_destroywin(win);
  917. X      m_flush();
  918. X      } 
  919. X   else
  920. X      message(SETMSG,"Sorry, Can't make prompt window");
  921. X   return(input);
  922. X   }
  923. X
  924. X/* read in icon */ 
  925. X
  926. XBITMAP *
  927. Xread_icon(name)
  928. Xchar *name;                /* name of icon file */
  929. X   {
  930. X   FILE *fp;                /* fp to read bitmap from */
  931. X   BITMAP *map, *bitmapread();
  932. X   char tmp[100];
  933. X
  934. X   if ((fp = fopen(name,"r")) == NULL ) {
  935. X      message(SETMSG,sprintf(tmp,"Can't find %s",name));
  936. X      return(BIT_NULL);
  937. X      }
  938. X
  939. X   if( !( map = bitmapread(fp) ) ) {
  940. X      fclose(fp);
  941. X      message(SETMSG,sprintf(tmp,"%s is not an icon or is damaged",name));
  942. X      return(BIT_NULL);
  943. X      }
  944. X
  945. X   fclose(fp);
  946. X   return(map);
  947. X   }
  948. X
  949. Xint
  950. Xget_scale(x,y,map)
  951. Xregister int *x, *y;
  952. XBITMAP *map;
  953. X   {
  954. X   char line[256];
  955. X   int w = W(map);
  956. X   int h = H(map);
  957. X   int count;
  958. X
  959. X   for(count=0;;count++) {
  960. X      get_size(&win_x,&win_y,&win_wide,&win_high);
  961. X      *x = (win_wide - x0)/w;
  962. X      *y = (win_high - y0 - font_high)/h;
  963. X      if (*x>=1 && *y>=1) 
  964. X         break;
  965. X      m_clear();
  966. X      m_clearmode(M_NOWRAP);
  967. X      m_printstr("Window is too small\n");
  968. X      m_gets(line); 
  969. X      }
  970. X   if (count)
  971. X      m_setmode(M_NOWRAP);
  972. X   return(count);
  973. X   }
  974. X
  975. X
  976. Xint
  977. Xwrite_icon(name,map)
  978. Xchar *name;
  979. XBITMAP *map;
  980. X   {
  981. X   FILE *fp = fopen(name,"w");
  982. X   char tmp[100];
  983. X
  984. X   if (fp == NULL  ||  !bitmapwrite(fp,map)) {
  985. X      dprintf(stderr,"Can't write file %s\n",name);
  986. X      message(SETMSG,sprintf(tmp,"Can't write file %s",name));
  987. X      return(0);
  988. X      }
  989. X   fclose(fp);
  990. X   return(1);
  991. X   }
  992. X
  993. X/* do mode to bit, fix up display */
  994. X
  995. Xint
  996. Xdo_bit(map,x,y,bitx,bity,mode)
  997. XBITMAP *map;
  998. Xint x,y;        /* scale factors */
  999. Xint bitx,bity;        /* bit to do */
  1000. Xint mode;        /* SET, CLEAR, or TOGGLE */
  1001. X   {
  1002. X   int state = bit_on(map,bitx,bity) ? ON : OFF;
  1003. X   switch(mode | state) {
  1004. X      case TOGGLE | OFF:
  1005. X      case TOGGLE | ON:
  1006. X      case SET | OFF:
  1007. X      case CLEAR | ON:
  1008. X         bit_point(map,bitx,bity,BIT_NOT(BIT_DST));
  1009. X         m_bitwrite(x0+bitx*x,y0+bity*y,x,y);
  1010. X         dprintf(stderr,"toggle (%d)\n",mode|state);
  1011. X         break;
  1012. X      }
  1013. X   }
  1014. X
  1015. X/* save map for undo */
  1016. X
  1017. XBITMAP *
  1018. Xset_undo(last,map)
  1019. XBITMAP *last, *map;
  1020. X   {
  1021. X   if (!last)
  1022. X      last = bit_alloc(W(map),H(map),BIT_NULL,1);
  1023. X   else if (W(last)!=W(map) || H(last)!=H(map)) {
  1024. X      bit_destroy(last);
  1025. X      last = bit_alloc(W(map),H(map),BIT_NULL,1);
  1026. X      }
  1027. X   bit_blit(last,0,0,W(last),H(last),BIT_SRC,map,0,0);
  1028. X   return(last);
  1029. X   }
  1030. X
  1031. X/* alloc and save space for the concatenation of s1 and s2 */
  1032. X
  1033. Xchar *str_save(s1,s2)
  1034. Xchar *s1, *s2;
  1035. X   {
  1036. X   char *malloc();
  1037. X   char *result;
  1038. X
  1039. X   if ((result = malloc(strlen(s1) + strlen(s2) + 1)) == NULL) {
  1040. X      fprintf(stderr,"Malloc failed\n");
  1041. X      clean(1);  
  1042. X      }
  1043. X
  1044. X   strcpy(result,s1);
  1045. X   strcat(result,s2);
  1046. X   return(result);
  1047. X   }
  1048. END_OF_FILE
  1049. # end of 'demo/icon/zoom.c'
  1050. fi
  1051. echo shar: End of archive 46 \(of 61\).
  1052. cp /dev/null ark46isdone
  1053. MISSING=""
  1054. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 \
  1055.     21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 \
  1056.     38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 \
  1057.     55 56 57 58 59 60 61 ; do
  1058.     if test ! -f ark${I}isdone ; then
  1059.     MISSING="${MISSING} ${I}"
  1060.     fi
  1061. done
  1062. if test "${MISSING}" = "" ; then
  1063.     echo You have unpacked all 61 archives.
  1064.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1065. else
  1066.     echo You still need to unpack the following archives:
  1067.     echo "        " ${MISSING}
  1068. fi
  1069. ##  End of shell archive.
  1070. exit 0
  1071.