home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / modelers / geomview / source.lha / Geomview / src / lib / forms / FORMS-2.0-PATCHES < prev    next >
Encoding:
Text File  |  1993-10-29  |  83.0 KB  |  2,951 lines

  1. Summary of changes made to FORMS 2.0, through October 1993,
  2. at the Geometry Center.
  3.  
  4.  
  5. FORMS/colorwheel.c:
  6.     New color-picker module.
  7.  
  8. FORMS/fouraxis.c:
  9.     New module, derived from positioner.c.
  10.     Allows specifying a direction in 4-space.
  11.  
  12.  
  13. FORMS/objects.c:
  14.     Be more intelligent about frozen forms: only redraw if
  15.     some object changed while the form was frozen.
  16.     Use the sign bit of the form->frozen field to tell.
  17.  
  18. FORMS/browser.c:
  19.     Add '@I' prefix to embed FL_ICON_STYLE (symbol font) items in a browser.
  20.  
  21. FORMS/draw.c:
  22.     Tie mouse (x,y) position to all mouse clicks.  Use this to ensure that we
  23.     always register a mouse click in its correct position, not the place where
  24.     the mouse lies when we get a chance to read it!
  25.     Click position is fed to the next caller to ask for the mouse position
  26.     after a click; later calls read the live mouse position.  Seems to work.
  27.  
  28.     Cache stuff as much as possible.  Don't load fonts or read color map unless
  29.     (until) we actually need them.  Might allow programs to start up at
  30.     a reasonable speed, since the SGI font manager is slower in 4.0.x than 3.3.
  31.  
  32.     Handle Icon font usefully -- use the Symbol font, and allow it to be scaled.
  33.  
  34.     Accommodate new font-sizing rule in IRIX 4.0.5: fonts are now
  35.     scaled to constant real size rather than constant size in pixels.
  36.     On IRIX 4.0.5 or greater, we discover the error this will cause and
  37.     scale all font sizes by its reciprocal (!).
  38.  
  39.  
  40. FORMS/forms.c:
  41.     More of record-mouse-position-on-click mod mentioned under draw.c.
  42.  
  43.     Cut out so-called Correction for Irix 4.0 INPUTCHANGE Bug.
  44.     With the bugfix installed, FORMS seems to lose inputchange's for new
  45.     windows appearing under the cursor; without it, it sees them correctly.
  46.  
  47. FORMS/bitmap.c:
  48.     Optimize drawing bitmaps.  Cache fl_getmcolor() values; use pointers
  49.     to scan input & output pixel arrays.  ~sixfold speedup.
  50.     Save 64K of static data.
  51.  
  52.  
  53. DESIGN/Makefile:
  54.     Add rule for fdesign2c, batch-mode translator from *.fd to *.{c,h}.
  55.  
  56. DESIGN/fd_forms.c:
  57. DESIGN/fd_main.c:
  58. DESIGN/fd_main.h:
  59.     Adapt to allow batch mode.
  60.  
  61. DESIGN/fd_objects.c:
  62.     Added colorwheel and fouraxis objects.
  63.  
  64. DESIGN/formsstubs.c:
  65.     Stubs for FORMS routines -- used for batch-mode fdesign2c program.
  66.  
  67.  
  68.  
  69. diff -r -c orig/DEMOS/Makefile new/DEMOS/Makefile
  70. *** orig/DEMOS/Makefile    Thu Nov 28 02:22:04 1991
  71. --- new/DEMOS/Makefile    Mon Aug 10 12:57:18 1992
  72. ***************
  73. *** 15,21 ****
  74.       demo21.o demo22.o demo23.o demo24.o demo25.o \
  75.       demo26.o demo27.o demo28.o demo29.o demo30.o \
  76.       demo31.o demo32.o demo33.o demo34.o demo35.o \
  77. !     demo36.o demo37.o demo38.o
  78.   #
  79.   DEMOS= ${DEMOSO:.o=}
  80.   
  81. --- 15,22 ----
  82.       demo21.o demo22.o demo23.o demo24.o demo25.o \
  83.       demo26.o demo27.o demo28.o demo29.o demo30.o \
  84.       demo31.o demo32.o demo33.o demo34.o demo35.o \
  85. !     demo36.o demo37.o demo38.o \
  86. !     demof01.o demof02.o
  87.   #
  88.   DEMOS= ${DEMOSO:.o=}
  89.   
  90. diff -r -c orig/DEMOS/Readme new/DEMOS/Readme
  91. *** orig/DEMOS/Readme    Mon Nov 18 13:26:09 1991
  92. --- new/DEMOS/Readme    Mon Aug 10 19:01:55 1992
  93. ***************
  94. *** 50,52 ****
  95. --- 50,56 ----
  96.   demo36    A demo of counters.
  97.   demo37    A strip chart.
  98.   demo38    All charts.
  99. + demof01    Fouraxis demo: fouraxis and numerical display
  100. + demof02 Fouraxis demo: fouraxis and basis-matrix display
  101. diff -r -c orig/DEMOS/demo.menu new/DEMOS/demo.menu
  102. *** orig/DEMOS/demo.menu    Tue Nov  5 06:39:04 1991
  103. --- new/DEMOS/demo.menu    Mon Aug 10 12:36:21 1992
  104. ***************
  105. *** 44,49 ****
  106. --- 44,51 ----
  107.           @other:Choice\nObjects:demo32
  108.           @other:Bitmaps:demo33
  109.           @other:Timer\nObjects:demo34
  110. +         @other:4-D Axis:demof01
  111. +         @other:4-D Axis\n+ Basis:demof02
  112.   
  113.   @main:Attributes:@attribs
  114.       @attribs:All\nBoxtypes:demo17
  115. Only in new/DEMOS: demof01.c
  116. Only in new/DEMOS: demof02.c
  117. diff -r -c orig/DESIGN/Makefile new/DESIGN/Makefile
  118. *** orig/DESIGN/Makefile    Wed Nov 27 09:51:42 1991
  119. --- new/DESIGN/Makefile    Mon Aug 31 11:01:18 1992
  120. ***************
  121. *** 9,24 ****
  122.   #
  123.   # Change the following for correct installation
  124.   #
  125. ! DIR= /usr/sbin
  126.   #
  127.   FILEo = fd_rubber.o fd_select.o fd_names.o fd_objects.o fd_attribs.o \
  128.           fd_forms.o fd_groups.o fd_file.o fd_print.o fd_theforms.o \
  129. !     fd_help.o fd_main.o
  130.   
  131.   all:    fdesign conv15to20
  132.   
  133.   fdesign: $(FILEo)
  134. !     ${CC} ${CFLAGS} ${LDFLAGS} $(FILEo) -o fdesign ${LIBS}
  135.   
  136.   conv15to20: conv15to20.o
  137.       ${CC} conv15to20.o -o conv15to20 -s
  138. --- 9,30 ----
  139.   #
  140.   # Change the following for correct installation
  141.   #
  142. ! DIR= /usr/local/bin
  143.   #
  144. + # Note fd_main.c in the following list.
  145. + # This forces recompilation with the appropriate -DBATCH setting.
  146.   FILEo = fd_rubber.o fd_select.o fd_names.o fd_objects.o fd_attribs.o \
  147.           fd_forms.o fd_groups.o fd_file.o fd_print.o fd_theforms.o \
  148. !     fd_help.o fd_main.c
  149.   
  150.   all:    fdesign conv15to20
  151.   
  152.   fdesign: $(FILEo)
  153. !     ${CC} ${CFLAGS} ${LDFLAGS} $(FILEo) -o $@ ${LIBS}
  154. ! fdesign2c:  $(FILEo) formsstubs.o
  155. !     ${CC} -DBATCH ${CFLAGS} ${LDFLAGS} ${FILEo} formsstubs.o -o $@ -lforms -lm -lc_s
  156.   
  157.   conv15to20: conv15to20.o
  158.       ${CC} conv15to20.o -o conv15to20 -s
  159. diff -r -c orig/DESIGN/fd_forms.c new/DESIGN/fd_forms.c
  160. *** orig/DESIGN/fd_forms.c    Wed Dec 11 10:35:17 1991
  161. --- new/DESIGN/fd_forms.c    Thu May 28 13:56:47 1992
  162. ***************
  163. *** 155,161 ****
  164.     LOADING AND SAVING
  165.   ****/
  166.   
  167. ! void load_forms(int merge, char *str)
  168.   /* loads or merges a file with form definitions */
  169.   {
  170.     int i,magic;
  171. --- 155,161 ----
  172.     LOADING AND SAVING
  173.   ****/
  174.   
  175. ! int load_forms(int merge, char *str)
  176.   /* loads or merges a file with form definitions */
  177.   {
  178.     int i,magic;
  179. ***************
  180. *** 168,174 ****
  181.       ff = fl_show_file_selector("Filename to merge forms from","","*.fd","");
  182.     else
  183.       ff = fl_show_file_selector("Filename to load forms from","","*.fd","");
  184. !   if (ff == NULL || ff[0] == '\0') return;
  185.     /* Append .fd if required. */
  186.     strcpy(fname,ff);
  187.     i = strlen(fname) -1;
  188. --- 168,174 ----
  189.       ff = fl_show_file_selector("Filename to merge forms from","","*.fd","");
  190.     else
  191.       ff = fl_show_file_selector("Filename to load forms from","","*.fd","");
  192. !   if (ff == NULL || ff[0] == '\0') return 0;
  193.     /* Append .fd if required. */
  194.     strcpy(fname,ff);
  195.     i = strlen(fname) -1;
  196. ***************
  197. *** 176,187 ****
  198.       strcat(fname,".fd");
  199.     /* Open the file for reading */
  200.     fn = fopen(fname,"r");
  201. !   if (fn == (FILE *) NULL) { fl_show_message("No such file!!","",""); return; }
  202.     /* Read in the definitions */
  203.     if (!merge) { fnumb = 0; fl_clear_browser(formbrowser);}
  204.     magic = 0;
  205.     fscanf(fn,"Magic: %d\n\n",&magic);
  206. !   if (magic != 12321) { fl_show_message("Wrong type of file!!","",""); return; }
  207.     fscanf(fn,"Internal Form Definition File\n");
  208.     fscanf(fn,"    (do not change)\n\n");
  209.     fscanf(fn,"Number of forms: %d\n",&i);
  210. --- 176,187 ----
  211.       strcat(fname,".fd");
  212.     /* Open the file for reading */
  213.     fn = fopen(fname,"r");
  214. !   if (fn == (FILE *) NULL) { fl_show_message("No such file!!",fname,""); return 0; }
  215.     /* Read in the definitions */
  216.     if (!merge) { fnumb = 0; fl_clear_browser(formbrowser);}
  217.     magic = 0;
  218.     fscanf(fn,"Magic: %d\n\n",&magic);
  219. !   if (magic != 12321) { fl_show_message("Wrong type of file!!",fname,""); return 0; }
  220.     fscanf(fn,"Internal Form Definition File\n");
  221.     fscanf(fn,"    (do not change)\n\n");
  222.     fscanf(fn,"Number of forms: %d\n",&i);
  223. ***************
  224. *** 194,200 ****
  225.       fl_add_browser_line(formbrowser,forms[fnumb].fname);
  226.       fnumb++;
  227.     }
  228. !   if (i>0) fl_show_message("Not all forms could be loaded!!","","");
  229.     if (i == 0 && !merge)
  230.     {
  231.       fscanf(fn,"\n==============================\n");
  232. --- 194,200 ----
  233.       fl_add_browser_line(formbrowser,forms[fnumb].fname);
  234.       fnumb++;
  235.     }
  236. !   if (i>0) fl_show_message("Not all forms could be loaded!!",fname,"");
  237.     if (i == 0 && !merge)
  238.     {
  239.       fscanf(fn,"\n==============================\n");
  240. ***************
  241. *** 204,212 ****
  242.     if (fnumb>0) set_form(0); else set_form(-1);
  243.     if (merge) changed = 1;
  244.     fclose(fn);
  245.   }
  246.   
  247. ! int save_forms()
  248.   /* saves the form definitions, retunrs whether saved */
  249.   {
  250.     int i,j;
  251. --- 204,213 ----
  252.     if (fnumb>0) set_form(0); else set_form(-1);
  253.     if (merge) changed = 1;
  254.     fclose(fn);
  255. +   return 1;
  256.   }
  257.   
  258. ! int save_forms(int do_fd, char *dfname)
  259.   /* saves the form definitions, retunrs whether saved */
  260.   {
  261.     int i,j;
  262. ***************
  263. *** 213,229 ****
  264.     FILE *fn;
  265.     char fname[256], filename[256], *ff;
  266.   
  267. !   /* Get the file name */
  268. !   ff = fl_show_file_selector("Filename to save forms to","","*.fd","");
  269. !   if (ff == NULL || ff[0] == '\0')
  270. !     { fl_show_message("No forms were saved.","",""); return 0; }
  271.   
  272.     /* Remove .fd is required */
  273. -   strcpy(filename,ff);
  274.     i = strlen(filename) -1;
  275.     if (filename[i] == 'd' && filename[i-1] == 'f' && filename[i-2] == '.')
  276.       filename[i-2] = '\0';
  277.   
  278.     /* Make the .h file. */
  279.     strcpy(fname,filename);
  280.     strcat(fname,".h");
  281. --- 214,251 ----
  282.     FILE *fn;
  283.     char fname[256], filename[256], *ff;
  284.   
  285. !   if(dfname == NULL) {
  286. !     /* Get the file name */
  287. !     ff = fl_show_file_selector("Filename to save forms to","","*.fd","");
  288. !     if (ff == NULL || ff[0] == '\0')
  289. !       { fl_show_message("No forms were saved.","",""); return 0; }
  290. !     strcpy(filename, ff);
  291. !   } else {
  292. !     strcpy(filename, dfname);
  293. !   }
  294.   
  295.     /* Remove .fd is required */
  296.     i = strlen(filename) -1;
  297.     if (filename[i] == 'd' && filename[i-1] == 'f' && filename[i-2] == '.')
  298.       filename[i-2] = '\0';
  299.   
  300. +   /* Make the .fd file. */
  301. +   if(do_fd) {
  302. +     strcpy(fname,filename);
  303. +     strcat(fname,".fd");
  304. +     fn = fopen(fname,"w");
  305. +     if (fn == (FILE *) NULL)
  306. +     { fl_show_message("Cannot create definition file!!","",""); return 0; }
  307. +     fprintf(fn,"Magic: 12321\n\n");
  308. +     fprintf(fn,"Internal Form Definition File\n");
  309. +     fprintf(fn,"    (do not change)\n\n");
  310. +     fprintf(fn,"Number of forms: %d\n",fnumb);
  311. +     for (i=0; i<fnumb; i++) write_form(fn,forms[i].form,forms[i].fname);
  312. +     fprintf(fn,"\n==============================\n%s\n",main_name);
  313. +     fclose(fn);
  314. +     sleep(1);        /* Ensure .fd older than .h and .c */
  315. +   }
  316.     /* Make the .h file. */
  317.     strcpy(fname,filename);
  318.     strcat(fname,".h");
  319. ***************
  320. *** 256,275 ****
  321.     fprintf(fn,"void %s()\n{\n",main_name);
  322.     for (i=0; i<fnumb; i++) fprintf(fn,"  create_form_%s();\n",forms[i].fname);
  323.     fprintf(fn,"}\n\n");
  324. -   fclose(fn);
  325. -   /* Make the .fd file. */
  326. -   strcpy(fname,filename);
  327. -   strcat(fname,".fd");
  328. -   fn = fopen(fname,"w");
  329. -   if (fn == (FILE *) NULL)
  330. -     { fl_show_message("Cannot create definition file!!","",""); return 0; }
  331. -   fprintf(fn,"Magic: 12321\n\n");
  332. -   fprintf(fn,"Internal Form Definition File\n");
  333. -   fprintf(fn,"    (do not change)\n\n");
  334. -   fprintf(fn,"Number of forms: %d\n",fnumb);
  335. -   for (i=0; i<fnumb; i++) write_form(fn,forms[i].form,forms[i].fname);
  336. -   fprintf(fn,"\n==============================\n%s\n",main_name);
  337.     fclose(fn);
  338.     return 1;
  339.   }
  340. --- 278,283 ----
  341. diff -r -c orig/DESIGN/fd_main.c new/DESIGN/fd_main.c
  342. *** orig/DESIGN/fd_main.c    Tue Dec 24 03:47:13 1991
  343. --- new/DESIGN/fd_main.c    Tue Apr 28 17:35:13 1992
  344. ***************
  345. *** 76,82 ****
  346.     {
  347.       rep = fl_show_choice("WARNING","Changes have not been saved.","",
  348.               3,"Save","Exit","Return");
  349. !     if (rep == 1) { if (! save_forms()) return; }
  350.       else if (rep == 3) return;
  351.     }
  352.     exit(0);
  353. --- 76,82 ----
  354.     {
  355.       rep = fl_show_choice("WARNING","Changes have not been saved.","",
  356.               3,"Save","Exit","Return");
  357. !     if (rep == 1) { if (! save_forms(1, NULL)) return; }
  358.       else if (rep == 3) return;
  359.     }
  360.     exit(0);
  361. ***************
  362. *** 110,116 ****
  363.   
  364.   void saveforms_cb(FL_OBJECT *obj, long arg) 
  365.   /* Save the current set of forms. */
  366. !   { changed = ! save_forms(); }
  367.   
  368.   void loadforms_cb(FL_OBJECT *obj, long arg) 
  369.   /* Load a new set of forms */
  370. --- 110,116 ----
  371.   
  372.   void saveforms_cb(FL_OBJECT *obj, long arg) 
  373.   /* Save the current set of forms. */
  374. !   { changed = ! save_forms(1, NULL); }
  375.   
  376.   void loadforms_cb(FL_OBJECT *obj, long arg) 
  377.   /* Load a new set of forms */
  378. ***************
  379. *** 118,124 ****
  380.     if (changed)
  381.     {
  382.       if (fl_show_question("Forms have been changed!","Should I save them?",""))
  383. !       { if (!save_forms()) return; }
  384.     }
  385.     load_forms(FALSE,NULL);
  386.     changed = 0;
  387. --- 118,124 ----
  388.     if (changed)
  389.     {
  390.       if (fl_show_question("Forms have been changed!","Should I save them?",""))
  391. !       { if (!save_forms(1, NULL)) return; }
  392.     }
  393.     load_forms(FALSE,NULL);
  394.     changed = 0;
  395. ***************
  396. *** 153,158 ****
  397. --- 153,159 ----
  398.     fl_activate_form(controlform);
  399.   }
  400.   
  401. + #ifndef BATCH
  402.   void main_loop()
  403.   /* The main event handling loop. */
  404.   {
  405. ***************
  406. *** 212,217 ****
  407. --- 213,219 ----
  408.       }
  409.     }
  410.   }
  411. + #endif /*!BATCH*/
  412.   
  413.   /* declarations to support use of getopt() system call */
  414.   extern char *optarg;
  415. ***************
  416. *** 273,278 ****
  417. --- 275,292 ----
  418.     redraw_the_form(1);
  419.     fl_show_form(controlform,FL_PLACE_POSITION,FALSE,NULL);
  420.   
  421. + #ifdef BATCH
  422. +   i = 0;
  423. +   while(optind < ac) {
  424. +     fprintf(stderr, "%s: ", av[optind]);
  425. +     if(load_forms(FALSE, av[optind]) && save_forms(0, av[optind]))
  426. +     fprintf(stderr, "done.\n");
  427. +     else i = 1;
  428. +     optind++;
  429. +   }
  430. +   exit(i);
  431. + #else /* !BATCH */
  432.     /* Load a file */
  433.     if (optind < ac)
  434.     {
  435. ***************
  436. *** 282,285 ****
  437. --- 296,300 ----
  438.   
  439.     /* Main loop */
  440.     main_loop();
  441. + #endif /* !BATCH */
  442.   }
  443. diff -r -c orig/DESIGN/fd_main.h new/DESIGN/fd_main.h
  444. *** orig/DESIGN/fd_main.h    Wed Dec 11 10:02:23 1991
  445. --- new/DESIGN/fd_main.h    Tue Apr 28 17:29:39 1992
  446. ***************
  447. *** 160,169 ****
  448.   /* Redraws the current form. The argument indicates whether the background
  449.      should be redrawn. */
  450.   
  451. ! void load_forms(int, char *);
  452.   /* loads the forms from a file */
  453.   
  454. ! int save_forms();
  455.   /* saves the forms to a file, returns whether actually saved */
  456.   
  457.   /******** fd_groups.c *********/
  458. --- 160,169 ----
  459.   /* Redraws the current form. The argument indicates whether the background
  460.      should be redrawn. */
  461.   
  462. ! int load_forms(int merge, char *fname);
  463.   /* loads the forms from a file */
  464.   
  465. ! int save_forms(int do_fd, char *fname);
  466.   /* saves the forms to a file, returns whether actually saved */
  467.   
  468.   /******** fd_groups.c *********/
  469. diff -r -c orig/DESIGN/fd_objects.c new/DESIGN/fd_objects.c
  470. *** orig/DESIGN/fd_objects.c    Thu Dec 12 03:41:01 1991
  471. --- new/DESIGN/fd_objects.c    Wed Dec 30 19:05:58 1992
  472. ***************
  473. *** 221,226 ****
  474. --- 221,235 ----
  475.       add_type_def(FL_TIMER,FL_HIDDEN_TIMER,"HIDDEN_TIMER");
  476.   
  477.   /* ADD NEW CLASSES HERE (and in the routine add_an_object below). */
  478. +   fl_add_browser_line(objectbrowser,"fouraxis");
  479. +   add_class_def(FL_FOURAXIS,"fouraxis",fl_create_fouraxis);
  480. +   add_type_def(FL_FOURAXIS,FL_NORMAL_FOURAXIS,"NORMAL_FOURAXIS");
  481. +   fl_add_browser_line(objectbrowser, "colorwheel");
  482. +   add_class_def(FL_COLORWHEEL, "colorwheel", fl_create_colorwheel);
  483. +   add_type_def(FL_COLORWHEEL, FL_NORMAL_COLORWHEEL, "NORMAL_COLORWHEEL");
  484.   } 
  485.   
  486.   /****
  487. ***************
  488. *** 342,348 ****
  489.       break;
  490.       case FL_TIMER:
  491.       obj = fl_add_timer(FL_NORMAL_TIMER,x,y,w,h,"Timer"); break;
  492. !     default:
  493.       fl_show_message("Error","","Trying to add unknow object type.");
  494.       exit(1);
  495.   /*
  496. --- 351,362 ----
  497.       break;
  498.       case FL_TIMER:
  499.       obj = fl_add_timer(FL_NORMAL_TIMER,x,y,w,h,"Timer"); break;
  500. !     case FL_FOURAXIS:
  501. !     obj = fl_add_fouraxis(FL_NORMAL_FOURAXIS, x,y,w,h,"4D axis"); break;
  502. !     case FL_COLORWHEEL:
  503. !     obj = fl_add_colorwheel(FL_NORMAL_COLORWHEEL,x,y,w,h,"Colorwheel");
  504. !     break;
  505. !      default:
  506.       fl_show_message("Error","","Trying to add unknow object type.");
  507.       exit(1);
  508.   /*
  509. Only in new/DESIGN: formsstubs.c
  510. Only in new/DOC/CLASSES: colorwheel.tex
  511. Only in new/DOC/CLASSES: fouraxis.tex
  512. diff -r -c orig/DOC/part3.tex new/DOC/part3.tex
  513. *** orig/DOC/part3.tex    Mon Nov  4 14:20:38 1991
  514. --- new/DOC/part3.tex    Wed Dec 30 13:54:00 1992
  515. ***************
  516. *** 42,47 ****
  517. --- 42,51 ----
  518.     Lets the user indicate an $(x,y)$ position with the mouse.\\
  519.   Counter &
  520.     A different way to let a user step through values.\\
  521. + Fouraxis &
  522. +   Lets the user indicate an $(x,y,z,w)$ direction (unit vector) in 4-space.\\
  523. + Colorwheel &
  524. +   Lets the user select an RGB color value.\\
  525.   \hline
  526.   \multicolumn{2}{|c|}{Input Objects}\\
  527.   \hline
  528. ***************
  529. *** 129,134 ****
  530. --- 133,140 ----
  531.   \input{CLASSES/dial.tex}
  532.   \input{CLASSES/positioner.tex}
  533.   \input{CLASSES/counter.tex}
  534. + \input{CLASSES/fouraxis.tex}
  535. + \input{CLASSES/colorwheel.tex}
  536.   
  537.   \chapter{Input objects}
  538.   
  539. diff -r -c orig/FORMS/INCLUDE/aaa.h new/FORMS/INCLUDE/aaa.h
  540. *** orig/FORMS/INCLUDE/aaa.h    Thu Nov 28 01:56:34 1991
  541. --- new/FORMS/INCLUDE/aaa.h    Wed Jun  9 19:56:12 1993
  542. ***************
  543. *** 182,188 ****
  544.   #define FL_FONT_BOLDNAME    "Helvetica-Bold"
  545.   #define FL_FONT_ITALICNAME    "Helvetica-Oblique"
  546.   #define FL_FONT_FIXEDNAME    "Courier"
  547. ! #define FL_FONT_ICONNAME    "Icon"
  548.   
  549.   #define FL_SMALL_FONT        8.0
  550.   #define FL_NORMAL_FONT        11.0
  551. --- 182,188 ----
  552.   #define FL_FONT_BOLDNAME    "Helvetica-Bold"
  553.   #define FL_FONT_ITALICNAME    "Helvetica-Oblique"
  554.   #define FL_FONT_FIXEDNAME    "Courier"
  555. ! #define FL_FONT_ICONNAME    "Symbol"
  556.   
  557.   #define FL_SMALL_FONT        8.0
  558.   #define FL_NORMAL_FONT        11.0
  559. ***************
  560. *** 326,332 ****
  561.   void    fl_unset_clipping(void);
  562.   
  563.   void    fl_init_fonts();
  564. ! void    fl_set_font(char [], char [], char [], char[]);
  565.   float    fl_get_char_height(float, int);
  566.   float    fl_get_char_width(float, int, char);
  567.   float    fl_get_string_width(float, int, char []);
  568. --- 326,332 ----
  569.   void    fl_unset_clipping(void);
  570.   
  571.   void    fl_init_fonts();
  572. ! void    fl_set_font(char [], char [], char [], char[], char []);
  573.   float    fl_get_char_height(float, int);
  574.   float    fl_get_char_width(float, int, char);
  575.   float    fl_get_string_width(float, int, char []);
  576. Only in new/FORMS/INCLUDE: colorwheel.h
  577. Only in new/FORMS/INCLUDE: fouraxis.h
  578. diff -r -c orig/FORMS/Makefile new/FORMS/Makefile
  579. *** orig/FORMS/Makefile    Wed Nov 27 09:33:55 1991
  580. --- new/FORMS/Makefile    Fri Feb 12 16:29:37 1993
  581. ***************
  582. *** 10,17 ****
  583.   #
  584.   # For instalation. Change this to your settings.
  585.   #
  586. ! INCLUDEDIR= /usr/include
  587. ! LIBDIR= /usr/lib
  588.   #
  589.   #   products
  590.   #
  591. --- 10,17 ----
  592.   #
  593.   # For instalation. Change this to your settings.
  594.   #
  595. ! INCLUDEDIR= /usr/local/include
  596. ! LIBDIR= /usr/local/lib
  597.   #
  598.   #   products
  599.   #
  600. ***************
  601. *** 20,36 ****
  602.   #
  603.   #   compilation control
  604.   #
  605. ! LIBOBJS= ${LIB}(box.o) ${LIB}(text.o) ${LIB}(slider.o) ${LIB}(input.o) \
  606. !          ${LIB}(menu.o) ${LIB}(button.o) ${LIB}(dial.o) ${LIB}(timer.o) \
  607. !          ${LIB}(free.o) ${LIB}(clock.o) ${LIB}(counter.o) \
  608. !          ${LIB}(browser.o) ${LIB}(positioner.o) ${LIB}(goodies.o) \
  609. !      ${LIB}(symbols.o) ${LIB}(draw.o)  ${LIB}(objects.o) ${LIB}(forms.o) \
  610. !      ${LIB}(events.o) ${LIB}(fselect.o) ${LIB}(choice.o) ${LIB}(bitmap.o) \
  611. !      ${LIB}(chart.o) ${LIB}(support.o)
  612.   
  613. ! all:        ${LIBOBJS}
  614.   
  615. ! ${LIBOBJS}:    ${INCLUDE}
  616.   
  617.   .c.a:
  618.       ${CC} -c ${CFLAGS} $<
  619. --- 20,37 ----
  620.   #
  621.   #   compilation control
  622.   #
  623. ! OBJS= box.o text.o slider.o input.o \
  624. !          menu.o button.o dial.o timer.o \
  625. !          free.o clock.o counter.o \
  626. !          browser.o positioner.o goodies.o \
  627. !      symbols.o draw.o  objects.o forms.o \
  628. !      events.o fselect.o choice.o bitmap.o fouraxis.o colorwheel.o \
  629. !      chart.o support.o
  630.   
  631. ! all:        ${LIB}
  632.   
  633. ! ${LIB}:    ${OBJS}
  634. !     ${AR} ${ARFLAGS} $@ ${OBJS}
  635.   
  636.   .c.a:
  637.       ${CC} -c ${CFLAGS} $<
  638. ***************
  639. *** 43,48 ****
  640.   empty:
  641.       -rm -f ${INCLUDE} ${LIB}
  642.   
  643. ! install:    ${LIBOBJS}
  644.       cp ${LIB} ${LIBDIR}
  645.       cp ${INCLUDE} ${INCLUDEDIR}
  646. --- 44,51 ----
  647.   empty:
  648.       -rm -f ${INCLUDE} ${LIB}
  649.   
  650. ! install:    ${LIB}
  651.       cp ${LIB} ${LIBDIR}
  652.       cp ${INCLUDE} ${INCLUDEDIR}
  653. + objs:    ${OBJS}
  654. diff -r -c orig/FORMS/bitmap.c new/FORMS/bitmap.c
  655. *** orig/FORMS/bitmap.c    Mon Nov 18 02:32:06 1991
  656. --- new/FORMS/bitmap.c    Thu Jul 22 23:09:20 1993
  657. ***************
  658. *** 17,31 ****
  659.   char *bits;            /* pointer to the bitmap */
  660.   } SPEC;
  661.   
  662. - static unsigned long thebits[FL_BITMAP_MAXSIZE];
  663.   static void draw_bitmap(FL_OBJECT *ob)
  664.   /* draws the bitmap */
  665.   {
  666.     SPEC *sp = ((SPEC *)(ob->spec));
  667. !   int i,j,c,k = 0;
  668. !   short r,g,b;
  669. !   int xx,yy;        /* position of bitmap */
  670.   
  671.     /* Draw the box */
  672.     fl_drw_box(ob->boxtype,ob->x,ob->y,ob->w,ob->h,ob->col2,FL_BITMAP_BW);
  673. --- 17,31 ----
  674.   char *bits;            /* pointer to the bitmap */
  675.   } SPEC;
  676.   
  677.   static void draw_bitmap(FL_OBJECT *ob)
  678.   /* draws the bitmap */
  679.   {
  680.     SPEC *sp = ((SPEC *)(ob->spec));
  681. !   
  682. !   unsigned int j,k = 0;
  683. !   long color[2];
  684. !   int i, xx,yy;        /* position of bitmap */
  685. !   unsigned long thebits[FL_BITMAP_MAXSIZE];
  686.   
  687.     /* Draw the box */
  688.     fl_drw_box(ob->boxtype,ob->x,ob->y,ob->w,ob->h,ob->col2,FL_BITMAP_BW);
  689. ***************
  690. *** 33,52 ****
  691.                   ob->lcol,ob->lsize,ob->lstyle,ob->label);
  692.   
  693.     if (sp->bits_w == 0) return;
  694.     /* Create the bitmap */
  695.     for (j=0; j<sp->bits_h; j++)
  696.     {
  697. !     for (i=0; i<sp->bits_w; i++)
  698. !     {
  699. !       if (sp->bits[k + i/8] & (1 << (i % 8))) c = ob->col1; else c = ob->col2;
  700. !       if (fl_rgbmode)
  701. !       {
  702. !         fl_getmcolor(c,&r,&g,&b);
  703. !         thebits[(sp->bits_h-j-1)*sp->bits_w+i] = 0x10000 * b + 0x100 * g + r;
  704. !       }
  705. !       else
  706. !         thebits[(sp->bits_h-j-1)*sp->bits_w+i] = (short)c;
  707. !     }
  708.       k += (sp->bits_w+7)/8;
  709.     }
  710.   
  711. --- 33,67 ----
  712.                   ob->lcol,ob->lsize,ob->lstyle,ob->label);
  713.   
  714.     if (sp->bits_w == 0) return;
  715. +   if(fl_rgbmode) {
  716. +     short r,g,b;
  717. +     fl_getmcolor(ob->col1, &r,&g,&b);  color[1] = (b<<16) | (g<<8) | r;
  718. +     fl_getmcolor(ob->col2, &r,&g,&b);  color[0] = (b<<16) | (g<<8) | r;
  719. +   } else {
  720. +     color[1] = ob->col1;
  721. +     color[0] = ob->col2;
  722. +   }
  723.     /* Create the bitmap */
  724.     for (j=0; j<sp->bits_h; j++)
  725.     {
  726. !     register unsigned long *op = &thebits[(sp->bits_h - j - 1) * sp->bits_w];
  727. !     unsigned char *ip = (unsigned char *)&sp->bits[k];
  728. !     i = sp->bits_w;
  729. !     do {
  730. !     register int byte = *ip++;
  731. !     switch(i <= 8 ? (i & 7) : 0) {
  732. !     case 0: *op++ = color[byte&1]; byte >>= 1;
  733. !     case 7: *op++ = color[byte&1]; byte >>= 1;
  734. !     case 6: *op++ = color[byte&1]; byte >>= 1;
  735. !     case 5: *op++ = color[byte&1]; byte >>= 1;
  736. !     case 4: *op++ = color[byte&1]; byte >>= 1;
  737. !     case 3: *op++ = color[byte&1]; byte >>= 1;
  738. !     case 2: *op++ = color[byte&1]; byte >>= 1;
  739. !     case 1: *op++ = color[byte&1]; byte >>= 1;
  740. !     }
  741. !     } while((i -= 8) > 0);
  742.       k += (sp->bits_w+7)/8;
  743.     }
  744.   
  745. diff -r -c orig/FORMS/browser.c new/FORMS/browser.c
  746. *** orig/FORMS/browser.c    Thu Dec 12 05:09:14 1991
  747. --- new/FORMS/browser.c    Tue Jun 22 21:10:34 1993
  748. ***************
  749. *** 153,158 ****
  750. --- 153,159 ----
  751.         case 's': size = FL_SMALL_FONT; break;
  752.         case 'b':    style = FL_BOLD_STYLE; break;
  753.         case 'i':    style = FL_ITALIC_STYLE; break;
  754. +       case 'I': style = FL_ICON_STYLE; break;
  755.         case 'f':    style = FL_FIXED_STYLE; break;
  756.         case 'c':    align = FL_ALIGN_CENTER; break;
  757.         case 'r':    align = FL_ALIGN_RIGHT; break;
  758. Only in new/FORMS: colorwheel.c
  759. diff -r -c orig/FORMS/draw.c new/FORMS/draw.c
  760. *** orig/FORMS/draw.c    Wed Nov 27 09:04:20 1991
  761. --- new/FORMS/draw.c    Wed Oct 20 19:05:49 1993
  762. ***************
  763. *** 17,22 ****
  764. --- 17,23 ----
  765.   #include <gl/device.h>
  766.   #include <fmclient.h>
  767.   #include <string.h>
  768. + #include <sys/utsname.h>    /* 4.0.5 hack */
  769.   #include "forms.h"
  770.   
  771.   /*********
  772. ***************
  773. *** 23,37 ****
  774.      Mouse stuff.
  775.   *********/
  776.   
  777.   void fl_get_mouse(float *xx,float *yy)
  778.   /* returns the position of the mouse in world coordinates*/
  779.   {
  780. !   long x,y;
  781.     getorigin(&x,&y);
  782. !   *xx = (float) (getvaluator(MOUSEX)-x);
  783. !   *yy = (float) (getvaluator(MOUSEY)-y);
  784.   }
  785.   
  786.   /*********
  787.      Clipping.
  788.   *********/
  789. --- 24,67 ----
  790.      Mouse stuff.
  791.   *********/
  792.   
  793. + static struct {
  794. +    long x, y;
  795. +    int valid;
  796. + } mouse;
  797. + /*
  798. +  * Remember, briefly, where the mouse was when a button is clicked;
  799. +  * lets us keep things straight when we're behind real time.
  800. +  */
  801. + void fl_mouse_click_at(long xpix, long ypix)
  802. + {
  803. +   mouse.x = xpix;
  804. +   mouse.y = ypix;
  805. +   mouse.valid = 1;
  806. + }
  807. + void fl_get_raw_mouse(long *xx, long *yy)
  808. + {
  809. +   if(!mouse.valid) {
  810. +     mouse.x = getvaluator(MOUSEX);
  811. +     mouse.y = getvaluator(MOUSEY);
  812. +   }
  813. +   *xx = mouse.x;
  814. +   *yy = mouse.y;
  815. +   mouse.valid = 0;
  816. + }
  817.   void fl_get_mouse(float *xx,float *yy)
  818.   /* returns the position of the mouse in world coordinates*/
  819.   {
  820. !   long x,y, mx,my;
  821. !   fl_get_raw_mouse(&mx, &my);
  822.     getorigin(&x,&y);
  823. !   *xx = mx - x;
  824. !   *yy = my - y;
  825.   }
  826.   
  827.   /*********
  828.      Clipping.
  829.   *********/
  830. ***************
  831. *** 59,93 ****
  832.      Font related stuff
  833.   *********/
  834.   
  835. ! static fmfonthandle thefont[5],smallfont[5],normalfont[5],largefont[5],
  836. !     iconfont;
  837. ! void fl_set_font(char normalname[], char boldname[],
  838. !         char italicname[], char fixedname[])
  839.   {
  840.     int i;
  841. !   fminit();
  842. !   thefont[0] = fmfindfont(normalname);
  843. !   thefont[1] = fmfindfont(boldname);
  844. !   thefont[2] = fmfindfont(italicname);
  845. !   thefont[3] = fmfindfont(fixedname);
  846. !   for (i=0; i<4; i++)
  847. !   {
  848. !     smallfont[i] = fmscalefont(thefont[i],FL_SMALL_FONT);
  849. !     normalfont[i] = fmscalefont(thefont[i],FL_NORMAL_FONT);
  850. !     largefont[i] = fmscalefont(thefont[i],FL_LARGE_FONT);
  851. !   }
  852. !   thefont[4] = thefont[0];
  853. !   smallfont[4] = smallfont[0];
  854. !   normalfont[4] = normalfont[0];
  855. !   largefont[4] = largefont[0];
  856.   }
  857.   
  858.   void fl_init_fonts()
  859.   {
  860. !   fl_set_font(FL_FONT_NAME,FL_FONT_BOLDNAME,
  861. !             FL_FONT_ITALICNAME,FL_FONT_FIXEDNAME);
  862. !   iconfont = fmfindfont(FL_FONT_ICONNAME);
  863.   }
  864.   
  865.   float fl_get_char_height(float size, int style)
  866. --- 89,166 ----
  867.      Font related stuff
  868.   *********/
  869.   
  870. ! static fmfonthandle thefont[6],smallfont[6],normalfont[6],largefont[6];
  871. ! static char *fontname[6] = {
  872. !     FL_FONT_NAME,        FL_FONT_BOLDNAME,    FL_FONT_ITALICNAME,
  873. !     FL_FONT_FIXEDNAME,    NULL,            FL_FONT_ICONNAME
  874. ! };
  875. ! static float fontscale = 0;
  876. ! void fl_set_font(char normal[], char bold[],
  877. !         char italic[], char fixed[],
  878. !         char icon[])
  879.   {
  880.     int i;
  881. !   fontname[FL_NORMAL_STYLE] = normal;
  882. !   fontname[FL_BOLD_STYLE] = bold;
  883. !   fontname[FL_ITALIC_STYLE] = italic;
  884. !   fontname[FL_FIXED_STYLE] = fixed;
  885. !   fontname[FL_ICON_STYLE] = icon;
  886. !    /* Invalidate font cache */
  887. !   bzero(thefont, sizeof(thefont));
  888. !   bzero(smallfont, sizeof(smallfont));
  889. !   bzero(normalfont, sizeof(normalfont));
  890. !   bzero(largefont, sizeof(largefont));
  891.   }
  892.   
  893.   void fl_init_fonts()
  894.   {
  895. !   if(fontscale == 0) {
  896. !     /* Kludge to handle fontmgr "bug" fix in >= 4.0.5:
  897. !      * Fonts are now scaled to appear as constant real size (Postscript style)
  898. !      * as opposed to constant size in pixels (as 3.x and 4.0.[1..4] fmgr did).
  899. !      * FORMS programs (at least fdesign'ed ones) assume constant pixel size,
  900. !      * so if this bugfix was applied, we apply the inverse transformation here.
  901. !      */
  902. !     struct utsname whatami;
  903. !     uname(&whatami);
  904. !     fontscale = 1.0;        /* Old systems work as we expect */
  905. !     if(strcmp(whatami.release, "4.0.5") >= 0)
  906. !     fontscale = ((float)getgdesc(GD_XMMAX)/getgdesc(GD_XPMAX)) / 0.265;
  907. !   }
  908. !   fminit();
  909. !  /* No need to do this now -- statically initialized.
  910. !   * fl_set_font(FL_FONT_NAME,FL_FONT_BOLDNAME,
  911. !   *            FL_FONT_ITALICNAME,FL_FONT_FIXEDNAME,
  912. !   *            FL_FONT_ICONNAME);
  913. !   */
  914. ! }
  915. ! fmfonthandle
  916. ! fl_get_font(float size, int style)
  917. ! {
  918. !   fmfonthandle fnt = NULL;
  919. !   fmfonthandle *fp = &fnt;
  920. !   if (style < 0 || style >= 6)
  921. !     {fl_error("fl_get_font","Unknown font style"); return NULL;}
  922. !   if (size == FL_SMALL_FONT) fp = &smallfont[style];
  923. !   else if (size == FL_NORMAL_FONT) fp = &normalfont[style];
  924. !   else if (size == FL_LARGE_FONT) fp = &largefont[style];
  925. !   if(*fp == NULL) {
  926. !     if(thefont[style] == NULL) {
  927. !     if(style == 0 || style == 4)
  928. !        thefont[0] = thefont[4] = fmfindfont(fontname[0]);
  929. !     else
  930. !        thefont[style] = fmfindfont(fontname[style]);
  931. !     }
  932. !     *fp = fmscalefont(thefont[style], size*fontscale);
  933. !   }
  934. !   if(*fp == NULL)
  935. !     fl_error("fl_get_font", "Unknown font");
  936. !   return *fp;
  937.   }
  938.   
  939.   float fl_get_char_height(float size, int style)
  940. ***************
  941. *** 95,109 ****
  942.   {
  943.     fmfontinfo info;
  944.     fmfonthandle fnt;
  945. !   if (style < 0 || style >= 6)
  946. !     {fl_error("fl_get_char_height","Unknown font style"); return 0.0;}
  947. !   if (style == FL_ICON_STYLE) fnt = iconfont;
  948. !   else if (size == FL_SMALL_FONT) fnt = smallfont[style];
  949. !   else if (size == FL_NORMAL_FONT) fnt = normalfont[style];
  950. !   else if (size == FL_LARGE_FONT) fnt = largefont[style];
  951. !   else  fnt = fmscalefont(thefont[style],size);
  952. !   if (fnt == NULL)
  953. !     {fl_error("fl_get_char_height","Font does not exist."); return 0.0;}
  954.     fmgetfontinfo(fnt,&info);
  955.     return (float) info.height;
  956.   }
  957. --- 168,175 ----
  958.   {
  959.     fmfontinfo info;
  960.     fmfonthandle fnt;
  961. !   if((fnt = fl_get_font(size, style)) == NULL)
  962. !     return 0.0;
  963.     fmgetfontinfo(fnt,&info);
  964.     return (float) info.height;
  965.   }
  966. ***************
  967. *** 113,127 ****
  968.   {
  969.     fmfontinfo info;
  970.     fmfonthandle fnt;
  971. !   if (style < 0 || style >= 6)
  972. !     {fl_error("fl_get_string_width","Unknown font style"); return 0.0;}
  973. !   if (style == FL_ICON_STYLE) fnt = iconfont;
  974. !   else if (size == FL_SMALL_FONT) fnt = smallfont[style];
  975. !   else if (size == FL_NORMAL_FONT) fnt = normalfont[style];
  976. !   else if (size == FL_LARGE_FONT) fnt = largefont[style];
  977. !   else  fnt = fmscalefont(thefont[style],size);
  978. !   if (fnt == NULL)
  979. !     {fl_error("fl_get_string_width","Font does not exist."); return 0.0;}
  980.     fmgetfontinfo(fnt,&info);
  981.     return (float) fmgetstrwidth(fnt,str);
  982.   }
  983. --- 179,186 ----
  984.   {
  985.     fmfontinfo info;
  986.     fmfonthandle fnt;
  987. !   if((fnt = fl_get_font(size, style)) == NULL)
  988. !     return 0.0;
  989.     fmgetfontinfo(fnt,&info);
  990.     return (float) fmgetstrwidth(fnt,str);
  991.   }
  992. ***************
  993. *** 138,173 ****
  994.      Color Stuff.
  995.   *********/
  996.   
  997. - static short fl_red[4096], fl_green[4096], fl_blue[4096];
  998.   
  999.   void fl_init_colormap()
  1000.   {
  1001. !   long cmwin, oldwin;
  1002. !   int i;
  1003. !   /* Read colormap colors into internal table */
  1004. !   oldwin = winget();
  1005. !   noport();
  1006. !   cmwin = winopen("CM");
  1007. !   for (i=0; i<4096; i++)
  1008. !     getmcolor(i,&fl_red[i],&fl_green[i],&fl_blue[i]);
  1009. !   winclose(cmwin);
  1010. !   if (oldwin >= 0) winset(oldwin);
  1011. !   /* Correct colors for small number of bitplanes */
  1012. !   if (getgdesc(GD_BITS_NORM_DBL_RED) <= 4)
  1013. !     for (i=0; i<4096; i++)
  1014. !     {
  1015. !        fl_red[i] = 8 * (fl_red[i] / 8);
  1016. !        fl_green[i] = 8 * (fl_green[i] / 8);
  1017. !        fl_blue[i] = 8 * (fl_blue[i] / 8);
  1018.       }
  1019.   }
  1020.   
  1021.   void fl_color(int col)
  1022.   /* Sets a colormap index in RGB mode. */
  1023.   {
  1024. !   if (fl_rgbmode)
  1025. !     RGBcolor(fl_red[col],fl_green[col],fl_blue[col]);
  1026. !   else
  1027.       color(col);
  1028.   }
  1029.   
  1030. --- 197,243 ----
  1031.      Color Stuff.
  1032.   *********/
  1033.   
  1034.   
  1035. + static long fl_cmap[4096];
  1036.   void fl_init_colormap()
  1037.   {
  1038. !   bzero(fl_cmap, sizeof(fl_cmap));
  1039. ! }
  1040. ! void fl_getmcolor(int index, short *red, short *green, short *blue)
  1041. ! {
  1042. !   long v;
  1043. !   short r,g,b;
  1044. !   if(!fl_rgbmode) {
  1045. !     getmcolor(index, red, green, blue);
  1046. !     return;
  1047. !   }
  1048. !   if(index < 0 || index >= 4096)
  1049. !     return;
  1050. !   if((v = fl_cmap[index]) != 0) {
  1051. !     *red = v & 0xFF;
  1052. !     *green = (v>>8) & 0xFF;
  1053. !     *blue = (v>>16) & 0xFF;
  1054. !   } else {
  1055. !     if(winget() <= 0) {
  1056. !     noport();
  1057. !     winopen("CM");
  1058.       }
  1059. +     getmcolor(index, red, green, blue);
  1060. +     fl_mapcolor(index, *red, *green, *blue);
  1061. +   }
  1062.   }
  1063.   
  1064.   void fl_color(int col)
  1065.   /* Sets a colormap index in RGB mode. */
  1066.   {
  1067. !   short r,g,b;
  1068. !   if (fl_rgbmode) {
  1069. !     fl_getmcolor(col, &r,&g,&b);
  1070. !     RGBcolor(r,g,b);
  1071. !   } else
  1072.       color(col);
  1073.   }
  1074.   
  1075. ***************
  1076. *** 174,194 ****
  1077.   void fl_mapcolor(int i, short red, short green, short blue)
  1078.   /* Changes a colormap index */
  1079.   {
  1080. !   if (fl_rgbmode)
  1081. !     { fl_red[i] = red; fl_green[i] = green; fl_blue[i] = blue;}
  1082. !   else
  1083.       mapcolor(i,red,green,blue);
  1084.   }
  1085.   
  1086. - void fl_getmcolor(int i, short *red, short *green, short *blue)
  1087. - /* Returns a colormap index */
  1088. - {
  1089. -   if (fl_rgbmode)
  1090. -     {*red = fl_red[i]; *green = fl_green[i]; *blue = fl_blue[i];}
  1091. -   else
  1092. -     getmcolor(i,red,green,blue);
  1093. - }
  1094.   /*********
  1095.      Drawing boxes.
  1096.   *********/
  1097. --- 244,257 ----
  1098.   void fl_mapcolor(int i, short red, short green, short blue)
  1099.   /* Changes a colormap index */
  1100.   {
  1101. !   if (fl_rgbmode) {
  1102. !     if(i >= 0 && i < 4096)
  1103. !     fl_cmap[i] = 0xFF000000 | ((blue&0xFF) << 16) |
  1104. !             ((green&0xFF) << 8) | ((red&0xFF));
  1105. !   } else
  1106.       mapcolor(i,red,green,blue);
  1107.   }
  1108.   
  1109.   /*********
  1110.      Drawing boxes.
  1111.   *********/
  1112. ***************
  1113. *** 359,372 ****
  1114.   
  1115.     if (pos!=0 && (str == NULL || str[0] == '\0')) return;
  1116.     /* Set the font correctly. */
  1117. !   if (style < 0 || style >= 6)
  1118. !     {fl_error("fl_drw_text_cursor","Unknown font style"); return;}
  1119. !   if (style == FL_ICON_STYLE) fnt = iconfont;
  1120. !   else if (size == FL_SMALL_FONT) fnt = smallfont[style];
  1121. !   else if (size == FL_NORMAL_FONT) fnt = normalfont[style];
  1122. !   else if (size == FL_LARGE_FONT) fnt = largefont[style];
  1123. !   else  fnt = fmscalefont(thefont[style],size);
  1124. !   if (fnt == NULL)
  1125.       {fl_error("fl_drw_test_cursor","Font does not exist."); return;}
  1126.     fmsetfont(fnt);
  1127.     fmgetfontinfo(fnt,&info);
  1128. --- 422,428 ----
  1129.   
  1130.     if (pos!=0 && (str == NULL || str[0] == '\0')) return;
  1131.     /* Set the font correctly. */
  1132. !   if((fnt = fl_get_font(size, style)) == NULL)
  1133.       {fl_error("fl_drw_test_cursor","Font does not exist."); return;}
  1134.     fmsetfont(fnt);
  1135.     fmgetfontinfo(fnt,&info);
  1136. diff -r -c orig/FORMS/events.c new/FORMS/events.c
  1137. *** orig/FORMS/events.c    Tue Nov 12 06:51:35 1991
  1138. --- new/FORMS/events.c    Thu May 28 17:58:51 1992
  1139. ***************
  1140. *** 46,53 ****
  1141.   
  1142.   #define QSIZE    700
  1143.   
  1144. ! static int queued[MAXSGIDEVICE];    /* devices queued by user */
  1145.   
  1146.   static short thedev[QSIZE];          /* The event queue */
  1147.   static short theval[QSIZE];
  1148.   static int head = 0 , tail = 0;
  1149. --- 46,57 ----
  1150.   
  1151.   #define QSIZE    700
  1152.   
  1153. ! static char queued[(MAXSGIDEVICE+7)/8];    /* devices queued by user */
  1154.   
  1155. + #define    BITSET(cvec, bit)  (cvec)[(bit) >> 3] |= 1 << ((bit)&7)
  1156. + #define BITCLEAR(cvec, bit)  (cvec)[(bit) >> 3] &= ~(1 << ((bit)&7))
  1157. + #define    BITTEST(cvec, bit)  ((cvec)[(bit) >> 3] & 1 << ((bit)&7))
  1158.   static short thedev[QSIZE];          /* The event queue */
  1159.   static short theval[QSIZE];
  1160.   static int head = 0 , tail = 0;
  1161. ***************
  1162. *** 67,81 ****
  1163.   /* initializes the event setting */
  1164.   {
  1165.     int i;
  1166. !   for (i=0; i<MAXSGIDEVICE; i++) queued[i] = !special_event( (Device) i);
  1167. !   queued[REDRAW] = TRUE;
  1168. !   queued[INPUTCHANGE] = TRUE;
  1169.   }
  1170.   
  1171.   void fl_qdevice(Device dev)
  1172.   /* queues a device */
  1173.   {
  1174. !   queued[dev] = TRUE;
  1175.     qdevice(dev);
  1176.   }
  1177.   
  1178. --- 71,89 ----
  1179.   /* initializes the event setting */
  1180.   {
  1181.     int i;
  1182. !   for (i=0; i<MAXSGIDEVICE; i++)
  1183. !     if(special_event( (Device) i))
  1184. !     BITSET(queued, i);
  1185. !     else
  1186. !     BITCLEAR(queued, i);
  1187. !   BITSET(queued, REDRAW);
  1188. !   BITSET(queued, INPUTCHANGE);
  1189.   }
  1190.   
  1191.   void fl_qdevice(Device dev)
  1192.   /* queues a device */
  1193.   {
  1194. !   BITSET(queued, dev);
  1195.     qdevice(dev);
  1196.   }
  1197.   
  1198. ***************
  1199. *** 82,94 ****
  1200.   void fl_unqdevice(Device dev)
  1201.   /* unqueues a device */
  1202.   {
  1203. !   if (special_event(dev)) queued[dev] = FALSE; else unqdevice(dev);
  1204.   }
  1205.   
  1206.   int fl_isqueued(Device dev)
  1207.   /* test whether a device is queued */
  1208.   {
  1209. !   return (queued[dev] && isqueued(dev));
  1210.   }
  1211.   
  1212.   long fl_qtest()
  1213. --- 90,102 ----
  1214.   void fl_unqdevice(Device dev)
  1215.   /* unqueues a device */
  1216.   {
  1217. !   if (special_event(dev)) BITCLEAR(queued, dev); else unqdevice(dev);
  1218.   }
  1219.   
  1220.   int fl_isqueued(Device dev)
  1221.   /* test whether a device is queued */
  1222.   {
  1223. !   return (BITTEST(queued, dev) && isqueued(dev));
  1224.   }
  1225.   
  1226.   long fl_qtest()
  1227. ***************
  1228. *** 107,113 ****
  1229.   void fl_qenter(short qtype, short val)
  1230.   /* Adds an event to the queue */
  1231.   {
  1232. !   if (special_event( (Device) qtype) && !queued[qtype]) return;
  1233.     new_events++;
  1234.     if (head == tail-1 || (head == QSIZE-1 && tail == 0))
  1235.       tail = (tail+1) % QSIZE;
  1236. --- 115,121 ----
  1237.   void fl_qenter(short qtype, short val)
  1238.   /* Adds an event to the queue */
  1239.   {
  1240. !   if (special_event( (Device) qtype) && !BITTEST(queued,qtype)) return;
  1241.     new_events++;
  1242.     if (head == tail-1 || (head == QSIZE-1 && tail == 0))
  1243.       tail = (tail+1) % QSIZE;
  1244. diff -r -c orig/FORMS/forms.c new/FORMS/forms.c
  1245. *** orig/FORMS/forms.c    Mon Dec 23 05:09:23 1991
  1246. --- new/FORMS/forms.c    Wed Oct 20 19:06:30 1993
  1247. ***************
  1248. *** 149,156 ****
  1249.         {wx = (screenw - (long)(form->w))/2; wy = (screenh - (long)(form->h))/2;}
  1250.       else if (place == FL_PLACE_MOUSE)
  1251.       {
  1252. !       wx = (long) (getvaluator(MOUSEX) - 0.5*form->w);
  1253. !       wy = (long) (getvaluator(MOUSEY) - 0.5*form->h);
  1254.       }
  1255.       else if (place == FL_PLACE_POSITION)
  1256.       {
  1257. --- 149,157 ----
  1258.         {wx = (screenw - (long)(form->w))/2; wy = (screenh - (long)(form->h))/2;}
  1259.       else if (place == FL_PLACE_MOUSE)
  1260.       {
  1261. !       fl_get_raw_mouse(&wx, &wy);
  1262. !       wx -= form->w / 2;
  1263. !       wy -= form->h / 2;
  1264.       }
  1265.       else if (place == FL_PLACE_POSITION)
  1266.       {
  1267. ***************
  1268. *** 177,182 ****
  1269. --- 178,186 ----
  1270.     qdevice(LEFTARROWKEY); qdevice(RIGHTARROWKEY);
  1271.     qdevice(UPARROWKEY); qdevice(DOWNARROWKEY);
  1272.     qdevice(WINQUIT);
  1273. +   tie(MOUSE1, MOUSEX, MOUSEY);
  1274. +   tie(MOUSE2, MOUSEX, MOUSEY);
  1275. +   tie(MOUSE3, MOUSEX, MOUSEY);
  1276.     reshape_form(form);
  1277.     fl_redraw_form(form);
  1278.     /* Check whether the window appear under the mouse and generate an
  1279. ***************
  1280. *** 184,190 ****
  1281.     */
  1282.     getorigin(&x,&y);
  1283.     getsize(&w,&h);
  1284. !   mx = getvaluator(MOUSEX); my = getvaluator(MOUSEY);
  1285.     if (mx>=x && mx<=x+w && my>=y && my<=y+h)
  1286.       qenter(INPUTCHANGE, (short) form->window);
  1287.     if (oldwin > 0 ) winset(oldwin);
  1288. --- 188,194 ----
  1289.     */
  1290.     getorigin(&x,&y);
  1291.     getsize(&w,&h);
  1292. !   fl_get_raw_mouse(&mx, &my);
  1293.     if (mx>=x && mx<=x+w && my>=y && my<=y+h)
  1294.       qenter(INPUTCHANGE, (short) form->window);
  1295.     if (oldwin > 0 ) winset(oldwin);
  1296. ***************
  1297. *** 226,232 ****
  1298.     winset(form->window);
  1299.     getorigin(&x,&y);
  1300.     getsize(&w,&h);
  1301. !   mx = getvaluator(MOUSEX); my = getvaluator(MOUSEY);
  1302.     if (mx>=x && mx<=x+w && my>=y && my<=y+h)
  1303.       qenter(INPUTCHANGE, 0);
  1304.   
  1305. --- 230,236 ----
  1306.     winset(form->window);
  1307.     getorigin(&x,&y);
  1308.     getsize(&w,&h);
  1309. !   fl_get_raw_mouse(&mx, &my);
  1310.     if (mx>=x && mx<=x+w && my>=y && my<=y+h)
  1311.       qenter(INPUTCHANGE, 0);
  1312.   
  1313. ***************
  1314. *** 432,437 ****
  1315. --- 436,452 ----
  1316.       case MOUSE1:
  1317.       case MOUSE2:
  1318.       case MOUSE3:
  1319. +     /* If mouse position is tie()d to mouse button, take advantage of that! */
  1320. +     if(qtest() == MOUSEX) {
  1321. +         short mx, my;
  1322. +         qread(&mx);
  1323. +         fl_qenter(MOUSEX, mx);
  1324. +         if(qtest() == MOUSEY) {
  1325. +         qread(&my);
  1326. +         fl_qenter(MOUSEY, my);
  1327. +         fl_mouse_click_at(mx, my);
  1328. +         }
  1329. +     }
  1330.       if (val)
  1331.       {
  1332.         if (getbutton(LEFTCTRLKEY) && getbutton(LEFTSHIFTKEY) &&
  1333. ***************
  1334. *** 461,467 ****
  1335.     gives strange effects. To avoid this we only treat an
  1336.     enter event if the previous one was a leave event.
  1337.   ************************/
  1338. !       if (lastinputchange != 0) break;
  1339.             lastinputchange = val;
  1340.   
  1341.         if (mouseform != NULL)
  1342. --- 476,488 ----
  1343.     gives strange effects. To avoid this we only treat an
  1344.     enter event if the previous one was a leave event.
  1345.   ************************/
  1346. !     /* No, don't do that.  It's quite possible to get a new window-enter
  1347. !      * event without a preceding window-leave -- when one window pops up
  1348. !      * over another one, which is common for popups!
  1349. !      * The commented-out code below causes FORMS to hose its input focus.
  1350. !      * -slevy 92.04.20
  1351. !      */
  1352. !       /* if (lastinputchange != 0) break; */
  1353.             lastinputchange = val;
  1354.   
  1355.         if (mouseform != NULL)
  1356. Only in new/FORMS: forms.h
  1357. Only in new/FORMS: fouraxis.c
  1358. diff -r -c orig/FORMS/objects.c new/FORMS/objects.c
  1359. *** orig/FORMS/objects.c    Thu Nov 28 08:12:45 1991
  1360. --- new/FORMS/objects.c    Wed Jul 21 19:54:57 1993
  1361. ***************
  1362. *** 383,389 ****
  1363.     if (obj == NULL)
  1364.       { fl_error("fl_redraw_object","Trying to draw NULL object."); return;}
  1365.     if (obj->form == NULL) return;
  1366. !   if (obj->frozen || obj->form->frozen || ! obj->form->visible) return;
  1367.     winset(obj->form->window);
  1368.     if (obj->objclass == FL_BEGIN_GROUP)
  1369.     {
  1370. --- 383,398 ----
  1371.     if (obj == NULL)
  1372.       { fl_error("fl_redraw_object","Trying to draw NULL object."); return;}
  1373.     if (obj->form == NULL) return;
  1374. !   if (obj->frozen) {
  1375. !     obj->frozen = -1;
  1376. !     return;
  1377. !   }
  1378. !   if(obj->form->frozen) {
  1379. !     obj->form->frozen = -1;
  1380. !     return;
  1381. !   }
  1382. !   if(! obj->form->visible)
  1383. !     return;
  1384.     winset(obj->form->window);
  1385.     if (obj->objclass == FL_BEGIN_GROUP)
  1386.     {
  1387. ***************
  1388. *** 415,421 ****
  1389.     long oldwin = winget();
  1390.     if (form == NULL)
  1391.       { fl_error("fl_redraw_form","Drawing NULL form."); return;}
  1392. !   if (form->frozen || ! form->visible) return;
  1393.     winset(form->window);
  1394.     ob = form->first;
  1395.     while ( ob  != NULL )
  1396. --- 424,434 ----
  1397.     long oldwin = winget();
  1398.     if (form == NULL)
  1399.       { fl_error("fl_redraw_form","Drawing NULL form."); return;}
  1400. !   if (form->frozen) {
  1401. !     form->frozen = -1;
  1402. !     return;
  1403. !   }
  1404. !   if (! form->visible) return;
  1405.     winset(form->window);
  1406.     ob = form->first;
  1407.     while ( ob  != NULL )
  1408. ***************
  1409. *** 440,448 ****
  1410.     {
  1411.       ob = obj;
  1412.       while ( (ob = ob->next) != NULL && ob->objclass != FL_END_GROUP )
  1413. !       ob->frozen = 1;
  1414.     }
  1415. !   obj->frozen = 1;
  1416.   }
  1417.   
  1418.   void fl_unfreeze_object(FL_OBJECT *obj)
  1419. --- 453,461 ----
  1420.     {
  1421.       ob = obj;
  1422.       while ( (ob = ob->next) != NULL && ob->objclass != FL_END_GROUP )
  1423. !       ob->frozen |= 1;
  1424.     }
  1425. !   obj->frozen |= 1;
  1426.   }
  1427.   
  1428.   void fl_unfreeze_object(FL_OBJECT *obj)
  1429. ***************
  1430. *** 449,464 ****
  1431.   /* Enable drawing of object */
  1432.   {
  1433.     FL_OBJECT *ob;
  1434.     if (obj == NULL)
  1435.       { fl_error("fl_freeze_object","Unfreezing NULL object."); return;}
  1436.     if (obj->objclass == FL_BEGIN_GROUP)
  1437.     {
  1438.       ob = obj;
  1439. !     while ( (ob = ob->next) != NULL && ob->objclass != FL_END_GROUP )
  1440.         ob->frozen = 0;
  1441.     }
  1442.     obj->frozen = 0;
  1443. !   fl_redraw_object(obj);
  1444.   }
  1445.   
  1446.   void fl_freeze_form(FL_FORM *form)
  1447. --- 462,482 ----
  1448.   /* Enable drawing of object */
  1449.   {
  1450.     FL_OBJECT *ob;
  1451. +   int touched = 0;
  1452.     if (obj == NULL)
  1453.       { fl_error("fl_freeze_object","Unfreezing NULL object."); return;}
  1454.     if (obj->objclass == FL_BEGIN_GROUP)
  1455.     {
  1456.       ob = obj;
  1457. !     while ( (ob = ob->next) != NULL && ob->objclass != FL_END_GROUP ) {
  1458. !       touched |= ob->frozen;
  1459.         ob->frozen = 0;
  1460. +     }
  1461.     }
  1462. +   touched |= obj->frozen;
  1463.     obj->frozen = 0;
  1464. !   if(touched < 0)
  1465. !     fl_redraw_object(obj);
  1466.   }
  1467.   
  1468.   void fl_freeze_form(FL_FORM *form)
  1469. ***************
  1470. *** 466,481 ****
  1471.   {
  1472.     if (form == NULL)
  1473.       { fl_error("fl_freeze_form","Freezing NULL form."); return;}
  1474. !   form->frozen = 1;
  1475.   }
  1476.   
  1477.   void fl_unfreeze_form(FL_FORM *form)
  1478.   /* Enable drawing of form */
  1479.   {
  1480.     if (form == NULL)
  1481.       { fl_error("fl_unfreeze_form","Unfreezing NULL form."); return;}
  1482.     form->frozen = 0;
  1483. !   fl_redraw_form(form);
  1484.   }
  1485.   
  1486.   /*-----------------------------------------------------------------------
  1487. --- 484,501 ----
  1488.   {
  1489.     if (form == NULL)
  1490.       { fl_error("fl_freeze_form","Freezing NULL form."); return;}
  1491. !   form->frozen |= 1;
  1492.   }
  1493.   
  1494.   void fl_unfreeze_form(FL_FORM *form)
  1495.   /* Enable drawing of form */
  1496.   {
  1497. +   int touched;
  1498.     if (form == NULL)
  1499.       { fl_error("fl_unfreeze_form","Unfreezing NULL form."); return;}
  1500. +   touched = form->frozen;
  1501.     form->frozen = 0;
  1502. !   if(touched < 0) fl_redraw_form(form);
  1503.   }
  1504.   
  1505.   /*-----------------------------------------------------------------------
  1506. diff -r -c orig/FORMS/support.c new/FORMS/support.c
  1507. *** orig/FORMS/support.c    Mon Nov 11 13:46:10 1991
  1508. --- new/FORMS/support.c    Wed Oct 20 18:52:34 1993
  1509. ***************
  1510. *** 30,35 ****
  1511. --- 30,39 ----
  1512.   {
  1513.     if (initialized) return;
  1514.     initialized = TRUE;
  1515. +   if(winget() <= 0) {
  1516. +       noport();
  1517. +       winopen("");
  1518. +   }
  1519.     /* Set the graphics mode based on the machine type */
  1520.     if (getgdesc(GD_BITS_NORM_SNG_RED) == 0) /* no rgbmode possible */
  1521.       { fl_doublebuf = FALSE; fl_rgbmode = FALSE;}
  1522.  
  1523.    ... create new file demof01.c ...
  1524. *** /dev/null    Wed Oct 20 19:15:53 1993
  1525. --- new/DEMOS/demof01.c    Mon Aug 10 19:21:28 1992
  1526. ***************
  1527. *** 0 ****
  1528. --- 1,62 ----
  1529. + #include "forms.h"
  1530. + FL_OBJECT *axis, *text, *quit;
  1531. + void
  1532. + Quit(FL_OBJECT *obj, long val)
  1533. + {
  1534. +     exit(0);
  1535. + }
  1536. + void
  1537. + TextIn(FL_OBJECT *obj, long val)
  1538. + {
  1539. +     float x,y,z,w;
  1540. +     if(sscanf(fl_get_input(obj), "%f %f %f", &x,&y,&z) == 3)
  1541. +     fl_set_fouraxis(axis, x,y,z);
  1542. +     sync_input();
  1543. + }
  1544. + void
  1545. + AxisIn(FL_OBJECT *obj, long val)
  1546. + {
  1547. +     sync_input();
  1548. + }
  1549. + sync_input()
  1550. + {
  1551. +     char stuff[80];
  1552. +     float x,y,z,w;
  1553. +     fl_get_fouraxis(axis, &x,&y,&z,&w);
  1554. +     sprintf(stuff, "%.4f %.4f %.4f %.4f", x,y,z,w);
  1555. +     fl_set_input(text, stuff);
  1556. + }
  1557. + main(argc, argv)
  1558. +   char *argv[];
  1559. + {
  1560. +   FL_FORM *mine;
  1561. +   FL_OBJECT *obj;
  1562. +   fl_init();
  1563. +   mine = fl_bgn_form(FL_NO_BOX,250.0,250.0);
  1564. +   obj = fl_add_box(FL_UP_BOX,0.0,0.0,280.0,340.0,"");
  1565. +   axis = obj = fl_add_fouraxis(argc>1?atoi(argv[1]):FL_NORMAL_FOURAXIS,10.0,40.0,160.0,160.0,"4D axis");
  1566. +     fl_set_call_back(obj,AxisIn,0);
  1567. +   quit = obj = fl_add_button(FL_NORMAL_BUTTON,180.0,20.0,60.0,60.0,"Quit");
  1568. +     fl_set_call_back(obj,Quit,0);
  1569. +   text = obj = fl_add_input(FL_NORMAL_INPUT,10.0,210.0,230.0,30.0,"");
  1570. +     fl_set_object_color(obj,9,9);
  1571. +     fl_set_object_lstyle(obj,FL_BOLD_STYLE);
  1572. +     fl_set_call_back(obj,TextIn,3);
  1573. +   fl_end_form();
  1574. +   fl_show_form(mine, FL_PLACE_SIZE, 1, "Axis");
  1575. +   sync_input();
  1576. +   while(fl_do_forms())
  1577. +     ;
  1578. +   exit(0);
  1579. + }
  1580.  
  1581.    ... create new file demof02.c ...
  1582. *** /dev/null    Wed Oct 20 19:15:53 1993
  1583. --- new/DEMOS/demof02.c    Mon Aug 10 19:00:04 1992
  1584. ***************
  1585. *** 0 ****
  1586. --- 1,84 ----
  1587. + #include "forms.h"
  1588. + FL_OBJECT *axis, *text[4], *quit;
  1589. + void
  1590. + Quit(FL_OBJECT *obj, long val)
  1591. + {
  1592. +     exit(0);
  1593. + }
  1594. + void
  1595. + TextIn(FL_OBJECT *obj, long val)
  1596. + {
  1597. +     float b[4][4];
  1598. +     fl_get_fouraxis_basis(axis, &b[0][0]);
  1599. +     if(sscanf(fl_get_input(obj), "%f %f %f %f",
  1600. +             &b[0][val], &b[1][val], &b[2][val], &b[3][val]) == 4) {
  1601. +     fl_set_fouraxis_basis(axis, &b[0][0]);
  1602. +     sync_inputs();
  1603. +     }
  1604. + }
  1605. + void
  1606. + AxisIn(FL_OBJECT *obj, long val)
  1607. + {
  1608. +     sync_inputs();
  1609. + }
  1610. + sync_inputs()
  1611. + {
  1612. +     char stuff[80];
  1613. +     float basis[4][4];
  1614. +     int i;
  1615. +     fl_get_fouraxis_basis(axis, &basis[0][0]);
  1616. +     for(i = 0; i < 4; i++) {
  1617. +     sprintf(stuff, "%7.3f %7.3f %7.3f %7.3f",
  1618. +         basis[0][i], basis[1][i], basis[2][i], basis[3][i]);
  1619. +     fl_set_input(text[i], stuff);
  1620. +     }
  1621. + }
  1622. + main()
  1623. + {
  1624. +   FL_FORM *mine;
  1625. +   FL_OBJECT *obj;
  1626. +   fl_init();
  1627. +   mine = fl_bgn_form(FL_NO_BOX,280.0,340.0);
  1628. +   obj = fl_add_box(FL_UP_BOX,0.0,0.0,280.0,340.0,"");
  1629. +   axis = obj = fl_add_fouraxis(FL_NORMAL_FOURAXIS,10.0,40.0,160.0,160.0,"4D axis");
  1630. +     fl_set_call_back(obj,AxisIn,0);
  1631. +   text[0] = obj = fl_add_input(FL_NORMAL_INPUT,30.0,300.0,240.0,30.0,"x'");
  1632. +     fl_set_object_color(obj,11,11);
  1633. +     fl_set_object_lstyle(obj,FL_BOLD_STYLE);
  1634. +     fl_set_call_back(obj,TextIn,0);
  1635. +   quit = obj = fl_add_button(FL_NORMAL_BUTTON,200.0,20.0,60.0,60.0,"Quit");
  1636. +     fl_set_call_back(obj,Quit,0);
  1637. +   text[1] = obj = fl_add_input(FL_NORMAL_INPUT,30.0,270.0,240.0,30.0,"y'");
  1638. +     fl_set_object_color(obj,11,11);
  1639. +     fl_set_object_lstyle(obj,FL_BOLD_STYLE);
  1640. +     fl_set_call_back(obj,TextIn,1);
  1641. +   text[2] = obj = fl_add_input(FL_NORMAL_INPUT,30.0,240.0,240.0,30.0,"z'");
  1642. +     fl_set_object_color(obj,11,11);
  1643. +     fl_set_object_lstyle(obj,FL_BOLD_STYLE);
  1644. +     fl_set_call_back(obj,TextIn,2);
  1645. +   text[3] = obj = fl_add_input(FL_NORMAL_INPUT,30.0,210.0,240.0,30.0,"w'");
  1646. +     fl_set_object_color(obj,9,9);
  1647. +     fl_set_object_lstyle(obj,FL_BOLD_STYLE);
  1648. +     fl_set_call_back(obj,TextIn,3);
  1649. +   obj = fl_add_text(FL_NORMAL_TEXT,180.0,150.0,90.0,50.0,"w' is the\nchosen \n4D vector");
  1650. +   obj = fl_add_box(FL_BORDER_BOX,178.0,146.0,90.0,1.0,"");
  1651. +   obj = fl_add_text(FL_NORMAL_TEXT,181.0,88.0,85.0,52.0,"x' y' z' are\northogonal\nto it.");
  1652. +   fl_end_form();
  1653. +   fl_show_form(mine, FL_PLACE_SIZE, 1, "Axis");
  1654. +   sync_inputs();
  1655. +   while(fl_do_forms())
  1656. +     ;
  1657. +   exit(0);
  1658. + }
  1659.  
  1660.    ... create new file formsstubs.c ...
  1661. *** /dev/null    Wed Oct 20 19:15:53 1993
  1662. --- new/DESIGN/formsstubs.c    Tue Jan 12 21:17:17 1993
  1663. ***************
  1664. *** 0 ****
  1665. --- 1,156 ----
  1666. + /*
  1667. +  * Graphics stub routines.
  1668. +  * Includes minimal mg, GL and forms stubs, sufficient to link the viewer
  1669. +  * without -lforms[2] and without -lgl_s, as of 1/11/92.
  1670. +  */
  1671. + #include <stdio.h>
  1672. + #include <fmclient.h>
  1673. +     /* GL stubs */
  1674. + deflinestyle() { ; }
  1675. + setlinestyle() { ; }
  1676. + pushattributes() { ; }
  1677. + popattributes() { ; }
  1678. + rot() { ; }
  1679. + move() { ; }
  1680. + draw() { ; }
  1681. + viewport() { ; }
  1682. + perspective() { ; }
  1683. + linewidth() { ; }
  1684. + blendfunction() { ; }
  1685. + c4f() { ; }
  1686. + RGBcolor() { ; }
  1687. + RGBmode() { ; }
  1688. + bgnclosedline() { ; }
  1689. + bgnline() { ; }
  1690. + bgnpolygon() { ; }
  1691. + circ() { ; }
  1692. + circf() { ; }
  1693. + cmov2() { ; }
  1694. + cmov2i() { ; }
  1695. + color() { ; }
  1696. + doublebuffer() { ; }
  1697. + endclosedline() { ; }
  1698. + endline() { ; }
  1699. + endpolygon() { ; }
  1700. + gconfig() { ; }
  1701. + getbutton() { return 0; }
  1702. + getcpos() { ; }
  1703. + getmatrix(float T[4][4]) { memset(T, 0, 16*sizeof(float)); T[0][0] = T[1][1] = T[2][2] = T[3][3] = 1.0; }
  1704. + getmcolor(int i, short *r, short *g, short *b) {
  1705. +     *r = i&1 ? 255:0;
  1706. +     *g = i&2 ? 255:0;
  1707. +     *b = i&4 ? 255:0;
  1708. + }
  1709. + getmmode() { return 2 /*MVIEWING*/; }
  1710. + getorigin(long *x0, long *y0) { *x0 = *y0 = 0; }
  1711. + getscrmask(long *x0, long *x1, long *y0, long *y1) { *x0 = *y0 = 0; *x1 = *y1 = 512; }
  1712. + getsize(long *xsize, long *ysize) { *xsize = *ysize = 512; }
  1713. + getvaluator() { static int v = 120; v++; v %= 512; return v; }
  1714. + getviewport(short *x0, short *x1, short *y0, short *y1) { getscrmask(x0,x1,y0,y1); }
  1715. + gl_beginstring() { ; }
  1716. + gl_drawbitmap() { ; }
  1717. + gl_endstring() { ; }
  1718. + isqueued() { return 0; }
  1719. + keepaspect() { ; }
  1720. + loadmatrix() { ; }
  1721. + lrectwrite() { ; }
  1722. + mapcolor() { ; }
  1723. + mmode() { ; }
  1724. + noborder() { ; }
  1725. + noport() { ; }
  1726. + ortho2() { ; }
  1727. + popmatrix() { ; }
  1728. + popviewport() { ; }
  1729. + prefposition() { ; }
  1730. + prefsize() { ; }
  1731. + pushmatrix() { ; }
  1732. + pushviewport() { ; }
  1733. + qdevice() { ; }
  1734. + qenter() { ; }
  1735. + qgetfd() { return 2; }
  1736. + qread() {int c; printf("qread -- <CR> to continue: "); while((c=getchar()) > 0 && c != '\n') ; return 0; }
  1737. + qtest() { return 0; }
  1738. + rect() { ; }
  1739. + rectf() { ; }
  1740. + reshapeviewport() { ; }
  1741. + ringbell() { write(2, "\7", 1); }
  1742. + rotate() { ; }
  1743. + scale() { ; }
  1744. + screenspace() { ; }
  1745. + scrmask() { ; }
  1746. + swapbuffers() { ; }
  1747. + tie() { ; }
  1748. + translate() { ; }
  1749. + unqdevice() { ; }
  1750. + v2f() { ; }
  1751. + winclose() { ; }
  1752. + static int winno = 128;
  1753. + winget() { return winno; }
  1754. + winopen() { return ++winno; }
  1755. + winpop() { ; }
  1756. + winset() { ; }
  1757. + getgdesc(code) {
  1758. +     switch(code) {
  1759. + #define GD_XPMAX        0
  1760. + #define GD_YPMAX        1
  1761. + #define GD_XMMAX        2
  1762. + #define GD_YMMAX        3
  1763. + #define GD_ZMIN            4
  1764. + #define GD_ZMAX            5
  1765. + #define GD_BITS_NORM_SNG_RED    6
  1766. + #define GD_BITS_NORM_DBL_RED    9
  1767. + #define GD_BITS_NORM_SNG_CMODE    12
  1768. + #define GD_BITS_NORM_DBL_CMODE    13
  1769. + #define GD_BITS_NORM_SNG_MMAP    14
  1770. + #define GD_BITS_NORM_DBL_MMAP    15
  1771. + #define GD_BITS_NORM_ZBUFFER    16
  1772. +     case GD_BITS_NORM_DBL_RED:
  1773. +     case GD_BITS_NORM_SNG_RED: return 8;
  1774. +     case GD_XPMAX: return 1280;
  1775. +     case GD_YPMAX: return 1024;
  1776. +     case GD_XMMAX: return 450;
  1777. +     default: printf("getgdesc(%d)?\n", code); return -1;
  1778. +     }
  1779. + }
  1780. + static long unfont;
  1781. + drawmode() { ; }
  1782. + mapw2() { ; }
  1783. + clear() { ; }
  1784. + fmfonthandle fmfindfont(char *name) { return &unfont; }
  1785. + fmgetfontinfo(fmfonthandle fnt, fmfontinfo *info) {
  1786. +     bzero(info, sizeof(*info));
  1787. +     info->xsize = info->ysize = info->width = info->height = 10;
  1788. +     info->resolution = 100;
  1789. + }
  1790. + fmgetstrwidth(fmfonthandle fnt, char *str) { return strlen(str)*8; }
  1791. + fmprstr() { ; }
  1792. + fmfonthandle fmscalefont(fmfontinfo *font, double v) { return &unfont; }
  1793. + void fmsetfont(fmfontinfo *font) { ; }
  1794. + fminit() { ; }
  1795. + arc() { ; }
  1796. + arcf() { ; }
  1797. + pnt() { ; }
  1798. + polf2() { ; }
  1799. + poly2() { ; }
  1800. + draw2() { ; }
  1801. + move2() { ; }
  1802. + pclos() { ; }
  1803. + pdr2() { ; }
  1804. + pmv2() { ; }
  1805. + addtopup() { ; }
  1806. + dopup() { ; }
  1807. + freepup() { ; }
  1808. + newpup() { ; }
  1809. + fl_show_message(char *s1, char *s2, char *s3)
  1810. + {
  1811. +     fprintf(stderr, "%s %s %s\n", s1, s2, s3);
  1812. + }
  1813.  
  1814.    ... create new file colorwheel.tex ...
  1815. *** /dev/null    Wed Oct 20 19:15:53 1993
  1816. --- new/DOC/CLASSES/colorwheel.tex    Wed Dec 30 14:43:50 1992
  1817. ***************
  1818. *** 0 ****
  1819. --- 1,99 ----
  1820. + \section{Colorwheel}
  1821. + \subsection*{Short Description}
  1822. + A colorwheel object allows the selction of colors by moving a point
  1823. + around a hexagon using the HSV color scheme.  The value of the
  1824. + colorwheel is set and returned as an RGBA value.
  1825. + \subsection*{Adding an object}
  1826. + A colorwheel can be added to a form using the call 
  1827. + \begin{verbatim}
  1828. +    FL_OBJECT *fl_add_colorwheel(int type, float x, float y, 
  1829. +                             float w, float h, char label[])
  1830. + \end{verbatim}
  1831. + The meaning of the parameters is as usual.  The label by default is
  1832. + placed below the box.
  1833. + \subsection*{Types}
  1834. + There is only one type of colorwheel at this time:  FL\_NORMAL\_COLORWHEEL.
  1835. + \subsection*{Interaction}
  1836. + The display shows a Gouraud-shaded hexagon with a black cursor in the
  1837. + middle.  The cursor may be moved around inside the hexagon by clicking
  1838. + or dragging the mouse.  The color under the cursor is the color which
  1839. + will be returned by fl\_get\_colorwheel().  
  1840. + There is no way for the user to set the intensity of the color using
  1841. + only the colorwheel.  HSV colorspace is actually a solid
  1842. + three-dimensional hexagonal pyramid.  Only a cross-section of the
  1843. + pyramid is shown in the hexagon at any time (For more details, see
  1844. + $\underline{Computer Graphics: Principles and Practice}$ by Foley,
  1845. + vanDam, Feiner, and Hughes).  The intensity may be set
  1846. + programmatically using fl\_set\_colorwheel\_intensity().  In general, the
  1847. + programmer will want to create a slider for this purpose and use
  1848. + fl\_set\_colorwheel\_intensity() to set the intensity of the colorwheel
  1849. + every time the value of the slider is changed.  The colors of the
  1850. + colorwheel will change to reflect the new intensity.  When the
  1851. + colorwheel is created, the intensity is set to 1.0, its maximum value.
  1852. + The colors become darker as the intensity is lowered toward 0.0, at
  1853. + which point the entire colorwheel will be black.
  1854. + There is also no way for the user of the colorwheel to set the alpha
  1855. + (transparency) value of the color.  Again, the programmer may want to
  1856. + create a slider for this parameter.  On computer systems which support
  1857. + transparency, the colorwheel will fade in and out as the alpha value
  1858. + is changed.  Alpha starts set to 1.0, or fully opaque.  A value of 0.0
  1859. + is equivalent to complete transparency.  The alpha value may be
  1860. + changed using the routine fl\_set\_colorwheel\_alpha().
  1861. + \subsection*{Other routines}
  1862. + To set the value of the colorwheel, use the routines:
  1863. + \begin{verbatim}
  1864. +   void fl_set_colorwheel(FL_OBJECT *obj, float *color)
  1865. +   void fl_set_colorwheel_intensity(FL_OBJECT *obj, float intensity)
  1866. +   void fl_set_colorwheel_alpha(FL_OBJECT *obj, float alpha)
  1867. + \end{verbatim}
  1868. + fl\_set\_colorwheel() sets the colorwheel to the rgb value specified in
  1869. + the color array.  Each component ranges between 0.0 and 1.0.  This
  1870. + routine may also change the intensity.
  1871. + fl\_set\_colorwheel\_intensity() sets the intensity to a value between
  1872. + 0.0 and 1.0.
  1873. + fl\_set\_colorwheel\_alpha() sets the transparency to a value between 0.0
  1874. + and 1.0.
  1875. + To get the value of the colorwheel, use the routines:
  1876. + \begin{verbatim}
  1877. +   void fl_get_colorwheel(FL_OBJECT *obj, float *color)
  1878. +   float fl_get_colorhweel_intensity(FL_OBJECT *obj)
  1879. +   float fl_get_colorwheel_alpha(FL_OBJECT *obj)
  1880. + \end{verbatim}
  1881. + The values are as described above.  Note that the value returned by
  1882. + fl\_get\_colorwheel() takes the current intensity into account.
  1883. + \subsection*{Attributes}
  1884. + Color1 controls the color of the background (default gray).
  1885. + Color2 controls the color of the cursor (default black).
  1886. + \subsection*{Remarks}
  1887. + Since the colorwheel uses Gouraud shading and transparency, the form
  1888. + must be in RGB mode (the default).  For best results, it should also
  1889. + be double-buffered (also the default).
  1890.  
  1891.     ... create new file fouraxis.tex ...
  1892. *** /dev/null    Wed Oct 20 19:15:53 1993
  1893. --- new/DOC/CLASSES/fouraxis.tex    Mon Aug 10 19:04:32 1992
  1894. ***************
  1895. *** 0 ****
  1896. --- 1,167 ----
  1897. + % For each class, a file like this should exist
  1898. + % It should also be added in class.tex
  1899. + \section{Fouraxis}
  1900. + \subsubsection*{Short description}
  1901. + A fouraxis allows the user to graphically specify a direction
  1902. + in a four-dimensional space:
  1903. + specifically a unit vector, where $x^2 + y^2 + z^2 + w^2 = 1$.
  1904. + It displays a wireframe sphere containing a set of movable axes,
  1905. + whose intersection indicates the $(x,y,z)$ components of the 4-vector.
  1906. + The $w$ component is computed from these.
  1907. + The object can return either the 4-vector itself, or a complete
  1908. + 4x4 orthonormal basis matrix with the specified vector as one of its columns.
  1909. + \subsubsection*{Adding an object}
  1910. + A fouraxis can be added to a form using the call
  1911. + \begin{verbatim}
  1912. +    FL_OBJECT *fl_add_fouraxis(int type, float x, float y,
  1913. +                                 float w, float h, char label[])
  1914. + \end{verbatim}
  1915. + The meaning of the parameters is as usual. The label by default is
  1916. + placed below the box.
  1917. + \subsubsection*{Types}
  1918. + Only one useful type of fouraxis exists at the moment:
  1919. + \verb+FL_NORMAL_FOURAXIS+, showing three orthogonal axes.
  1920. + \subsubsection*{Interaction}
  1921. + The display shows a wireframe sphere and three orthogonal lines:
  1922. + a red vector extending from the origin to the $(x,y,z)$ component of the
  1923. + chosen point, and two other vectors reaching from the $(x,y,z)$ point
  1924. + to the surface of the unit sphere as a perspective aid.
  1925. + In the wireframe sphere, $x$ increases rightward, $y$ away from the viewer,
  1926. + and $z$ upward.
  1927. + The left mouse button rotates the chosen $(x,y,z)$ point within the sphere,
  1928. + keeping its radial component constant.  Horizontal motion rotates
  1929. + in longitude (the $x-y$ plane), while vertical motion rotates in latitude.
  1930. + The right mouse button moves the chosen point radially.
  1931. + \vspace{.1 in}
  1932. + To understand the 3-D picture's relation to the four-dimensional vector,
  1933. + consider how a 2-D person could specify a direction in 3-D space.
  1934. + For each direction in 3-space, there's a point on the surface of a unit sphere
  1935. + ($x^2 + y^2 + z^2 = 1$).  A 2-D person could choose a point on the
  1936. + unit disk $x^2 + y^2 \le 1$, and take it to mean the vector whose endpoint
  1937. + on the sphere lies directly above or below that point.  The disk's center
  1938. + corresponds to the north (or south) pole of the sphere, and the edge of the
  1939. + disk to the sphere's equator.  Generally, $z = \sqrt{1 - x^2 - y^2}$.
  1940. + How to choose between the positive and negative hemispheres?
  1941. + Note that for every direction with negative $z$ component there's
  1942. + an exactly opposite direction with $z > 0$.  For many purposes,
  1943. + e.g. orthogonal projection or slicing, opposite directions are equivalent,
  1944. + so we can simply limit $z$ to a single hemisphere.
  1945. + The fouraxis object lets you choose a point in the unit 3-ball
  1946. + with $x^2 + y^2 + z^2 \le 1$, and computes $w$ to create a unit 4-vector
  1947. + lying in the $w \ge 0$ hemisphere.
  1948. + \vspace{.1 in}
  1949. + In some applications you only want the fouraxis to be returned to the
  1950. + application program when the user releases the mouse, i.e., not all the time.
  1951. + The routine
  1952. + \begin{verbatim}
  1953. +    void fl_set_fouraxis_return(FL_OBJECT *obj, int always)
  1954. + \end{verbatim}
  1955. + controls this; set {\em always} to FALSE to get this effect.
  1956. + \subsubsection*{Other routines}
  1957. + To set the value of the fouraxis, use the routines:
  1958. + \begin{verbatim}
  1959. +    void fl_set_fouraxis(FL_OBJECT *obj, float x, float y, float z)
  1960. +    void fl_set_fouraxis_basis(FL_OBJECT *obj, float *matrix)
  1961. + \end{verbatim}
  1962. + The first form just sets the $(x,y,z)$ components, computing $w$ to form
  1963. + a unit vector.  The second form supplies a complete 4x4 basis matrix;
  1964. + the fouraxis object orthogonalizes it (perturbing the matrix if it was
  1965. + nearly singular) and uses the fourth column as the chosen $(x,y,z,w)$ vector.
  1966. + (The user-supplied matrix is not changed.)
  1967. + Orthogonalization begins with the fourth column, so if that's already a unit
  1968. + vector, it becomes the exactly the chosen vector.
  1969. + The matrix is assumed in row-major order, i.e. its "fourth column" is
  1970. + $matrix[4*j + 3]$ for $0 \le j \le 3$.
  1971. + \vspace{.1 in}
  1972. + To obtain the current values of the fouraxis, use
  1973. + \begin{verbatim}
  1974. +    void fl_get_fouraxis(FL_OBJECT *obj,
  1975. +             float *x, float *y, float *z, float *w)
  1976. +    void fl_get_fouraxis_basis(FL_OBJECT *obj, float *matrix)
  1977. + \end{verbatim}
  1978. + fl\_get\_fouraxis() returns the current components of the chosen vector.
  1979. + fl\_get\_fouraxis\_basis() returns a complete orthonormal basis, whose
  1980. + fourth column is the chosen vector.
  1981. + \vspace{.1 in}
  1982. + The wireframe sphere's appearance may be adjusted with
  1983. + \begin{verbatim}
  1984. +     void fl_set_fouraxis_grid(FL_OBJECT *obj, int lat, int lon, int color)
  1985. +     void fl_get_fouraxis_grid(FL_OBJECT *obj, int *lat, int *lon, int *color)
  1986. + \end{verbatim}
  1987. + specifying respectively the number of latitude and longitude circles
  1988. + and their color; defaults are 9, 12, and 0 (black).
  1989. + \verb+fl_set_fouraxis_grid()+
  1990. + sets the values; \verb+fl_get_fouraxis_grid()+ returns current values.
  1991. + \subsubsection*{Attributes}
  1992. + Color1 controls the color of the box (default gray),
  1993. + color2 is the color of the radial vector (default red).
  1994. + \subsubsection*{Remarks}
  1995. + Demos appear in demof01.c and demof02.c.
  1996. + \vspace{.1 in}
  1997. + The orthogonal blue axes bear no relation to the other vectors
  1998. + in the orthonormal basis; they're simply a perspective guide!
  1999. + \vspace {.1 in}
  2000. + The basis matrix might be useful in applications which take a
  2001. + 3-D projection of a 4-D object.  The 4x4 matrix $M$ specifies
  2002. + a change of basis into a coordinate system whose fourth coordinate
  2003. + is along the vector chosen with the fouraxis widget.
  2004. + It's easy to construct either orthogonal or perspective projections into
  2005. + 3-space using the basis.  Given a 4-component column vector $(x,y,z,w)$
  2006. + representing a point $p$, let the product $M p = (x',y',z',w')$.
  2007. + For orthogonal projection, just discard $w'$: $(x',y',z')$ is the result of
  2008. + projecting $p$.  For perspective projection, you'll need to specify a place
  2009. + to project from; choose some constant $w'_0$, which should be outside the
  2010. + range of $w'$ values of the 4-D object.  The further $w'_0$ is from the
  2011. + object's $w'$ range, the less the perspective distortion.
  2012. + A perspective projection of $p$ is then $(x',y',z')/(w' - w'_0)$.
  2013. + The basis' $(x',y',z')$ directions are somewhat arbitrary.
  2014. + The widget tries to change them as little as possible
  2015. + from their initial condition (the identity matrix), or from the
  2016. + latest state set with \verb+fl_set_fouraxis_basis()+.
  2017. + \vspace{.1 in}
  2018. + Two experimental fouraxis types exist, which use different
  2019. + perspective cues to show where the vector's tip lies in the 3-ball.
  2020. + \verb+FL_CIRCLE_FOURAXIS+ simply draws a solid blue circle, showing the
  2021. + sphere's intersection with the plane normal to the chosen vector.
  2022. + \verb+FL_SPOKED_FOURAXIS+ shows a circle with five radial spokes.  Neither one
  2023. + looks as good as \verb+FL_NORMAL_FOURAXIS+ to my eye.
  2024.  
  2025.     ... create new file colorwheel.h ...
  2026. *** /dev/null    Wed Oct 20 19:15:53 1993
  2027. --- new/FORMS/INCLUDE/colorwheel.h    Wed Dec 30 16:55:33 1992
  2028. ***************
  2029. *** 0 ****
  2030. --- 1,24 ----
  2031. + #ifndef COLORWHEEL_H
  2032. + #define COLORWHEEL_H
  2033. + #define FL_COLORWHEEL_BW         FL_BUTTON_BW
  2034. + #define FL_COLORWHEEL_CURSOR        .025
  2035. + #define FL_COLORWHEEL             1492
  2036. + #define FL_NORMAL_COLORWHEEL         0
  2037. + FL_OBJECT *fl_create_colorwheel(int type, float x, float y, float w,
  2038. +                 float h, char label[]);
  2039. + FL_OBJECT *fl_add_colorwheel(int type, float x, float y, float w, float h,
  2040. +                char label[]);
  2041. + void fl_set_colorwheel(FL_OBJECT *obj, float *color);
  2042. + void fl_set_colorwheel_intensity(FL_OBJECT *obj, float intensity);
  2043. + void fl_set_colorwheel_alpha(FL_OBJECT *obj, float alpha);
  2044. + void fl_get_colorwheel(FL_OBJECT *obj, float *color);
  2045. + float fl_get_colorwheel_intensity(FL_OBJECT *obj);
  2046. + float fl_get_colorwheel_alpha(FL_OBJECT *obj);
  2047. +      
  2048. + #endif
  2049.  
  2050.    ... create new file fouraxis.h ...
  2051. *** /dev/null    Wed Oct 20 19:15:53 1993
  2052. --- new/FORMS/INCLUDE/fouraxis.h    Mon Aug 31 11:09:53 1992
  2053. ***************
  2054. *** 0 ****
  2055. --- 1,41 ----
  2056. + /************   Object Class: Fouraxis (unit vector in 4-space)  ************/
  2057. + /***** Class    *****/
  2058. + #define FL_FOURAXIS        1034
  2059. + /***** Types    *****/
  2060. + #define FL_NORMAL_FOURAXIS    0
  2061. + #define    FL_CIRCLE_FOURAXIS    1
  2062. + #define    FL_SPOKED_FOURAXIS    2
  2063. + /***** Defaults *****/
  2064. + #define FL_FOURAXIS_BOXTYPE    FL_DOWN_BOX
  2065. + #define FL_FOURAXIS_COL1    FL_COL1
  2066. + #define FL_FOURAXIS_COL2    1
  2067. + #define FL_FOURAXIS_LCOL    FL_LCOL
  2068. + #define FL_FOURAXIS_ALIGN    FL_ALIGN_BOTTOM
  2069. + /***** Others   *****/
  2070. + #define FL_FOURAXIS_BW        FL_BOUND_WIDTH
  2071. + /***** Routines *****/
  2072. + FL_OBJECT    *fl_create_fouraxis(int, float, float, float, float, char []);
  2073. + FL_OBJECT    *fl_add_fouraxis(int, float, float, float, float, char []);
  2074. +         /* Set direction vector.  w chosen to form unit vector */
  2075. + void     fl_set_fouraxis(FL_OBJECT *, float x, float y, float z);
  2076. + void     fl_get_fouraxis(FL_OBJECT *, float *xp, float *yp, float *zp, float *wp);
  2077. +         /* Also maintains an orthonormal basis matrix, with column 3
  2078. +          * (w) a unit vector in the chosen direction
  2079. +          * and other columns chosen appropriately.
  2080. +          */
  2081. + void    fl_get_fouraxis_basis(FL_OBJECT *, float * /* really float[4][4] */);
  2082. + void    fl_set_fouraxis_basis(FL_OBJECT *, float * /* really float[4][4] */);
  2083. + void     fl_set_fouraxis_return(FL_OBJECT *, int);
  2084.  
  2085.    ... create new file colorwheel.c ...
  2086. *** /dev/null    Wed Oct 20 19:15:53 1993
  2087. --- new/FORMS/colorwheel.c    Thu Oct 14 19:43:18 1993
  2088. ***************
  2089. *** 0 ****
  2090. --- 1,307 ----
  2091. + #include <stdio.h>
  2092. + #include <limits.h>
  2093. + #include <math.h>
  2094. + #include <gl.h>
  2095. + #include "forms.h"
  2096. + /* The colors at the vertices of the hexagon */
  2097. + static float colors[][4] = {{1, 1, 1, 1},
  2098. +                   {1, 0, 0, 1}, {1, 1, 0, 1}, {0, 1, 0, 1},
  2099. +                   {0, 1, 1, 1}, {0, 0, 1, 1}, {1, 0, 1, 1}};
  2100. + /* The vertices of the unit hexagon */
  2101. + static float verts[7][2];
  2102. + /* 
  2103. +  * obj->spec contains:
  2104. +  * 14 floats containing the center followed by the vertices of the hexagon
  2105. +  * 2 floats containing the position of the pointer in the hexagon
  2106. +  */
  2107. + /* These macros rely on the object in question being stored in obj */
  2108. + typedef struct {
  2109. +   float pointer[2];
  2110. +   float intensity;
  2111. +   float alpha;
  2112. +   float radius;
  2113. +   float colors[7][4];
  2114. + } SpecStruct;
  2115. + #define NEWRADIUS(a)    (((a)->w < (a)->h ? (a)->w/2.0 : (a)->h/2.0))
  2116. + #define CURSOR_RADIUS    .95
  2117. + #define SPEC_SIZE    (sizeof(SpecStruct))
  2118. + #define VERT         (((SpecStruct *)obj->spec)->vert)
  2119. + #define POINTER     (((SpecStruct *)obj->spec)->pointer)
  2120. + #define INTENSITY    (((SpecStruct *)obj->spec)->intensity)
  2121. + #define ALPHAVAL    (((SpecStruct *)obj->spec)->alpha)
  2122. + #define RADIUS        (((SpecStruct *)obj->spec)->radius)
  2123. + #define COLOR        (((SpecStruct *)obj->spec)->colors)
  2124. + #define MIN(a, b)     ((a) < (b) ? (a) : (b))
  2125. + #define MAX(a, b)     ((a) > (b) ? (a) : (b))
  2126. + #define ONE(a)        (MIN(MAX((a), 0.0), 1.0))
  2127. + #define MAX3(a, b, c) \
  2128. + ((a) > (b) ? \
  2129. +  ((a) > (c) ? (a) : (c)) : \
  2130. +  ((b) > (c) ? (b) : (c)))
  2131. + #define MIN3(a, b, c) \
  2132. + ((a) < (b) ? \
  2133. +  ((a) < (c) ? (a) : (c)) : \
  2134. +  ((b) < (c) ? (b) : (c))) \
  2135. + static int handle_colorwheel(FL_OBJECT *obj, int event, float mx, float my, 
  2136. +                char key);
  2137. + static float scale_to_hexagon(FL_OBJECT *obj, float x, float y);
  2138. + FL_OBJECT *fl_create_colorwheel(int type, float x, float y, float w,
  2139. +                 float h, char label[])
  2140. + {
  2141. +   FL_OBJECT *obj;
  2142. +   /* We might be recomputing these, but c'est la vie */
  2143. +   verts[0][0] = verts[0][1] = 0.0;
  2144. +   
  2145. +   verts[1][0] = 1.0;
  2146. +   verts[4][0] = -verts[1][0];
  2147. +   verts[1][1] = verts[4][1] = 0.0;
  2148. +   
  2149. +   verts[2][0] = verts[6][0] = cos(M_PI / 3.0);
  2150. +   verts[3][0] = verts[5][0] = -verts[2][0];
  2151. +   verts[2][1] = verts[3][1] = sin(M_PI / 3.0);
  2152. +   verts[5][1] = verts[6][1] = -verts[2][1];
  2153. +   obj = fl_make_object(FL_COLORWHEEL, type, x, y, w, h, label, 
  2154. +                handle_colorwheel);
  2155. +   obj->boxtype = FL_UP_BOX;
  2156. +   obj->lcol = BLACK;
  2157. +   obj->col1 = FL_BUTTON_COL1;
  2158. +   obj->col2 = BLACK;
  2159. +   obj->align = FL_ALIGN_BOTTOM;
  2160. +   obj->spec = (int *)malloc(SPEC_SIZE);
  2161. +   POINTER[0] = POINTER[1] = 0.0;
  2162. +   RADIUS = NEWRADIUS(obj);
  2163. +   INTENSITY = 1.0;
  2164. +   ALPHAVAL = 1.0;
  2165. +   return obj;
  2166. + }
  2167. + FL_OBJECT *fl_add_colorwheel(int type, float x, float y, float w, float h,
  2168. +                char label[])
  2169. + {
  2170. +   FL_OBJECT *obj;
  2171. +   obj = fl_create_colorwheel(type, x, y, w, h, label);
  2172. +   fl_add_object(fl_current_form, obj);
  2173. +   return obj;
  2174. + }
  2175. + static int handle_colorwheel(FL_OBJECT *obj, int event, float mx, float my, 
  2176. +                char key)
  2177. + {
  2178. +   int i;
  2179. +   int center[2];
  2180. +   float scalef;
  2181. +   switch(event) {
  2182. +   case FL_DRAW:
  2183. +     fl_drw_box(obj->boxtype, obj->x, obj->y, obj->w, obj->h, obj->col1,
  2184. +            FL_COLORWHEEL_BW);
  2185. +     for (i = 0; i < 7; i++) {
  2186. +       COLOR[i][0] = colors[i][0] * INTENSITY;
  2187. +       COLOR[i][1] = colors[i][1] * INTENSITY;
  2188. +       COLOR[i][2] = colors[i][2] * INTENSITY;
  2189. +       COLOR[i][3] = ALPHAVAL;
  2190. +     }
  2191. +     blendfunction(BF_SA, BF_MSA);
  2192. +     center[0] = obj->x + obj->w / 2.0;
  2193. +     center[1] = obj->y + obj->h / 2.0;
  2194. +     pushmatrix();
  2195. +     translate(center[0], center[1], 0.0);
  2196. +     RADIUS = NEWRADIUS(obj);
  2197. +     scale(RADIUS, RADIUS, RADIUS);
  2198. +     for (i = 0; i < 6; i++) {
  2199. +       bgnpolygon();
  2200. +       c4f(COLOR[0]);
  2201. +       v2f(verts[0]);
  2202. +       
  2203. +       c4f(COLOR[i + 1]);
  2204. +       v2f(verts[i+1]);
  2205. +       c4f(COLOR[((i+1)%6) + 1]);
  2206. +       v2f(verts[((i+1)%6)+1]); 
  2207. +       endpolygon();
  2208. +     }
  2209. +     scale(CURSOR_RADIUS, CURSOR_RADIUS, CURSOR_RADIUS);
  2210. +     fl_rect(POINTER[0] - FL_COLORWHEEL_CURSOR, 
  2211. +         POINTER[1] - FL_COLORWHEEL_CURSOR, 
  2212. +         2.0 * FL_COLORWHEEL_CURSOR, 2.0 * FL_COLORWHEEL_CURSOR, 
  2213. +         obj->col2); 
  2214. +     popmatrix();
  2215. +     fl_drw_text_beside(obj->align, obj->x, obj->y, obj->w, obj->h,
  2216. +                obj->lcol, obj->lsize, obj->lstyle, obj->label);
  2217. +     return 0;
  2218. +   case FL_PUSH:
  2219. +   case FL_RELEASE:
  2220. +   case FL_MOUSE:
  2221. +     RADIUS = NEWRADIUS(obj);
  2222. +     POINTER[0] = (mx - obj->w/2.0 - obj->x) / RADIUS;
  2223. +     POINTER[1] = (my - obj->h/2.0 - obj->y) / RADIUS;
  2224. +     
  2225. +     /* Get it within the hexagon vertically */
  2226. +     scalef = scale_to_hexagon(obj, POINTER[0], POINTER[1]);
  2227. +     if (scalef < 1.0) {
  2228. +       POINTER[0] *= scalef;
  2229. +       POINTER[1] *= scalef;
  2230. +     }
  2231. +     
  2232. +     fl_redraw_object(obj);
  2233. +     return 1;
  2234. +   default: 
  2235. +     return 0;
  2236. +   }
  2237. + }
  2238. + void fl_set_colorwheel_alpha(FL_OBJECT *obj, float alpha) {
  2239. +   ALPHAVAL = ONE(alpha);
  2240. +   fl_redraw_object(obj);
  2241. + }
  2242. + float fl_get_colorwheel_alpha(FL_OBJECT *obj) {
  2243. +   return ALPHAVAL;
  2244. + }
  2245. + void fl_set_colorwheel_intensity(FL_OBJECT *obj, float intensity) {
  2246. +   INTENSITY = ONE(intensity);
  2247. +   fl_redraw_object(obj);
  2248. + }
  2249. + float fl_get_colorwheel_intensity(FL_OBJECT *obj) {
  2250. +   return INTENSITY;
  2251. + }
  2252. + void fl_set_colorwheel(FL_OBJECT *obj, float *color)
  2253. + {
  2254. +   float h, s, v;
  2255. +   float min, max, delta, scale;
  2256. +   float r = ONE(color[0]), g = ONE(color[1]), b = ONE(color[2]);
  2257. +   max = MAX3(r, g, b);
  2258. +   min = MIN3(r, g, b);
  2259. +   v = max;
  2260. +   if (max > .001) s = (max - min) / max;
  2261. +   else s = 0.0;
  2262. +   if (s < .001) POINTER[0] = POINTER[1] = 0.0;
  2263. +   else {
  2264. +     delta = max - min;
  2265. +     if (r == max) h = (g - b) / delta;
  2266. +     else if (g == max) h = 2.0 + (b - r) / delta;
  2267. +     else if (b == max) h = 4.0 + (r - g) / delta;
  2268. +     h *= 60.0;
  2269. +     if (h < .001) h += 360.0;
  2270. +     h = (h / 180.0) * M_PI;
  2271. +     scale = scale_to_hexagon(obj, cos(h), sin(h));
  2272. +     POINTER[0] = cos(h) * s * scale;
  2273. +     POINTER[1] = sin(h) * s * scale;
  2274. +   }
  2275. +   INTENSITY = v;
  2276. +   fl_redraw_object(obj);
  2277. + }
  2278. + void fl_get_colorwheel(FL_OBJECT *obj, float *color) 
  2279. + {
  2280. +   int i;
  2281. +   float f, p, q, t;
  2282. +   float h, s, v;
  2283. +   float radius;
  2284. +   v = INTENSITY;
  2285. +   if (fabs(POINTER[0]) < .001 && fabs(POINTER[1]) < .001) {
  2286. +     color[0] = color[1] = color[2] = v;
  2287. +     return;
  2288. +   }
  2289. +   s = 1.0 / scale_to_hexagon(obj, POINTER[0], POINTER[1]);
  2290. +   /* The point must already be inside the hexagon, but we may be suffering
  2291. +    * from round-off error */
  2292. +   if (s > 1.0) s = 1.0;
  2293. +   h = (atan2(POINTER[1],POINTER[0]) / M_PI) * 180.0;
  2294. +   if (h < 0.0) h = 360.0 + h;
  2295. +   if (h >= 360.0) h = 0.0;
  2296. +   h = h / 60.0;
  2297. +   i = floor(h);
  2298. +   f = h - (float)i;
  2299. +   p = v * (1.0 - s);
  2300. +   q = v * (1.0 - (s * f));
  2301. +   t = v * (1.0 - (s * (1.0 - f)));
  2302. +   switch(i) {
  2303. +   case 0:
  2304. +     color[0] = v;
  2305. +     color[1] = t;
  2306. +     color[2] = p; 
  2307. +     break;
  2308. +   case 1: 
  2309. +     color[0] = q;
  2310. +     color[1] = v;
  2311. +     color[2] = p;
  2312. +     break;
  2313. +   case 2:
  2314. +     color[0] = p;
  2315. +     color[1] = v;
  2316. +     color[2] = t;
  2317. +     break;
  2318. +   case 3:
  2319. +     color[0] = p;
  2320. +     color[1] = q;
  2321. +     color[2] = v;
  2322. +     break;
  2323. +   case 4:
  2324. +     color[0] = t;
  2325. +     color[1] = p;
  2326. +     color[2] = v;
  2327. +     break;
  2328. +   case 5:
  2329. +     color[0] = v;
  2330. +     color[1] = p;
  2331. +     color[2] = q;
  2332. +     break;
  2333. +   default:
  2334. +     break;
  2335. +   }
  2336. + }
  2337. + /* 
  2338. +  * This finds the t that should multiply x and y to place the point
  2339. +  * on the hexagon.
  2340. +  * Returns 1000 ("large") if x == 0 && y == 0
  2341. +  * < 1.0 = point outside
  2342. +  * > 1.0 = point inside
  2343. + */
  2344. + #define HEX 1.73205    /* sqrt(3) */
  2345. + static float scale_to_hexagon(FL_OBJECT *obj, float x, float y)
  2346. + {
  2347. +   x = fabs(x);
  2348. +   y = fabs(y);
  2349. +   if (y == 0) {
  2350. +     return x < .001 ? 1000 : 1/x;    /* Scale X to horiz hexagon corner */
  2351. +   } else if (x*HEX < y) {
  2352. +     return .5*HEX/y;        /* Scale Y to top of hexagon, at sqrt(3)/2 */
  2353. +   } else {
  2354. +     return HEX/(y + HEX*x);        /* Scale to slanted hexagon side */
  2355. +   }
  2356. + }
  2357. + #undef HEX
  2358.  
  2359.  ... create new file fouraxis.c ...
  2360. *** /dev/null    Wed Oct 20 19:15:53 1993
  2361. --- new/FORMS/fouraxis.c    Fri Nov  6 10:14:05 1992
  2362. ***************
  2363. *** 0 ****
  2364. --- 1,397 ----
  2365. + /************************************************************************
  2366. +  *                                    *
  2367. +  *  Object class: FOURAXIS                        *
  2368. +  *                                    *
  2369. +  *  Written by: Stuart Levy; adapted from Mark Overmars' POSITIONER    *
  2370. +  *                                    *
  2371. +  *  Version 1.1                              *
  2372. +  *  Date:   28 May 1992                            *
  2373. +  ************************************************************************/
  2374. + #include <gl/gl.h>
  2375. + #include <gl/device.h>
  2376. + #include <sys/types.h>
  2377. + #include <math.h>
  2378. + #include <malloc.h>
  2379. + #include "forms.h"
  2380. + /* State of a fouraxis */
  2381. + typedef struct {
  2382. +    int gridcolor;            /* color for grid drawing */
  2383. +    int gridlong, gridlat;        /* how many grid circles to draw */
  2384. +    int colorless;            /* Crosses in red/green/blue, else col2 */
  2385. +    int allout;                /* All crosses extend to sphere edge */
  2386. +     
  2387. +    float rho, theta, phi;        /* user-interface controls */
  2388. +    float omx, omy;            /* prev mouse position */
  2389. +    int   whatsdown;            /* -1: omx,omy invalid.
  2390. +                      * 0: left mouse down.  1: right mouse.
  2391. +                      */
  2392. +    float T[4][4];            /* Initial basis matrix, which we */
  2393. +                     /* should try to approximate */
  2394. +    int always;                    /* whether always returning value */
  2395. + } SPEC;
  2396. + #define    X 0
  2397. + #define    Y 1
  2398. + #define Z 2
  2399. + #define W 3
  2400. + static void orthog4(float T[4][4]);
  2401. + static void transpose(float *src, float *dst);
  2402. + static void drawsphere(register SPEC *sp)
  2403. + {
  2404. +   register int i;
  2405. +   static int setls = 0;
  2406. +   if(!setls) {
  2407. +     deflinestyle(FL_FOURAXIS, 0xCCCC);
  2408. +     setls = 1;
  2409. +   }
  2410. +   pushattributes();
  2411. +   pushmatrix();
  2412. +   setlinestyle(FL_FOURAXIS);
  2413. +   for(i = sp->gridlong; --i >= 0; ) {
  2414. +     circ(0.0, 0.0, 1.0);
  2415. +     rot(180./sp->gridlong, 'y');
  2416. +   }
  2417. +   popmatrix();
  2418. +   pushmatrix();
  2419. +   rot(90., 'x');
  2420. +   circ(0.0, 0.0, 1.0);
  2421. +   for(i = sp->gridlat; --i > 0; ) {
  2422. +     float s = sin(M_PI_2 * i / sp->gridlat);
  2423. +     float c = fsqrt(1 - s*s);
  2424. +     translate(0.0, 0.0, c);
  2425. +     circ(0.0, 0.0, s);
  2426. +     translate(0.0, 0.0, -2*c);
  2427. +     circ(0.0, 0.0, s);
  2428. +     translate(0.0, 0.0, c);
  2429. +   }
  2430. +   popmatrix();
  2431. +   popattributes();
  2432. + }
  2433. +  
  2434. + static void drawaxis(register SPEC *sp, FL_OBJECT *ob)
  2435. + {
  2436. +   float v = fsqrt(1 - sp->rho * sp->rho);
  2437. +   int i;
  2438. +   pushmatrix();
  2439. +   pushattributes();
  2440. +   rot(sp->theta, 'y');
  2441. +   rot(sp->phi, 'z');
  2442. +   move(0., 0., 0.);
  2443. +   draw(sp->allout ? 1. : sp->rho, 0., 0.);
  2444. +   switch(ob->type & 7) {
  2445. +   case FL_NORMAL_FOURAXIS:
  2446. +     if(!sp->colorless) fl_color(4);
  2447. +     move(sp->rho, 0., 0.);
  2448. +     draw(sp->rho, v, 0.);
  2449. +     move(sp->rho, 0., 0.);
  2450. +     draw(sp->rho, 0., v);
  2451. +     break;
  2452. +   case FL_SPOKED_FOURAXIS:
  2453. +   case FL_CIRCLE_FOURAXIS:
  2454. +     if(!sp->colorless) fl_color(4);
  2455. +     translate(sp->rho, 0., 0.);
  2456. +     rot(90., 'y');
  2457. +     circ(0., 0., v);
  2458. +     if((ob->type & 7) == FL_CIRCLE_FOURAXIS)
  2459. +         break;
  2460. +     setlinestyle(FL_FOURAXIS);
  2461. +     for(i=0; i<5; i++) {
  2462. +       move(0., 0., 0.);
  2463. +       draw(v, 0., 0.);
  2464. +       rot(72., 'z');
  2465. +     }
  2466. +   }
  2467. +   popattributes();
  2468. +   popmatrix();
  2469. + }
  2470. +     
  2471. + static void draw_fouraxis(register FL_OBJECT *ob)
  2472. + /* Draws a fouraxis */
  2473. + {
  2474. +   SPEC *sp = ((SPEC *)(ob->spec));
  2475. +   Matrix T;
  2476. +   float wx, wy;
  2477. +   wx = FL_FOURAXIS_BW;
  2478. +   wy = FL_FOURAXIS_BW;
  2479. +   fl_drw_box(ob->boxtype,ob->x,ob->y,ob->w,ob->h,ob->col1,FL_FOURAXIS_BW);
  2480. +   fl_drw_text_beside(ob->align,ob->x,ob->y,ob->w,ob->h,
  2481. +                         ob->lcol,ob->lsize,ob->lstyle,ob->label);
  2482. +   pushmatrix();
  2483. +   pushviewport();
  2484. +   pushattributes();
  2485. +   viewport(ob->x + wx, ob->x + ob->w - wx, ob->y + wy, ob->y + ob->h - wy);
  2486. +   perspective(900, (float)(ob->w - 2*wx) / (ob->h - 2*wy), .5, 4);
  2487. +   translate(0., 0., -1.5);
  2488. +   fl_color(sp->gridcolor);
  2489. +   drawsphere(sp);
  2490. +   linewidth(2);
  2491. +   fl_color(ob->col2);
  2492. +   drawaxis(sp, ob);
  2493. +   popattributes();
  2494. +   popviewport();
  2495. +   popmatrix();
  2496. + }
  2497. + static int handle_mouse(FL_OBJECT *ob,float mx,float my, int key)
  2498. + /* Handle a mouse position change */
  2499. + {
  2500. +   register SPEC *sp = ((SPEC *)(ob->spec));
  2501. +   float du, dv;
  2502. +   du = (mx - sp->omx) / ob->w;
  2503. +   dv = (my - sp->omy) / ob->h;
  2504. +   sp->omx = mx;
  2505. +   sp->omy = my;
  2506. +   if(sp->whatsdown < 0) {
  2507. +     sp->whatsdown = getbutton(RIGHTMOUSE);
  2508. +     return 0;
  2509. +   }
  2510. +   if(du == 0 && dv == 0)
  2511. +     return 0;
  2512. +   if(sp->whatsdown) {
  2513. +     sp->rho += .5 * (du-dv);  /* rightmouse: rho (x motion) / w (y motion) */
  2514. +     if(sp->rho < 0) sp->rho = 0;
  2515. +     else if(sp->rho > 1) sp->rho = 1;
  2516. +   } else {
  2517. +     sp->theta += 180. * du;   /* leftmouse: theta (x) / phi (y) */
  2518. +     sp->phi += 90. * dv;
  2519. +     if(sp->phi > 90.) sp->phi = 90.;
  2520. +     else if(sp->phi < -90.) sp->phi = -90.;
  2521. +   }
  2522. +   fl_redraw_object(ob);
  2523. +   return 1;
  2524. + }
  2525. + static int handle_fouraxis(FL_OBJECT *ob,int event,float mx,float my,int key)
  2526. + /* Handles an event */
  2527. + {
  2528. +   SPEC *sp = (SPEC *) ob->spec;
  2529. +   switch (event)
  2530. +   {
  2531. +     case FL_DRAW:
  2532. +     draw_fouraxis(ob);
  2533. +     return 0;
  2534. +     case FL_PUSH:
  2535. +     case FL_MOUSE:
  2536. +         return ( handle_mouse(ob,mx,my,key) && sp->always);
  2537. +     case FL_RELEASE:
  2538. +     sp->whatsdown = -1;
  2539. +         return (! sp->always);
  2540. +   }
  2541. +   return 0;
  2542. + }
  2543. + /*------------------------------*/
  2544. + FL_OBJECT *fl_create_fouraxis(int type,float x,float y,float w,float h,char label[])
  2545. + /* creates an object */
  2546. + {
  2547. +   FL_OBJECT *ob;
  2548. +   register SPEC *sp;
  2549. +   ob = fl_make_object(FL_FOURAXIS,type,x,y,w,h,label,handle_fouraxis);
  2550. +   ob->boxtype = FL_FOURAXIS_BOXTYPE;
  2551. +   ob->col1 = FL_FOURAXIS_COL1;
  2552. +   ob->col2 = FL_FOURAXIS_COL2;
  2553. +   ob->align = FL_FOURAXIS_ALIGN;
  2554. +   ob->lcol = FL_FOURAXIS_LCOL;
  2555. +   ob->spec = (int *) malloc(sizeof(SPEC));
  2556. +   sp = (SPEC *)ob->spec;
  2557. +   sp->rho = 0.5;
  2558. +   sp->theta = 45.;
  2559. +   sp->phi = 45.;
  2560. +   sp->whatsdown = -1;
  2561. +   sp->gridlong = 12;    /* 24 meridians */
  2562. +   sp->gridlat = 9;    /* 18 parallels */
  2563. +   sp->gridcolor = 0;    /* black wireframe sphere */
  2564. +   sp->colorless = type & 8;
  2565. +   sp->allout = type & 0x10;
  2566. +   sp->always = TRUE;
  2567. +   bzero(sp->T, 16*sizeof(float));
  2568. +   return ob;
  2569. + }
  2570. + FL_OBJECT *fl_add_fouraxis(int type,float x,float y,float w,float h,char label[])
  2571. + /* Adds an object */
  2572. + {
  2573. +   FL_OBJECT *ob;
  2574. +   ob = fl_create_fouraxis(type,x,y,w,h,label);
  2575. +   fl_add_object(fl_current_form,ob);
  2576. +   return ob;
  2577. + }
  2578. + void fl_set_fouraxis(FL_OBJECT *ob,float x, float y, float z)
  2579. + /* Aims the axis */
  2580. + {
  2581. +   register SPEC *sp = (SPEC *)ob->spec;
  2582. +   float xy2 = x*x + y*y;
  2583. +   register int i,j;
  2584. +   /* Map to rho, theta, phi */
  2585. +   sp->rho = fsqrt(xy2 + z*z);
  2586. +   sp->theta = (y == 0 && x == 0) ? 0 : (180/M_PI)*atan2(y,x);
  2587. +   sp->phi = (sp->rho == 0) ? 0 : (180/M_PI)*atan2(z, fsqrt(xy2));
  2588. +   sp->T[W][X] = x;  sp->T[W][Y] = y;  sp->T[W][Z] = z;
  2589. +   sp->T[W][W] = fsqrt(1 - xy2 + z*z);
  2590. +   fl_redraw_object(ob);
  2591. + }
  2592. + void fl_get_fouraxis(FL_OBJECT *ob,float *x, float *y, float *z, float *w)
  2593. + /* Returns the axis */
  2594. + {
  2595. +   register SPEC *sp = (SPEC *)ob->spec;
  2596. +   float r;
  2597. +   *w = fsqrt(1 - sp->rho*sp->rho);
  2598. +   r = sp->rho * cos(sp->phi * M_PI/180);
  2599. +   *x = r * cos(sp->theta * M_PI/180);
  2600. +   *y = r * sin(sp->theta * M_PI/180);
  2601. +   *z = sp->rho * sin(sp->phi * M_PI/180);
  2602. + }
  2603. + void fl_set_fouraxis_grid(FL_OBJECT *ob, int lat, int lon, int col)
  2604. + {
  2605. +   register SPEC *sp = (SPEC *)ob->spec;
  2606. +   if(lat >= 0) sp->gridlat = lat;
  2607. +   if(lon >= 0) sp->gridlong = lon;
  2608. +   if(col >= 0) sp->gridcolor = col;
  2609. + }
  2610. + void fl_get_fouraxis_grid(FL_OBJECT *ob, int *lat, int *lon, int *col)
  2611. + {
  2612. +   register SPEC *sp = (SPEC *)ob->spec;
  2613. +   if(lat) *lat = sp->gridlat;
  2614. +   if(lon) *lon = sp->gridlong;
  2615. +   if(col) *col = sp->gridcolor;
  2616. + }
  2617. + static void transpose(float *src, float *dst)
  2618. + {
  2619. +   register int i, j;
  2620. +   register float v;
  2621. +   for(i=0; i<4; i++) for(j=0; j<4; j++)
  2622. +     dst[i*4+j] = src[j*4+i];
  2623. + }
  2624. + void fl_set_fouraxis_basis(FL_OBJECT *ob, float *matrix)
  2625. + {
  2626. +   register SPEC *sp = (SPEC *)ob->spec;
  2627. +   float T[4][4];
  2628. +   transpose(matrix, (float *)sp->T);
  2629. +   bcopy(sp->T, T, sizeof(T));
  2630. +   orthog4(T);
  2631. +   fl_set_fouraxis(ob, T[W][X], T[W][Y], T[W][Z]);
  2632. + }
  2633. + void fl_get_fouraxis_basis(FL_OBJECT *ob, float *matrix)
  2634. + {
  2635. +   register SPEC *sp = (SPEC *)ob->spec;
  2636. +   float T[4][4];
  2637. +   bcopy(sp->T, T, sizeof(T));
  2638. +   fl_get_fouraxis(ob, &T[W][X], &T[W][Y], &T[W][Z], &T[W][W]);
  2639. +   orthog4(T);
  2640. +   transpose((float *)T, matrix);
  2641. + }
  2642. + void fl_set_fouraxis_return(FL_OBJECT *ob, int value)
  2643. + /* Sets whether to return value all the time */
  2644. + {
  2645. +   ((SPEC *)(ob->spec))->always = value;
  2646. + }
  2647. + #include <math.h>
  2648. + typedef float Point[4];
  2649. + #define DOT(a, b)    ((a)[0]*(b)[0] + (a)[1]*(b)[1] + (a)[2]*(b)[2] + (a)[3]*(b)[3])
  2650. + #define    VCOPY(src,dst)    bcopy((char*)(src), (char*)(dst), sizeof(Point))
  2651. + #define    VSCALE(s, dst) (dst)[0]*=s, (dst)[1]*=s, (dst)[2]*=s, (dst)[3]*=s
  2652. + #define    VSSUB(src,s, dst) { register float t = s; \
  2653. +               (dst)[0] -= t*(src)[0], \
  2654. +               (dst)[1] -= t*(src)[1], \
  2655. +               (dst)[2] -= t*(src)[2], \
  2656. +               (dst)[3] -= t*(src)[3]; \
  2657. +             }
  2658. + /*
  2659. +  * orthog4() accepts three 4-space vectors -- pw, pz, py -- and
  2660. +  * constructs an orthogonal basis of unit vectors X, Y, Z, W where
  2661. +  * W = normalized pw,
  2662. +  * Z is the normalized projection of pz on the space orthogonal to pw,
  2663. +  * Y is the normalized projection of py on the plane orthogonal to pw and pz,
  2664. +  * X is perpendicular to the other three.
  2665. +  * In degenerate cases (zero or nearly coplanar vectors pw, pz, py),
  2666. +  * the vectors are arbitrarily perturbed until they're distinct.
  2667. +  * Result is a 4x4 matrix representing a transformation from
  2668. +  * the supplied coordinate system to the newly constructed one.
  2669. +  * The vectors X, Y, Z, W appear as columns 0, 1, 2, 3 of the resulting matrix.
  2670. +  */
  2671. + static void
  2672. + orthog4(register float M[4][4])
  2673. + {
  2674. +     register float s;
  2675. +     register int k;
  2676. +     s = DOT(M[3],M[3]);
  2677. +     if(s == 0)
  2678. +     M[3][3] = 1.0;
  2679. +     else {
  2680. +     s = 1/fsqrt(s);
  2681. +     VSCALE(s, M[3]);
  2682. +     }
  2683. +     for(k = 2; ; k++, k %= 4) {
  2684. +     VSSUB(M[3], DOT(M[3],M[2]), M[2]);
  2685. +     if((s = DOT(M[2],M[2])) > 0.05)
  2686. +         break;
  2687. +     M[2][k] += 1.0;
  2688. +     }
  2689. +     VSCALE(1/fsqrt(s), M[2]);
  2690. +     for(k = 1; ; k++, k %= 4) {
  2691. +     VSSUB(M[3], DOT(M[3],M[1]), M[1]);
  2692. +     VSSUB(M[2], DOT(M[2],M[1]), M[1]);
  2693. +     s = DOT(M[1],M[1]);
  2694. +     if(s > 0.05)
  2695. +         break;
  2696. +     M[1][k] += 1.0;
  2697. +     }
  2698. +     for(k = 0; ; k++, k %= 4) {
  2699. +     VSSUB(M[3], DOT(M[3],M[0]), M[0]);
  2700. +     VSSUB(M[2], DOT(M[2],M[0]), M[0]);
  2701. +     VSSUB(M[1], DOT(M[1],M[0]), M[0]);
  2702. +     if((s = DOT(M[0],M[0])) > 0.05)
  2703. +         break;
  2704. +     M[0][k] += 1.0;
  2705. +     }
  2706. +     VSCALE(1/fsqrt(s), M[0]);
  2707. + }
  2708.