home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / procssng / ccs / ccs-11tl.lha / lbl / xview / segal / cursor.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-09-23  |  9.1 KB  |  367 lines

  1. /*
  2.  *  cursor.c   routines for handling cursors   -Brian Tierney, LBL
  3.  *   for use with segal
  4.  *
  5.  *   these routines handle the creation of various sized square and
  6.  *       round paint and erase cursors.
  7.  */
  8.  
  9. #include "common.h"
  10.  
  11. Xv_singlecolor fg;        /* color for the cursor */
  12.  
  13. /*************************************************/
  14. void
  15. set_watch_cursor()
  16. {
  17.     int i;
  18.  
  19.     For_all_windows XDefineCursor(display, win[i].xid, watch_cursor);
  20.     XFlush(display);
  21. }
  22.  
  23. /***********************************************/
  24. void
  25. unset_watch_cursor()
  26. {
  27.     void change_cursor_proc();
  28.  
  29.     int i;
  30.  
  31.     For_all_windows XUndefineCursor(display, win[i].xid);
  32.     change_cursor_proc();
  33. }
  34.  
  35. /***************************************************************/
  36. void
  37. change_cursor_proc()
  38. {
  39.     if(brush.mask_affect == MASK_PAINT) {
  40.         if(brush.shape == BRUSH_ROUND)
  41.             xv_set(canvas_paint_window(Paint_win_paint->canvas),
  42.                 WIN_CURSOR, my_cursor[brush.size][win[WIN_PAINT].zoom_mag-1].paint,
  43.                 NULL);
  44.         else
  45.             xv_set(canvas_paint_window(Paint_win_paint->canvas),
  46.                 WIN_CURSOR, my_cursor[brush.size][win[WIN_PAINT].zoom_mag-1].sq_paint,
  47.                 NULL);
  48.     }
  49.     else {
  50.         if(brush.shape == BRUSH_ROUND)
  51.             xv_set(canvas_paint_window(Paint_win_paint->canvas),
  52.                 WIN_CURSOR, my_cursor[brush.size][win[WIN_PAINT].zoom_mag-1].erase,
  53.                 NULL);
  54.         else
  55.             xv_set(canvas_paint_window(Paint_win_paint->canvas),
  56.                 WIN_CURSOR, my_cursor[brush.size][win[WIN_PAINT].zoom_mag-1].sq_erase,
  57.                 NULL);
  58.     }
  59.     XFlush(display);
  60. }
  61.  
  62. /******************************************************/
  63. void
  64. create_cursors()
  65. {
  66.     void make_box_cursor();
  67.     void make_round_cursor();
  68.  
  69.     int i, bsize, mag, size;
  70.  
  71.     vprint_if" creating edit cursors... \n");
  72.  
  73. #define RED_CURSOR
  74.  
  75. #ifdef BLUE_CURSOR
  76.     fg.green = 255, fg.blue = 255, fg.red = 0;    /* blue  cursors */
  77. #endif
  78. #ifdef YELLOW_CURSOR
  79.     fg.green = 255, fg.blue = 0, fg.red = 255;    /* yellow  cursors */
  80. #endif
  81. #ifdef RED_CURSOR
  82.     fg.green = 0, fg.blue = 0, fg.red = 255;    /* red  cursors */
  83. #endif
  84.  
  85.     for (bsize = 0; bsize < NUM_BRUSH_SIZES; bsize++) /* 1..5, 10, 20 */
  86.     for (mag = 0; mag < MAX_ZOOM_MAG; mag++) {
  87.         if (bsize == 5) /* index # 5 is 10x10 cursor */
  88.         size = (mag+1) * 10;
  89.         else if (bsize == 6) /* index # 6 is 20x20 cursor */
  90.         size = (mag+1) * 20;
  91.         else
  92.         size = (mag+1) * (bsize+1);
  93.  
  94.         make_box_cursor(bsize, mag, size);
  95.         make_round_cursor(bsize, mag, size);
  96.     }
  97. }
  98.  
  99. /******************************************************/
  100. void
  101. make_box_cursor(bsize, mag, box_size)
  102. int bsize, mag, box_size;
  103. {
  104.     Server_image serv_image;
  105.     Pixmap    pixmap;
  106.     GC        cgc;
  107.     XGCValues gcvalues;
  108.     int       size, hot;
  109.  
  110.     if (box_size <= 18)        /* min cursor size */
  111.     size = 20;
  112.     else
  113.     size = box_size + 2;
  114.  
  115.     serv_image = (Server_image) xv_create(XV_NULL, SERVER_IMAGE,
  116.                       XV_WIDTH, size,
  117.                       XV_HEIGHT, size,
  118.                       NULL);
  119.  
  120.     pixmap = (Pixmap) xv_get(serv_image, XV_XID, NULL);
  121.  
  122.     /* make paint cursor */
  123.     gcvalues.foreground = 0;
  124.     gcvalues.background = 1;
  125.     cgc = XCreateGC(display, pixmap,
  126.             GCForeground | GCBackground, &gcvalues);
  127.     XFillRectangle(display, pixmap, cgc, 0, 0, size, size);
  128.  
  129.     gcvalues.foreground = 1;
  130.     gcvalues.background = 0;
  131.     XChangeGC(display, cgc, GCForeground | GCBackground, &gcvalues);
  132.  
  133.     hot = (size - box_size) / 2;/* upper, left corner */
  134.  
  135.     /* draw paint cursor shape into pixmap */
  136.     XDrawLine(display, pixmap, cgc, 1, 1, hot, hot);
  137.     XDrawRectangle(display, pixmap, cgc, hot - 1, hot - 1,
  138.            box_size, box_size);
  139.  
  140.     my_cursor[bsize][mag].sq_paint = xv_create(XV_NULL, CURSOR,
  141.                      CURSOR_IMAGE, serv_image,
  142.                      CURSOR_XHOT, hot,
  143.                      CURSOR_YHOT, hot,
  144.                      CURSOR_FOREGROUND_COLOR, &fg,
  145.                      NULL);
  146.  
  147.     /* make erase cursor */
  148.     gcvalues.foreground = 0;
  149.     gcvalues.background = 1;
  150.     XChangeGC(display, cgc, GCForeground | GCBackground, &gcvalues);
  151.     XFillRectangle(display, pixmap, cgc, 0, 0, size, size);
  152.  
  153.     gcvalues.foreground = 1;
  154.     gcvalues.background = 0;
  155.     XChangeGC(display, cgc, GCForeground | GCBackground, &gcvalues);
  156.  
  157.     /* draw cursor shape into pixmap */
  158.     XDrawRectangle(display, pixmap, cgc, hot - 1, hot - 1,
  159.            box_size, box_size);
  160.     /* draw X thru box (plus handle ) for erase cursor */
  161.     XDrawLine(display, pixmap, cgc, 1, size - 3, hot + box_size - 1, hot - 1);
  162.     XDrawLine(display, pixmap, cgc, hot - 1, hot - 1,
  163.           hot + box_size - 1, hot + box_size - 1);
  164.  
  165.     my_cursor[bsize][mag].sq_erase = xv_create(XV_NULL, CURSOR,
  166.                      CURSOR_IMAGE, serv_image,
  167.                      CURSOR_XHOT, hot,
  168.                      CURSOR_YHOT, hot,
  169.                      CURSOR_FOREGROUND_COLOR, &fg,
  170.                      NULL);
  171.     XFreeGC(display, cgc);
  172. }
  173.  
  174. /******************************************************/
  175. void
  176. make_round_cursor(bsize, mag, cir_size)
  177. int bsize, mag, cir_size;
  178. {
  179.     Server_image serv_image;
  180.     Pixmap    pixmap;
  181.     GC        cgc;
  182.     XGCValues gcvalues;
  183.     int       start, s1, s2, hot;
  184.     float     val;
  185.     u_char  **alloc_2d_byte_array();
  186.  
  187. /* #define CDEBUG */
  188.  
  189.     if (cir_size <= 20)        /* minimum size */
  190.     my_cursor[bsize][mag].size = 24;
  191.     else
  192.     my_cursor[bsize][mag].size = cir_size + 4;
  193.     my_cursor[bsize][mag].radius = cir_size / 2;
  194.  
  195. #ifdef CDEBUG
  196.     fprintf(stderr, "bsize, mag: %d,   size: %d, diam: %d, rad: %d \n",
  197.         bsize, mag, my_cursor[bsize][mag].size, cir_size,
  198.         my_cursor[bsize][mag].radius);
  199. #endif
  200.  
  201.     serv_image = (Server_image) xv_create(XV_NULL, SERVER_IMAGE,
  202.         XV_WIDTH, my_cursor[bsize][mag].size,
  203.         XV_HEIGHT, my_cursor[bsize][mag].size,
  204.         NULL);
  205.  
  206.     pixmap = (Pixmap) xv_get(serv_image, XV_XID, NULL);
  207.  
  208.     /* make paint cursor */
  209.     gcvalues.foreground = 0;
  210.     gcvalues.background = 1;
  211.     cgc = XCreateGC(display, pixmap,
  212.         GCForeground | GCBackground, &gcvalues);
  213.  
  214.     /* clear server image */
  215.     XFillRectangle(display, pixmap, cgc, 0, 0,
  216.         my_cursor[bsize][mag].size, my_cursor[bsize][mag].size);
  217.  
  218.     gcvalues.foreground = 1;
  219.     gcvalues.background = 0;
  220.     XChangeGC(display, cgc, GCForeground | GCBackground, &gcvalues);
  221.  
  222.     hot = my_cursor[bsize][mag].size / 2;    /* center of circle */
  223.     start = hot - my_cursor[bsize][mag].radius;
  224.  
  225.     /* upper left hand corner */
  226.     my_cursor[bsize][mag].corner = start;
  227.  
  228.     /* draw cursor shape into pixmap */
  229.     XDrawLine(display, pixmap, cgc, 1, 1, hot, hot);
  230.     XDrawPoint(display, pixmap, cgc, start, start);
  231.     XDrawArc(display, pixmap, cgc, start, start,
  232.         cir_size, cir_size,
  233.         0, 360 * 64);
  234.  
  235.     my_cursor[bsize][mag].paint = xv_create(XV_NULL, CURSOR,
  236.         CURSOR_IMAGE, serv_image,
  237.         CURSOR_XHOT, start,
  238.         CURSOR_YHOT, start,
  239.         CURSOR_FOREGROUND_COLOR, &fg,
  240.         NULL);
  241.  
  242.     /* make erase cursor */
  243.     gcvalues.foreground = 0;
  244.     gcvalues.background = 1;
  245.     XChangeGC(display, cgc, GCForeground | GCBackground, &gcvalues);
  246.     XFillRectangle(display, pixmap, cgc, 0, 0,
  247.         my_cursor[bsize][mag].size, my_cursor[bsize][mag].size);
  248.  
  249.     gcvalues.foreground = 1;
  250.     gcvalues.background = 0;
  251.     XChangeGC(display, cgc, GCForeground | GCBackground, &gcvalues);
  252.  
  253.     /* draw cursor shape into pixmap */
  254.     XDrawLine(display, pixmap, cgc, 1, my_cursor[bsize][mag].size - 1,
  255.         hot, hot);
  256.     XDrawArc(display, pixmap, cgc, start, start,
  257.         cir_size, cir_size, 0, 360 * 64);
  258.  
  259.     /* draw X thru circle for erase cursor */
  260.     val = (cir_size / 2.) * (cir_size / 2.);
  261.     s1 = hot - (int) sqrt((double) (val / 2.));
  262.     s2 = hot + (int) sqrt((double) (val / 2.));
  263.  
  264.     XDrawLine(display, pixmap, cgc, s1, s1, s2, s2);
  265.     XDrawLine(display, pixmap, cgc, s1, s2, s2, s1);
  266.  
  267.     my_cursor[bsize][mag].erase = xv_create(XV_NULL, CURSOR,
  268.         CURSOR_IMAGE, serv_image,
  269.         CURSOR_XHOT, start,
  270.         CURSOR_YHOT, start,
  271.         CURSOR_FOREGROUND_COLOR, &fg,
  272.         NULL);
  273.  
  274.     /* build paint mask matrix */
  275.     /* in SEGAL 3d, only one of these matrices is needed */
  276.     if(mag == 0) {
  277.         my_cursor[bsize][mag].paint_mask_matrix =
  278.         alloc_2d_byte_array(my_cursor[bsize][mag].size,
  279.             my_cursor[bsize][mag].size);
  280.  
  281.         build_paint_mask_matrix(my_cursor[bsize][mag].radius,
  282.             (my_cursor[bsize][mag].size / 2),
  283.             my_cursor[bsize][mag].paint_mask_matrix);
  284.  
  285. #ifdef CDEBUG
  286.         if (my_cursor[bsize][mag].size < 40)
  287.         show_mask(my_cursor[bsize][mag].paint_mask_matrix,
  288.             my_cursor[bsize][mag].size);
  289. #endif
  290.     }
  291.  
  292.     XFreeGC(display, cgc);
  293. }
  294.  
  295. /*****************************************/
  296. build_paint_mask_matrix(radius, shift, mask)
  297.     int       radius, shift;
  298.     u_char  **mask;
  299.  /*
  300.   * this routine inspired by routine on page 445 of Foley & Van Dam which is
  301.   * accredited to J. Michner
  302.   */
  303. {
  304.     int       x, y, d;
  305.  
  306.     x = 0;
  307.     y = radius;
  308.     d = 3 - 2 * radius;
  309.  
  310.     while (x < y) {
  311.     set_points(x, y, shift, mask);
  312.     if (d < 0)
  313.         d = d + 4 * x + 6;
  314.     else {
  315.         d = d + 4 * (x - y) + 10;
  316.         y--;
  317.     }
  318.     x++;
  319.     }
  320.     if (x == y)
  321.     set_points(x, y, shift, mask);
  322. }
  323.  
  324. /**************************************/
  325. set_points(x, y, shift, mask)
  326.     int       x, y, shift;
  327.     u_char  **mask;
  328. {
  329.     int       x1, y1, x2, y2;
  330.     register int i;
  331.  
  332.     /* shift origin */
  333.     x1 = x + shift;
  334.     x2 = -x + shift;
  335.     y1 = y + shift;
  336.     y2 = -y + shift;
  337.  
  338.     for (i = x2; i <= x1; i++) {
  339.     mask[i][y1] = TRUE;
  340.     mask[i][y2] = TRUE;
  341.     }
  342.     for (i = y2; i <= y1; i++) {
  343.     mask[i][x1] = TRUE;
  344.     mask[i][x2] = TRUE;
  345.     }
  346. }
  347.  
  348. /*************************************************/
  349. #ifdef CDEBUG
  350. show_mask(mask, size)        /* for debugging */
  351.     u_char  **mask;
  352.     int       size;
  353. {
  354.     int       x, y;
  355.  
  356.     fprintf(stderr, " \n\n mask size %d is: ", size);
  357.     for (y = 0; y < size; y++) {
  358.     fprintf(stderr, " \n");
  359.     for (x = 0; x < size; x++) {
  360.         fprintf(stderr, "%d ", mask[y][x]);
  361.     }
  362.     }
  363.     fprintf(stderr, "\n");
  364. }
  365.  
  366. #endif
  367.