home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / amiga / gui / x / xfig.lha / src / x11 / u_search.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-07-26  |  18.8 KB  |  843 lines

  1. /*
  2.  * FIG : Facility for Interactive Generation of figures
  3.  * Copyright (c) 1985 by Supoj Sutanthavibul
  4.  *
  5.  * "Permission to use, copy, modify, distribute, and sell this software and its
  6.  * documentation for any purpose is hereby granted without fee, provided that
  7.  * the above copyright notice appear in all copies and that both the copyright
  8.  * notice and this permission notice appear in supporting documentation. 
  9.  * No representations are made about the suitability of this software for 
  10.  * any purpose.  It is provided "as is" without express or implied warranty."
  11.  */
  12.  
  13. #include "fig.h"
  14. #include "resources.h"
  15. #include "object.h"
  16. #include "mode.h"
  17. #include "u_list.h"
  18. #include "w_zoom.h"
  19.  
  20. #define TOLERANCE 3
  21.  
  22. static        (*manipulate) ();
  23. static        (*handlerproc_left) ();
  24. static        (*handlerproc_middle) ();
  25. static        (*handlerproc_right) ();
  26. static int    type;
  27. static long    objectcount;
  28. static long    n;
  29. static int    csr_x, csr_y;
  30.  
  31. static F_point    point1, point2;
  32.  
  33. static F_arc   *a;
  34. static F_ellipse *e;
  35. static F_line  *l;
  36. static F_spline *s;
  37. static F_text  *t;
  38. static F_compound *c;
  39.  
  40. char
  41. next_arc_found(x, y, tolerance, px, py, shift)
  42.     int            x, y, tolerance, *px, *py;
  43.     int            shift;
  44. {                /* (px, py) is the control point on the
  45.                  * circumference of an arc which is the
  46.                  * closest to (x, y)                 */
  47.  
  48.     int            i;
  49.  
  50.     if (!arc_in_mask())
  51.     return (0);
  52.     if (a == NULL)
  53.     a = last_arc(objects.arcs);
  54.     else if (shift)
  55.     a = prev_arc(objects.arcs, a);
  56.  
  57.     for (; a != NULL; a = prev_arc(objects.arcs, a), n++) {
  58.     for (i = 0; i < 3; i++)
  59.         if ((abs(a->point[i].x - x) <= tolerance) &&
  60.         (abs(a->point[i].y - y) <= tolerance)) {
  61.         *px = a->point[i].x;
  62.         *py = a->point[i].y;
  63.         return (1);
  64.         }
  65.     }
  66.     return (0);
  67. }
  68.  
  69.  
  70. char
  71. next_ellipse_found(x, y, tolerance, px, py, shift)
  72.     int            x, y, tolerance, *px, *py;
  73.     int            shift;
  74. {                /* (px, py) is the point on the circumference
  75.                  * of an ellipse which is the closest to (x,
  76.                  * y)                 */
  77.  
  78.     int            a, b, dx, dy;
  79.     float        dis, r, tol;
  80.  
  81.     if (!ellipse_in_mask())
  82.     return (0);
  83.     if (e == NULL)
  84.     e = last_ellipse(objects.ellipses);
  85.     else if (shift)
  86.     e = prev_ellipse(objects.ellipses, e);
  87.  
  88.     tol = (float) tolerance;
  89.     for (; e != NULL; e = prev_ellipse(objects.ellipses, e), n++) {
  90.     dx = x - e->center.x;
  91.     dy = y - e->center.y;
  92.     a = e->radiuses.x;
  93.     b = e->radiuses.y;
  94.     /* prevent sqrt(0) core dumps */
  95.     if (dx == 0 && dy == 0)
  96.         dis = 0;        /* so we return below */
  97.     else
  98.         dis = sqrt((double) (dx * dx + dy * dy));
  99.     if (dis < tol) {
  100.         *px = e->center.x;
  101.         *py = e->center.y;
  102.         return (1);
  103.     }
  104.     if (abs(x - e->start.x) <= tolerance && abs(y - e->start.y) <= tolerance) {
  105.         *px = e->start.x;
  106.         *py = e->start.y;
  107.         return (1);
  108.     }
  109.     if (abs(x - e->end.x) <= tolerance && abs(y - e->end.y) <= tolerance) {
  110.         *px = e->end.x;
  111.         *py = e->end.y;
  112.         return (1);
  113.     }
  114.     if (a * dy == 0 && b * dx == 0)
  115.         r = 0;        /* prevent core dumps */
  116.     else
  117.         r = a * b * dis / sqrt((double) (1.0 * b * b * dx * dx + 1.0 * a * a * dy * dy));
  118.     if (fabs(dis - r) <= tol) {
  119.         *px = (int) (r * dx / dis + ((dx < 0) ? -.5 : .5)) + e->center.x;
  120.         *py = (int) (r * dy / dis + ((dy < 0) ? -.5 : .5)) + e->center.y;
  121.         return (1);
  122.     }
  123.     }
  124.     return (0);
  125. }
  126.  
  127. char
  128. next_line_found(x, y, tolerance, px, py, shift)
  129.     int            x, y, tolerance, *px, *py, shift;
  130. {                /* return the pointer to lines object if the
  131.                  * search is successful otherwise return
  132.                  * NULL.  The value returned via (px, py) is
  133.                  * the closest point on the vector to point
  134.                  * (x, y)                     */
  135.  
  136.     F_point       *point;
  137.     int            x1, y1, x2, y2;
  138.     float        tol2;
  139.  
  140.     tol2 = (float) tolerance *tolerance;
  141.  
  142.     if (!anyline_in_mask())
  143.     return (0);
  144.     if (l == NULL)
  145.     l = last_line(objects.lines);
  146.     else if (shift)
  147.     l = prev_line(objects.lines, l);
  148.  
  149.     for (; l != NULL; l = prev_line(objects.lines, l))
  150.     if (validline_in_mask(l)) {
  151.         n++;
  152.         point = l->points;
  153.         x1 = point->x;
  154.         y1 = point->y;
  155.         if (abs(x - x1) <= tolerance && abs(y - y1) <= tolerance) {
  156.         *px = x1;
  157.         *py = y1;
  158.         return (1);
  159.         }
  160.         for (point = point->next; point != NULL; point = point->next) {
  161.         x2 = point->x;
  162.         y2 = point->y;
  163.         if (close_to_vector(x1, y1, x2, y2, x, y, tolerance, tol2,
  164.                     px, py))
  165.             return (1);
  166.         x1 = x2;
  167.         y1 = y2;
  168.         }
  169.     }
  170.     return (0);
  171. }
  172.  
  173. char
  174. next_spline_found(x, y, tolerance, px, py, shift)
  175.     int            x, y, tolerance, *px, *py;
  176.     int            shift;
  177. {                /* return the pointer to lines object if the
  178.                  * search is successful otherwise return
  179.                  * NULL.  */
  180.  
  181.     F_point       *point;
  182.     int            x1, y1, x2, y2;
  183.     float        tol2;
  184.  
  185.     if (!anyspline_in_mask())
  186.     return (0);
  187.     if (s == NULL)
  188.     s = last_spline(objects.splines);
  189.     else if (shift)
  190.     s = prev_spline(objects.splines, s);
  191.  
  192.     tol2 = (float) tolerance *tolerance;
  193.  
  194.     for (; s != NULL; s = prev_spline(objects.splines, s))
  195.     if (validspline_in_mask(s)) {
  196.         n++;
  197.         point = s->points;
  198.         x1 = point->x;
  199.         y1 = point->y;
  200.         for (point = point->next; point != NULL; point = point->next) {
  201.         x2 = point->x;
  202.         y2 = point->y;
  203.         if (close_to_vector(x1, y1, x2, y2, x, y, tolerance, tol2,
  204.                     px, py))
  205.             return (1);
  206.         x1 = x2;
  207.         y1 = y2;
  208.         }
  209.     }
  210.     return (0);
  211. }
  212.  
  213. char
  214. next_text_found(x, y, tolerance, px, py, shift)
  215.     int            x, y, tolerance, *px, *py;
  216.     int            shift;
  217. {
  218.     int            halflen, dx, dy;
  219.     int            txmin, txmax, tymin, tymax;
  220.  
  221.     if (!anytext_in_mask())
  222.     return (0);
  223.     if (t == NULL)
  224.     t = last_text(objects.texts);
  225.     else if (shift)
  226.     t = prev_text(objects.texts, t);
  227.  
  228.     for (; t != NULL; t = prev_text(objects.texts, t))
  229.     if (validtext_in_mask(t)) {
  230.         n++;
  231.         text_bound(t, &txmin, &tymin, &txmax, &tymax);
  232.         if (x >= txmin-tolerance && x <= txmax+tolerance &&
  233.             y >= tymin-tolerance && y <= tymax+tolerance) {
  234.             *px = x;
  235.             *py = y;
  236.             return (1);
  237.         }
  238.     }
  239.     return (0);
  240. }
  241.  
  242. int
  243. next_compound_found(x, y, tolerance, px, py, shift)
  244.     int            x, y, tolerance, *px, *py;
  245.     int            shift;
  246. {
  247.     float        tol2;
  248.  
  249.     if (!compound_in_mask())
  250.     return (0);
  251.     if (c == NULL)
  252.     c = last_compound(objects.compounds);
  253.     else if (shift)
  254.     c = prev_compound(objects.compounds, c);
  255.  
  256.     tol2 = tolerance * tolerance;
  257.  
  258.     for (; c != NULL; c = prev_compound(objects.compounds, c), n++) {
  259.     if (close_to_vector(c->nwcorner.x, c->nwcorner.y, c->nwcorner.x,
  260.                 c->secorner.y, x, y, tolerance, tol2, px, py))
  261.         return (1);
  262.     if (close_to_vector(c->secorner.x, c->secorner.y, c->nwcorner.x,
  263.                 c->secorner.y, x, y, tolerance, tol2, px, py))
  264.         return (1);
  265.     if (close_to_vector(c->secorner.x, c->secorner.y, c->secorner.x,
  266.                 c->nwcorner.y, x, y, tolerance, tol2, px, py))
  267.         return (1);
  268.     if (close_to_vector(c->nwcorner.x, c->nwcorner.y, c->secorner.x,
  269.                 c->nwcorner.y, x, y, tolerance, tol2, px, py))
  270.         return (1);
  271.     }
  272.     return (0);
  273. }
  274.  
  275. show_objecthighlight()
  276. {
  277.     if (highlighting)
  278.     return;
  279.     highlighting = 1;
  280.     toggle_objecthighlight();
  281. }
  282.  
  283. erase_objecthighlight()
  284. {
  285.     if (!highlighting)
  286.     return;
  287.     highlighting = 0;
  288.     toggle_objecthighlight();
  289.     if (type == -1) {
  290.     e = NULL;
  291.     type = O_ELLIPSE;
  292.     }
  293. }
  294.  
  295. toggle_objecthighlight()
  296. {
  297.     switch (type) {
  298.     case O_ELLIPSE:
  299.     toggle_ellipsehighlight(e);
  300.     break;
  301.     case O_POLYLINE:
  302.     toggle_linehighlight(l);
  303.     break;
  304.     case O_SPLINE:
  305.     toggle_splinehighlight(s);
  306.     break;
  307.     case O_TEXT:
  308.     toggle_texthighlight(t);
  309.     break;
  310.     case O_ARC:
  311.     toggle_archighlight(a);
  312.     break;
  313.     case O_COMPOUND:
  314.     toggle_compoundhighlight(c);
  315.     break;
  316.     default:
  317.     toggle_csrhighlight(csr_x, csr_y);
  318.     }
  319. }
  320.  
  321. static void
  322. init_search()
  323. {
  324.     if (highlighting)
  325.     erase_objecthighlight();
  326.     else {
  327.     objectcount = 0;
  328.     if (ellipse_in_mask())
  329.         for (e = objects.ellipses; e != NULL; e = e->next)
  330.         objectcount++;
  331.     if (anyline_in_mask())
  332.         for (l = objects.lines; l != NULL; l = l->next)
  333.         if (validline_in_mask(l))
  334.             objectcount++;
  335.     if (anyspline_in_mask())
  336.         for (s = objects.splines; s != NULL; s = s->next)
  337.         if (validspline_in_mask(s))
  338.             objectcount++;
  339.     if (anytext_in_mask())
  340.         for (t = objects.texts; t != NULL; t = t->next)
  341.         if (validtext_in_mask(t))
  342.             objectcount++;
  343.     if (arc_in_mask())
  344.         for (a = objects.arcs; a != NULL; a = a->next)
  345.         objectcount++;
  346.     if (compound_in_mask())
  347.         for (c = objects.compounds; c != NULL; c = c->next)
  348.         objectcount++;
  349.     e = NULL;
  350.     type = O_ELLIPSE;
  351.     }
  352. }
  353.  
  354. void
  355. do_object_search(x, y, shift)
  356.     int            x, y;
  357.     unsigned int    shift;    /* Shift Key Status from XEvent */
  358. {
  359.     int            px, py;
  360.     char        found = 0;
  361.  
  362.     init_search();
  363.     for (n = 0; n < objectcount;) {
  364.     switch (type) {
  365.     case O_ELLIPSE:
  366.         found = next_ellipse_found(x, y, TOLERANCE, &px, &py, shift);
  367.         break;
  368.     case O_POLYLINE:
  369.         found = next_line_found(x, y, TOLERANCE, &px, &py, shift);
  370.         break;
  371.     case O_SPLINE:
  372.         found = next_spline_found(x, y, TOLERANCE, &px, &py, shift);
  373.         break;
  374.     case O_TEXT:
  375.         found = next_text_found(x, y, TOLERANCE, &px, &py, shift);
  376.         break;
  377.     case O_ARC:
  378.         found = next_arc_found(x, y, TOLERANCE, &px, &py, shift);
  379.         break;
  380.     case O_COMPOUND:
  381.         found = next_compound_found(x, y, TOLERANCE, &px, &py, shift);
  382.         break;
  383.     }
  384.  
  385.     if (found)
  386.         break;
  387.  
  388.     switch (type) {
  389.     case O_ELLIPSE:
  390.         type = O_POLYLINE;
  391.         l = NULL;
  392.         break;
  393.     case O_POLYLINE:
  394.         type = O_SPLINE;
  395.         s = NULL;
  396.         break;
  397.     case O_SPLINE:
  398.         type = O_TEXT;
  399.         t = NULL;
  400.         break;
  401.     case O_TEXT:
  402.         type = O_ARC;
  403.         a = NULL;
  404.         break;
  405.     case O_ARC:
  406.         type = O_COMPOUND;
  407.         c = NULL;
  408.         break;
  409.     case O_COMPOUND:
  410.         type = O_ELLIPSE;
  411.         e = NULL;
  412.         break;
  413.     }
  414.     }
  415.     if (!found) {        /* nothing found */
  416.     csr_x = x;
  417.     csr_y = y;
  418.     type = -1;
  419.     show_objecthighlight();
  420.     } else if (shift) {        /* show selected object */
  421.     show_objecthighlight();
  422.     } else {            /* user selected an object */
  423.     erase_objecthighlight();
  424.     switch (type) {
  425.     case O_ELLIPSE:
  426.         manipulate(e, type, x, y, px, py);
  427.         break;
  428.     case O_POLYLINE:
  429.         manipulate(l, type, x, y, px, py);
  430.         break;
  431.     case O_SPLINE:
  432.         manipulate(s, type, x, y, px, py);
  433.         break;
  434.     case O_TEXT:
  435.         manipulate(t, type, x, y, px, py);
  436.         break;
  437.     case O_ARC:
  438.         manipulate(a, type, x, y, px, py);
  439.         break;
  440.     case O_COMPOUND:
  441.         manipulate(c, type, x, y, px, py);
  442.         break;
  443.     }
  444.     }
  445. }
  446.  
  447. object_search_left(x, y, shift)
  448.     int            x, y;
  449.     unsigned int    shift;    /* Shift Key Status from XEvent */
  450. {
  451.     manipulate = handlerproc_left;
  452.     do_object_search(x, y, shift);
  453. }
  454.  
  455. object_search_middle(x, y, shift)
  456.     int            x, y;
  457.     unsigned int    shift;    /* Shift Key Status from XEvent */
  458. {
  459.     manipulate = handlerproc_middle;
  460.     do_object_search(x, y, shift);
  461. }
  462.  
  463. object_search_right(x, y, shift)
  464.     int            x, y;
  465.     unsigned int    shift;    /* Shift Key Status from XEvent */
  466. {
  467.     manipulate = handlerproc_right;
  468.     do_object_search(x, y, shift);
  469. }
  470.  
  471. char
  472. next_ellipse_point_found(x, y, tol, point_num, shift)
  473.     int            x, y, tol, shift, *point_num;
  474.  
  475. /* dirty trick - point_num is called as a `F_point *point_num' */
  476. {
  477.  
  478.     if (!ellipse_in_mask())
  479.     return (0);
  480.     if (e == NULL)
  481.     e = last_ellipse(objects.ellipses);
  482.     else if (shift)
  483.     e = prev_ellipse(objects.ellipses, e);
  484.  
  485.     for (; e != NULL; e = prev_ellipse(objects.ellipses, e), n++) {
  486.     if (abs(e->start.x - x) <= tol && abs(e->start.y - y) <= tol) {
  487.         *point_num = 0;
  488.         return (1);
  489.     }
  490.     if (abs(e->end.x - x) <= tol && abs(e->end.y - y) <= tol) {
  491.         *point_num = 1;
  492.         return (1);
  493.     }
  494.     }
  495.     return (0);
  496. }
  497.  
  498. char
  499. next_arc_point_found(x, y, tol, point_num, shift)
  500.     int            x, y, tol, shift, *point_num;
  501.  
  502. /* dirty trick - point_num is called as a `F_point *point_num' */
  503. {
  504.     int            i;
  505.  
  506.     if (!arc_in_mask())
  507.     return (0);
  508.     if (a == NULL)
  509.     a = last_arc(objects.arcs);
  510.     else if (shift)
  511.     a = prev_arc(objects.arcs, a);
  512.  
  513.     for (; a != NULL; a = prev_arc(objects.arcs, a), n++) {
  514.     for (i = 0; i < 3; i++) {
  515.         if (abs(a->point[i].x - x) <= tol &&
  516.         abs(a->point[i].y - y) <= tol) {
  517.         *point_num = i;
  518.         return (1);
  519.         }
  520.     }
  521.     }
  522.     return (0);
  523. }
  524.  
  525. char
  526. next_spline_point_found(x, y, tol, p, q, shift)
  527.     int            x, y, tol, shift;
  528.     F_point      **p, **q;
  529. {
  530.     if (!anyspline_in_mask())
  531.     return (0);
  532.     if (s == NULL)
  533.     s = last_spline(objects.splines);
  534.     else if (shift)
  535.     s = prev_spline(objects.splines, s);
  536.  
  537.     for (; s != NULL; s = prev_spline(objects.splines, s))
  538.     if (validspline_in_mask(s)) {
  539.         n++;
  540.         *p = NULL;
  541.         for (*q = s->points; *q != NULL; *p = *q, *q = (*q)->next) {
  542.         if (abs((*q)->x - x) <= tol && abs((*q)->y - y) <= tol)
  543.             return (1);
  544.         }
  545.     }
  546.     return (0);
  547. }
  548.  
  549. char
  550. next_line_point_found(x, y, tol, p, q, shift)
  551.     int            x, y, tol, shift;
  552.     F_point      **p, **q;
  553. {
  554.     F_point       *a, *b;
  555.  
  556.     if (!anyline_in_mask())
  557.     return (0);
  558.     if (l == NULL)
  559.     l = last_line(objects.lines);
  560.     else if (shift)
  561.     l = prev_line(objects.lines, l);
  562.  
  563.     for (; l != NULL; l = prev_line(objects.lines, l))
  564.     if (validline_in_mask(l)) {
  565.         n++;
  566.         for (a = NULL, b = l->points; b != NULL; a = b, b = b->next) {
  567.         if (abs(b->x - x) <= tol && abs(b->y - y) <= tol) {
  568.             *p = a;
  569.             *q = b;
  570.             return (1);
  571.         }
  572.         }
  573.     }
  574.     return (0);
  575. }
  576.  
  577. char
  578. next_compound_point_found(x, y, tol, p, q, shift)
  579.     int            x, y, tol, shift, *p, *q;
  580.  
  581. /* dirty trick - p and q are called with type `F_point' */
  582. {
  583.     if (!compound_in_mask())
  584.     return (0);
  585.     if (c == NULL)
  586.     c = last_compound(objects.compounds);
  587.     else if (shift)
  588.     c = prev_compound(objects.compounds, c);
  589.  
  590.     for (; c != NULL; c = prev_compound(objects.compounds, c), n++) {
  591.     if (abs(c->nwcorner.x - x) <= tol &&
  592.         abs(c->nwcorner.y - y) <= tol) {
  593.         *p = c->nwcorner.x;
  594.         *q = c->nwcorner.y;
  595.         return (1);
  596.     }
  597.     if (abs(c->nwcorner.x - x) <= tol &&
  598.         abs(c->secorner.y - y) <= tol) {
  599.         *p = c->nwcorner.x;
  600.         *q = c->secorner.y;
  601.         return (1);
  602.     }
  603.     if (abs(c->secorner.x - x) <= tol &&
  604.         abs(c->nwcorner.y - y) <= tol) {
  605.         *p = c->secorner.x;
  606.         *q = c->nwcorner.y;
  607.         return (1);
  608.     }
  609.     if (abs(c->secorner.x - x) <= tol &&
  610.         abs(c->secorner.y - y) <= tol) {
  611.         *p = c->secorner.x;
  612.         *q = c->secorner.y;
  613.         return (1);
  614.     }
  615.     }
  616.     return (0);
  617. }
  618.  
  619. void
  620. init_searchproc_left(handlerproc)
  621.     int            (*handlerproc) ();
  622.  
  623. {
  624.     handlerproc_left = handlerproc;
  625. }
  626.  
  627. void
  628. init_searchproc_middle(handlerproc)
  629.     int            (*handlerproc) ();
  630.  
  631. {
  632.     handlerproc_middle = handlerproc;
  633. }
  634.  
  635. void
  636. init_searchproc_right(handlerproc)
  637.     int            (*handlerproc) ();
  638.  
  639. {
  640.     handlerproc_right = handlerproc;
  641. }
  642.  
  643. void
  644. do_point_search(x, y, shift)
  645.     int            x, y;
  646.     unsigned int    shift;    /* Shift Key Status from XEvent */
  647. {
  648.     F_point       *px, *py;
  649.     char        found = 0;
  650.  
  651.     px = &point1;
  652.     py = &point2;
  653.     init_search();
  654.     for (n = 0; n < objectcount;) {
  655.     switch (type) {
  656.     case O_ELLIPSE:
  657.         /* dirty trick - px returns point_num */
  658.         found = next_ellipse_point_found(x, y, TOLERANCE, &px, shift);
  659.         break;
  660.     case O_POLYLINE:
  661.         found = next_line_point_found(x, y, TOLERANCE, &px, &py, shift);
  662.         break;
  663.     case O_SPLINE:
  664.         found = next_spline_point_found(x, y, TOLERANCE, &px, &py, shift);
  665.         break;
  666.     case O_ARC:
  667.         /* dirty trick - px returns point_num */
  668.         found = next_arc_point_found(x, y, TOLERANCE, &px, shift);
  669.         break;
  670.     case O_COMPOUND:
  671.         found = next_compound_point_found(x, y, TOLERANCE, &px, &py, shift);
  672.         break;
  673.     }
  674.     if (found) {
  675.         if (shift)
  676.         show_objecthighlight();
  677.         break;
  678.     }
  679.     switch (type) {
  680.     case O_ELLIPSE:
  681.         type = O_POLYLINE;
  682.         l = NULL;
  683.         break;
  684.     case O_POLYLINE:
  685.         type = O_SPLINE;
  686.         s = NULL;
  687.         break;
  688.     case O_SPLINE:
  689.         type = O_ARC;
  690.         a = NULL;
  691.         break;
  692.     case O_ARC:
  693.         type = O_COMPOUND;
  694.         c = NULL;
  695.         break;
  696.     case O_COMPOUND:
  697.         type = O_ELLIPSE;
  698.         e = NULL;
  699.         break;
  700.     }
  701.     }
  702.     if (!found) {
  703.     csr_x = x;
  704.     csr_y = y;
  705.     type = -1;
  706.     show_objecthighlight();
  707.     } else if (shift) {
  708.     show_objecthighlight();
  709.     } else {
  710.     erase_objecthighlight();
  711.     switch (type) {
  712.     case O_ELLIPSE:
  713.         manipulate(e, type, x, y, px, py);
  714.         break;
  715.     case O_POLYLINE:
  716.         manipulate(l, type, x, y, px, py);
  717.         break;
  718.     case O_SPLINE:
  719.         manipulate(s, type, x, y, px, py);
  720.         break;
  721.     case O_ARC:
  722.         manipulate(a, type, x, y, px, py);
  723.         break;
  724.     case O_COMPOUND:
  725.         manipulate(c, type, x, y, px, py);
  726.         break;
  727.     }
  728.     }
  729. }
  730.  
  731. point_search_left(x, y, shift)
  732.     int            x, y;
  733.     unsigned int    shift;    /* Shift Key Status from XEvent */
  734. {
  735.     manipulate = handlerproc_left;
  736.     do_point_search(x, y, shift);
  737. }
  738.  
  739. point_search_middle(x, y, shift)
  740.     int            x, y;
  741.     unsigned int    shift;    /* Shift Key Status from XEvent */
  742. {
  743.     manipulate = handlerproc_middle;
  744.     do_point_search(x, y, shift);
  745. }
  746.  
  747. point_search_right(x, y, shift)
  748.     int            x, y;
  749.     unsigned int    shift;    /* Shift Key Status from XEvent */
  750. {
  751.     manipulate = handlerproc_right;
  752.     do_point_search(x, y, shift);
  753. }
  754.  
  755. /* =============================================================== */
  756.  
  757. /* These are some of the original search subroutines which are still in use */
  758.  
  759. F_text           *
  760. text_search(x, y)
  761.     int            x, y;
  762. {
  763.     F_text       *t;
  764.     int            xmin, xmax, ymin, ymax;
  765.  
  766.     for (t = objects.texts; t != NULL; t = t->next) {
  767.     text_bound(t, &xmin, &ymin, &xmax, &ymax);
  768.     if (x >= xmin && x <= xmax &&
  769.         y >= ymin && y <= ymax)
  770.         return(t);
  771.     }
  772.     return (NULL);
  773. }
  774.  
  775. F_compound     *
  776. compound_search(x, y, tolerance, px, py)
  777.     int            x, y, tolerance, *px, *py;
  778. {
  779.     F_compound       *c;
  780.     float        tol2;
  781.  
  782.     tol2 = tolerance * tolerance;
  783.  
  784.     for (c = objects.compounds; c != NULL; c = c->next) {
  785.     if (close_to_vector(c->nwcorner.x, c->nwcorner.y, c->nwcorner.x,
  786.                 c->secorner.y, x, y, tolerance, tol2, px, py))
  787.         return (c);
  788.     if (close_to_vector(c->secorner.x, c->secorner.y, c->nwcorner.x,
  789.                 c->secorner.y, x, y, tolerance, tol2, px, py))
  790.         return (c);
  791.     if (close_to_vector(c->secorner.x, c->secorner.y, c->secorner.x,
  792.                 c->nwcorner.y, x, y, tolerance, tol2, px, py))
  793.         return (c);
  794.     if (close_to_vector(c->nwcorner.x, c->nwcorner.y, c->secorner.x,
  795.                 c->nwcorner.y, x, y, tolerance, tol2, px, py))
  796.         return (c);
  797.     }
  798.     return (NULL);
  799. }
  800.  
  801. F_compound     *
  802. compound_point_search(x, y, tol, cx, cy, fx, fy)
  803.     int            x, y, tol, *cx, *cy, *fx, *fy;
  804. {
  805.     F_compound       *c;
  806.  
  807.     for (c = objects.compounds; c != NULL; c = c->next) {
  808.     if (abs(c->nwcorner.x - x) <= tol &&
  809.         abs(c->nwcorner.y - y) <= tol) {
  810.         *cx = c->nwcorner.x;
  811.         *cy = c->nwcorner.y;
  812.         *fx = c->secorner.x;
  813.         *fy = c->secorner.y;
  814.         return (c);
  815.     }
  816.     if (abs(c->nwcorner.x - x) <= tol &&
  817.         abs(c->secorner.y - y) <= tol) {
  818.         *cx = c->nwcorner.x;
  819.         *cy = c->secorner.y;
  820.         *fx = c->secorner.x;
  821.         *fy = c->nwcorner.y;
  822.         return (c);
  823.     }
  824.     if (abs(c->secorner.x - x) <= tol &&
  825.         abs(c->nwcorner.y - y) <= tol) {
  826.         *cx = c->secorner.x;
  827.         *cy = c->nwcorner.y;
  828.         *fx = c->nwcorner.x;
  829.         *fy = c->secorner.y;
  830.         return (c);
  831.     }
  832.     if (abs(c->secorner.x - x) <= tol &&
  833.         abs(c->secorner.y - y) <= tol) {
  834.         *cx = c->secorner.x;
  835.         *cy = c->secorner.y;
  836.         *fx = c->nwcorner.x;
  837.         *fy = c->nwcorner.y;
  838.         return (c);
  839.     }
  840.     }
  841.     return (NULL);
  842. }
  843.