home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / library / dos / diverses / leda / src / graphics / _sunview.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-11-15  |  30.3 KB  |  1,483 lines

  1. /*******************************************************************************
  2. +
  3. +  LEDA  2.1.1                                                 11-15-1991
  4. +
  5. +
  6. +  _sunview.c
  7. +
  8. +
  9. +  Copyright (c) 1991  by  Max-Planck-Institut fuer Informatik
  10. +  Im Stadtwald, 6600 Saarbruecken, FRG     
  11. +  All rights reserved.
  12. *******************************************************************************/
  13.  
  14.  
  15. #include <suntool/sunview.h>
  16. #include <suntool/canvas.h>
  17. #include <suntool/panel.h>
  18. #include <math.h>
  19. #include <string.h>
  20. #include <stdio.h>
  21.  
  22.  
  23. #define NOCLIP 0x1
  24.  
  25. #define XCOL(c) PIX_SRC ^ PIX_DST | PIX_COLOR(c)
  26.  
  27. #define COL(c) PIX_SRC|PIX_COLOR(c)
  28.  
  29. #define pix_mode(c) (pix_mode_op  | PIX_COLOR(c))
  30.  
  31. #define XPIX(coord) (int)(xorigin + (coord)*x_draw_scale)
  32. #define YPIX(coord) (int)(yorigin - (coord)*x_draw_scale)
  33.  
  34. #define XREAL(pix)  ((double)(pix-xorigin)/x_draw_scale)
  35. #define YREAL(pix)  ((double)(yorigin-pix)/x_draw_scale)
  36.  
  37.  
  38. extern Notify_error notify_dispatch();
  39.  
  40. static short icon_image[] = {
  41.  
  42. #include "leda.icon"
  43.  
  44. };
  45.  
  46. static mpr_static(leda_icon_pixrect,64,64,1,icon_image);
  47.  
  48.  
  49.  
  50. static char default_frame_label[128];
  51.  
  52. static char frame_label[80];
  53.  
  54. static char read_frame_format[] = "%8.2f %8.2f      %s";
  55.  
  56. static Frame    frame;
  57. static Canvas    canvas;
  58. static Pixwin  *pw = 0;
  59. static Icon    icon;
  60.  
  61. static Frame panel_frame;
  62. static Panel panel;
  63.  
  64. typedef void (*PRD)();
  65. typedef void (*PMA)();
  66.  
  67. static void x_draw_default_redraw() { /* do nothing */ }
  68.  
  69. static void x_draw_mouse_default_action(x,y) 
  70. double x,y;
  71. { /* do nothing */}
  72.  
  73. PRD x_draw_redraw = x_draw_default_redraw;
  74. PMA x_draw_mouse_action = x_draw_mouse_default_action;
  75.  
  76. static int x_draw_done;
  77.  
  78. static Pixfont *font;
  79.  
  80. static int pix_mode_op;
  81.  
  82. static int xdots,ydots, xorigin,yorigin;  /* pixels          */
  83.  
  84. static int mouse_key,mouse_xpix, mouse_ypix; 
  85. static int mouse_last_xpix, mouse_last_ypix;
  86. static int mouse_start_xpix, mouse_start_ypix;  /* start for segments  ... */
  87. static int mouse_read_kind;
  88.  
  89.  
  90. static double mouse_xreal,mouse_yreal;
  91. static double mouse_last_xreal,mouse_last_yreal;
  92. static double mouse_start_xreal,mouse_start_yreal;
  93.  
  94.  
  95. /* external variables */
  96.  
  97.  
  98. int SCREEN_WIDTH = 1152;
  99. int SCREEN_HEIGHT = 900;
  100.  
  101.    
  102. double x_draw_xmax,x_draw_xmin,x_draw_ymax,x_draw_ymin,x_draw_scale;   
  103.  
  104. int x_draw_grid_mode;
  105. int x_draw_depth;
  106.  
  107. int    x_draw_line_width, 
  108.        x_draw_node_width, 
  109.        x_draw_line_style, 
  110.        x_draw_text_mode, 
  111.        x_draw_drawing_mode,
  112.        x_draw_screen_flush;
  113.  
  114.  
  115. static unsigned char RED[256],GREEN[256],BLUE[256];
  116.  
  117. static char* x_draw_default_font = "screen.r.12";
  118.  
  119.  
  120. static Pr_texture *Line_style = 0;
  121.  
  122. static Pr_texture *solid;
  123. static Pr_texture *dashed;
  124. static Pr_texture *dotted;
  125.  
  126. /*
  127. x_draw_new_color(r,g,b)
  128. int r,g,b;
  129. { int col = col_count;
  130.   col_count++;
  131.   RED[col] =   r;  
  132.   GREEN[col] =   g;  
  133.   BLUE[col] =   b;
  134.   pw_setcmsname(pw,"new_color");
  135.   pw_putcolormap(pw,0,col_count,RED,GREEN,BLUE);
  136.   return col;
  137.  }
  138. */
  139.  
  140.  
  141.  
  142. x_draw_init_colors()
  143. { RED[0] = 255;  GREEN[0] = 255;  BLUE[0] = 255;  /* white  */
  144.   RED[1] =   0;  GREEN[1] =   0;  BLUE[1] =   0;  /* black  */
  145.   RED[2] = 255;  GREEN[2] =   0;  BLUE[2] =   0;  /* red    */
  146.   RED[3] =   0;  GREEN[3] = 255;  BLUE[3] =   0;  /* green  */
  147.   RED[4] =   0;  GREEN[4] = 100;  BLUE[4] = 255;  /* blue   */
  148.   RED[5] = 128;  GREEN[5] = 128;  BLUE[5] =   0;  /* yellow */
  149.   RED[6] = 128;  GREEN[6] =   0;  BLUE[6] = 178;  /* violet */
  150.   RED[7] = 192;  GREEN[7] =  64;  BLUE[7] =   0;  /* orange */
  151. /*
  152. indigo: RED[]  =  64;     GREEN[]  =   0;  BLUE[]  =  76; 
  153. */
  154.   pw_setcmsname(pw,"new_color");
  155.   pw_putcolormap(pw,0,8,RED,GREEN,BLUE);
  156.  }
  157.  
  158.  
  159. x_draw_set_redraw(f)
  160. PRD f;
  161. { x_draw_redraw = f; }
  162.  
  163. x_draw_set_frame_label(message)
  164. char* message;
  165. { strcpy(frame_label,message); }
  166.  
  167. x_draw_reset_frame_label()
  168. { strcpy(frame_label,default_frame_label); }
  169.  
  170. void x_draw_mouse_segment_action(x,y)
  171. double x,y;
  172. { pw_vector(pw, mouse_start_xpix,mouse_start_ypix,
  173.                 XPIX(x), YPIX(y),PIX_SRC^PIX_DST,1); 
  174. }
  175.  
  176. void x_draw_mouse_rect_action(x,y)
  177. double x,y;
  178. {   int save_pix_mode = pix_mode_op;
  179.     pix_mode_op = PIX_SRC ^ PIX_DST;
  180.     x_draw_rectangle(mouse_start_xreal,mouse_start_yreal,x,y,1,1);
  181.     pix_mode_op = save_pix_mode;
  182.  } 
  183.  
  184. void x_draw_mouse_circle_action(x,y)
  185. double x,y;
  186. {   double r = hypot(x - mouse_start_xreal, y - mouse_start_yreal);
  187.     int save_pix_mode = pix_mode_op;
  188.     pix_mode_op = PIX_SRC ^ PIX_DST;
  189.     x_draw_circle(mouse_start_xreal, mouse_start_yreal, r, 1, 1);    
  190.     pix_mode_op = save_pix_mode;
  191. }
  192.  
  193.  
  194. x_draw_set_font(fname)
  195. char* fname;
  196. { char buf[256];
  197.   Pixfont *f;
  198.  
  199.   sprintf(buf,"/usr/lib/fonts/fixedwidthfonts/%s",fname); 
  200.  
  201.   if ( f=pf_open(buf) ) 
  202.   { font =f ;
  203.     return 1;
  204.    }
  205.   else return 0;
  206.  
  207. }
  208.  
  209. x_draw_set_line_style(s)
  210. int s;
  211. { int save = x_draw_line_style;
  212.   x_draw_line_style = s;
  213.    
  214.    switch (x_draw_line_style)  {
  215.  
  216.    case 0 : Line_style = solid;
  217.             break;
  218.  
  219.    case 1 : Line_style = dashed;
  220.             break;
  221.  
  222.    case 2 : Line_style = dotted;
  223.             break;
  224.  
  225.    default: break;
  226.  
  227.    }
  228.   return save;
  229. }
  230.  
  231. int x_draw_set_mode(m)
  232. int m;
  233. { int save = x_draw_drawing_mode;
  234.   x_draw_drawing_mode = m;
  235.    
  236.    switch (x_draw_drawing_mode)  {
  237.  
  238.    case 0 : pix_mode_op  = PIX_SRC;
  239.             break;
  240.  
  241.    case 1 : pix_mode_op = PIX_SRC ^ PIX_DST;
  242.             break;
  243.  
  244.    default: break;
  245.  
  246.    }
  247.   return save;
  248. }
  249.  
  250. int x_draw_set_line_width(w)
  251. int w;
  252. { int save = x_draw_line_width;
  253.   x_draw_line_width = w;
  254.   return save;
  255.  }
  256.  
  257. int x_draw_set_node_width(w)
  258. int w;
  259. { int save = x_draw_node_width;
  260.   x_draw_node_width = w;
  261.   return save;
  262.  }
  263.  
  264. int x_draw_set_text_mode(m)
  265. int m;
  266. { int save = x_draw_text_mode;
  267.   x_draw_text_mode = m;
  268.   return save;
  269.  }
  270.  
  271.  
  272.  
  273. static void my_event_proc(canvas,event)
  274. Canvas canvas;
  275. Event* event;
  276.   char s[256];
  277.  
  278.   /*int k = event_action(event);  does not work for SUN3  */
  279.  
  280.   int k = event_id(event);
  281.  
  282.   switch (k) {
  283.  
  284.   case WIN_RESIZE: x_draw_init(x_draw_xmin,x_draw_xmax,x_draw_ymin,x_draw_grid_mode);
  285.                    break;
  286.  
  287.   case MS_LEFT:   mouse_key = 1;
  288.                   if (event_ctrl_is_down(event))  mouse_key +=3;
  289.                   if (event_shift_is_down(event)) mouse_key = -mouse_key;
  290.                   break;
  291.  
  292.   case MS_MIDDLE: mouse_key = 2;
  293.                   if (event_ctrl_is_down(event))  mouse_key +=3;
  294.                   if (event_shift_is_down(event)) mouse_key = -mouse_key;
  295.                   break;
  296.  
  297.   case MS_RIGHT:  mouse_key = 3;
  298.                   if (event_ctrl_is_down(event))  mouse_key +=3;
  299.                   if (event_shift_is_down(event)) mouse_key = -mouse_key;
  300.                   break;
  301.  
  302.   case KEY_RIGHT(7): /* left arrow */
  303.                      mouse_xpix -= (int)x_draw_scale*x_draw_grid_mode;
  304.                      window_set(canvas,WIN_MOUSE_XY,mouse_xpix,mouse_ypix,0);
  305.                      break;
  306.  
  307.   case KEY_RIGHT(9): /* right arrow */
  308.                      mouse_xpix += (int)x_draw_scale*x_draw_grid_mode;
  309.                      window_set(canvas,WIN_MOUSE_XY,mouse_xpix,mouse_ypix,0);
  310.                      break;
  311.  
  312.   case KEY_RIGHT(11): /* down arrow */
  313.                      mouse_ypix += (int)x_draw_scale*x_draw_grid_mode;
  314.                      window_set(canvas,WIN_MOUSE_XY,mouse_xpix,mouse_ypix,0);
  315.                      break;
  316.  
  317.   case KEY_RIGHT(5): /* up arrow */
  318.                      mouse_ypix -= (int)x_draw_scale*x_draw_grid_mode;
  319.                      window_set(canvas,WIN_MOUSE_XY,mouse_xpix,mouse_ypix,0);
  320.                      break;
  321.  
  322.   case KEY_RIGHT(1): /* center */
  323.                      mouse_xpix = XPIX(0);
  324.                      mouse_ypix = YPIX(0);
  325.                      window_set(canvas,WIN_MOUSE_XY,mouse_xpix,mouse_ypix,0);
  326.                      break;
  327.  
  328.  
  329.   default: mouse_xpix = event_x(event);
  330.            mouse_ypix = event_y(event);
  331.            break;
  332.  
  333.   }
  334.  
  335.  
  336.   if (x_draw_grid_mode)  x_draw_cursor();
  337.   
  338.     mouse_xreal =  x_draw_xmin+((double)mouse_xpix)/x_draw_scale;
  339.     mouse_yreal =  x_draw_ymax-((double)mouse_ypix)/x_draw_scale;
  340.   
  341.   if (x_draw_grid_mode) 
  342.   { 
  343.     mouse_xreal = x_draw_grid_mode * (int)(mouse_xreal/x_draw_grid_mode + ((mouse_xreal > 0) ? 0.5 : -0.5));
  344.     mouse_yreal = x_draw_grid_mode * (int)(mouse_yreal/x_draw_grid_mode + ((mouse_yreal > 0) ? 0.5 : -0.5));
  345.     mouse_xpix  = XPIX(mouse_xreal);
  346.     mouse_ypix  = YPIX(mouse_yreal);
  347.   
  348.     x_draw_cursor();
  349.   }
  350.  
  351.  
  352.   sprintf(s,read_frame_format, mouse_xreal,mouse_yreal,frame_label);
  353.   window_set(frame,FRAME_LABEL,s,0);
  354.  
  355.  
  356.   if (x_draw_mouse_action)  /* user defined action */
  357.   { x_draw_mouse_action(mouse_last_xreal,mouse_last_yreal);
  358.     x_draw_mouse_action(mouse_xreal,mouse_yreal);
  359.    }
  360.     
  361.  
  362.   mouse_last_xpix = mouse_xpix;
  363.   mouse_last_ypix = mouse_ypix;
  364.  
  365.   mouse_last_xreal = mouse_xreal;
  366.   mouse_last_yreal = mouse_yreal;
  367.  
  368. }
  369.  
  370. int x_read_mouse(kind, xstart,ystart,x,y)
  371. int    kind;   /* 0: point, 1: segment, 2:rectangle, 3: circle */
  372. double xstart;
  373. double ystart;
  374. double *x;
  375. double *y;
  376.   PMA f;
  377.  
  378.   switch(kind) {
  379.  
  380.   case 0 : f = x_draw_mouse_default_action;
  381.           break;
  382.  
  383.   case 1:  f = x_draw_mouse_segment_action;
  384.            break;
  385.  
  386.   case 2:  f = x_draw_mouse_rect_action;
  387.            break;
  388.  
  389.   case 3:  f = x_draw_mouse_circle_action;
  390.            break;
  391.  
  392.   default: f = x_draw_mouse_default_action;
  393.            break;
  394.  
  395.   }
  396.  
  397.   return x_read_mouse_action(f,xstart,ystart,x,y);
  398.  
  399. }
  400.  
  401. int x_read_mouse_action(action, xstart,ystart,x,y)
  402. PMA   action;
  403. double xstart;
  404. double ystart;
  405. double *x;
  406. double *y;
  407.   x_draw_mouse_action = action;
  408.  
  409.   mouse_key = 0;
  410.  
  411.   mouse_start_xreal = xstart;
  412.   mouse_start_yreal = ystart;
  413.  
  414.   mouse_start_xpix = XPIX(xstart);
  415.   mouse_start_ypix = YPIX(ystart);
  416.  
  417.   if (x_draw_grid_mode) x_draw_cursor();
  418.  
  419.   if (x_draw_mouse_action)  /* user defined action */
  420.   { x_draw_mouse_action(mouse_last_xreal,mouse_last_yreal);
  421.    }
  422.  
  423.  
  424.  
  425.   while (!mouse_key && !x_draw_done)  notify_dispatch();
  426.  
  427.   if (x_draw_done) return 0;
  428.  
  429.  
  430.   if (x_draw_mouse_action)  /* user defined action */
  431.   { x_draw_mouse_action(mouse_xreal,mouse_yreal);
  432.    }
  433.  
  434.  
  435.   if (x_draw_grid_mode) x_draw_cursor();
  436.  
  437.   *x = mouse_xreal;
  438.   *y = mouse_yreal;
  439.  
  440.  
  441.   return mouse_key;
  442. }
  443.   
  444.  
  445.  
  446.  
  447.  
  448.  
  449. Notify_value my_notice_destroy(frame, status)
  450. Frame frame;
  451. Destroy_status status;
  452. {
  453.   if (status !=DESTROY_CHECKING)
  454.   {
  455.     x_draw_done = 1;
  456.     (void) notify_stop();
  457.    }
  458.  
  459.   return (notify_next_destroy_func(frame,status));
  460. }
  461.  
  462.  
  463.  
  464.  
  465. x_draw_init_window(w_width,w_height,w_xpos,w_ypos,label)
  466. int w_width,
  467.     w_height,
  468.     w_xpos,
  469.     w_ypos;
  470. char* label;
  471.   if (pw!=0) 
  472.   { fprintf(stderr,"warning: second initialization of window ignored.\n");
  473.     return;
  474.    } 
  475.  
  476.   strcpy(default_frame_label,label);
  477.  
  478.   icon = icon_create(ICON_IMAGE, &leda_icon_pixrect, 0);
  479.  
  480.   frame = window_create(0, FRAME, 
  481.               WIN_WIDTH,    w_width,
  482.               WIN_HEIGHT,   w_height,
  483.               WIN_X,        w_xpos,
  484.               WIN_Y,        w_ypos,
  485.               FRAME_ICON,  icon,
  486.               FRAME_NO_CONFIRM, TRUE,
  487.               FRAME_LABEL, default_frame_label, 0);
  488.  
  489.   canvas = window_create(frame, CANVAS, 
  490.               WIN_CONSUME_KBD_EVENT,    WIN_RIGHT_KEYS,
  491.               WIN_IGNORE_PICK_EVENT,    WIN_UP_EVENTS,
  492.               WIN_EVENT_PROC,           my_event_proc,
  493.               0); 
  494.  
  495.   pw = canvas_pixwin(canvas);
  496.  
  497.   notify_interpose_destroy_func(frame,my_notice_destroy);
  498.  
  499.   window_set(frame,WIN_SHOW,TRUE,0);
  500.  
  501.  
  502.  
  503. /* init panel */
  504.  
  505.     panel_frame = window_create(0, FRAME,
  506.                              FRAME_NO_CONFIRM, TRUE, 
  507.                              WIN_X, 100, WIN_Y, 100, 0);
  508.  
  509.     panel = window_create(panel_frame, PANEL, 0);
  510.  
  511.  
  512.  
  513.   x_draw_set_font(x_draw_default_font);
  514.  
  515.   pix_mode_op = PIX_SRC;
  516.  
  517.   x_draw_init_colors(); 
  518.  
  519.   solid  = 0;
  520.   dashed = (Pr_texture*) malloc(sizeof(Pr_texture));
  521.   dashed->pattern = pr_tex_dashed;
  522.   dotted = (Pr_texture*) malloc(sizeof(Pr_texture));
  523.   dotted->pattern = pr_tex_dotted;
  524.  
  525.   x_draw_line_style   = 0;   /* solid */
  526.   x_draw_node_width   = 12;
  527.   x_draw_line_width   = 1;
  528.   x_draw_text_mode    = 0;   /* transparent   */
  529.   x_draw_drawing_mode = 0;   /* src           */
  530.  
  531. }
  532.  
  533.  
  534. x_draw_init(x0,x1,y0,g_mode)
  535. double x0,x1,y0;
  536. int g_mode;
  537. {
  538.   double x,y;
  539.  
  540.   if (x0>=x1) 
  541.   { fprintf(stderr,"Illegal arguments in draw_init: x0 >= x1\n");
  542.     exit(1);
  543.    }
  544.  
  545.   x_draw_grid_mode = g_mode; 
  546.  
  547.   x_draw_reset_frame_label();
  548.  
  549.   xdots = (int)window_get(canvas, CANVAS_WIDTH);
  550.   ydots = (int)window_get(canvas, CANVAS_HEIGHT);
  551.  
  552.   x_draw_depth = pw->pw_pixrect->pr_depth;
  553.  
  554.   x_draw_scale = ((double)xdots)/(x1-x0);
  555.  
  556.   /* at least grid distance of 2 pixels */
  557.   if ((x_draw_grid_mode) && (x_draw_grid_mode*x_draw_scale < 2)) 
  558.   { x_draw_grid_mode=0;  
  559.     fprintf(stderr,"warning: grid distance to small.\n");
  560.    }
  561.  
  562.   if (x_draw_grid_mode) 
  563.     if (x_draw_scale < 1) x_draw_scale = 1;
  564.     else x_draw_scale = (int)x_draw_scale;
  565.  
  566.   x_draw_xmin = x0;
  567.   x_draw_ymin = y0;
  568.   x_draw_xmax = x0+xdots/x_draw_scale;
  569.   x_draw_ymax = y0+ydots/x_draw_scale;
  570.  
  571.   xorigin = -x0*x_draw_scale;
  572.   yorigin = ydots+y0*x_draw_scale;
  573.  
  574.   mouse_xreal = 0;
  575.   mouse_yreal = 0;
  576.  
  577.   x_draw_clear(0);
  578.  
  579.  if (x_draw_grid_mode)  x_draw_cursor();
  580.  
  581.  notify_dispatch();
  582.  
  583.  if (x_draw_grid_mode)  x_draw_cursor();
  584.  
  585.  (*x_draw_redraw)();
  586.  
  587. }
  588.  
  589.  
  590. x_show_window() 
  591. { while (!x_draw_done) notify_dispatch(); }
  592.  
  593. x_draw_end()
  594. { if (pw)
  595.   { pw_close(pw);
  596.     pf_close(font);
  597.     /* window_destroy(frame); */
  598.     pw = 0;
  599.    }
  600. }
  601.  
  602. x_draw_line(x1, y1, x2, y2, col)
  603. double x1,y1,x2,y2;
  604. int col;
  605.   int C[4];
  606.   int i;
  607.   int M = 32768;   /* 2^15    */ 
  608.  
  609.   Pr_brush br;
  610.   br.width = x_draw_line_width;
  611.  
  612.  
  613.   C[0] = XPIX(x1);
  614.   C[1] = YPIX(y1);
  615.   C[2] = XPIX(x2);
  616.   C[3] = YPIX(y2);
  617.  
  618.   /* 
  619.     Fehler beim Clipping fuer Koordinaten mit Absolutwert in
  620.     [i*2^15..(i+1)*2^15-1],i ungerade.
  621.   */
  622.  
  623.  /*
  624.   for(i=0; i<4; i++)
  625.     if ((C[i]/M) % 2) C[i] = -C[i];
  626.  
  627.  */
  628.  
  629.   pw_line(pw,C[0],C[1],C[2],C[3],&br,Line_style,pix_mode(col));
  630.  
  631. }
  632.  
  633.  
  634. x_draw_point(x,y,col)
  635. double x,y;
  636. int col;
  637.  
  638. { int X,Y;
  639.  
  640.   Pr_brush br;
  641.   br.width = 1;
  642.  
  643.   X = XPIX(x);
  644.   Y = YPIX(y);
  645.  
  646.   if (x_draw_depth==1 && col>1) col = 1;
  647.  
  648.   pw_line(pw,X-2,Y-2,X+2,Y+2,&br,solid,pix_mode(col));
  649.   pw_line(pw,X+1,Y-1,X+2,Y-2,&br,solid,pix_mode(col));
  650.   pw_line(pw,X-1,Y+1,X-2,Y+2,&br,solid,pix_mode(col));
  651.  
  652.  
  653. }
  654.  
  655.  
  656. x_draw_node(x0,y0,col)
  657. double x0,y0;
  658. int col;
  659.  
  660. { int X0,Y0,x,y,e;
  661.  
  662.   int r = x_draw_node_width;
  663.  
  664.   struct pr_pos *points;
  665.   int n = 8*r;
  666.   int i = 0;
  667.  
  668.   points = (struct pr_pos*) malloc(n*sizeof(struct pr_pos));
  669.  
  670.  
  671.   X0 = XPIX(x0);
  672.   Y0 = YPIX(y0);
  673.  
  674.   if (x_draw_depth==1 && col>1) col = 1;
  675.  
  676.     x = 0;
  677.     y = r;
  678.     e = 3-2*y;
  679.  
  680.    points[i].x = X0;   points[i].y = Y0+r;
  681.    i++;
  682.    points[i].x = X0;   points[i].y = Y0-r;
  683.    i++;
  684.    points[i].x = X0+r; points[i].y = Y0;
  685.    i++;
  686.    points[i].x = X0-r; points[i].y = Y0;
  687.    i++;
  688.   
  689.     for (x=1;x<y;)
  690.     { points[i].x = X0+x; points[i].y = Y0+y;
  691.       i++;
  692.       points[i].x = X0+x; points[i].y = Y0-y;
  693.       i++;
  694.       points[i].x = X0-x; points[i].y = Y0+y;
  695.       i++;
  696.       points[i].x = X0-x; points[i].y = Y0-y;
  697.       i++;
  698.       points[i].x = X0+y; points[i].y = Y0+x;
  699.       i++;
  700.       points[i].x = X0+y; points[i].y = Y0-x;
  701.       i++;
  702.       points[i].x = X0-y; points[i].y = Y0+x;
  703.       i++;
  704.       points[i].x = X0-y; points[i].y = Y0-x;
  705.       i++;
  706.  
  707.       x++;
  708.       if (e>=0) { y--; e = e - 4*y; }
  709.       e = e + 4*x + 2;
  710.      }
  711.  
  712.  
  713.    points[i].x = X0+x; points[i].y = Y0+y;
  714.    i++;
  715.    points[i].x = X0+x; points[i].y = Y0-y;
  716.    i++;
  717.    points[i].x = X0-x; points[i].y = Y0+y;
  718.    i++;
  719.    points[i].x = X0-x; points[i].y = Y0-y;
  720.    i++;
  721.  
  722.    pw_polypoint(pw,0,0,i,points,pix_mode(col));
  723.  
  724.    free((char*)points);
  725.  
  726. }
  727.  
  728. x_draw_message(line,s,c)
  729. int line;
  730. char* s;
  731. int c;
  732. { int x = 30;
  733.   int y = 30*line;;
  734.   x_draw_set_font("cour.b.24");
  735.   pw_ttext(pw,x,y,XCOL(c),font,s);
  736.   x_draw_set_font(x_draw_default_font);
  737. }
  738.  
  739. x_draw_text_node(x0,y0,s,col)
  740. double x0,y0;
  741. int col;
  742. char* s;
  743.   if (x_draw_depth==1 || col == 1)
  744.    { x_draw_node(x0,y0,1);
  745.      x_draw_ctext(x0,y0,s,1);
  746.     }
  747.   else
  748.    { x_draw_filled_node(x0,y0,col);
  749.      x_draw_ctext(x0,y0,s,0);
  750.     }
  751.  
  752.  }
  753.  
  754. x_draw_int_node(x0,y0,i,col)
  755. double x0,y0;
  756. int i,col;
  757.   char buf[16];
  758.   sprintf(buf,"%d",i);
  759.   x_draw_text_node(x0,y0,buf,col);
  760.  }
  761.  
  762.  
  763. x_draw_filled_node(x0,y0,col)
  764. double x0,y0;
  765. int col;
  766.   int X0,Y0,x,y,e;
  767.   int r = x_draw_node_width;
  768.  
  769.   Pr_brush br;
  770.   br.width = 1;
  771.  
  772.   X0 = XPIX(x0);
  773.   Y0 = YPIX(y0);
  774.  
  775.   x = 1;
  776.   y = r;
  777.   e = 3-2*r;
  778.  
  779.   pw_line(pw,X0,Y0+y,X0,Y0-y,&br,0,pix_mode(col));
  780.  
  781.   while (x<=y)
  782.   { pw_line(pw,X0+x,Y0+y,X0+x,Y0,  &br,0,pix_mode(col));
  783.     pw_line(pw,X0+x,Y0-y,X0+x,Y0-1,&br,0,pix_mode(col));
  784.     pw_line(pw,X0-x,Y0+y,X0-x,Y0,  &br,0,pix_mode(col));
  785.     pw_line(pw,X0-x,Y0-y,X0-x,Y0-1,&br,0,pix_mode(col));
  786.  
  787.  
  788.     if (x<y && e>=0) 
  789.     { pw_line(pw,X0+y,Y0+x,X0+y,Y0,  &br,0,pix_mode(col));
  790.       pw_line(pw,X0+y,Y0-x,X0+y,Y0-1,&br,0,pix_mode(col));
  791.       pw_line(pw,X0-y,Y0+x,X0-y,Y0,  &br,0,pix_mode(col));
  792.       pw_line(pw,X0-y,Y0-x,X0-y,Y0-1,&br,0,pix_mode(col));
  793.       y--; 
  794.       e = e - 4*y; 
  795.      }
  796.  
  797.     x++;
  798.  
  799.     e = e + 4*x + 2;
  800.    }
  801.  
  802. }
  803.  
  804. x_draw_ellipse()
  805. { fprintf(stderr,"sorry, draw ellipse not iplemented\n"); }
  806.  
  807. x_draw_filled_ellipse()
  808. { fprintf(stderr,"sorry, draw ellipse not iplemented\n"); }
  809.  
  810. x_draw_circle(x0,y0,r,col)
  811. double x0,y0,r; 
  812. int col;
  813.  
  814. { int save = x_draw_node_width;
  815.   x_draw_node_width = (int)(r*x_draw_scale);
  816.   x_draw_node(x0,y0,col);
  817.   x_draw_node_width = save;
  818.  }
  819.  
  820.  
  821. x_draw_filled_circle(x0,y0,r,col)
  822. double x0,y0,r; 
  823. int col;
  824. { int save = x_draw_node_width;
  825.   x_draw_node_width = (int)(r*x_draw_scale);
  826.   x_draw_filled_node(x0,y0,col);
  827.   x_draw_node_width = save;
  828.  }
  829.  
  830.  
  831. x_draw_xpix(x)
  832. double x;
  833. { return XPIX(x); }
  834.  
  835. x_draw_ypix(x)
  836. double x;
  837. { return YPIX(x); }
  838.  
  839. x_draw_pix(x,y,col)
  840. double x,y;
  841. int col;
  842. { pw_put(pw,XPIX(x),YPIX(y),col); }
  843.  
  844.  
  845. x_draw_plot_xy(x0,x1,f,col)
  846. double x0,x1;
  847. double (*f)();
  848. int col;
  849.  
  850.   int x = XPIX(x0);
  851.   int y_old = YPIX((*f)(x0));
  852.   int i,y_new;
  853.   int size = 0;
  854.   int n = 0;
  855.  
  856.   struct pr_pos *points;
  857.  
  858.   for(x = XPIX(x0)+1; x <= XPIX(x1); x++)
  859.   { y_new = YPIX((*f)(XREAL(x)));
  860.     if (y_new > y_old)
  861.        size += (y_new-y_old+1);
  862.     else
  863.        size += (y_old-y_new+1);
  864.     y_old = y_new;
  865.    }
  866.  
  867.   points = (struct pr_pos*) malloc(size*sizeof(struct pr_pos));
  868.  
  869.   y_old = YPIX((*f)(x0));
  870.  
  871.   for(x = XPIX(x0)+1; x <= XPIX(x1); x++)
  872.   { y_new = YPIX((*f)(XREAL(x)));
  873.     if (y_new > y_old)
  874.       for(i=y_old; i<=y_new; i++)  
  875.       { points[n].x = x; 
  876.         points[n].y = i;
  877.         n++;
  878.        }
  879.     else
  880.       for(i=y_old; i>=y_new; i--)  
  881.       { points[n].x = x; 
  882.         points[n].y = i;
  883.         n++;
  884.        }
  885.     y_old = y_new;
  886.   }
  887.  
  888.  pw_polypoint(pw,0,0,size,points,pix_mode(col));
  889.  
  890.  free((char*)points);
  891.   
  892. }
  893.  
  894. x_draw_plot_yx(y0,y1,f,col)
  895. double y0,y1;
  896. double (*f)();
  897. int col;
  898.  
  899.   int y;
  900.   int i,x_new;
  901.   int x_old = XPIX((*f)(y0));
  902.   int size = 0;
  903.   int n = 0;
  904.  
  905.   struct pr_pos *points;
  906.  
  907.   for(y = YPIX(y0)-1; y >= YPIX(y1); y--)
  908.   { x_new = XPIX((*f)(YREAL(y)));
  909.     if (x_new > x_old)
  910.        size += (x_new-x_old+1);
  911.     else
  912.        size += (x_old-x_new+1);
  913.     x_old = x_new;
  914.    }
  915.  
  916.   points = (struct pr_pos*) malloc(size*sizeof(struct pr_pos));
  917.  
  918.   x_old = XPIX((*f)(y0));
  919.  
  920.   for(y = YPIX(y0)-1; y >= YPIX(y1); y--)
  921.   { 
  922.     x_new = XPIX((*f)(YREAL(y)));
  923.     if (x_new > x_old)
  924.       for(i=x_old; i<=x_new; i++)  
  925.       { points[n].x = i; 
  926.         points[n].y = y;
  927.         n++;
  928.        }
  929.     else
  930.       for(i=x_old; i>=x_new; i--)  
  931.       { points[n].x = i; 
  932.         points[n].y = y;
  933.         n++;
  934.        }
  935.     x_old = x_new;
  936.   }
  937.  
  938.  pw_polypoint(pw,0,0,size,points,pix_mode(col));
  939.  
  940.  free((char*)points);
  941.   
  942. }
  943.  
  944.  
  945. x_draw_filled_polygon(n,xcoord,ycoord,col)
  946. int col, n;
  947. double *xcoord, *ycoord;
  948. {struct pr_pos *edges;
  949.  int i;
  950.  
  951.  edges = (struct pr_pos*) malloc(n*sizeof(struct pr_pos));
  952.  
  953.  for(i=0;i<n;i++) 
  954.  { edges[i].x = XPIX(xcoord[i]);
  955.    edges[i].y = YPIX(ycoord[i]);
  956.   }
  957.  
  958.  pw_polygon_2(pw,0,0,1,&n,edges,pix_mode(col),0,0,0);
  959.  
  960. /*
  961.  free((char*)edges);
  962. */
  963.  
  964.  }
  965.  
  966. x_draw_polygon(n,xcoord,ycoord,col)
  967. int col, n;
  968. double *xcoord, *ycoord;
  969. { int i;
  970.  
  971.   for(i=0;i<n-1;i++) 
  972.     x_draw_line(xcoord[i],ycoord[i], xcoord[i+1],ycoord[i+1],col);
  973.  
  974.   x_draw_line(xcoord[n-1],ycoord[n-1],xcoord[0],ycoord[0],col);
  975.  
  976.  }
  977.  
  978. x_draw_rectangle(x1,y1,x2,y2,col)
  979. double x1,y1,x2,y2;
  980. int col;
  981. {
  982.  x_draw_line(x1,y1,x1,y2,col);
  983.  x_draw_line(x1,y2,x2,y2,col);
  984.  x_draw_line(x2,y2,x2,y1,col);
  985.  x_draw_line(x2,y1,x1,y1,col);
  986.  
  987.  }
  988.  
  989.  
  990. x_draw_filled_rectangle(x1,y1,x2,y2,col)
  991. double x1,y1,x2,y2; 
  992. int col;
  993. { double xcoord[4], ycoord[4];
  994.  
  995.  xcoord[0] = x1;   
  996.  ycoord[0] = y1;   
  997.  xcoord[1] = x1;  
  998.  ycoord[1] = y2;   
  999.  xcoord[2] = x2; 
  1000.  ycoord[2] = y2;   
  1001.  xcoord[3] = x2;
  1002.  ycoord[3] = y1;
  1003.  
  1004.  x_draw_filled_polygon(4,xcoord,ycoord,col);
  1005.  
  1006.  }
  1007.  
  1008. x_draw_copy_rect(x1,y1,x2,y2,x,y)
  1009. double x1,y1,x2,y2,x,y;
  1010. {
  1011.  pw_copy(pw,XPIX(x1),YPIX(y1),(x2-x1)*x_draw_scale,(y2-y1)*x_draw_scale,
  1012.          pix_mode(1), pw,XPIX(x),YPIX(y));
  1013.  }
  1014.  
  1015.  
  1016. x_draw_clear(col)
  1017. int col;
  1018. {struct pr_pos edges[4];
  1019.  struct pr_pos *grid_points;
  1020.  int i=0;
  1021.  int n = 4;
  1022.  double x,y;
  1023.  int save;
  1024.  
  1025.  edges[0].x = 0;
  1026.  edges[0].y = 0;
  1027.  edges[1].x = xdots;
  1028.  edges[1].y = 0;
  1029.  edges[2].x = xdots;
  1030.  edges[2].y = ydots;
  1031.  edges[3].x = 0;
  1032.  edges[3].y = ydots;
  1033.  
  1034.  pw_polygon_2(pw,0,0,1,&n,edges,COL(col),0,0,0);
  1035.  
  1036.  save = x_draw_set_node_width(1);
  1037.  
  1038.  n = 0;
  1039.  if (x_draw_grid_mode) /* draw grid */
  1040.  { for(x = (int)(x_draw_xmin/x_draw_grid_mode)*x_draw_grid_mode; x<=x_draw_xmax; x+=x_draw_grid_mode)
  1041.    for(y = (int)(x_draw_ymin/x_draw_grid_mode)*x_draw_grid_mode; y<=x_draw_ymax; y+=x_draw_grid_mode)
  1042.      n++;
  1043.  
  1044.    grid_points = (struct pr_pos*) malloc(n*sizeof(struct pr_pos));
  1045.  
  1046.  
  1047.    for(x = (int)(x_draw_xmin/x_draw_grid_mode)*x_draw_grid_mode; x<=x_draw_xmax; x+=x_draw_grid_mode)
  1048.    for(y = (int)(x_draw_ymin/x_draw_grid_mode)*x_draw_grid_mode; y<=x_draw_ymax; y+=x_draw_grid_mode)
  1049.    { if (x*y == 0) x_draw_filled_node(x,y,1,1);
  1050.      else { grid_points[i].x = XPIX(x);
  1051.             grid_points[i].y = YPIX(y);
  1052.             i++;
  1053.            }
  1054.     }
  1055.    pw_polypoint(pw,0,0,n,grid_points,COL(1));
  1056.   }
  1057.  
  1058.   x_draw_set_node_width(save);
  1059.  
  1060.  }
  1061.  
  1062.  
  1063. /* TEXT  */
  1064.  
  1065. x_draw_text(x,y,s,col)
  1066. double x,y;
  1067. char * s;
  1068. int col;
  1069. { if (x_draw_text_mode == 1)   /* opaque */
  1070.     pw_text(pw,XPIX(x),YPIX(y),pix_mode(col),font,s);
  1071.   else
  1072.     pw_ttext(pw,XPIX(x),YPIX(y),pix_mode(col),font,s);
  1073. }
  1074.  
  1075. x_draw_ctext(x,y,s,col)
  1076. double x,y;
  1077. char * s;
  1078. int col;
  1079.   struct pr_size size;
  1080.   size = pf_textwidth(strlen(s),font,s);
  1081.   x -= ((double)size.x)/(2*x_draw_scale);
  1082.   y -= ((double)size.y)/(3*x_draw_scale);
  1083.   x_draw_text(x,y,s,col);
  1084. }
  1085.  
  1086.  
  1087. x_draw_int(x0,y0,i,col)
  1088. double x0,y0;
  1089. int i,col;
  1090.   char buf[16];
  1091.   sprintf(buf,"%d",i);
  1092.   x_draw_ctext(x0,y0,buf,col);
  1093.  }
  1094.  
  1095.  
  1096. x_draw_cursor()
  1097.   int X,Y;
  1098.  
  1099.   X = XPIX(mouse_xreal);
  1100.   Y = YPIX(mouse_yreal);
  1101.  
  1102.   pw_vector(pw,X,Y,X+10,Y,PIX_SRC^PIX_DST,1);
  1103.   pw_vector(pw,X,Y,X-10,Y,PIX_SRC^PIX_DST,1);
  1104.   pw_vector(pw,X,Y,X,Y+10,PIX_SRC^PIX_DST,1);
  1105.   pw_vector(pw,X,Y,X,Y-10,PIX_SRC^PIX_DST,1);
  1106.  
  1107. }
  1108.  
  1109.  
  1110. int x_draw_screen_width()
  1111. { Rect *r;
  1112.   Frame frame = window_create(0, FRAME,NULL); 
  1113.   r = (Rect *) window_get(frame, WIN_SCREEN_RECT);
  1114.   window_destroy(frame);
  1115.   return(r->r_width);
  1116. }
  1117.  
  1118.  
  1119. int x_draw_screen_height()
  1120. { Rect *r;
  1121.   Frame frame = window_create(0, FRAME,NULL); 
  1122.   r = (Rect *) window_get(frame, WIN_SCREEN_RECT);
  1123.   window_destroy(frame);
  1124.   return(r->r_height);
  1125. }
  1126.  
  1127. static void
  1128. center_frame(frame)
  1129. Frame frame;
  1130. { Rect * r;
  1131.   int left,top,width,height;
  1132.  
  1133.     /* center frame on the screen */
  1134.  
  1135.     r = (Rect *) window_get(frame, WIN_SCREEN_RECT);
  1136.  
  1137.     width = (int) window_get(frame, WIN_WIDTH);
  1138.     height = (int) window_get(frame, WIN_HEIGHT);
  1139.  
  1140.     left = (r->r_width - width) / 2;
  1141.     top = (r->r_height - height) / 2;
  1142.  
  1143.     if (left < 0)
  1144.     left = 0;
  1145.     if (top < 0)
  1146.     top = 0;
  1147.  
  1148.     window_set(frame, WIN_X, left, WIN_Y, top, 0);
  1149. }
  1150.  
  1151.  
  1152. int x_draw_confirm(header)
  1153. char *header;
  1154. { /* ask for yes or no */
  1155.   char* s[2];
  1156.   s[0] = "NO";
  1157.   s[1] = "YES";
  1158.   return x_draw_read_panel(header,2,s,0);
  1159. }
  1160.  
  1161. int x_draw_acknowledge(header)
  1162. char *header;
  1163. { /* ask for ok */
  1164.   char *s = "OK";
  1165.   return x_draw_read_panel(header,1,&s,0);
  1166. }
  1167.  
  1168. static Frame    init_panel_frame();
  1169. static void    panel_input_notify();
  1170. static int      panel_answer;
  1171.  
  1172. int x_draw_read_panel(message,n,labels,vertical)
  1173. char    *message;
  1174. int n;
  1175. char    **labels;
  1176. int    vertical;
  1177. {
  1178.     Frame    panel_frame;
  1179.     int        answer;
  1180.  
  1181.     if (x_draw_grid_mode) x_draw_cursor();
  1182.  
  1183.     /* create the panel_frame */
  1184.     panel_frame = init_panel_frame(message,n,labels,vertical);
  1185.  
  1186.     /* make the user answer */
  1187.     window_main_loop(panel_frame);
  1188.  
  1189.     /* destroy the panel_frame */
  1190.     window_set(panel_frame, FRAME_NO_CONFIRM, TRUE, 0);
  1191.     window_destroy(panel_frame);
  1192.  
  1193.     if (x_draw_grid_mode) x_draw_cursor();
  1194.  
  1195.     return panel_answer;
  1196. }
  1197.  
  1198.  
  1199. static Frame
  1200. init_panel_frame(message,num,label,vertical)
  1201. char    *message;
  1202. int     num;
  1203. char   **label;
  1204. int    vertical;
  1205. {
  1206.     Frame        panel_frame;
  1207.     Panel        panel;
  1208.     Panel_item        message_item;
  1209.     int            left, top, width, height;
  1210.     struct pixrect    *pr[32];
  1211.     Rect                *r;
  1212.     int                 i;
  1213.  
  1214.     panel_frame = window_create(0, FRAME, FRAME_SHOW_LABEL, FALSE, 0);
  1215.  
  1216.     panel = window_create(panel_frame, PANEL, 0);
  1217.  
  1218.     message_item = panel_create_item(panel, PANEL_MESSAGE, 
  1219.                            PANEL_LABEL_STRING, message,
  1220.                        0);
  1221.  
  1222.     r = (Rect *) panel_get(message_item, PANEL_ITEM_RECT);
  1223.  
  1224.     width = 0;
  1225.  
  1226.     for(i=0;i<num;i++)
  1227.     { pr[i] = panel_button_image(panel, label[i], 3, 0);
  1228.       width += pr[i]->pr_width;
  1229.      }
  1230.  
  1231.     /* center buttons under the message */
  1232.  
  1233.     left = (r->r_width - width) / 2;
  1234.     if (left < 0)
  1235.     left = 0;
  1236.  
  1237.     height = rect_bottom(r) + 5;
  1238.     top = height;
  1239.  
  1240.     panel_create_item(panel, PANEL_BUTTON, 
  1241.         PANEL_ITEM_X, left, PANEL_ITEM_Y, top,
  1242.             PANEL_LABEL_IMAGE, pr[0],
  1243.             PANEL_CLIENT_DATA, 0,
  1244.             PANEL_NOTIFY_PROC, panel_input_notify,
  1245.             0);
  1246.  
  1247.  
  1248.     for(i=1;i<num;i++)
  1249.     { if (vertical)
  1250.          panel_create_item(panel, PANEL_BUTTON, 
  1251.                  PANEL_ITEM_X, left, PANEL_ITEM_Y, top+=height,
  1252.                  PANEL_LABEL_IMAGE, pr[i],
  1253.                  PANEL_CLIENT_DATA, i,
  1254.                  PANEL_NOTIFY_PROC, panel_input_notify,
  1255.                  0);
  1256.       else
  1257.          panel_create_item(panel, PANEL_BUTTON, 
  1258.                     PANEL_LABEL_IMAGE, pr[i],
  1259.                     PANEL_CLIENT_DATA, i,
  1260.                     PANEL_NOTIFY_PROC, panel_input_notify,
  1261.                     0);
  1262.     }
  1263.  
  1264.  
  1265.     window_fit(panel);
  1266.     window_fit(panel_frame);
  1267.  
  1268.     center_frame(panel_frame);
  1269.  
  1270.     return panel_frame;
  1271.  
  1272. }
  1273.  
  1274.  
  1275. /* notify proc */
  1276. static void panel_input_notify(item, event)
  1277. Panel_item    item;
  1278. Event        *event;
  1279. {   panel_answer = (int)panel_get(item, PANEL_CLIENT_DATA);
  1280.     notify_stop(); 
  1281. }
  1282.  
  1283.  
  1284.  
  1285.  
  1286. /* Text Panels */
  1287.  
  1288.  
  1289. static Frame  init_text_panel_frame();
  1290. static void   text_panel_ok_notify();
  1291. static void   text_panel_input_notify();
  1292. static void   text_panel_menu_proc();
  1293. static char   text_panel_answer[256];
  1294.  
  1295. static char **text_panel_menu_strings;
  1296. static Menu   text_panel_menu;
  1297. static Frame  text_panel_frame;
  1298. static Panel  text_panel;
  1299. static Panel_item panel_text_item;
  1300.  
  1301. char* x_draw_read_text_panel(message,menu_label,n,items)
  1302. int      n;
  1303. char   **items;
  1304. char    *message;
  1305. char    *menu_label;
  1306. {
  1307.     if (x_draw_grid_mode) x_draw_cursor();
  1308.  
  1309.     init_text_panel_frame(message,menu_label,n,items);
  1310.  
  1311.     window_main_loop(text_panel_frame);
  1312.  
  1313.     window_set(text_panel_frame, FRAME_NO_CONFIRM, TRUE, 0);
  1314.     window_destroy(text_panel_frame);
  1315.  
  1316.     if (x_draw_grid_mode) x_draw_cursor();
  1317.  
  1318.     return text_panel_answer;
  1319. }
  1320.  
  1321.  
  1322.  
  1323.  
  1324.  
  1325. static Frame
  1326. init_text_panel_frame(message,menu_l,n,items)
  1327. int      n;
  1328. char    *message;
  1329. char    *menu_l;
  1330. char   **items;
  1331. {
  1332.     Panel_item        message_item;
  1333.     int            left, top, width, height;
  1334.     Rect        *r;
  1335.     int i;
  1336.     int cols;
  1337.     char* menu_label[64];
  1338.   
  1339.     cols = 1 +n/15;
  1340.  
  1341.     sprintf(menu_label,"%s -->",menu_l);
  1342.  
  1343.  
  1344.     text_panel_frame = window_create(0, FRAME, FRAME_SHOW_LABEL, FALSE, 0);
  1345.  
  1346.     text_panel = window_create(text_panel_frame, PANEL, 0);
  1347.  
  1348.     panel_text_item = panel_create_item(text_panel, PANEL_TEXT, 
  1349.                            PANEL_ITEM_Y, 15,
  1350.                            PANEL_NOTIFY_PROC,  text_panel_input_notify,
  1351.                            PANEL_LABEL_STRING, message,
  1352.                            PANEL_VALUE_DISPLAY_LENGTH, 25,
  1353.                            PANEL_VALUE_STORED_LENGTH, 256, 
  1354.                         /* PANEL_VALUE, default_text,   */
  1355.                        0);
  1356.  
  1357.     if (n > 0)
  1358.     { text_panel_menu_strings = items;
  1359.  
  1360.       text_panel_menu = menu_create( MENU_DEFAULT, 0, MENU_NCOLS, cols, 0);
  1361.  
  1362.       for(i=0;i<n;i++) menu_set(text_panel_menu,MENU_STRING_ITEM,items[i],i,0);
  1363.  
  1364.       panel_create_item(text_panel, PANEL_BUTTON,
  1365.               PANEL_LABEL_IMAGE,panel_button_image(text_panel,menu_label,0,0), 
  1366.               PANEL_EVENT_PROC, text_panel_menu_proc,
  1367.                         0);
  1368.      }
  1369.  
  1370.  
  1371.     window_fit(text_panel);
  1372.     window_fit(text_panel_frame);
  1373.  
  1374.     center_frame(text_panel_frame);
  1375.  
  1376. }
  1377.  
  1378.  
  1379. /* notify proc */
  1380. static void text_panel_input_notify(item, event)
  1381. Panel_item    item;
  1382. Event        *event;
  1383. {
  1384.     strcpy(text_panel_answer,(char*)panel_get_value(item));
  1385.     notify_stop();
  1386. }
  1387.  
  1388.  
  1389. static void text_panel_menu_proc(item, event)
  1390. Panel_item item;
  1391. Event *event;
  1392. { int i;
  1393.   if (event_id(event) == MS_RIGHT && event_is_down(event))
  1394.   { i = (int)menu_show(text_panel_menu, text_panel, event,0);
  1395.     window_set(panel_text_item,PANEL_VALUE,text_panel_menu_strings[i],0);
  1396.     strcpy(text_panel_answer,text_panel_menu_strings[i]);
  1397.     notify_stop();
  1398.    }
  1399.   else panel_default_handle_event(item,event);
  1400. }
  1401.  
  1402. void x_draw_flush() {}
  1403.  
  1404. void x_draw_notice() {}
  1405.  
  1406.  
  1407. x_draw_message_panel(argc, argv)
  1408. char *argv[];
  1409. {
  1410.     Frame      panel_frame;
  1411.     Panel      panel;
  1412.     Panel_item item,but;
  1413.     int        i,left, top, width, height;
  1414.     Rect      *r;
  1415.  
  1416.     if (x_draw_grid_mode) x_draw_cursor();
  1417.  
  1418.     panel_frame = window_create(0, FRAME,
  1419.                                 FRAME_LABEL, argv[0],
  1420.                                 0);
  1421.  
  1422.     panel = window_create(panel_frame, PANEL,0);
  1423.  
  1424.     if (argc > 1)
  1425.     { item = panel_create_item(panel, PANEL_MESSAGE, 
  1426.                 PANEL_ITEM_Y,20,
  1427.                 PANEL_ITEM_X,25,
  1428.                 PANEL_LABEL_BOLD, TRUE, 
  1429.                 PANEL_LABEL_STRING, argv[1],
  1430.                 NULL);
  1431.       r = (Rect *) panel_get(item, PANEL_ITEM_RECT);
  1432.       width = r->r_width;
  1433.      }
  1434.  
  1435.     for(i = 2; i< argc; i++)
  1436.     { item = panel_create_item(panel, PANEL_MESSAGE, 
  1437.                 PANEL_ITEM_X,25,
  1438.                 PANEL_ITEM_Y,20*i,
  1439.                 PANEL_LABEL_BOLD, TRUE, 
  1440.                 PANEL_LABEL_STRING, argv[i],
  1441.                 NULL);
  1442.       r = (Rect *) panel_get(item, PANEL_ITEM_RECT);
  1443.       if (width < r->r_width) width = r->r_width;
  1444.      }
  1445.  
  1446.     but = panel_create_item(panel, PANEL_BUTTON,
  1447. /*
  1448.                 PANEL_ITEM_X,width/2 - 15,
  1449. */
  1450.                 PANEL_CLIENT_DATA, 0,
  1451.                 PANEL_LABEL_IMAGE, panel_button_image(panel, "OK", 3, 0),
  1452.                 PANEL_NOTIFY_PROC, panel_input_notify,
  1453.                 NULL);
  1454.  
  1455.     window_fit(panel);
  1456.     window_fit(panel_frame);
  1457.  
  1458.     center_frame(panel_frame);
  1459.  
  1460.     window_main_loop(panel_frame);
  1461.  
  1462.     window_set(panel_frame, FRAME_NO_CONFIRM, TRUE, 0);
  1463.     window_destroy(panel_frame);
  1464.  
  1465.     if (x_draw_grid_mode) x_draw_cursor();
  1466.  
  1467. }
  1468.  
  1469.