home *** CD-ROM | disk | FTP | other *** search
/ CICA 1995 May / cica_0595_4.zip / cica_0595_4 / UTIL / GPT34SRC / TERM / MIF.TRM < prev    next >
Text File  |  1993-05-11  |  19KB  |  614 lines

  1. /*
  2.  * $Id: mif.trm%v 3.38.2.125 1993/05/05 00:13:05 woo Exp woo $
  3.  */
  4.  
  5. /* GNUPLOT -- mif.trm */
  6. /*
  7.  * Copyright (C) 1992
  8.  *
  9.  * Permission to use, copy, and distribute this software and its
  10.  * documentation for any purpose with or without fee is hereby granted, 
  11.  * provided that the above copyright notice appear in all copies and 
  12.  * that both that copyright notice and this permission notice appear 
  13.  * in supporting documentation.
  14.  *
  15.  * Permission to modify the software is granted, but not the right to
  16.  * distribute the modified code.  Modifications are to be distributed 
  17.  * as patches to released version.
  18.  *  
  19.  * This software  is provided "as is" without express or implied warranty.
  20.  * 
  21.  * This file is included by ../term.c.
  22.  *
  23.  * This terminal driver was developed for
  24.  *      gnuplot for unix version 3.0 (patchlevel 1)
  25.  *      gnuplot for unix version 3.2 (patchlevel 2)
  26.  *
  27.  * This terminal driver supports:
  28.  *      Frame Maker MIF format version 3.00
  29.  *
  30.  * Options for this terminal driver (set terminal mif [options]):
  31.  *      colour /        Draw primitives with line types >= 0 in colour (sep. 2-7)
  32.  *      monochrome      Draw primitives in black (sep. 0)
  33.  *
  34.  *      polyline /      Draw lines as continous curves
  35.  *      vectors         Draw lines as collections of vectors
  36.  *
  37.  *      help / ?        Print short usage description on stderr
  38.  *
  39.  * Properties for this terminal driver:
  40.  *     -Gnuplot size of worksheet:              MIF_XMAX * MIF_YMAX
  41.  *     -Unit in MIF output:                     cm
  42.  *     -Plot primitives with the same pen will
  43.  *      be grouped in the same MIF group.
  44.  *     -Plot primitives with line types >= 0
  45.  *      will as default be drawn in colour.
  46.  *     -Lines are plotted as collections of
  47.  *      vectors, or as continous lines (default)
  48.  *     -Plot primitives in a plot will be in a
  49.  *      Frame in MIF. Several plot Frames will
  50.  *      be collected in one large Frame.
  51.  *     -Point size of MIF output characters:    MIF_PSIZE
  52.  *     -Used font for MIF output characters:    Times
  53.  *
  54.  * AUTHORS:
  55.  *      Olof Franksson, Physics IV, KTH, S-100 44 Stockholm, Sweden
  56.  * 
  57.  * COMMENTS:
  58.  *      Send comments and/or suggestions to olof@fysik4.kth.se
  59.  * 
  60.  */
  61. #if !defined(cfree)
  62. #define cfree free
  63. #endif
  64.  
  65. /** Coordinates **/
  66. #define GNP_TO_MIF(P)   (((float) (P)) / 1000.0)        /* Converts gnuplot units to MIF units */
  67. #define MIF_XMAX 15000                  /* Basic unit: 0.01 mm (15cm -> 15*10*100=15000) */
  68. #define MIF_YMAX 10000                  /* Basic unit: 0.01 mm (10cm -> 10*10*100=10000) */
  69.  
  70. #define MIF_XLAST (MIF_XMAX - 1)
  71. #define MIF_YLAST (MIF_YMAX - 1)
  72.  
  73. static struct mif_line { /* Line point structure specification */
  74.     float fpos_x;           /* Line point X coordinate */
  75.     float fpos_y;           /*            Y coordinate */
  76.     struct mif_line *next;  /* Pointer to next line point */
  77.     struct mif_line *prev;  /* Pointer to previous line point */
  78. } mif_line = { /* Current position structure. Adjust for orign. Local for this file. */
  79.     GNP_TO_MIF(0),
  80.     GNP_TO_MIF(MIF_YLAST),
  81.     &mif_line,
  82.     &mif_line
  83. };
  84.  
  85. /** Characters **/
  86. #define MIF_PSIZE 9                     /* Point size of used characters */
  87.  
  88. #define MIF_VCHAR (MIF_YMAX/25)         /* Distance between rows (a guess) */
  89. #define MIF_HCHAR (MIF_XMAX/100)        /* Distance between characters (a guess) */
  90.  
  91. /** Scale marks **/
  92. #define MIF_VTIC  (MIF_YMAX/150)        /* Size of scale mark (vert) */
  93. #define MIF_HTIC  (MIF_XMAX/225)        /* Size of scale mark (hor) */
  94.  
  95. /** Drawing properties **/
  96. static char mif_justify[64];                    /* How to justify the used text */
  97. static char mif_pen[64], mif_pen_width[64], mif_separation[64];         /* How to plot */
  98.  
  99. #define MIF_NPENS 16                    /* Number of MIF pen types */
  100. static int mif_pentype = 0;             /* Pen type to use. Also used to create groups for graphics */
  101. #define MIF_PEN_TO_GROUP(P)     ( 1 + (P) )     /* Map pen type to group number. Must be >= 1 */
  102.  
  103. /** MIF groups administration **/
  104. #define MIF_NGROUP_ID           20
  105. static struct mif_group_id {
  106.     int group_existance;
  107. #define MIF_GROUP_EXISTS        1       /* This group id should generate a MIF group */
  108. #define MIF_GROUP_NOT_EXISTS    0       /* This group id should not generate a MIF group */
  109.  
  110.     int group_id;
  111. #define MIF_INVALID_GROUP_ID    0       /* An invalid MIF group ID */
  112.  
  113. } mif_group_id[MIF_NGROUP_ID];            /* List of used group ID:s and corresponding MIF groups existance */
  114.  
  115. /** Semaphores **/
  116. static int mif_initialized = 0;        /* != 0 when output is active */
  117. static int mif_in_frame = 0;            /* != 0 when inside a plot frame */
  118. static int mif_frameno = -1;            /* Current frame number */
  119. static int mif_colour = TRUE;           /* == TRUE when colour should be used */
  120. static int mif_polyline = TRUE;         /* == TRUE when lines are drawn as continous curves */
  121.  
  122. /** Declaration of routine/s for internal use **/
  123. static int insert_mif_line(), proc_group_id();
  124. static int put_mif_line(), free_mif_line();
  125.  
  126. /** Routine/s **/
  127.  
  128. /* Called when this terminal type is set in order to parse options */
  129. MIF_options()
  130. {
  131.     extern char term_options[];     /* Declared in ../setshow.c */
  132.     static char GPFAR mifhelp[] = "\
  133. Usage: set terminal mif [options]\n\
  134. \toptions:\n\
  135. \t\tcolour /        Draw primitives with line types >= 0 in colour (sep. 2-7)\n\
  136. \t\tmonochrome      Draw primitives in black (sep. 0)                        \n\
  137. \n\
  138. \t\tpolyline /      Draw lines as continous curves                           \n\
  139. \t\tvectors         Draw lines as collections of vectors                     \n\
  140. \n\
  141. \t\thelp / ?        Print short usage description on stderr                  \n";
  142.  
  143.     if (!END_OF_COMMAND) {
  144.         /* Colour options */
  145.         if (!END_OF_COMMAND && almost_equals(c_token, "m$onochrome")) {    /* Compare up to $ */
  146.             mif_colour = FALSE;
  147.             c_token++;
  148.         }
  149.         if (!END_OF_COMMAND && almost_equals(c_token, "c$olour")) {   /* Compare up to $ */
  150.             mif_colour = TRUE;
  151.             c_token++;
  152.         }
  153.  
  154.         /* Curve options */
  155.         if (!END_OF_COMMAND && almost_equals(c_token, "v$ectors")) {   /* Compare up to $ */
  156.             mif_polyline = FALSE;
  157.             c_token++;
  158.         }
  159.         if (!END_OF_COMMAND && almost_equals(c_token, "p$olyline")) {   /* Compare up to $ */
  160.             mif_polyline = TRUE;
  161.             c_token++;
  162.         }
  163.  
  164.         /* Short help */
  165.         if ( !END_OF_COMMAND &&
  166.              (almost_equals(c_token, "h$elp") ||
  167.               almost_equals(c_token, "?$")) ) { /* Compare up to $ */
  168.             fprintf(stderr, mifhelp);
  169.             c_token++;
  170.         }
  171.     }
  172.  
  173.     sprintf(term_options, "%s %s", (mif_colour == TRUE)? "colour": "monochrome",
  174.                        (mif_polyline == TRUE)? "polyline": "vectors");
  175. }
  176.  
  177. /* Set up a MIF output file */
  178. MIF_init()
  179. {
  180.     int i;
  181.     static char GPFAR mifi1[] = "\
  182. <MIFFile 3.00> # Generated by gnuplot version %s patchlevel %s; identifies this as a MIF file\n\
  183. #\n\
  184. # Set a default pen pattern, pen width, unit and font for subsequent objects\n\
  185. <Pen 0>\n\
  186. <Fill 15>\n\
  187. <PenWidth 0.5 pt>\n\
  188. <Separation 0>\n\
  189. <Units Ucm>\n\
  190. <Font <FFamily `Times'> <FSize %d> <FPlain Yes>>\n\
  191. #\n";
  192.  
  193.  
  194.     extern char version[];        /* Declared in ../version.c */
  195.     extern char patchlevel[];
  196.  
  197.     /* Process if not inside a MIF file and Frame */
  198.     if (mif_initialized == 0 && mif_in_frame == 0) {
  199.         /* Tell this terminal driver that the output is initialized and no current frames are processed */
  200.         mif_initialized = 1;
  201.         mif_in_frame = 0;
  202.  
  203.         /* Reset internal position */
  204.         free_mif_line();
  205.         mif_line.fpos_x = GNP_TO_MIF(0);
  206.         mif_line.fpos_y = GNP_TO_MIF(MIF_YLAST);
  207.  
  208.         /* Reset drawing properties strings */
  209.         mif_pen[0] = '\0';
  210.         mif_pen_width[0] = '\0';
  211.         mif_separation[0] = '\0';
  212.         sprintf(mif_justify, " <TLAlignment Left> ");
  213.  
  214.         /* Reset group ID generator */
  215.         for (i = 0; i < MIF_NGROUP_ID; i++) {
  216.             mif_group_id[i].group_id = MIF_INVALID_GROUP_ID;
  217.             mif_group_id[i].group_existance = MIF_GROUP_NOT_EXISTS;
  218.         }
  219.  
  220.         /* Identify ourselves and Setup a default environment to use */
  221.         fprintf(outfile, mifi1, version, patchlevel, MIF_PSIZE);
  222.     } /* MIF file created */
  223. }
  224.  
  225. /* Finish of a MIF output file */
  226. MIF_reset()
  227. {
  228.     /* Process if inside a MIF file and not inside a Frame */
  229.     if (mif_initialized != 0 && mif_in_frame == 0) {
  230.         /* Finish off the MIF file */
  231.         fprintf(outfile, "#\n");
  232.         fprintf(outfile, "# End of MIFFile\n");
  233.  
  234.         /* Tell this terminal driver that the output is finished */
  235.         mif_initialized = 0;
  236.     } /* MIF file finished */
  237. }
  238.  
  239. /* Start plotting a Frame (-> graphics mode) */
  240. MIF_graphics()
  241. {
  242.     int i;
  243.     static char GPFAR mifg1[] = "\
  244. #\n\
  245. # Frame number %d with plot of graphics\n\
  246. <Frame\n\
  247. \t<Pen 15>\n\
  248. \t<Fill 15>\n\
  249. \t<PenWidth  0.5 pt>\n\
  250. \t<Separation 0>\n\
  251. \t<BRect 0.000 %.3f %.3f %.3f>\n\
  252. \t<NSOffset  0.000>\n\
  253. \t<BLOffset  0.000>\n";
  254.  
  255.     /* Process if not inside a Frame */
  256.     if (mif_initialized != 0 && mif_in_frame == 0) {
  257.         /* Tell that this terminal driver is working with a plot frame */
  258.         mif_in_frame = 1;
  259.  
  260.         /* Update frame number */
  261.         mif_frameno++;
  262.  
  263.         /* Set current position */
  264.         free_mif_line();
  265.         mif_line.fpos_x = GNP_TO_MIF(0);
  266.         mif_line.fpos_y = GNP_TO_MIF(MIF_YLAST);
  267.  
  268.         /* Set drawing properties */
  269.         mif_pen[0] = '\0';
  270.         mif_pen_width[0] = '\0';
  271.         mif_separation[0] = '\0';
  272.         sprintf(mif_justify, " <TLAlignment Left> ");
  273.  
  274.         /* Reset group ID generator */
  275.         for (i = 0; i < MIF_NGROUP_ID; i++) {
  276.             mif_group_id[i].group_id = MIF_INVALID_GROUP_ID;
  277.             mif_group_id[i].group_existance = MIF_GROUP_NOT_EXISTS;
  278.         }
  279.  
  280.         /* Frame preamble */
  281.         fprintf(outfile, mifg1,
  282.             mif_frameno,
  283.             ((float) mif_frameno)*GNP_TO_MIF(MIF_YMAX+100), 
  284.             GNP_TO_MIF(MIF_XMAX), GNP_TO_MIF(MIF_YMAX));
  285.         
  286.     } /* Frame created */
  287. }
  288.  
  289. /* Stop plotting a Frame (-> text mode) */
  290. MIF_text()
  291. {
  292.     int i;
  293.  
  294.     /* Process if inside a Frame */
  295.     if (mif_initialized != 0 && mif_in_frame != 0) {
  296.  
  297.         /* Draw pending line */
  298.         if (mif_polyline == TRUE)
  299.             put_mif_line();
  300.  
  301.         /* Group the used plot primitives */
  302.         fprintf(outfile, "\t#\n");
  303.         fprintf(outfile, "\t# Group the the objects in groups to make the chart easier to manipulate\n");
  304.         fprintf(outfile, "\t# after it's imported into FrameMaker.\n");
  305.  
  306.         for (i = 0; i < MIF_NGROUP_ID; i++) {
  307.             if (mif_group_id[i].group_id != MIF_INVALID_GROUP_ID &&
  308.                 mif_group_id[i].group_existance == MIF_GROUP_EXISTS) {
  309.                 fprintf(outfile, "\t<Group\n");
  310.                 fprintf(outfile, "\t\t<ID %d>\n", mif_group_id[i].group_id);
  311.                 fprintf(outfile, "\t>\n");
  312.             }
  313.         }
  314.  
  315.         /* Frame post amble */
  316.         fprintf(outfile, ">\n");
  317.         fprintf(outfile, "# End of Frame number %d\n", mif_frameno);
  318.         fprintf(outfile, "#\n");
  319.  
  320.         /* Tell that this terminal driver is not working with a plot frame */
  321.         mif_in_frame = 0;
  322.     } /* Frame finshed */
  323. }
  324.  
  325. /* Select type of line in grapics */
  326. /* NOTE: actually written to output the first time a primitive is drawn AFTER this call */
  327. MIF_linetype(linetype)
  328. int linetype;           /* -2=border, -1=X/Y-axis, 0-13=lines, and 14-=mapped back */
  329. {
  330.     /* Process if inside a Frame */
  331.     if (mif_initialized != 0 && mif_in_frame != 0) {
  332.  
  333.         /* Draw pending line */
  334.         if (mif_polyline == TRUE)
  335.             put_mif_line();
  336.  
  337.         /* Translate gnuplot pen types to MIF pen types */
  338.         if (linetype < 0) {     /* Special lines */
  339.             if (linetype == -1) {
  340.                 mif_pentype = 8+MIF_NPENS;      /* -1 */
  341.                 if (mif_colour == TRUE)
  342.                     sprintf(mif_separation, " <Separation 0> ");
  343.             }
  344.             else {
  345.                 mif_pentype = 0+MIF_NPENS;      /* -2 or less */
  346.                 if (mif_colour == TRUE)
  347.                     sprintf(mif_separation, " <Separation 0> ");
  348.             }
  349.             sprintf(mif_pen_width, " <PenWidth 1.0 pt> ");
  350.         }
  351.         else {                  /* Normal lines */
  352.             mif_pentype = (linetype)%MIF_NPENS;     /* 0-(MIF_NPENS-1) */
  353.             sprintf(mif_pen_width, " <PenWidth 0.5 pt> ");
  354.             if (mif_colour == TRUE)
  355.                 sprintf(mif_separation, " <Separation %d> ", 2+(mif_pentype%6));        /* 2-7 */
  356.         }
  357.  
  358.         /* Set pen type */
  359.         sprintf(mif_pen, " <Pen %d> ", (mif_pentype%MIF_NPENS));
  360.  
  361.     } /* Primitive processed */
  362. }
  363.  
  364. /* Justify following text lines (MIF_put_text()) relative to the insertion point */
  365. MIF_justify_text(mode)
  366. /* NOTE: actually written to output in text primitives which are drawn AFTER this call */
  367. enum JUSTIFY mode;
  368. {
  369.     int rval = TRUE;
  370.  
  371.     /* Process if inside a Frame */
  372.     if (mif_initialized != 0 && mif_in_frame != 0) {
  373.         switch (mode) {
  374.         case LEFT:
  375.             sprintf(mif_justify, " <TLAlignment Left> ");
  376.             break;
  377.         case CENTRE:
  378.             sprintf(mif_justify, " <TLAlignment Center> ");
  379.             break;
  380.         case RIGHT:
  381.             sprintf(mif_justify, " <TLAlignment Right> ");
  382.             break;
  383.         default:
  384.             rval = FALSE;
  385.             break;
  386.         }
  387.  
  388.     } /* Primitive processed */
  389.     else {
  390.         rval = FALSE;
  391.     }
  392.  
  393.     return(rval);
  394. }
  395.  
  396. /* Draw a vector from current position to (x, y) and change current position. */
  397. /* NOTE: actually written to output the first time another primitive is called AFTER this call */
  398. MIF_vector(x, y)
  399. unsigned int x, y;
  400. {
  401.     /* Process if inside a Frame */
  402.     if (mif_initialized != 0 && mif_in_frame != 0) {
  403.  
  404.         /* Setup the vector as a part of the line */
  405.         insert_mif_line(GNP_TO_MIF(x), GNP_TO_MIF(MIF_YLAST-y));
  406.  
  407.         /* Draw pending line -> vector */
  408.         if (mif_polyline == FALSE)
  409.             put_mif_line();
  410.  
  411.     } /* Vector processed */
  412. }
  413.  
  414. /* Move current position */
  415. MIF_move(x, y)
  416. unsigned int x, y;
  417. {
  418.     /* Process if inside a Frame */
  419.     if (mif_initialized != 0 && mif_in_frame != 0) {
  420.  
  421.         /* Draw pending line */
  422.         if (mif_polyline == TRUE)
  423.             put_mif_line();
  424.  
  425.         mif_line.fpos_x = GNP_TO_MIF(x);
  426.         mif_line.fpos_y = GNP_TO_MIF(MIF_YLAST-y);
  427.     }
  428. }
  429.  
  430. /* Draw the text string str at (x, y). Adjust according to MIF_justify_text(). Change current position. */
  431. MIF_put_text(x, y, str)
  432. unsigned int x, y;
  433. char str[];
  434. {
  435.     /* Process if inside a Frame */
  436.     if (mif_initialized != 0 && mif_in_frame != 0) {
  437.  
  438.         /* Draw pending line */
  439.         if (mif_polyline == TRUE)
  440.             put_mif_line();
  441.  
  442.         /* Adjust current position for text-graphics alignment */
  443.         MIF_move(x, y-MIF_VCHAR/5);
  444.  
  445.         if (strlen(str) > 0) {
  446.  
  447.             /* Draw the text */
  448.             fprintf(outfile, "\t<TextLine <GroupID %d> %s %s %s\n",
  449.                      MIF_PEN_TO_GROUP(mif_pentype), mif_pen, mif_pen_width, mif_separation);
  450.             fprintf(outfile, "\t\t<TLOrigin  %.3f %.3f> %s <String `%s'>\n",
  451.                     mif_line.fpos_x, mif_line.fpos_y, mif_justify, str);
  452.             fprintf(outfile, "\t>\n");
  453.  
  454.             /* Register the used group ID */
  455.             proc_group_id(MIF_PEN_TO_GROUP(mif_pentype));
  456.  
  457.             /* Avoid to redraw this. The MIF system should remember it. */
  458.             mif_pen[0] = '\0';
  459.             mif_pen_width[0] = '\0';
  460.             mif_separation[0] = '\0';
  461.  
  462.             mif_justify[0] = '\0';  /* Independent of linetype */
  463.         }
  464.     } /* Text processed */
  465. }
  466.  
  467. /* Draw the pending line. Change current position. */
  468. static int put_mif_line()
  469. {
  470.     int np, i;
  471.     struct mif_line *tline;
  472.  
  473.     /* Process if inside a Frame */
  474.     if (mif_initialized != 0 && mif_in_frame != 0) {
  475.  
  476.         /* Count the number of available points */
  477.         for (tline = mif_line.next, np = 1; tline != &mif_line; tline = tline->next, np++)
  478.             ;
  479.  
  480.         /* Draw line (at least two points) */
  481.         if (np >= 2) {
  482.             /* Line preamble */
  483.             fprintf(outfile, "\t<PolyLine <GroupID %d> %s %s %s\n",
  484.                      MIF_PEN_TO_GROUP(mif_pentype), mif_pen, mif_pen_width, mif_separation);
  485.  
  486.             /* Draw the line elements */
  487.             fprintf(outfile, "\t\t<NumPoints %d> ", np);
  488.             for (i = 0, tline = &mif_line; i < np; i++, tline = tline->next) {
  489.                 if (i%4 == 0)
  490.                     fprintf(outfile, "\n\t\t");
  491.                 fprintf(outfile, "<Point  %.3f %.3f> ", tline->fpos_x, tline->fpos_y);
  492.             }
  493.  
  494.             /* Line post amble */
  495.             fprintf(outfile, "\n\t>\n");
  496.  
  497.             /* Register the used group ID */
  498.             proc_group_id(MIF_PEN_TO_GROUP(mif_pentype));
  499.  
  500.             /* Avoid to redraw this. The MIF system should remember it. */
  501.             mif_pen[0] = '\0';
  502.             mif_pen_width[0] = '\0';
  503.             mif_separation[0] = '\0';
  504.  
  505.             /* Move current position to end of line */
  506.             mif_line.fpos_x = mif_line.prev->fpos_x;
  507.             mif_line.fpos_y = mif_line.prev->fpos_y;
  508.  
  509.             /* Restore the line */
  510.             free_mif_line();
  511.         }
  512.  
  513.     } /* Line processed */
  514. }
  515.  
  516. /* Insert one point in the line */
  517. static int insert_mif_line(fx, fy)
  518. float fx, fy;
  519. {
  520.     int rval = TRUE;
  521.  
  522.     if ((mif_line.prev->next = (struct mif_line *) alloc(sizeof(struct mif_line),"MIF driver")) != (struct mif_line *) NULL) {
  523.         /* Link */
  524.         mif_line.prev->next->next = &mif_line;
  525.         mif_line.prev->next->prev = mif_line.prev;
  526.         mif_line.prev = mif_line.prev->next;
  527.  
  528.         /* Fill */
  529.         mif_line.prev->fpos_x = fx;
  530.         mif_line.prev->fpos_y = fy;
  531.  
  532.         rval = TRUE;
  533.     }
  534.     else { /* Failed to allocate */
  535.         /* Relink */
  536.         mif_line.prev->next = &mif_line;
  537.  
  538.         rval = FALSE;
  539.     }
  540.  
  541.     return(rval);
  542. }
  543.  
  544. /* Deallocate the used line structure elements */
  545. static int free_mif_line()
  546. {
  547.     struct mif_line *tline;
  548.  
  549.     while (mif_line.prev != &mif_line) {
  550.         /* Unlink */
  551.         tline = mif_line.prev;
  552.         mif_line.prev = mif_line.prev->prev;
  553.         mif_line.prev->next = &mif_line;
  554.  
  555.         /* Deallocate */
  556.         free(tline);
  557.     }
  558.  
  559.     /* Make sure that the list will be empty */
  560.     mif_line.prev = &mif_line;
  561.     mif_line.next = &mif_line;
  562. }
  563.  
  564. /* Register group ID. Update group ID existance. */
  565. /* Returns:     1       group_id belongs to a MIF group
  566.         0       group_id does not belong to a MIF group
  567.            -1       not inside a Frame
  568.            -2       group ID list is full
  569.  */
  570. static int proc_group_id(group_id)
  571. int group_id;
  572. {
  573.     int i, rval = 0;
  574.  
  575.     /* Process if inside a Frame */
  576.     if (mif_initialized != 0 && mif_in_frame != 0) {
  577.  
  578.         /* Find out the group ID, or a free group ID slot index. */
  579.         for (i = 0; i < MIF_NGROUP_ID &&
  580.                 mif_group_id[i].group_id != MIF_INVALID_GROUP_ID &&
  581.                 mif_group_id[i].group_id != group_id;
  582.                                         i++) {
  583.             /* Don't check the group_existance variable */
  584.         }
  585.  
  586.         if (i < MIF_NGROUP_ID) {
  587.             if (mif_group_id[i].group_id == MIF_INVALID_GROUP_ID) {
  588.                 /* Register as new group ID for eventual use as MIF group */
  589.                 mif_group_id[i].group_id = group_id;
  590.                 mif_group_id[i].group_existance = MIF_GROUP_NOT_EXISTS;
  591.             }
  592.             else {
  593.                 /* If second use of this group ID -> create a new MIF group */
  594.                 if (mif_group_id[i].group_id == group_id) {
  595.                     mif_group_id[i].group_existance = MIF_GROUP_EXISTS;
  596.                     /* NOTE: a group MUST have at least two members. */
  597.                     rval = 1;
  598.                 }
  599.             }
  600.         }
  601.         else {
  602.             rval = -2;      /* No place for this group ID in the list */
  603.         }
  604.  
  605.     } /* Group ID processed */
  606.     else {
  607.         rval = -1;      /* Not inside a Frame */
  608.     }
  609.  
  610.     /* Return MIF group status */
  611.     return(rval);
  612. }
  613.  
  614.