home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / x / volume19 / xfig / part16 < prev    next >
Encoding:
Text File  |  1993-05-26  |  56.1 KB  |  1,923 lines

  1. Newsgroups: comp.sources.x
  2. From: envbvs@epb9.lbl.gov (Brian V. Smith)
  3. Subject: v19i128:  xfig - Draw amd manipulate objects in an X-Window, Part16/27
  4. Message-ID: <1993May21.021612.6699@sparky.imd.sterling.com>
  5. X-Md4-Signature: e6f62b323df83edec580a78cd74c4d96
  6. Sender: chris@sparky.imd.sterling.com (Chris Olson)
  7. Organization: Sterling Software
  8. Date: Fri, 21 May 1993 02:16:12 GMT
  9. Approved: chris@sparky.imd.sterling.com
  10.  
  11. Submitted-by: envbvs@epb9.lbl.gov (Brian V. Smith)
  12. Posting-number: Volume 19, Issue 128
  13. Archive-name: xfig/part16
  14. Environment: X11
  15. Supersedes: xfig: Volume 16, Issue 6-30,39
  16.  
  17. #! /bin/sh
  18. # This is a shell archive.  Remove anything before this line, then unpack
  19. # it by saving it into a file and typing "sh file".  To overwrite existing
  20. # files, type "sh file -c".  You can also feed this as standard input via
  21. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  22. # will see the following message at the end:
  23. #        "End of archive 16 (of 27)."
  24. # Contents:  e_scale.c main.c
  25. # Wrapped by envbvs@epb9.lbl.gov.lbl.gov on Mon May  3 12:06:00 1993
  26. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  27. if test -f 'e_scale.c' -a "${1}" != "-c" ; then 
  28.   echo shar: Will not clobber existing file \"'e_scale.c'\"
  29. else
  30. echo shar: Extracting \"'e_scale.c'\" \(26235 characters\)
  31. sed "s/^X//" >'e_scale.c' <<'END_OF_FILE'
  32. X/*
  33. X * FIG : Facility for Interactive Generation of figures
  34. X * Copyright (c) 1985 by Supoj Sutanthavibul
  35. X *
  36. X * "Permission to use, copy, modify, distribute, and sell this software and its
  37. X * documentation for any purpose is hereby granted without fee, provided that
  38. X * the above copyright notice appear in all copies and that both the copyright
  39. X * notice and this permission notice appear in supporting documentation. 
  40. X * No representations are made about the suitability of this software for 
  41. X * any purpose.  It is provided "as is" without express or implied warranty."
  42. X */
  43. X
  44. X#include "fig.h"
  45. X#include "resources.h"
  46. X#include "mode.h"
  47. X#include "object.h"
  48. X#include "paintop.h"
  49. X#include "u_create.h"
  50. X#include "u_draw.h"
  51. X#include "u_elastic.h"
  52. X#include "u_search.h"
  53. X#include "u_undo.h"
  54. X#include "w_canvas.h"
  55. X#include "w_mousefun.h"
  56. X
  57. Xstatic int    init_box_scale();
  58. Xstatic Boolean    init_boxscale_ellipse();
  59. Xstatic Boolean    init_boxscale_line();
  60. Xstatic Boolean    init_boxscale_compound();
  61. Xstatic int    assign_newboxpoint();
  62. Xstatic int    boxrelocate_ellipsepoint();
  63. X
  64. Xstatic int    init_center_scale();
  65. Xstatic int    init_scale_arc();
  66. Xstatic int    init_scale_compound();
  67. Xstatic int    init_scale_ellipse();
  68. Xstatic int    init_scale_line();
  69. Xstatic int    init_scale_spline();
  70. Xstatic int    rescale_points();
  71. Xstatic int    relocate_ellipsepoint();
  72. Xstatic int    relocate_arcpoint();
  73. X
  74. Xstatic int    fix_scale_arc();
  75. Xstatic int    fix_scale_spline();
  76. Xstatic int    fix_scale_line();
  77. Xstatic int    fix_scale_ellipse();
  78. Xstatic int    fix_boxscale_ellipse();
  79. Xstatic int    fix_boxscale_line();
  80. Xstatic int    fix_scale_compound();
  81. Xstatic int    fix_boxscale_compound();
  82. X
  83. Xstatic int    cancel_scale_arc();
  84. Xstatic int    cancel_scale_spline();
  85. Xstatic int    cancel_scale_line();
  86. Xstatic int    cancel_scale_ellipse();
  87. Xstatic int    cancel_boxscale_ellipse();
  88. Xstatic int    cancel_boxscale_line();
  89. Xstatic int    cancel_scale_compound();
  90. Xstatic int    cancel_boxscale_compound();
  91. Xstatic int    prescale_compound();
  92. X
  93. Xscale_selected()
  94. X{
  95. X    set_mousefun("scale box", "scale about center", "");
  96. X    canvas_kbd_proc = null_proc;
  97. X    canvas_locmove_proc = null_proc;
  98. X    init_searchproc_left(init_box_scale);
  99. X    init_searchproc_middle(init_center_scale);
  100. X    canvas_leftbut_proc = object_search_left;
  101. X    canvas_middlebut_proc = object_search_middle;
  102. X    canvas_rightbut_proc = null_proc;
  103. X    set_cursor(pick15_cursor);
  104. X    reset_action_on();
  105. X}
  106. X
  107. Xstatic
  108. Xinit_box_scale(obj, type, x, y, px, py)
  109. X    char       *obj;
  110. X    int            type, x, y;
  111. X    int            px, py;
  112. X{
  113. X    switch (type) {
  114. X    case O_POLYLINE:
  115. X    cur_l = (F_line *) obj;
  116. X    if (!init_boxscale_line(px, py))    /* non-box line */
  117. X        return;
  118. X    break;
  119. X    case O_ELLIPSE:
  120. X    cur_e = (F_ellipse *) obj;
  121. X    if (!init_boxscale_ellipse(px, py))    /* selected center, ignore */
  122. X        return;
  123. X    break;
  124. X    case O_COMPOUND:
  125. X    cur_c = (F_compound *) obj;
  126. X    if (!init_boxscale_compound(px, py))    /* non-box compound */
  127. X        return;
  128. X    break;
  129. X    default:
  130. X    return;
  131. X    }
  132. X    set_mousefun("new posn", "", "cancel");
  133. X    draw_mousefun_canvas();
  134. X    canvas_middlebut_proc = null_proc;
  135. X}
  136. X
  137. Xstatic
  138. Xinit_center_scale(obj, type, x, y, px, py)
  139. X    char       *obj;
  140. X    int            type, x, y, px, py;
  141. X{
  142. X    double        dx, dy, l;
  143. X
  144. X    cur_x = from_x = px;
  145. X    cur_y = from_y = py;
  146. X    constrained = BOX_SCALE;
  147. X    switch (type) {
  148. X    case O_POLYLINE:
  149. X    cur_l = (F_line *) obj;
  150. X    if (!init_scale_line()) /* selected center */
  151. X        return;
  152. X    break;
  153. X    case O_SPLINE:
  154. X    cur_s = (F_spline *) obj;
  155. X    if (!init_scale_spline())    /* selected center */
  156. X        return;
  157. X    break;
  158. X    case O_ELLIPSE:
  159. X    cur_e = (F_ellipse *) obj;
  160. X    if (!init_scale_ellipse())    /* selected center */
  161. X        return;
  162. X    break;
  163. X    case O_ARC:
  164. X    cur_a = (F_arc *) obj;
  165. X    if (!init_scale_arc())    /* selected center */
  166. X        return;
  167. X    break;
  168. X    case O_COMPOUND:
  169. X    cur_c = (F_compound *) obj;
  170. X    init_scale_compound();
  171. X    break;
  172. X    }
  173. X
  174. X    dx = (double) (from_x - fix_x);
  175. X    dy = (double) (from_y - fix_y);
  176. X    l = sqrt(dx * dx + dy * dy);
  177. X    cosa = fabs(dx / l);
  178. X    sina = fabs(dy / l);
  179. X
  180. X    set_mousefun("", "new posn", "cancel");
  181. X    draw_mousefun_canvas();
  182. X    canvas_leftbut_proc = null_proc;
  183. X}
  184. X
  185. Xstatic
  186. Xwrapup_scale()
  187. X{
  188. X    reset_action_on();
  189. X    scale_selected();
  190. X    draw_mousefun_canvas();
  191. X}
  192. X
  193. X/*************************  ellipse  *******************************/
  194. X
  195. Xstatic        Boolean
  196. Xinit_boxscale_ellipse(x, y)
  197. X    int            x, y;
  198. X{
  199. X    double        dx, dy, l;
  200. X
  201. X    if (cur_e->type == T_ELLIPSE_BY_RAD ||
  202. X    cur_e->type == T_CIRCLE_BY_RAD) {
  203. X    put_msg("Can't use box scale on selected object");
  204. X    return False;
  205. X    }
  206. X    if (x == cur_e->start.x && y == cur_e->start.y) {
  207. X    fix_x = cur_e->end.x;
  208. X    fix_y = cur_e->end.y;
  209. X    cur_x = from_x = x;
  210. X    cur_y = from_y = y;
  211. X    } else if (x == cur_e->end.x && y == cur_e->end.y) {
  212. X    fix_x = cur_e->start.x;
  213. X    fix_y = cur_e->start.y;
  214. X    cur_x = from_x = x;
  215. X    cur_y = from_y = y;
  216. X    } else {
  217. X    put_msg("Can't use box scale on selected object");
  218. X    return False;
  219. X    }
  220. X    cur_angle = cur_e->angle;
  221. X
  222. X    if (cur_x == fix_x || cur_y == fix_y) {
  223. X    put_msg("Can't use box scale on selected object");
  224. X    return False;
  225. X    }
  226. X    set_action_on();
  227. X    toggle_ellipsemarker(cur_e);
  228. X    constrained = BOX_SCALE;
  229. X    dx = (double) (cur_x - fix_x);
  230. X    dy = (double) (cur_y - fix_y);
  231. X    l = sqrt(dx * dx + dy * dy);
  232. X    cosa = fabs(dx / l);
  233. X    sina = fabs(dy / l);
  234. X
  235. X    set_temp_cursor(crosshair_cursor);
  236. X    if (cur_e->type == T_CIRCLE_BY_DIA) {
  237. X    canvas_locmove_proc = constrained_resizing_cbd;
  238. X    elastic_cbd();
  239. X    } else {
  240. X    canvas_locmove_proc = constrained_resizing_ebd;
  241. X    elastic_ebd();
  242. X    }
  243. X    canvas_leftbut_proc = fix_boxscale_ellipse;
  244. X    canvas_rightbut_proc = cancel_boxscale_ellipse;
  245. X    return True;
  246. X}
  247. X
  248. Xstatic
  249. Xcancel_boxscale_ellipse()
  250. X{
  251. X    if (cur_e->type == T_CIRCLE_BY_DIA)
  252. X    elastic_cbd();
  253. X    else
  254. X    elastic_ebd();
  255. X    toggle_ellipsemarker(cur_e);
  256. X    wrapup_scale();
  257. X}
  258. X
  259. Xstatic
  260. Xfix_boxscale_ellipse(x, y)
  261. X    int            x, y;
  262. X{
  263. X    if (cur_e->type == T_CIRCLE_BY_DIA)
  264. X    elastic_cbd();
  265. X    else
  266. X    elastic_ebd();
  267. X    adjust_box_pos(x, y, from_x, from_y, &cur_x, &cur_y);
  268. X    new_e = copy_ellipse(cur_e);
  269. X    boxrelocate_ellipsepoint(new_e, cur_x, cur_y);
  270. X    change_ellipse(cur_e, new_e);
  271. X    toggle_ellipsemarker(new_e);
  272. X    wrapup_scale();
  273. X}
  274. X
  275. Xstatic
  276. Xboxrelocate_ellipsepoint(ellipse, x, y)
  277. X    F_ellipse       *ellipse;
  278. X    int            x, y;
  279. X{
  280. X    int            dx, dy;
  281. X
  282. X    set_temp_cursor(wait_cursor);
  283. X    draw_ellipse(ellipse, ERASE);
  284. X    if (ellipse->start.x == fix_x)
  285. X    ellipse->end.x = x;
  286. X    if (ellipse->start.y == fix_y)
  287. X    ellipse->end.y = y;
  288. X    if (ellipse->end.x == fix_x)
  289. X    ellipse->start.x = x;
  290. X    if (ellipse->end.y == fix_y)
  291. X    ellipse->start.y = y;
  292. X    if (ellipse->type == T_CIRCLE_BY_DIA) {
  293. X    dx = ellipse->center.x = (fix_x + x) / 2 + .5;
  294. X    dy = ellipse->center.y = (fix_y + y) / 2 + .5;
  295. X    dx -= x;
  296. X    dy -= y;
  297. X    ellipse->radiuses.x = sqrt((double) (dx * dx + dy * dy)) + .5;
  298. X    ellipse->radiuses.y = ellipse->radiuses.x;
  299. X    } else {
  300. X    ellipse->center.x = (fix_x + x) / 2;
  301. X    ellipse->center.y = (fix_y + y) / 2;
  302. X    ellipse->radiuses.x = abs(ellipse->center.x - fix_x);
  303. X    ellipse->radiuses.y = abs(ellipse->center.y - fix_y);
  304. X    }
  305. X    draw_ellipse(ellipse, PAINT);
  306. X    reset_cursor();
  307. X}
  308. X
  309. Xstatic
  310. Xinit_scale_ellipse()
  311. X{
  312. X    fix_x = cur_e->center.x;
  313. X    fix_y = cur_e->center.y;
  314. X    cur_angle = cur_e->angle;
  315. X    if (from_x == fix_x && from_y == fix_y) {
  316. X    put_msg("Center point selected, ignored");
  317. X    return False;
  318. X    }
  319. X    set_action_on();
  320. X    toggle_ellipsemarker(cur_e);
  321. X    set_temp_cursor(crosshair_cursor);
  322. X    canvas_locmove_proc = scaling_ellipse;
  323. X    elastic_scaleellipse(cur_e);
  324. X    canvas_middlebut_proc = fix_scale_ellipse;
  325. X    canvas_rightbut_proc = cancel_scale_ellipse;
  326. X    return True;        /* all is Ok */
  327. X}
  328. X
  329. Xstatic
  330. Xcancel_scale_ellipse()
  331. X{
  332. X    elastic_scaleellipse(cur_e);
  333. X    toggle_ellipsemarker(cur_e);
  334. X    wrapup_scale();
  335. X}
  336. X
  337. Xstatic
  338. Xfix_scale_ellipse(x, y)
  339. X    int            x, y;
  340. X{
  341. X    elastic_scaleellipse(cur_e);
  342. X    adjust_box_pos(x, y, from_x, from_y, &cur_x, &cur_y);
  343. X    new_e = copy_ellipse(cur_e);
  344. X    relocate_ellipsepoint(new_e, cur_x, cur_y);
  345. X    change_ellipse(cur_e, new_e);
  346. X    toggle_ellipsemarker(new_e);
  347. X    wrapup_scale();
  348. X}
  349. X
  350. Xstatic
  351. Xrelocate_ellipsepoint(ellipse, x, y)
  352. X    F_ellipse       *ellipse;
  353. X    int            x, y;
  354. X{
  355. X    int            newx, newy, oldx, oldy;
  356. X    float        newd, oldd, scalefact;
  357. X
  358. X    set_temp_cursor(wait_cursor);
  359. X    draw_ellipse(ellipse, ERASE);
  360. X
  361. X    newx = x - fix_x;
  362. X    newy = y - fix_y;
  363. X    newd = sqrt((double) (newx * newx + newy * newy));
  364. X    oldx = from_x - fix_x;
  365. X    oldy = from_y - fix_y;
  366. X    oldd = sqrt((double) (oldx * oldx + oldy * oldy));
  367. X    scalefact = newd / oldd;
  368. X
  369. X    ellipse->radiuses.x = ellipse->radiuses.x * scalefact;
  370. X    ellipse->radiuses.y = ellipse->radiuses.y * scalefact;
  371. X    ellipse->end.x = fix_x + (ellipse->end.x - fix_x) * scalefact;
  372. X    ellipse->end.y = fix_y + (ellipse->end.y - fix_y) * scalefact;
  373. X    ellipse->start.x = fix_x + (ellipse->start.x - fix_x) * scalefact;
  374. X    ellipse->start.y = fix_y + (ellipse->start.y - fix_y) * scalefact;
  375. X    draw_ellipse(ellipse, PAINT);
  376. X    reset_cursor();
  377. X}
  378. X
  379. X/***************************  arc  *********************************/
  380. X
  381. Xstatic
  382. Xinit_scale_arc()
  383. X{
  384. X    fix_x = cur_a->center.x;
  385. X    fix_y = cur_a->center.y;
  386. X    if (from_x == fix_x && from_y == fix_y) {
  387. X    put_msg("Center point selected, ignored");
  388. X    return False;
  389. X    }
  390. X    set_action_on();
  391. X    toggle_arcmarker(cur_a);
  392. X    elastic_scalearc(cur_a);
  393. X    set_temp_cursor(crosshair_cursor);
  394. X    canvas_locmove_proc = scaling_arc;
  395. X    canvas_middlebut_proc = fix_scale_arc;
  396. X    canvas_rightbut_proc = cancel_scale_arc;
  397. X    return True;
  398. X}
  399. X
  400. Xstatic
  401. Xcancel_scale_arc()
  402. X{
  403. X    elastic_scalearc(cur_a);
  404. X    toggle_arcmarker(cur_a);
  405. X    wrapup_scale();
  406. X}
  407. X
  408. Xstatic
  409. Xfix_scale_arc(x, y)
  410. X    int            x, y;
  411. X{
  412. X    elastic_scalearc(cur_a);
  413. X    adjust_box_pos(x, y, from_x, from_y, &x, &y);
  414. X    new_a = copy_arc(cur_a);
  415. X    relocate_arcpoint(new_a, x, y);
  416. X    change_arc(cur_a, new_a);
  417. X    toggle_arcmarker(new_a);
  418. X    wrapup_scale();
  419. X}
  420. X
  421. Xstatic
  422. Xrelocate_arcpoint(arc, x, y)
  423. X    F_arc       *arc;
  424. X    int            x, y;
  425. X{
  426. X    int            newx, newy, oldx, oldy;
  427. X    float        newd, oldd, scalefact, xx, yy;
  428. X    F_pos        p0, p1, p2;
  429. X
  430. X    newx = x - fix_x;
  431. X    newy = y - fix_y;
  432. X    newd = sqrt((double) (newx * newx + newy * newy));
  433. X
  434. X    oldx = from_x - fix_x;
  435. X    oldy = from_y - fix_y;
  436. X    oldd = sqrt((double) (oldx * oldx + oldy * oldy));
  437. X
  438. X    scalefact = newd / oldd;
  439. X
  440. X    p0 = arc->point[0];
  441. X    p1 = arc->point[1];
  442. X    p2 = arc->point[2];
  443. X    p0.x = fix_x + (p0.x - fix_x) * scalefact;
  444. X    p0.y = fix_y + (p0.y - fix_y) * scalefact;
  445. X    p1.x = fix_x + (p1.x - fix_x) * scalefact;
  446. X    p1.y = fix_y + (p1.y - fix_y) * scalefact;
  447. X    p2.x = fix_x + (p2.x - fix_x) * scalefact;
  448. X    p2.y = fix_y + (p2.y - fix_y) * scalefact;
  449. X    if (compute_arccenter(p0, p1, p2, &xx, &yy)) {
  450. X    set_temp_cursor(wait_cursor);
  451. X    draw_arc(arc, ERASE);    /* erase old arc */
  452. X    arc->point[0].x = p0.x;
  453. X    arc->point[0].y = p0.y;
  454. X    arc->point[1].x = p1.x;
  455. X    arc->point[1].y = p1.y;
  456. X    arc->point[2].x = p2.x;
  457. X    arc->point[2].y = p2.y;
  458. X    arc->center.x = xx;
  459. X    arc->center.y = yy;
  460. X    arc->direction = compute_direction(p0, p1, p2);
  461. X    draw_arc(arc, PAINT);    /* draw new arc */
  462. X    reset_cursor();
  463. X    }
  464. X    set_modifiedflag();
  465. X}
  466. X
  467. X/**************************  spline  *******************************/
  468. X
  469. Xstatic
  470. Xinit_scale_spline()
  471. X{
  472. X    int            sumx, sumy, cnt;
  473. X    F_point       *p;
  474. X
  475. X    p = cur_s->points;
  476. X    if (closed_spline(cur_s))
  477. X    p = p->next;
  478. X    for (sumx = 0, sumy = 0, cnt = 0; p != NULL; p = p->next) {
  479. X    sumx = sumx + p->x;
  480. X    sumy = sumy + p->y;
  481. X    cnt++;
  482. X    }
  483. X    fix_x = sumx / cnt;
  484. X    fix_y = sumy / cnt;
  485. X    if (from_x == fix_x && from_y == fix_y) {
  486. X    put_msg("Center point selected, ignored");
  487. X    return False;
  488. X    }
  489. X    set_action_on();
  490. X    set_temp_cursor(crosshair_cursor);
  491. X    toggle_splinemarker(cur_s);
  492. X    draw_spline(cur_s, ERASE);
  493. X    elastic_scalepts(cur_s->points);
  494. X    canvas_locmove_proc = scaling_spline;
  495. X    canvas_middlebut_proc = fix_scale_spline;
  496. X    canvas_rightbut_proc = cancel_scale_spline;
  497. X    return True;
  498. X}
  499. X
  500. Xstatic
  501. Xcancel_scale_spline()
  502. X{
  503. X    elastic_scalepts(cur_s->points);
  504. X    draw_spline(cur_s, PAINT);
  505. X    toggle_splinemarker(cur_s);
  506. X    wrapup_scale();
  507. X}
  508. X
  509. Xstatic
  510. Xfix_scale_spline(x, y)
  511. X    int            x, y;
  512. X{
  513. X    elastic_scalepts(cur_s->points);
  514. X    adjust_box_pos(x, y, from_x, from_y, &x, &y);
  515. X    /* make a copy of the original and save as unchanged object */
  516. X    old_s = copy_spline(cur_s);
  517. X    clean_up();
  518. X    set_latestspline(old_s);
  519. X    set_action_object(F_CHANGE, O_SPLINE);
  520. X    old_s->next = cur_s;
  521. X    /* now change the original to become the new object */
  522. X    rescale_points(cur_s->points, x, y);
  523. X    if (int_spline(cur_s))
  524. X    remake_control_points(cur_s);
  525. X    draw_spline(cur_s, PAINT);
  526. X    toggle_splinemarker(cur_s);
  527. X    wrapup_scale();
  528. X}
  529. X
  530. X/***************************  compound    ********************************/
  531. X
  532. Xstatic        Boolean
  533. Xinit_boxscale_compound(x, y)
  534. X    int            x, y;
  535. X{
  536. X    int            xmin, ymin, xmax, ymax;
  537. X    double        dx, dy, l;
  538. X
  539. X    xmin = min2(cur_c->secorner.x, cur_c->nwcorner.x);
  540. X    ymin = min2(cur_c->secorner.y, cur_c->nwcorner.y);
  541. X    xmax = max2(cur_c->secorner.x, cur_c->nwcorner.x);
  542. X    ymax = max2(cur_c->secorner.y, cur_c->nwcorner.y);
  543. X
  544. X    if (xmin == xmax || ymin == ymax) {
  545. X    put_msg("Can't use box scale on selected object");
  546. X    return False;
  547. X    }
  548. X    set_action_on();
  549. X    toggle_compoundmarker(cur_c);
  550. X    draw_compoundelements(cur_c, ERASE);
  551. X    set_temp_cursor(crosshair_cursor);
  552. X
  553. X    if (x == xmin) {
  554. X    fix_x = xmax;
  555. X    from_x = x;
  556. X    if (y == ymin) {
  557. X        fix_y = ymax;
  558. X        from_y = y;
  559. X        constrained = BOX_SCALE;
  560. X    } else if (y == ymax) {
  561. X        fix_y = ymin;
  562. X        from_y = y;
  563. X        constrained = BOX_SCALE;
  564. X    } else {
  565. X        fix_y = ymax;
  566. X        from_y = ymin;
  567. X        constrained = BOX_HSTRETCH;
  568. X    }
  569. X    } else if (x == xmax) {
  570. X    fix_x = xmin;
  571. X    from_x = x;
  572. X    if (y == ymin) {
  573. X        fix_y = ymax;
  574. X        from_y = y;
  575. X        constrained = BOX_SCALE;
  576. X    } else if (y == ymax) {
  577. X        fix_y = ymin;
  578. X        from_y = y;
  579. X        constrained = BOX_SCALE;
  580. X    } else {
  581. X        fix_y = ymax;
  582. X        from_y = ymin;
  583. X        constrained = BOX_HSTRETCH;
  584. X    }
  585. X    } else {
  586. X    if (y == ymin) {
  587. X        fix_y = ymax;
  588. X        from_y = y;
  589. X        fix_x = xmax;
  590. X        from_x = xmin;
  591. X        constrained = BOX_VSTRETCH;
  592. X    } else {        /* y == ymax */
  593. X        fix_y = ymin;
  594. X        from_y = y;
  595. X        fix_x = xmax;
  596. X        from_x = xmin;
  597. X        constrained = BOX_VSTRETCH;
  598. X    }
  599. X    }
  600. X
  601. X    cur_x = from_x;
  602. X    cur_y = from_y;
  603. X
  604. X    if (constrained == BOX_SCALE) {
  605. X    dx = (double) (cur_x - fix_x);
  606. X    dy = (double) (cur_y - fix_y);
  607. X    l = sqrt(dx * dx + dy * dy);
  608. X    cosa = fabs(dx / l);
  609. X    sina = fabs(dy / l);
  610. X    }
  611. X    elastic_box(fix_x, fix_y, cur_x, cur_y);
  612. X    canvas_locmove_proc = constrained_resizing_box;
  613. X    canvas_leftbut_proc = fix_boxscale_compound;
  614. X    canvas_rightbut_proc = cancel_boxscale_compound;
  615. X    return True;
  616. X}
  617. X
  618. Xstatic
  619. Xcancel_boxscale_compound()
  620. X{
  621. X    elastic_box(fix_x, fix_y, cur_x, cur_y);
  622. X    draw_compoundelements(cur_c, PAINT);
  623. X    toggle_compoundmarker(cur_c);
  624. X    wrapup_scale();
  625. X}
  626. X
  627. Xstatic
  628. Xfix_boxscale_compound(x, y)
  629. X    int            x, y;
  630. X{
  631. X    float        scalex, scaley;
  632. X
  633. X    elastic_box(fix_x, fix_y, cur_x, cur_y);
  634. X    adjust_box_pos(x, y, from_x, from_y, &x, &y);
  635. X    new_c = copy_compound(cur_c);
  636. X    scalex = ((float) (x - fix_x)) / (from_x - fix_x);
  637. X    scaley = ((float) (y - fix_y)) / (from_y - fix_y);
  638. X    scale_compound(new_c, scalex, scaley, fix_x, fix_y);
  639. X    change_compound(cur_c, new_c);
  640. X    draw_compoundelements(new_c, PAINT);
  641. X    toggle_compoundmarker(new_c);
  642. X    wrapup_scale();
  643. X}
  644. X
  645. Xstatic
  646. Xinit_scale_compound()
  647. X{
  648. X    fix_x = (cur_c->nwcorner.x + cur_c->secorner.x) / 2;
  649. X    fix_y = (cur_c->nwcorner.y + cur_c->secorner.y) / 2;
  650. X    set_action_on();
  651. X    toggle_compoundmarker(cur_c);
  652. X    set_temp_cursor(crosshair_cursor);
  653. X    draw_compoundelements(cur_c, ERASE);
  654. X    elastic_scalecompound(cur_c);
  655. X    canvas_locmove_proc = scaling_compound;
  656. X    canvas_middlebut_proc = fix_scale_compound;
  657. X    canvas_rightbut_proc = cancel_scale_compound;
  658. X}
  659. X
  660. Xstatic
  661. Xcancel_scale_compound()
  662. X{
  663. X    elastic_scalecompound(cur_c);
  664. X    draw_compoundelements(cur_c, PAINT);
  665. X    toggle_compoundmarker(cur_c);
  666. X    wrapup_scale();
  667. X}
  668. X
  669. Xstatic
  670. Xfix_scale_compound(x, y)
  671. X    int            x, y;
  672. X{
  673. X    elastic_scalecompound(cur_c);
  674. X    adjust_box_pos(x, y, from_x, from_y, &cur_x, &cur_y);
  675. X    /* make a copy of the original and save as unchanged object */
  676. X    old_c = copy_compound(cur_c);
  677. X    clean_up();
  678. X    set_latestcompound(old_c);
  679. X    set_action_object(F_CHANGE, O_COMPOUND);
  680. X    old_c->next = cur_c;
  681. X    /* now change the original to become the new object */
  682. X    prescale_compound(cur_c, cur_x, cur_y);
  683. X    draw_compoundelements(cur_c, PAINT);
  684. X    toggle_compoundmarker(cur_c);
  685. X    wrapup_scale();
  686. X}
  687. X
  688. Xstatic int
  689. Xprescale_compound(c, x, y)
  690. X    F_compound       *c;
  691. X    int            x, y;
  692. X{
  693. X    int            newx, newy, oldx, oldy;
  694. X    float        newd, oldd, scalefact;
  695. X
  696. X    newx = x - fix_x;
  697. X    newy = y - fix_y;
  698. X    newd = sqrt((double) (newx * newx + newy * newy));
  699. X    oldx = from_x - fix_x;
  700. X    oldy = from_y - fix_y;
  701. X    oldd = sqrt((double) (oldx * oldx + oldy * oldy));
  702. X    scalefact = newd / oldd;
  703. X    scale_compound(c, scalefact, scalefact, fix_x, fix_y);
  704. X}
  705. X
  706. Xscale_compound(c, sx, sy, refx, refy)
  707. X    F_compound       *c;
  708. X    float        sx, sy;
  709. X    int            refx, refy;
  710. X{
  711. X    F_line       *l;
  712. X    F_spline       *s;
  713. X    F_ellipse       *e;
  714. X    F_text       *t;
  715. X    F_arc       *a;
  716. X    F_compound       *c1;
  717. X    int            x1, y1, x2, y2;
  718. X
  719. X    x1 = round(refx + (c->nwcorner.x - refx) * sx);
  720. X    y1 = round(refy + (c->nwcorner.y - refy) * sy);
  721. X    x2 = round(refx + (c->secorner.x - refx) * sx);
  722. X    y2 = round(refy + (c->secorner.y - refy) * sy);
  723. X    c->nwcorner.x = min2(x1, x2);
  724. X    c->nwcorner.y = min2(y1, y2);
  725. X    c->secorner.x = max2(x1, x2);
  726. X    c->secorner.y = max2(y1, y2);
  727. X
  728. X    for (l = c->lines; l != NULL; l = l->next) {
  729. X    scale_line(l, sx, sy, refx, refy);
  730. X    }
  731. X    for (s = c->splines; s != NULL; s = s->next) {
  732. X    scale_spline(s, sx, sy, refx, refy);
  733. X    }
  734. X    for (a = c->arcs; a != NULL; a = a->next) {
  735. X    scale_arc(a, sx, sy, refx, refy);
  736. X    }
  737. X    for (e = c->ellipses; e != NULL; e = e->next) {
  738. X    scale_ellipse(e, sx, sy, refx, refy);
  739. X    }
  740. X    for (t = c->texts; t != NULL; t = t->next) {
  741. X    scale_text(t, sx, sy, refx, refy);
  742. X    }
  743. X    for (c1 = c->compounds; c1 != NULL; c1 = c1->next) {
  744. X    scale_compound(c1, sx, sy, refx, refy);
  745. X    }
  746. X}
  747. X
  748. Xscale_line(l, sx, sy, refx, refy)
  749. X    F_line       *l;
  750. X    float        sx, sy;
  751. X    int            refx, refy;
  752. X{
  753. X    F_point       *p;
  754. X
  755. X    for (p = l->points; p != NULL; p = p->next) {
  756. X    p->x = round(refx + (p->x - refx) * sx);
  757. X    p->y = round(refy + (p->y - refy) * sy);
  758. X    }
  759. X}
  760. X
  761. Xscale_spline(s, sx, sy, refx, refy)
  762. X    F_spline       *s;
  763. X    float        sx, sy;
  764. X    int            refx, refy;
  765. X{
  766. X    F_point       *p;
  767. X    F_control       *c;
  768. X
  769. X    for (p = s->points; p != NULL; p = p->next) {
  770. X    p->x = round(refx + (p->x - refx) * sx);
  771. X    p->y = round(refy + (p->y - refy) * sy);
  772. X    }
  773. X    for (c = s->controls; c != NULL; c = c->next) {
  774. X    c->lx = refx + (c->lx - refx) * sx;
  775. X    c->ly = refy + (c->ly - refy) * sy;
  776. X    c->rx = refx + (c->rx - refx) * sx;
  777. X    c->ry = refy + (c->ry - refy) * sy;
  778. X    }
  779. X}
  780. X
  781. Xscale_arc(a, sx, sy, refx, refy)
  782. X    F_arc       *a;
  783. X    float        sx, sy;
  784. X    int            refx, refy;
  785. X{
  786. X    int            i;
  787. X
  788. X    for (i = 0; i < 3; i++) {
  789. X    a->point[i].x = round(refx + (a->point[i].x - refx) * sx);
  790. X    a->point[i].y = round(refy + (a->point[i].y - refy) * sy);
  791. X    }
  792. X    compute_arccenter(a->point[0], a->point[1], a->point[2],
  793. X              &a->center.x, &a->center.y);
  794. X    a->direction = compute_direction(a->point[0], a->point[1], a->point[2]);
  795. X}
  796. X
  797. Xscale_ellipse(e, sx, sy, refx, refy)
  798. X    F_ellipse       *e;
  799. X    float        sx, sy;
  800. X    int            refx, refy;
  801. X{
  802. X    e->center.x = round(refx + (e->center.x - refx) * sx);
  803. X    e->center.y = round(refy + (e->center.y - refy) * sy);
  804. X    e->start.x = round(refx + (e->start.x - refx) * sx);
  805. X    e->start.y = round(refy + (e->start.y - refy) * sy);
  806. X    e->end.x = round(refx + (e->end.x - refx) * sx);
  807. X    e->end.y = round(refy + (e->end.y - refy) * sy);
  808. X    e->radiuses.x = abs(round(e->radiuses.x * sx));
  809. X    e->radiuses.y = abs(round(e->radiuses.y * sy));
  810. X    /* if this WAS a circle and is NOW an ellipse, change type to reflect */
  811. X    if (e->type == T_CIRCLE_BY_RAD || e->type == T_CIRCLE_BY_DIA) {
  812. X    if (e->radiuses.x != e->radiuses.y)
  813. X        e->type -= 2;
  814. X    }
  815. X    /* conversely, if this WAS an ellipse and is NOW a circle, change type */
  816. X    else if (e->type == T_ELLIPSE_BY_RAD || e->type == T_ELLIPSE_BY_DIA) {
  817. X    if (e->radiuses.x == e->radiuses.y)
  818. X        e->type += 2;
  819. X    }
  820. X}
  821. X
  822. Xscale_text(t, sx, sy, refx, refy)
  823. X    F_text       *t;
  824. X    float        sx, sy;
  825. X    int            refx, refy;
  826. X{
  827. X    t->base_x = round(refx + (t->base_x - refx) * sx);
  828. X    t->base_y = round(refy + (t->base_y - refy) * sy);
  829. X    if (!rigid_text(t)) {
  830. X    t->size = round(t->size * sx);
  831. X    t->height = round(t->height * sx);
  832. X    t->length = round(t->length * sx);
  833. X    }
  834. X    /* rescale font */
  835. X    reload_text_fstruct(t);
  836. X}
  837. X
  838. X
  839. X/***************************  line  ********************************/
  840. X
  841. Xstatic        Boolean
  842. Xinit_boxscale_line(x, y)
  843. X    int            x, y;
  844. X{
  845. X    int            xmin, ymin, xmax, ymax;
  846. X    F_point       *p0, *p1, *p2;
  847. X    double        dx, dy, l;
  848. X
  849. X    if (cur_l->type != T_BOX &&
  850. X    cur_l->type != T_ARC_BOX &&
  851. X    cur_l->type != T_EPS_BOX) {
  852. X    put_msg("Can't use box scale on selected object");
  853. X    return False;
  854. X    }
  855. X    p0 = cur_l->points;
  856. X    p1 = p0->next;
  857. X    p2 = p1->next;
  858. X    xmin = min3(p0->x, p1->x, p2->x);
  859. X    ymin = min3(p0->y, p1->y, p2->y);
  860. X    xmax = max3(p0->x, p1->x, p2->x);
  861. X    ymax = max3(p0->y, p1->y, p2->y);
  862. X
  863. X    if (xmin == xmax || ymin == ymax) {
  864. X    put_msg("Can't use box scale on selected object");
  865. X    return False;
  866. X    }
  867. X    set_action_on();
  868. X    toggle_linemarker(cur_l);
  869. X
  870. X    if (x == xmin) {
  871. X    fix_x = xmax;
  872. X    from_x = x;
  873. X    if (y == ymin) {
  874. X        fix_y = ymax;
  875. X        from_y = y;
  876. X        constrained = BOX_SCALE;
  877. X    } else if (y == ymax) {
  878. X        fix_y = ymin;
  879. X        from_y = y;
  880. X        constrained = BOX_SCALE;
  881. X    } else {
  882. X        fix_y = ymax;
  883. X        from_y = ymin;
  884. X        constrained = BOX_HSTRETCH;
  885. X    }
  886. X    } else if (x == xmax) {
  887. X    fix_x = xmin;
  888. X    from_x = x;
  889. X    if (y == ymin) {
  890. X        fix_y = ymax;
  891. X        from_y = y;
  892. X        constrained = BOX_SCALE;
  893. X    } else if (y == ymax) {
  894. X        fix_y = ymin;
  895. X        from_y = y;
  896. X        constrained = BOX_SCALE;
  897. X    } else {
  898. X        fix_y = ymax;
  899. X        from_y = ymin;
  900. X        constrained = BOX_HSTRETCH;
  901. X    }
  902. X    } else {
  903. X    if (y == ymin) {
  904. X        fix_y = ymax;
  905. X        from_y = y;
  906. X        fix_x = xmax;
  907. X        from_x = xmin;
  908. X        constrained = BOX_VSTRETCH;
  909. X    } else {        /* y == ymax */
  910. X        fix_y = ymin;
  911. X        from_y = y;
  912. X        fix_x = xmax;
  913. X        from_x = xmin;
  914. X        constrained = BOX_VSTRETCH;
  915. X    }
  916. X    }
  917. X
  918. X    cur_x = from_x;
  919. X    cur_y = from_y;
  920. X    set_temp_cursor(crosshair_cursor);
  921. X    draw_line(cur_l, ERASE);
  922. X
  923. X    if (constrained == BOX_SCALE) {
  924. X    dx = (double) (cur_x - fix_x);
  925. X    dy = (double) (cur_y - fix_y);
  926. X    l = sqrt(dx * dx + dy * dy);
  927. X    cosa = fabs(dx / l);
  928. X    sina = fabs(dy / l);
  929. X    }
  930. X    elastic_box(fix_x, fix_y, cur_x, cur_y);
  931. X    canvas_locmove_proc = constrained_resizing_box;
  932. X    canvas_leftbut_proc = fix_boxscale_line;
  933. X    canvas_rightbut_proc = cancel_boxscale_line;
  934. X    return True;
  935. X}
  936. X
  937. Xstatic
  938. Xcancel_boxscale_line()
  939. X{
  940. X    elastic_box(fix_x, fix_y, cur_x, cur_y);
  941. X    draw_line(cur_l, PAINT);
  942. X    toggle_linemarker(cur_l);
  943. X    wrapup_scale();
  944. X}
  945. X
  946. Xstatic
  947. Xfix_boxscale_line(x, y)
  948. X    int            x, y;
  949. X{
  950. X    elastic_box(fix_x, fix_y, cur_x, cur_y);
  951. X    adjust_box_pos(x, y, from_x, from_y, &x, &y);
  952. X    new_l = copy_line(cur_l);
  953. X    draw_line(cur_l, ERASE);
  954. X    assign_newboxpoint(new_l, fix_x, fix_y, x, y);
  955. X    if (new_l->type == T_EPS_BOX) {
  956. X    if (signof(fix_x - from_x) != signof(fix_x - x))
  957. X        new_l->eps->flipped = 1 - new_l->eps->flipped;
  958. X    if (signof(fix_y - from_y) != signof(fix_y - y))
  959. X        new_l->eps->flipped = 1 - new_l->eps->flipped;
  960. X    }
  961. X    change_line(cur_l, new_l);
  962. X    draw_line(new_l, PAINT);
  963. X    toggle_linemarker(new_l);
  964. X    wrapup_scale();
  965. X}
  966. X
  967. Xstatic
  968. Xassign_newboxpoint(b, x1, y1, x2, y2)
  969. X    F_line       *b;
  970. X    int            x1, y1, x2, y2;
  971. X{
  972. X    F_point       *p;
  973. X
  974. X    p = b->points;
  975. X    if (p->x != x1)
  976. X    p->x = x2;
  977. X    if (p->y != y1)
  978. X    p->y = y2;
  979. X    p = p->next;
  980. X    if (p->x != x1)
  981. X    p->x = x2;
  982. X    if (p->y != y1)
  983. X    p->y = y2;
  984. X    p = p->next;
  985. X    if (p->x != x1)
  986. X    p->x = x2;
  987. X    if (p->y != y1)
  988. X    p->y = y2;
  989. X    p = p->next;
  990. X    if (p->x != x1)
  991. X    p->x = x2;
  992. X    if (p->y != y1)
  993. X    p->y = y2;
  994. X    p = p->next;
  995. X    if (p->x != x1)
  996. X    p->x = x2;
  997. X    if (p->y != y1)
  998. X    p->y = y2;
  999. X}
  1000. X
  1001. Xstatic
  1002. Xinit_scale_line()
  1003. X{
  1004. X    int            sumx, sumy, cnt;
  1005. X    F_point       *p;
  1006. X
  1007. X    p = cur_l->points;
  1008. X    if (cur_l->type != T_POLYLINE)
  1009. X    p = p->next;
  1010. X    for (sumx = 0, sumy = 0, cnt = 0; p != NULL; p = p->next) {
  1011. X    sumx = sumx + p->x;
  1012. X    sumy = sumy + p->y;
  1013. X    cnt++;
  1014. X    }
  1015. X    fix_x = sumx / cnt;
  1016. X    fix_y = sumy / cnt;
  1017. X    if (from_x == fix_x && from_y == fix_y) {
  1018. X    put_msg("Center point selected, ignored");
  1019. X    return False;
  1020. X    }
  1021. X    set_action_on();
  1022. X    toggle_linemarker(cur_l);
  1023. X    set_temp_cursor(crosshair_cursor);
  1024. X    draw_line(cur_l, ERASE);
  1025. X    elastic_scalepts(cur_l->points);
  1026. X    canvas_locmove_proc = scaling_line;
  1027. X    canvas_middlebut_proc = fix_scale_line;
  1028. X    canvas_rightbut_proc = cancel_scale_line;
  1029. X    return True;
  1030. X}
  1031. X
  1032. Xstatic
  1033. Xcancel_scale_line()
  1034. X{
  1035. X    elastic_scalepts(cur_l->points);
  1036. X    draw_line(cur_l, PAINT);
  1037. X    toggle_linemarker(cur_l);
  1038. X    wrapup_scale();
  1039. X}
  1040. X
  1041. Xstatic
  1042. Xfix_scale_line(x, y)
  1043. X    int            x, y;
  1044. X{
  1045. X    elastic_scalepts(cur_l->points);
  1046. X    adjust_box_pos(x, y, from_x, from_y, &x, &y);
  1047. X    /* make a copy of the original and save as unchanged object */
  1048. X    old_l = copy_line(cur_l);
  1049. X    clean_up();
  1050. X    set_latestline(old_l);
  1051. X    set_action_object(F_CHANGE, O_POLYLINE);
  1052. X    old_l->next = cur_l;
  1053. X    /* now change the original to become the new object */
  1054. X    rescale_points(cur_l->points, x, y);
  1055. X    draw_line(cur_l, PAINT);
  1056. X    toggle_linemarker(cur_l);
  1057. X    wrapup_scale();
  1058. X}
  1059. X
  1060. Xstatic
  1061. Xrescale_points(pts, x, y)
  1062. X    F_point       *pts;
  1063. X    int            x, y;
  1064. X{
  1065. X    F_point       *p;
  1066. X    int            newx, newy, oldx, oldy;
  1067. X    float        newd, oldd, scalefact;
  1068. X
  1069. X    p = pts;
  1070. X    newx = x - fix_x;
  1071. X    newy = y - fix_y;
  1072. X    newd = sqrt((double) (newx * newx + newy * newy));
  1073. X
  1074. X    oldx = from_x - fix_x;
  1075. X    oldy = from_y - fix_y;
  1076. X    oldd = sqrt((double) (oldx * oldx + oldy * oldy));
  1077. X
  1078. X    scalefact = newd / oldd;
  1079. X    for (p = pts; p != NULL; p = p->next) {
  1080. X    p->x = fix_x + (p->x - fix_x) * scalefact;
  1081. X    p->y = fix_y + (p->y - fix_y) * scalefact;
  1082. X    }
  1083. X    set_modifiedflag();
  1084. X}
  1085. END_OF_FILE
  1086. if test 26235 -ne `wc -c <'e_scale.c'`; then
  1087.     echo shar: \"'e_scale.c'\" unpacked with wrong size!
  1088. fi
  1089. # end of 'e_scale.c'
  1090. fi
  1091. if test -f 'main.c' -a "${1}" != "-c" ; then 
  1092.   echo shar: Will not clobber existing file \"'main.c'\"
  1093. else
  1094. echo shar: Extracting \"'main.c'\" \(26813 characters\)
  1095. sed "s/^X//" >'main.c' <<'END_OF_FILE'
  1096. X/*
  1097. X * FIG : Facility for Interactive Generation of figures
  1098. X * Copyright (c) 1985 by Supoj Sutanthavibul
  1099. X *
  1100. X * "Permission to use, copy, modify, distribute, and sell this software and its
  1101. X * documentation for any purpose is hereby granted without fee, provided that
  1102. X * the above copyright notice appear in all copies and that both the copyright
  1103. X * notice and this permission notice appear in supporting documentation. 
  1104. X * No representations are made about the suitability of this software for 
  1105. X * any purpose.  It is provided "as is" without express or implied warranty."
  1106. X */
  1107. X
  1108. X#include "fig.h"
  1109. X#include "figx.h"
  1110. X#include "version.h"
  1111. X#include "patchlevel.h"
  1112. X#include "resources.h"
  1113. X#include "object.h"
  1114. X#include "mode.h"
  1115. X#include "u_fonts.h"
  1116. X#include "w_drawprim.h"
  1117. X#include "w_mousefun.h"
  1118. X#include "w_setup.h"
  1119. X#include "w_util.h"
  1120. X
  1121. X/************** EXTERNAL functions **************/
  1122. X
  1123. Xextern void    quit(), undo(), paste(), redisplay_canvas(), delete_all_cmd();
  1124. Xextern void    popup_print_panel(), popup_file_panel(), popup_export_panel();
  1125. Xextern void    do_load(), do_save(), popup_unit_panel();
  1126. X
  1127. Xextern void    setup_cmd_panel();
  1128. Xextern        X_error_handler();
  1129. Xextern void    error_handler();
  1130. Xextern void    my_quit();
  1131. Xextern int    ignore_exp_cnt;
  1132. Xextern int    psfontnum();
  1133. Xextern int    latexfontnum();
  1134. X
  1135. X#include "fig.icon.X"
  1136. XPixmap        fig_icon;
  1137. X
  1138. Xstatic char    tool_name[100];
  1139. Xstatic        sigwinched();
  1140. X
  1141. X/************** FIG options ******************/
  1142. X
  1143. Xstatic char    *filename = NULL;
  1144. X
  1145. Xstatic Boolean    true = True;
  1146. Xstatic Boolean    false = False;
  1147. Xstatic int    zero = 0;
  1148. Xstatic float    one = 1.0;
  1149. X
  1150. X/* actions so that we may install accelerators at the top level */
  1151. Xstatic XtActionsRec    main_actions[] =
  1152. X{
  1153. X    {"Quit", (XtActionProc) quit},
  1154. X    {"Delete_all", (XtActionProc) delete_all_cmd},
  1155. X    {"Undo", (XtActionProc) undo},
  1156. X    {"Redraw", (XtActionProc) redisplay_canvas},
  1157. X    {"Paste", (XtActionProc) paste},
  1158. X    {"File", (XtActionProc) popup_file_panel},
  1159. X      {"LoadFile", (XtActionProc) do_load},
  1160. X      {"SaveFile", (XtActionProc) do_save},
  1161. X    {"Export", (XtActionProc) popup_export_panel},
  1162. X    {"Print", (XtActionProc) popup_print_panel},
  1163. X    {"Units", (XtActionProc) popup_unit_panel},
  1164. X};
  1165. X
  1166. Xstatic XtResource application_resources[] = {
  1167. X    {"iconGeometry",  "IconGeometry",  XtRString,  sizeof(char *),
  1168. X    XtOffset(appresPtr,iconGeometry), XtRString, (caddr_t) NULL},
  1169. X    {"showallbuttons", "ShowAllButtons", XtRBoolean, sizeof(Boolean),
  1170. X    XtOffset(appresPtr, ShowAllButtons), XtRBoolean, (caddr_t) & false},
  1171. X    {XtNjustify, XtCJustify, XtRBoolean, sizeof(Boolean),
  1172. X    XtOffset(appresPtr, RHS_PANEL), XtRBoolean, (caddr_t) & false},
  1173. X    {"landscape", XtCOrientation, XtRBoolean, sizeof(Boolean),
  1174. X    XtOffset(appresPtr, landscape), XtRBoolean, (caddr_t) & true},
  1175. X    {"debug", "Debug", XtRBoolean, sizeof(Boolean),
  1176. X    XtOffset(appresPtr, DEBUG), XtRBoolean, (caddr_t) & false},
  1177. X    {"pwidth", XtCWidth, XtRFloat, sizeof(float),
  1178. X    XtOffset(appresPtr, tmp_width), XtRInt, (caddr_t) & zero},
  1179. X    {"pheight", XtCHeight, XtRFloat, sizeof(float),
  1180. X    XtOffset(appresPtr, tmp_height), XtRInt, (caddr_t) & zero},
  1181. X    {XtNreverseVideo, XtCReverseVideo, XtRBoolean, sizeof(Boolean),
  1182. X    XtOffset(appresPtr, INVERSE), XtRBoolean, (caddr_t) & false},
  1183. X    {"trackCursor", "Track", XtRBoolean, sizeof(Boolean),
  1184. X    XtOffset(appresPtr, TRACKING), XtRBoolean, (caddr_t) & true},
  1185. X    {"inches", "Inches", XtRBoolean, sizeof(Boolean),
  1186. X    XtOffset(appresPtr, INCHES), XtRBoolean, (caddr_t) & true},
  1187. X    {"boldFont", "Font", XtRString, sizeof(char *),
  1188. X    XtOffset(appresPtr, boldFont), XtRString, (caddr_t) NULL},
  1189. X    {"normalFont", "Font", XtRString, sizeof(char *),
  1190. X    XtOffset(appresPtr, normalFont), XtRString, (caddr_t) NULL},
  1191. X    {"buttonFont", "Font", XtRString, sizeof(char *),
  1192. X    XtOffset(appresPtr, buttonFont), XtRString, (caddr_t) NULL},
  1193. X    {"startlatexFont", "StartlatexFont", XtRString, sizeof(char *),
  1194. X    XtOffset(appresPtr, startlatexFont), XtRString, (caddr_t) NULL},
  1195. X    {"startpsFont", "StartpsFont", XtRString, sizeof(char *),
  1196. X    XtOffset(appresPtr, startpsFont), XtRString, (caddr_t) NULL},
  1197. X    {"startfontsize", "StartFontSize", XtRInt, sizeof(int),
  1198. X    XtOffset(appresPtr, startfontsize), XtRInt, (caddr_t) & zero},
  1199. X    {"internalborderwidth", "InternalBorderWidth", XtRInt, sizeof(int),
  1200. X    XtOffset(appresPtr, internalborderwidth), XtRInt, (caddr_t) & zero},
  1201. X    {"latexfonts", "Latexfonts", XtRBoolean, sizeof(Boolean),
  1202. X    XtOffset(appresPtr, latexfonts), XtRBoolean, (caddr_t) & false},
  1203. X    {"specialtext", "SpecialText", XtRBoolean, sizeof(Boolean),
  1204. X    XtOffset(appresPtr, specialtext), XtRBoolean, (caddr_t) & false},
  1205. X    {"scalablefonts", "ScalableFonts", XtRBoolean, sizeof(Boolean),
  1206. X    XtOffset(appresPtr, SCALABLEFONTS), XtRBoolean, (caddr_t) & false},
  1207. X    {"color0", "Color0", XtRPixel, sizeof(Pixel),
  1208. X    XtOffset(appresPtr, color[0]), XtRString, (caddr_t) "black"},
  1209. X    {"color1", "Color1", XtRPixel, sizeof(Pixel),
  1210. X    XtOffset(appresPtr, color[1]), XtRString, (caddr_t) "blue"},
  1211. X    {"color2", "Color2", XtRPixel, sizeof(Pixel),
  1212. X    XtOffset(appresPtr, color[2]), XtRString, (caddr_t) "green"},
  1213. X    {"color3", "Color3", XtRPixel, sizeof(Pixel),
  1214. X    XtOffset(appresPtr, color[3]), XtRString, (caddr_t) "cyan"},
  1215. X    {"color4", "Color4", XtRPixel, sizeof(Pixel),
  1216. X    XtOffset(appresPtr, color[4]), XtRString, (caddr_t) "red"},
  1217. X    {"color5", "Color5", XtRPixel, sizeof(Pixel),
  1218. X    XtOffset(appresPtr, color[5]), XtRString, (caddr_t) "magenta"},
  1219. X    {"color6", "Color6", XtRPixel, sizeof(Pixel),
  1220. X    XtOffset(appresPtr, color[6]), XtRString, (caddr_t) "yellow"},
  1221. X    {"color7", "Color7", XtRPixel, sizeof(Pixel),
  1222. X    XtOffset(appresPtr, color[7]), XtRString, (caddr_t) "white"},
  1223. X    {"monochrome", "Monochrome", XtRBoolean, sizeof(Boolean),
  1224. X    XtOffset(appresPtr, monochrome), XtRBoolean, (caddr_t) & false},
  1225. X    {"latexfonts", "Latexfonts", XtRBoolean, sizeof(Boolean),
  1226. X    XtOffset(appresPtr, latexfonts), XtRBoolean, (caddr_t) & false},
  1227. X    {"keyFile", "KeyFile", XtRString, sizeof(char *),
  1228. X    XtOffset(appresPtr, keyFile), XtRString, (caddr_t) "CompKeyDB"},
  1229. X    {"exportLanguage", "ExportLanguage", XtRString, sizeof(char *),
  1230. X    XtOffset(appresPtr, exportLanguage), XtRString, (caddr_t) "eps"},
  1231. X    {"flushleft", "FlushLeft", XtRBoolean, sizeof(Boolean),
  1232. X    XtOffset(appresPtr, flushleft), XtRBoolean, (caddr_t) & false},
  1233. X    {"textoutline", "TextOutline", XtRBoolean, sizeof(Boolean),
  1234. X    XtOffset(appresPtr, textoutline), XtRBoolean, (caddr_t) & false},
  1235. X    {"userscale", "UserScale", XtRFloat, sizeof(float),
  1236. X    XtOffset(appresPtr, user_scale), XtRFloat, (caddr_t) & one},
  1237. X    {"userunit", "UserUnit", XtRString, sizeof(char *),
  1238. X    XtOffset(appresPtr, user_unit), XtRString, (caddr_t) ""},
  1239. X};
  1240. X
  1241. Xstatic XrmOptionDescRec options[] =
  1242. X{
  1243. X    {"-iconGeometry", ".iconGeometry", XrmoptionSepArg, (caddr_t) NULL},
  1244. X    {"-showallbuttons", ".showallbuttons", XrmoptionNoArg, "True"},
  1245. X    {"-right", ".justify", XrmoptionNoArg, "True"},
  1246. X    {"-left", ".justify", XrmoptionNoArg, "False"},
  1247. X    {"-debug", ".debug", XrmoptionNoArg, "True"},
  1248. X    {"-landscape", ".landscape", XrmoptionNoArg, "True"},
  1249. X    {"-Landscape", ".landscape", XrmoptionNoArg, "True"},
  1250. X    {"-portrait", ".landscape", XrmoptionNoArg, "False"},
  1251. X    {"-Portrait", ".landscape", XrmoptionNoArg, "False"},
  1252. X    {"-pwidth", ".pwidth", XrmoptionSepArg, 0},
  1253. X    {"-pheight", ".pheight", XrmoptionSepArg, 0},
  1254. X    {"-inverse", ".reverseVideo", XrmoptionNoArg, "True"},
  1255. X    {"-notrack", ".trackCursor", XrmoptionNoArg, "False"},
  1256. X    {"-track", ".trackCursor", XrmoptionNoArg, "True"},
  1257. X    {"-inches", ".inches", XrmoptionNoArg, "True"},
  1258. X    {"-imperial", ".inches", XrmoptionNoArg, "True"},
  1259. X    {"-centimeters", ".inches", XrmoptionNoArg, "False"},
  1260. X    {"-metric", ".inches", XrmoptionNoArg, "False"},
  1261. X    {"-boldFont", ".boldFont", XrmoptionSepArg, 0},
  1262. X    {"-normalFont", ".normalFont", XrmoptionSepArg, 0},
  1263. X    {"-buttonFont", ".buttonFont", XrmoptionSepArg, 0},
  1264. X    {"-startpsFont", ".startpsFont", XrmoptionSepArg, 0},
  1265. X    {"-startlatexFont", ".startlatexFont", XrmoptionSepArg, 0},
  1266. X    {"-startFontSize", ".startfontsize", XrmoptionSepArg, 0},
  1267. X    {"-startfontsize", ".startfontsize", XrmoptionSepArg, 0},
  1268. X    {"-latexfonts", ".latexfonts", XrmoptionNoArg, "True"},
  1269. X    {"-specialtext", ".specialtext", XrmoptionNoArg, "True"},
  1270. X    {"-scalablefonts", ".scalablefonts", XrmoptionNoArg, "True"},
  1271. X    {"-noscalablefonts", ".scalablefonts", XrmoptionNoArg, "False"},
  1272. X    {"-monochrome", ".monochrome", XrmoptionNoArg, "True"},
  1273. X    {"-internalBW", ".internalborderwidth", XrmoptionSepArg, 0},
  1274. X    {"-internalBorderWidth", ".internalborderwidth", XrmoptionSepArg, 0},
  1275. X    {"-keyFile", ".keyFile", XrmoptionSepArg, 0},
  1276. X    {"-exportLanguage", ".exportLanguage", XrmoptionSepArg, 0},
  1277. X    {"-flushleft", ".flushleft", XrmoptionNoArg, "True"},
  1278. X    {"-textoutline", ".textoutline", XrmoptionNoArg, "True"},
  1279. X    {"-userscale", ".userscale", XrmoptionSepArg, 0},
  1280. X    {"-userunit", ".userunit", XrmoptionSepArg, 0},
  1281. X};
  1282. X
  1283. XAtom wm_delete_window;
  1284. X
  1285. Xstatic XtCallbackRec callbacks[] =
  1286. X{
  1287. X    {NULL, NULL},
  1288. X};
  1289. X
  1290. Xstatic Arg    form_args[] =
  1291. X{
  1292. X    {XtNcallback, (XtArgVal) callbacks},
  1293. X    {XtNinput, (XtArgVal) True},
  1294. X    {XtNdefaultDistance, (XtArgVal) 0},
  1295. X    {XtNresizable, (XtArgVal) False},
  1296. X};
  1297. X
  1298. Xstatic void    check_for_resize();
  1299. Xstatic void    check_colors();
  1300. XXtActionsRec    form_actions[] =
  1301. X{
  1302. X    {"ResizeForm", (XtActionProc) check_for_resize},
  1303. X    {"Quit", (XtActionProc) my_quit},
  1304. X};
  1305. X
  1306. Xextern void clear_text_key();
  1307. Xextern void paste_panel_key();
  1308. Xstatic XtActionsRec text_panel_actions[] =
  1309. X{
  1310. X    {"PastePanelKey", (XtActionProc) paste_panel_key} ,
  1311. X    {"EmptyTextKey", (XtActionProc) clear_text_key} ,
  1312. X};
  1313. X
  1314. Xstatic String    form_translations =
  1315. X            "<ConfigureNotify>:ResizeForm()\n";
  1316. Xstatic String    tool_translations =
  1317. X            "<Message>WM_PROTOCOLS:Quit()\n";
  1318. X
  1319. X#define NCHILDREN    9
  1320. Xstatic TOOL    form;
  1321. X
  1322. Xmain(argc, argv)
  1323. X    int            argc;
  1324. X    char       *argv[];
  1325. X
  1326. X{
  1327. X    TOOL        children[NCHILDREN];
  1328. X    int            ichild;
  1329. X    int            init_canv_wd, init_canv_ht;
  1330. X    XWMHints       *wmhints;
  1331. X    char        i;
  1332. X    char       *userhome;
  1333. X    Dimension        w, h;
  1334. X
  1335. X    DeclareArgs(5);
  1336. X
  1337. X    /* we are not writing the figure to the bitmap */
  1338. X    writing_bitmap = False;
  1339. X
  1340. X    /* get the TMPDIR environment variable for temporary files */
  1341. X    if ((TMPDIR = getenv("XFIGTMPDIR"))==NULL)
  1342. X    TMPDIR = "/tmp";
  1343. X
  1344. X    (void) sprintf(tool_name, " XFIG %s(.%s) (Protocol %s)",
  1345. X           FIG_VERSION, PATCHLEVEL, PROTOCOL_VERSION);
  1346. X    (void) strcat(file_header, PROTOCOL_VERSION);
  1347. X    tool = XtAppInitialize(&tool_app, (String) "Fig", (XrmOptionDescList) options,
  1348. X               (Cardinal) XtNumber(options),
  1349. X#if XtSpecificationRelease < 5
  1350. X               (Cardinal *) & argc,
  1351. X               (String *) argv,
  1352. X#else
  1353. X               &argc,
  1354. X               argv,
  1355. X#endif
  1356. X               (String *) NULL,
  1357. X#if XtSpecificationRelease < 5
  1358. X               (String *) NULL, 
  1359. X#else
  1360. X               (ArgList) NULL,
  1361. X#endif
  1362. X               (Cardinal) 0);
  1363. X
  1364. X
  1365. X    /* install actions to get to the functions with accelerators */
  1366. X    XtAppAddActions(tool_app, main_actions, XtNumber(main_actions));
  1367. X
  1368. X    fix_converters();
  1369. X    XtGetApplicationResources(tool, &appres, application_resources,
  1370. X                  XtNumber(application_resources), NULL, 0);
  1371. X
  1372. X    i = 1;
  1373. X    while (argc-- > 1) {
  1374. X    if (*argv[i] != '-') {    /* search for non - name */
  1375. X        filename = argv[i];
  1376. X        break;
  1377. X    }
  1378. X    i++;
  1379. X    }
  1380. X
  1381. X    tool_d = XtDisplay(tool);
  1382. X    tool_s = XtScreen(tool);
  1383. X    tool_sn = DefaultScreen(tool_d);
  1384. X
  1385. X    if (appres.iconGeometry != (char *) 0) {
  1386. X        int scr, x, y, junk;
  1387. X        Arg args[2];
  1388. X
  1389. X        for(scr = 0;
  1390. X            tool_s != ScreenOfDisplay(tool_d, scr);
  1391. X            scr++);
  1392. X
  1393. X        XGeometry(tool_d, scr, appres.iconGeometry,
  1394. X                  "", 0, 0, 0, 0, 0, &x, &y, &junk, &junk);
  1395. X        XtSetArg(args[0], XtNiconX, x);
  1396. X        XtSetArg(args[1], XtNiconY, y);
  1397. X        XtSetValues(tool, args, XtNumber(args));
  1398. X    }
  1399. X
  1400. X    print_flushleft = export_flushleft = appres.flushleft;    /* set both resources */
  1401. X    print_landscape = appres.landscape; /* match print and screen format to start */
  1402. X
  1403. X    /* turn off PSFONT_TEXT flag if user specified -latexfonts */
  1404. X    if (appres.latexfonts)
  1405. X    cur_textflags = cur_textflags & (~PSFONT_TEXT);
  1406. X    if (appres.specialtext)
  1407. X    cur_textflags = cur_textflags | SPECIAL_TEXT;
  1408. X
  1409. X    /* turn off PSFONT_TEXT flag if user specified -latexfonts */
  1410. X    if (appres.latexfonts)
  1411. X    cur_textflags = cur_textflags & (~PSFONT_TEXT);
  1412. X
  1413. X    if (appres.user_unit)
  1414. X    strncpy(cur_fig_units, appres.user_unit, sizeof(cur_fig_units));
  1415. X    else
  1416. X    cur_fig_units[0] = '\0';
  1417. X
  1418. X    if (CellsOfScreen(tool_s) == 2 && appres.INVERSE) {
  1419. X    XrmValue    value;
  1420. X    XrmDatabase    newdb = (XrmDatabase) 0, old;
  1421. X
  1422. X    value.size = sizeof("White");
  1423. X    value.addr = "White";
  1424. X    XrmPutResource(&newdb, "xfig*borderColor", "String",
  1425. X               &value);
  1426. X    value.size = sizeof("White");
  1427. X    value.addr = "White";
  1428. X    XrmPutResource(&newdb, "xfig*foreground", "String",
  1429. X               &value);
  1430. X    value.size = sizeof("Black");
  1431. X    value.addr = "Black";
  1432. X    XrmPutResource(&newdb, "xfig*background", "String",
  1433. X               &value);
  1434. X    old = XtDatabase(tool_d);
  1435. X    XrmMergeDatabases(newdb, &old);
  1436. X
  1437. X    /* now set the tool part, since its already created */
  1438. X    FirstArg(XtNborderColor, WhitePixelOfScreen(tool_s));
  1439. X    NextArg(XtNforeground, WhitePixelOfScreen(tool_s));
  1440. X    NextArg(XtNbackground, BlackPixelOfScreen(tool_s));
  1441. X    SetValues(tool);
  1442. X    }
  1443. X    init_font();
  1444. X
  1445. X    gc = DefaultGC(tool_d, tool_sn);
  1446. X    bold_gc = DefaultGC(tool_d, tool_sn);
  1447. X    button_gc = DefaultGC(tool_d, tool_sn);
  1448. X
  1449. X    /* set the roman and bold fonts for the message windows */
  1450. X    XSetFont(tool_d, gc, roman_font->fid);
  1451. X    XSetFont(tool_d, bold_gc, bold_font->fid);
  1452. X    XSetFont(tool_d, button_gc, button_font->fid);
  1453. X
  1454. X    /*
  1455. X     * check if the NUMCOLORS drawing colors could be allocated and have
  1456. X     * different palette entries
  1457. X     */
  1458. X    check_colors();
  1459. X
  1460. X    init_cursor();
  1461. X    form = XtCreateManagedWidget("form", formWidgetClass, tool,
  1462. X                 form_args, XtNumber(form_args));
  1463. X
  1464. X    if (cur_fontsize == 0)
  1465. X    cur_fontsize = (int) appres.startfontsize;
  1466. X    if (cur_fontsize == 0)
  1467. X    cur_fontsize = DEF_FONTSIZE;
  1468. X
  1469. X    if (cur_latex_font == 0)
  1470. X    cur_latex_font = latexfontnum (appres.startlatexFont);
  1471. X
  1472. X    if (cur_ps_font == 0)
  1473. X    cur_ps_font = psfontnum (appres.startpsFont);
  1474. X
  1475. X    if (INTERNAL_BW == 0)
  1476. X    INTERNAL_BW = (int) appres.internalborderwidth;
  1477. X    if (INTERNAL_BW <= 0)
  1478. X    INTERNAL_BW = DEF_INTERNAL_BW;
  1479. X
  1480. X    SW_PER_ROW = SW_PER_ROW_PORT;
  1481. X    SW_PER_COL = SW_PER_COL_PORT;
  1482. X    init_canv_wd = appres.tmp_width *
  1483. X    (appres.INCHES ? PIX_PER_INCH : PIX_PER_CM);
  1484. X    init_canv_ht = appres.tmp_height *
  1485. X    (appres.INCHES ? PIX_PER_INCH : PIX_PER_CM);
  1486. X
  1487. X    if (init_canv_wd == 0)
  1488. X    init_canv_wd = appres.landscape ? DEF_CANVAS_WD_LAND :
  1489. X        DEF_CANVAS_WD_PORT;
  1490. X
  1491. X    if (init_canv_ht == 0)
  1492. X    init_canv_ht = appres.landscape ? DEF_CANVAS_HT_LAND :
  1493. X        DEF_CANVAS_HT_PORT;
  1494. X
  1495. X    if ((init_canv_ht < DEF_CANVAS_HT_PORT) ||
  1496. X    (HeightOfScreen(tool_s) < DEF_CANVAS_HT_PORT)) {
  1497. X    SW_PER_ROW = SW_PER_ROW_LAND;
  1498. X    SW_PER_COL = SW_PER_COL_LAND;
  1499. X    }
  1500. X    setup_sizes(init_canv_wd, init_canv_ht);
  1501. X    (void) init_cmd_panel(form);
  1502. X    (void) init_msg(form,filename);
  1503. X    (void) init_mousefun(form);
  1504. X    (void) init_mode_panel(form);
  1505. X    (void) init_topruler(form);
  1506. X    (void) init_canvas(form);
  1507. X    (void) init_fontmenu(form); /* printer font menu */
  1508. X    (void) init_unitbox(form);
  1509. X    (void) init_sideruler(form);
  1510. X    (void) init_ind_panel(form);
  1511. X
  1512. X    ichild = 0;
  1513. X    children[ichild++] = cmd_panel;    /* command buttons */
  1514. X    children[ichild++] = mousefun;    /* labels for mouse fns */
  1515. X    children[ichild++] = msg_form;    /* message window form */
  1516. X    children[ichild++] = mode_panel;    /* current mode */
  1517. X    children[ichild++] = topruler_sw;    /* top ruler */
  1518. X    children[ichild++] = unitbox_sw;    /* box containing units */
  1519. X    children[ichild++] = sideruler_sw;    /* side ruler */
  1520. X    children[ichild++] = canvas_sw;    /* main drawing canvas */
  1521. X    children[ichild++] = ind_viewp;    /* current settings indicators */
  1522. X
  1523. X    /*
  1524. X     * until the following XtRealizeWidget() is called, there are NO windows
  1525. X     * in existence
  1526. X     */
  1527. X
  1528. X    XtManageChildren(children, NCHILDREN);
  1529. X    XtRealizeWidget(tool);
  1530. X
  1531. X    wm_delete_window = XInternAtom(XtDisplay(tool), "WM_DELETE_WINDOW", False);
  1532. X    (void) XSetWMProtocols(XtDisplay(tool), XtWindow(tool),
  1533. X               &wm_delete_window, 1);
  1534. X
  1535. X    fig_icon = XCreateBitmapFromData(tool_d, XtWindow(tool),
  1536. X                     (char *) fig_bits, fig_width, fig_height);
  1537. X
  1538. X    FirstArg(XtNtitle, tool_name);
  1539. X    NextArg(XtNiconPixmap, fig_icon);
  1540. X    SetValues(tool);
  1541. X    /* Set the input field to true to allow keyboard input */
  1542. X    wmhints = XGetWMHints(tool_d, XtWindow(tool));
  1543. X    wmhints->flags |= InputHint;/* add in input hint */
  1544. X    wmhints->input = True;
  1545. X    XSetWMHints(tool_d, XtWindow(tool), wmhints);
  1546. X    XFree((char *) wmhints);
  1547. X
  1548. X    if (appres.RHS_PANEL) {    /* side button panel is on right size */
  1549. X    FirstArg(XtNfromHoriz, 0);
  1550. X    NextArg(XtNhorizDistance, SIDERULER_WD + INTERNAL_BW);
  1551. X    SetValues(topruler_sw);
  1552. X
  1553. X    FirstArg(XtNfromHoriz, 0);
  1554. X    NextArg(XtNhorizDistance, 0);
  1555. X    NextArg(XtNfromVert, topruler_sw);
  1556. X    NextArg(XtNleft, XtChainLeft);    /* chain to left of form */
  1557. X    NextArg(XtNright, XtChainLeft);
  1558. X    SetValues(sideruler_sw);
  1559. X
  1560. X    FirstArg(XtNfromHoriz, 0);
  1561. X    NextArg(XtNhorizDistance, 0);
  1562. X    NextArg(XtNfromVert, msg_form);
  1563. X    NextArg(XtNleft, XtChainLeft);    /* chain to left of form */
  1564. X    NextArg(XtNright, XtChainLeft);
  1565. X    SetValues(unitbox_sw);
  1566. X
  1567. X    /* relocate the side button panel */
  1568. X    XtUnmanageChild(mode_panel);
  1569. X    XtUnmanageChild(canvas_sw);
  1570. X    FirstArg(XtNfromHoriz, canvas_sw);    /* panel right of canvas */
  1571. X    NextArg(XtNhorizDistance, -INTERNAL_BW);
  1572. X    NextArg(XtNfromVert, mousefun);
  1573. X    NextArg(XtNleft, XtChainRight);
  1574. X    NextArg(XtNright, XtChainRight);
  1575. X    SetValues(mode_panel);
  1576. X    FirstArg(XtNfromHoriz, sideruler_sw);    /* panel right of canvas */
  1577. X    SetValues(canvas_sw);
  1578. X    XtManageChild(canvas_sw);
  1579. X    XtManageChild(mode_panel);
  1580. X    }
  1581. X
  1582. X    init_gc();
  1583. X    setup_cmd_panel();
  1584. X    setup_msg();
  1585. X    setup_canvas();
  1586. X    setup_rulers();
  1587. X    setup_mode_panel();
  1588. X    setup_mousefun();
  1589. X    setup_fontmenu();        /* setup bitmaps in printer font menu */
  1590. X    setup_ind_panel();
  1591. X    get_directory(cur_dir);
  1592. X
  1593. X    /* parse the export language resource */
  1594. X    for (i=0; i<NUM_EXP_LANG; i++)
  1595. X    if (strcmp(appres.exportLanguage, lang_items[i])==0)
  1596. X        break;
  1597. X    /* found it set the language number */
  1598. X    if (i < NUM_EXP_LANG)
  1599. X    cur_exp_lang = i;
  1600. X    else
  1601. X    file_msg("Unknown export language: %s, using default: %s",
  1602. X        appres.exportLanguage, lang_items[cur_exp_lang]);
  1603. X
  1604. X    /* install the accelerators - cmd_panel, ind_panel and mode_panel
  1605. X    accelerators are installed in their respective setup_xxx procedures */
  1606. X    XtInstallAllAccelerators(canvas_sw, tool);
  1607. X    XtInstallAllAccelerators(mousefun, tool);
  1608. X    XtInstallAllAccelerators(msg_form, tool);
  1609. X    XtInstallAllAccelerators(topruler_sw, tool);
  1610. X    XtInstallAllAccelerators(sideruler_sw, tool);
  1611. X    XtInstallAllAccelerators(unitbox_sw, tool);
  1612. X
  1613. X    FirstArg(XtNwidth, &w);
  1614. X    NextArg(XtNheight, &h);
  1615. X    GetValues(tool);
  1616. X    TOOL_WD = (int) w;
  1617. X    TOOL_HT = (int) h;
  1618. X    XtAppAddActions(tool_app, form_actions, XtNumber(form_actions));
  1619. X    XtAppAddActions(tool_app, text_panel_actions, XtNumber(text_panel_actions));
  1620. X    XtOverrideTranslations(tool, XtParseTranslationTable(tool_translations));
  1621. X    XtOverrideTranslations(form, XtParseTranslationTable(form_translations));
  1622. X
  1623. X    XSetErrorHandler(X_error_handler);
  1624. X    XSetIOErrorHandler((XIOErrorHandler) X_error_handler);
  1625. X    (void) signal(SIGHUP, error_handler);
  1626. X    (void) signal(SIGFPE, error_handler);
  1627. X#ifndef NO_SIBGUS
  1628. X    (void) signal(SIGBUS, error_handler);
  1629. X#endif
  1630. X    (void) signal(SIGSEGV, error_handler);
  1631. X    (void) signal(SIGINT, SIG_IGN);    /* in case user accidentally types
  1632. X                     * ctrl-c */
  1633. X
  1634. X    put_msg("READY, please select a mode or load a file");
  1635. X
  1636. X    /*
  1637. X     * decide on filename for cut buffer: first try users HOME directory to
  1638. X     * allow cutting and pasting between sessions, if this fails create
  1639. X     * unique filename in /tmp dir
  1640. X     */
  1641. X
  1642. X    userhome = getenv("HOME");
  1643. X    if (userhome != NULL && *strcpy(cut_buf_name, userhome) != '\0') {
  1644. X    strcat(cut_buf_name, "/.xfig");
  1645. X    } else {
  1646. X    sprintf(cut_buf_name, "%s%06d", "/tmp/xfig", getpid());
  1647. X    }
  1648. X
  1649. X    if (filename == NULL)
  1650. X    strcpy(cur_filename, DEF_NAME);
  1651. X    else
  1652. X    load_file(filename);
  1653. X    update_cur_filename(cur_filename);
  1654. X
  1655. X    app_flush();
  1656. X
  1657. X    XtAppMainLoop(tool_app);
  1658. X}
  1659. X
  1660. Xstatic void
  1661. Xcheck_for_resize(tool, event, params, nparams)
  1662. X    TOOL        tool;
  1663. X    XButtonEvent   *event;
  1664. X    String       *params;
  1665. X    Cardinal       *nparams;
  1666. X{
  1667. X    XConfigureEvent *xc = (XConfigureEvent *) event;
  1668. X    Dimension        b;
  1669. X    int            dx, dy;
  1670. X
  1671. X    DeclareArgs(3);
  1672. X
  1673. X    if (xc->width == TOOL_WD && xc->height == TOOL_HT)
  1674. X    return;            /* no size change */
  1675. X    dx = xc->width - TOOL_WD;
  1676. X    dy = xc->height - TOOL_HT;
  1677. X    TOOL_WD = xc->width;
  1678. X    TOOL_HT = xc->height;
  1679. X    setup_sizes(CANVAS_WD + dx, CANVAS_HT + dy);
  1680. X
  1681. X    XawFormDoLayout(form, False);
  1682. X    ignore_exp_cnt++;        /* canvas is resized twice - redraw only once */
  1683. X
  1684. X    FirstArg(XtNborderWidth, &b);
  1685. X    /* first redo the top panels */
  1686. X    GetValues(cmd_panel);
  1687. X    XtResizeWidget(cmd_panel, CMDPANEL_WD, CMDPANEL_HT, b);
  1688. X    GetValues(mousefun);
  1689. X    XtResizeWidget(mousefun, MOUSEFUN_WD, MOUSEFUN_HT, b);
  1690. X    XtUnmanageChild(mousefun);
  1691. X    resize_mousefun();
  1692. X    XtManageChild(mousefun);    /* so that it shifts with msg_panel */
  1693. X    /* resize the message form by setting the current filename */
  1694. X    update_cur_filename(cur_filename);
  1695. X
  1696. X    /* now redo the center area */
  1697. X    XtUnmanageChild(mode_panel);
  1698. X    FirstArg(XtNheight, (MODEPANEL_SPACE + 1) / 2);
  1699. X    SetValues(d_label);
  1700. X    FirstArg(XtNheight, (MODEPANEL_SPACE) / 2);
  1701. X    SetValues(e_label);
  1702. X    XtManageChild(mode_panel);    /* so that it adjusts properly */
  1703. X
  1704. X    FirstArg(XtNborderWidth, &b);
  1705. X    GetValues(canvas_sw);
  1706. X    XtResizeWidget(canvas_sw, CANVAS_WD, CANVAS_HT, b);
  1707. X    GetValues(topruler_sw);
  1708. X    XtResizeWidget(topruler_sw, TOPRULER_WD, TOPRULER_HT, b);
  1709. X    resize_topruler();
  1710. X    GetValues(sideruler_sw);
  1711. X    XtResizeWidget(sideruler_sw, SIDERULER_WD, SIDERULER_HT, b);
  1712. X    resize_sideruler();
  1713. X    XtUnmanageChild(sideruler_sw);
  1714. X    XtManageChild(sideruler_sw);/* so that it shifts with canvas */
  1715. X    XtUnmanageChild(unitbox_sw);
  1716. X    XtManageChild(unitbox_sw);    /* so that it shifts with canvas */
  1717. X
  1718. X    XawFormDoLayout(form, True);
  1719. X}
  1720. X
  1721. X
  1722. Xstatic void
  1723. Xcheck_colors()
  1724. X{
  1725. X    int            i, j;
  1726. X
  1727. X    /* if monochrome resource is set, do not even check for colors */
  1728. X    if (appres.monochrome) {
  1729. X    all_colors_available = false;
  1730. X    return;
  1731. X    }
  1732. X    all_colors_available = true;
  1733. X
  1734. X    /* check if the drawing colors have different palette entries */
  1735. X    for (i = 0; i < NUMCOLORS - 1; i++) {
  1736. X    for (j = i + 1; j < NUMCOLORS; j++) {
  1737. X        if (appres.color[i] == appres.color[j]) {
  1738. X        all_colors_available = false;
  1739. X        break;
  1740. X        }
  1741. X    }
  1742. X    if (!all_colors_available)
  1743. X        break;
  1744. X    }
  1745. X}
  1746. X
  1747. X/* useful when using ups */
  1748. XXSyncOn()
  1749. X{
  1750. X    XSynchronize(tool_d, True);
  1751. X    XFlush(tool_d);
  1752. X}
  1753. X
  1754. XXSyncOff()
  1755. X{
  1756. X    XSynchronize(tool_d, False);
  1757. X    XFlush(tool_d);
  1758. X}
  1759. X
  1760. X#ifdef NOSTRSTR
  1761. X
  1762. Xchar *strstr(s1, s2)
  1763. X    char *s1, *s2;
  1764. X{
  1765. X    int len2;
  1766. X    char *stmp;
  1767. X
  1768. X    len2 = strlen(s2);
  1769. X    for (stmp = s1; *stmp != NULL; stmp++)
  1770. X    if (strncmp(stmp, s2, len2)==0)
  1771. X        return stmp;
  1772. X    return NULL;
  1773. X}
  1774. X#endif
  1775. X#ifdef NOSTRTOL
  1776. X/*-
  1777. X * Copyright (c) 1990 The Regents of the University of California.
  1778. X * All rights reserved.
  1779. X *
  1780. X * Redistribution and use in source and binary forms are permitted
  1781. X * provided that: (1) source distributions retain this entire copyright
  1782. X * notice and comment, and (2) distributions including binaries display
  1783. X * the following acknowledgement:  ``This product includes software
  1784. X * developed by the University of California, Berkeley and its contributors''
  1785. X * in the documentation or other materials provided with the distribution
  1786. X * and in all advertising materials mentioning features or use of this
  1787. X * software. Neither the name of the University nor the names of its
  1788. X * contributors may be used to endorse or promote products derived
  1789. X * from this software without specific prior written permission.
  1790. X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  1791. X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  1792. X * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  1793. X */
  1794. X
  1795. X#if defined(LIBC_SCCS) && !defined(lint)
  1796. Xstatic char sccsid[] = "@(#)strtol.c    5.3 (Berkeley) 5/17/90";
  1797. X#endif /* LIBC_SCCS and not lint */
  1798. X
  1799. X#include <ctype.h>
  1800. X#include <errno.h>
  1801. X
  1802. X#define    ULONG_MAX    0xffffffff    /* max value for an unsigned long */
  1803. X#define    LONG_MAX    0x7fffffff    /* max value for a long */
  1804. X#define    LONG_MIN    0x80000000    /* min value for a long */
  1805. X
  1806. X/*
  1807. X * Convert a string to a long integer.
  1808. X *
  1809. X * Ignores `locale' stuff.  Assumes that the upper and lower case
  1810. X * alphabets and digits are each contiguous.
  1811. X */
  1812. Xlong
  1813. Xstrtol(nptr, endptr, base)
  1814. X    char *nptr, **endptr;
  1815. X    register int base;
  1816. X{
  1817. X    register char *s = nptr;
  1818. X    register unsigned long acc;
  1819. X    register int c;
  1820. X    register unsigned long cutoff;
  1821. X    register int neg = 0, any, cutlim;
  1822. X
  1823. X    /*
  1824. X     * Skip white space and pick up leading +/- sign if any.
  1825. X     * If base is 0, allow 0x for hex and 0 for octal, else
  1826. X     * assume decimal; if base is already 16, allow 0x.
  1827. X     */
  1828. X    do {
  1829. X        c = *s++;
  1830. X    } while (isspace(c));
  1831. X    if (c == '-') {
  1832. X        neg = 1;
  1833. X        c = *s++;
  1834. X    } else if (c == '+')
  1835. X        c = *s++;
  1836. X    if ((base == 0 || base == 16) &&
  1837. X        c == '0' && (*s == 'x' || *s == 'X')) {
  1838. X        c = s[1];
  1839. X        s += 2;
  1840. X        base = 16;
  1841. X    }
  1842. X    if (base == 0)
  1843. X        base = c == '0' ? 8 : 10;
  1844. X
  1845. X    /*
  1846. X     * Compute the cutoff value between legal numbers and illegal
  1847. X     * numbers.  That is the largest legal value, divided by the
  1848. X     * base.  An input number that is greater than this value, if
  1849. X     * followed by a legal input character, is too big.  One that
  1850. X     * is equal to this value may be valid or not; the limit
  1851. X     * between valid and invalid numbers is then based on the last
  1852. X     * digit.  For instance, if the range for longs is
  1853. X     * [-2147483648..2147483647] and the input base is 10,
  1854. X     * cutoff will be set to 214748364 and cutlim to either
  1855. X     * 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated
  1856. X     * a value > 214748364, or equal but the next digit is > 7 (or 8),
  1857. X     * the number is too big, and we will return a range error.
  1858. X     *
  1859. X     * Set any if any `digits' consumed; make it negative to indicate
  1860. X     * overflow.
  1861. X     */
  1862. X    cutoff = neg ? -(unsigned long)LONG_MIN : LONG_MAX;
  1863. X    cutlim = cutoff % (unsigned long)base;
  1864. X    cutoff /= (unsigned long)base;
  1865. X    for (acc = 0, any = 0; c = *s++) {
  1866. X        if (isdigit(c))
  1867. X            c -= '0';
  1868. X        else if (isalpha(c))
  1869. X            c -= isupper(c) ? 'A' - 10 : 'a' - 10;
  1870. X        else
  1871. X            break;
  1872. X        if (c >= base)
  1873. X            break;
  1874. X        if (any < 0 || acc > cutoff || acc == cutoff && c > cutlim)
  1875. X            any = -1;
  1876. X        else {
  1877. X            any = 1;
  1878. X            acc *= base;
  1879. X            acc += c;
  1880. X        }
  1881. X    }
  1882. X    if (any < 0) {
  1883. X        acc = neg ? LONG_MIN : LONG_MAX;
  1884. X        errno = ERANGE;
  1885. X    } else if (neg)
  1886. X        acc = -acc;
  1887. X    if (endptr != 0)
  1888. X        *endptr = any ? s - 1 : nptr;
  1889. X    return (acc);
  1890. X}
  1891. X#endif
  1892. END_OF_FILE
  1893. if test 26813 -ne `wc -c <'main.c'`; then
  1894.     echo shar: \"'main.c'\" unpacked with wrong size!
  1895. fi
  1896. # end of 'main.c'
  1897. fi
  1898. echo shar: End of archive 16 \(of 27\).
  1899. cp /dev/null ark16isdone
  1900. MISSING=""
  1901. 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 ; do
  1902.     if test ! -f ark${I}isdone ; then
  1903.     MISSING="${MISSING} ${I}"
  1904.     fi
  1905. done
  1906. if test "${MISSING}" = "" ; then
  1907.     echo You have unpacked all 27 archives.
  1908.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1909. else
  1910.     echo You still need to unpack the following archives:
  1911.     echo "        " ${MISSING}
  1912. fi
  1913. ##  End of shell archive.
  1914. exit 0
  1915.  
  1916. exit 0 # Just in case...
  1917. -- 
  1918.   // chris@IMD.Sterling.COM       | Send comp.sources.x submissions to:
  1919. \X/  Amiga - The only way to fly! |    sources-x@imd.sterling.com
  1920.  "It's intuitively obvious to the |
  1921.   most casual observer..."        | GCS d+/-- p+ c++ l+ m+ s++/+ g+ w+ t+ r+ x+
  1922.