home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1 / Nebula One.iso / Graphics / Plotting / aa_Intel_Only / Gnuplot / GnuplotSource / term / mif.trm < prev    next >
Encoding:
Text File  |  1995-06-12  |  18.2 KB  |  607 lines

  1. /*
  2.  * $Id: mif.trm,v 1.5 1993/05/18 03:57:41 davis Exp $
  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.  
  133.     if (!END_OF_COMMAND) {
  134.         /* Colour options */
  135.         if (!END_OF_COMMAND && almost_equals(c_token, "m$onochrome")) {    /* Compare up to $ */
  136.             mif_colour = FALSE;
  137.             c_token++;
  138.         }
  139.         if (!END_OF_COMMAND && almost_equals(c_token, "c$olour")) {   /* Compare up to $ */
  140.             mif_colour = TRUE;
  141.             c_token++;
  142.         }
  143.  
  144.         /* Curve options */
  145.         if (!END_OF_COMMAND && almost_equals(c_token, "v$ectors")) {   /* Compare up to $ */
  146.             mif_polyline = FALSE;
  147.             c_token++;
  148.         }
  149.         if (!END_OF_COMMAND && almost_equals(c_token, "p$olyline")) {   /* Compare up to $ */
  150.             mif_polyline = TRUE;
  151.             c_token++;
  152.         }
  153.  
  154.         /* Short help */
  155.         if ( !END_OF_COMMAND &&
  156.              (almost_equals(c_token, "h$elp") ||
  157.               almost_equals(c_token, "?$")) ) { /* Compare up to $ */
  158.             fprintf(stderr, "Usage: set terminal mif [options]\n");
  159.             fprintf(stderr, "\toptions:\n");
  160.             fprintf(stderr, "\t\tcolour /        Draw primitives with line types >= 0 in colour (sep. 2-7)\n");
  161.             fprintf(stderr, "\t\tmonochrome      Draw primitives in black (sep. 0)                        \n");
  162.             fprintf(stderr, "\n");
  163.             fprintf(stderr, "\t\tpolyline /      Draw lines as continous curves                           \n");
  164.             fprintf(stderr, "\t\tvectors         Draw lines as collections of vectors                     \n");
  165.             fprintf(stderr, "\n");
  166.             fprintf(stderr, "\t\thelp / ?        Print short usage description on stderr                  \n");
  167.  
  168.             c_token++;
  169.         }
  170.     }
  171.  
  172.     sprintf(term_options, "%s %s", (mif_colour == TRUE)? "colour": "monochrome",
  173.                        (mif_polyline == TRUE)? "polyline": "vectors");
  174. }
  175.  
  176. /* Set up a MIF output file */
  177. MIF_init()
  178. {
  179.     int i;
  180.  
  181.     extern char version[];        /* Declared in ../version.c */
  182.     extern char patchlevel[];
  183.  
  184.     /* Process if not inside a MIF file and Frame */
  185.     if (mif_initialized == 0 && mif_in_frame == 0) {
  186.         /* Tell this terminal driver that the output is initialized and no current frames are processed */
  187.         mif_initialized = 1;
  188.         mif_in_frame = 0;
  189.  
  190.         /* Reset internal position */
  191.         free_mif_line();
  192.         mif_line.fpos_x = GNP_TO_MIF(0);
  193.         mif_line.fpos_y = GNP_TO_MIF(MIF_YLAST);
  194.  
  195.         /* Reset drawing properties strings */
  196.         mif_pen[0] = '\0';
  197.         mif_pen_width[0] = '\0';
  198.         mif_separation[0] = '\0';
  199.         sprintf(mif_justify, " <TLAlignment Left> ");
  200.  
  201.         /* Reset group ID generator */
  202.         for (i = 0; i < MIF_NGROUP_ID; i++) {
  203.             mif_group_id[i].group_id = MIF_INVALID_GROUP_ID;
  204.             mif_group_id[i].group_existance = MIF_GROUP_NOT_EXISTS;
  205.         }
  206.  
  207.         /* Identify ourselves */
  208.         fprintf(outfile, "<MIFFile 3.00> # Generated by gnuplot version %s patchlevel %s; identifies this as a MIF file\n", version, patchlevel);
  209.         fprintf(outfile, "#\n");
  210.  
  211.         /* Setup a default environment to use */
  212.         fprintf(outfile, "# Set a default pen pattern, pen width, unit and font for subsequent objects\n");
  213.         fprintf(outfile, "<Pen 0>\n");
  214.         fprintf(outfile, "<Fill 15>\n");
  215.         fprintf(outfile, "<PenWidth 0.5 pt>\n");
  216.         fprintf(outfile, "<Separation 0>\n");
  217.         fprintf(outfile, "<Units Ucm>\n");
  218.         fprintf(outfile, "<Font <FFamily `Times'> <FSize %d> <FPlain Yes>>\n", MIF_PSIZE);
  219.         fprintf(outfile, "#\n");
  220.     } /* MIF file created */
  221. }
  222.  
  223. /* Finish of a MIF output file */
  224. MIF_reset()
  225. {
  226.     /* Process if inside a MIF file and not inside a Frame */
  227.     if (mif_initialized != 0 && mif_in_frame == 0) {
  228.         /* Finish off the MIF file */
  229.         fprintf(outfile, "#\n");
  230.         fprintf(outfile, "# End of MIFFile\n");
  231.  
  232.         /* Tell this terminal driver that the output is finished */
  233.         mif_initialized = 0;
  234.     } /* MIF file finished */
  235. }
  236.  
  237. /* Start plotting a Frame (-> graphics mode) */
  238. MIF_graphics()
  239. {
  240.     int i;
  241.  
  242.     /* Process if not inside a Frame */
  243.     if (mif_initialized != 0 && mif_in_frame == 0) {
  244.         /* Tell that this terminal driver is working with a plot frame */
  245.         mif_in_frame = 1;
  246.  
  247.         /* Update frame number */
  248.         mif_frameno++;
  249.  
  250.         /* Set current position */
  251.         free_mif_line();
  252.         mif_line.fpos_x = GNP_TO_MIF(0);
  253.         mif_line.fpos_y = GNP_TO_MIF(MIF_YLAST);
  254.  
  255.         /* Set drawing properties */
  256.         mif_pen[0] = '\0';
  257.         mif_pen_width[0] = '\0';
  258.         mif_separation[0] = '\0';
  259.         sprintf(mif_justify, " <TLAlignment Left> ");
  260.  
  261.         /* Reset group ID generator */
  262.         for (i = 0; i < MIF_NGROUP_ID; i++) {
  263.             mif_group_id[i].group_id = MIF_INVALID_GROUP_ID;
  264.             mif_group_id[i].group_existance = MIF_GROUP_NOT_EXISTS;
  265.         }
  266.  
  267.         /* Frame preamble */
  268.         fprintf(outfile, "#\n");
  269.         fprintf(outfile, "# Frame number %d with plot of graphics\n", mif_frameno);
  270.         fprintf(outfile, "<Frame\n");
  271.         fprintf(outfile, "\t<Pen 15>\n");
  272.         fprintf(outfile, "\t<Fill 15>\n");
  273.         fprintf(outfile, "\t<PenWidth  0.5 pt>\n");
  274.         fprintf(outfile, "\t<Separation 0>\n");
  275.         fprintf(outfile, "\t<BRect 0.000 %.3f %.3f %.3f>\n",
  276.                  ((float) mif_frameno)*GNP_TO_MIF(MIF_YMAX+100), GNP_TO_MIF(MIF_XMAX), GNP_TO_MIF(MIF_YMAX));
  277.         fprintf(outfile, "\t<NSOffset  0.000>\n");
  278.         fprintf(outfile, "\t<BLOffset  0.000>\n");
  279.     } /* Frame created */
  280. }
  281.  
  282. /* Stop plotting a Frame (-> text mode) */
  283. MIF_text()
  284. {
  285.     int i;
  286.  
  287.     /* Process if inside a Frame */
  288.     if (mif_initialized != 0 && mif_in_frame != 0) {
  289.  
  290.         /* Draw pending line */
  291.         if (mif_polyline == TRUE)
  292.             put_mif_line();
  293.  
  294.         /* Group the used plot primitives */
  295.         fprintf(outfile, "\t#\n");
  296.         fprintf(outfile, "\t# Group the the objects in groups to make the chart easier to manipulate\n");
  297.         fprintf(outfile, "\t# after it's imported into FrameMaker.\n");
  298.  
  299.         for (i = 0; i < MIF_NGROUP_ID; i++) {
  300.             if (mif_group_id[i].group_id != MIF_INVALID_GROUP_ID &&
  301.                 mif_group_id[i].group_existance == MIF_GROUP_EXISTS) {
  302.                 fprintf(outfile, "\t<Group\n");
  303.                 fprintf(outfile, "\t\t<ID %d>\n", mif_group_id[i].group_id);
  304.                 fprintf(outfile, "\t>\n");
  305.             }
  306.         }
  307.  
  308.         /* Frame post amble */
  309.         fprintf(outfile, ">\n");
  310.         fprintf(outfile, "# End of Frame number %d\n", mif_frameno);
  311.         fprintf(outfile, "#\n");
  312.  
  313.         /* Tell that this terminal driver is not working with a plot frame */
  314.         mif_in_frame = 0;
  315.     } /* Frame finshed */
  316. }
  317.  
  318. /* Select type of line in grapics */
  319. /* NOTE: actually written to output the first time a primitive is drawn AFTER this call */
  320. MIF_linetype(linetype)
  321. int linetype;           /* -2=border, -1=X/Y-axis, 0-13=lines, and 14-=mapped back */
  322. {
  323.     /* Process if inside a Frame */
  324.     if (mif_initialized != 0 && mif_in_frame != 0) {
  325.  
  326.         /* Draw pending line */
  327.         if (mif_polyline == TRUE)
  328.             put_mif_line();
  329.  
  330.         /* Translate gnuplot pen types to MIF pen types */
  331.         if (linetype < 0) {     /* Special lines */
  332.             if (linetype == -1) {
  333.                 mif_pentype = 8+MIF_NPENS;      /* -1 */
  334.                 if (mif_colour == TRUE)
  335.                     sprintf(mif_separation, " <Separation 0> ");
  336.             }
  337.             else {
  338.                 mif_pentype = 0+MIF_NPENS;      /* -2 or less */
  339.                 if (mif_colour == TRUE)
  340.                     sprintf(mif_separation, " <Separation 0> ");
  341.             }
  342.             sprintf(mif_pen_width, " <PenWidth 1.0 pt> ");
  343.         }
  344.         else {                  /* Normal lines */
  345.             mif_pentype = (linetype)%MIF_NPENS;     /* 0-(MIF_NPENS-1) */
  346.             sprintf(mif_pen_width, " <PenWidth 0.5 pt> ");
  347.             if (mif_colour == TRUE)
  348.                 sprintf(mif_separation, " <Separation %d> ", 2+(mif_pentype%6));        /* 2-7 */
  349.         }
  350.  
  351.         /* Set pen type */
  352.         sprintf(mif_pen, " <Pen %d> ", (mif_pentype%MIF_NPENS));
  353.  
  354.     } /* Primitive processed */
  355. }
  356.  
  357. /* Justify following text lines (MIF_put_text()) relative to the insertion point */
  358. MIF_justify_text(mode)
  359. /* NOTE: actually written to output in text primitives which are drawn AFTER this call */
  360. enum JUSTIFY mode;
  361. {
  362.     int rval = TRUE;
  363.  
  364.     /* Process if inside a Frame */
  365.     if (mif_initialized != 0 && mif_in_frame != 0) {
  366.         switch (mode) {
  367.         case LEFT:
  368.             sprintf(mif_justify, " <TLAlignment Left> ");
  369.             break;
  370.         case CENTRE:
  371.             sprintf(mif_justify, " <TLAlignment Center> ");
  372.             break;
  373.         case RIGHT:
  374.             sprintf(mif_justify, " <TLAlignment Right> ");
  375.             break;
  376.         default:
  377.             rval = FALSE;
  378.             break;
  379.         }
  380.  
  381.     } /* Primitive processed */
  382.     else {
  383.         rval = FALSE;
  384.     }
  385.  
  386.     return(rval);
  387. }
  388.  
  389. /* Draw a vector from current position to (x, y) and change current position. */
  390. /* NOTE: actually written to output the first time another primitive is called AFTER this call */
  391. MIF_vector(x, y)
  392. unsigned int x, y;
  393. {
  394.     /* Process if inside a Frame */
  395.     if (mif_initialized != 0 && mif_in_frame != 0) {
  396.  
  397.         /* Setup the vector as a part of the line */
  398.         insert_mif_line(GNP_TO_MIF(x), GNP_TO_MIF(MIF_YLAST-y));
  399.  
  400.         /* Draw pending line -> vector */
  401.         if (mif_polyline == FALSE)
  402.             put_mif_line();
  403.  
  404.     } /* Vector processed */
  405. }
  406.  
  407. /* Move current position */
  408. MIF_move(x, y)
  409. unsigned int x, y;
  410. {
  411.     /* Process if inside a Frame */
  412.     if (mif_initialized != 0 && mif_in_frame != 0) {
  413.  
  414.         /* Draw pending line */
  415.         if (mif_polyline == TRUE)
  416.             put_mif_line();
  417.  
  418.         mif_line.fpos_x = GNP_TO_MIF(x);
  419.         mif_line.fpos_y = GNP_TO_MIF(MIF_YLAST-y);
  420.     }
  421. }
  422.  
  423. /* Draw the text string str at (x, y). Adjust according to MIF_justify_text(). Change current position. */
  424. MIF_put_text(x, y, str)
  425. unsigned int x, y;
  426. char str[];
  427. {
  428.     /* Process if inside a Frame */
  429.     if (mif_initialized != 0 && mif_in_frame != 0) {
  430.  
  431.         /* Draw pending line */
  432.         if (mif_polyline == TRUE)
  433.             put_mif_line();
  434.  
  435.         /* Adjust current position for text-graphics alignment */
  436.         MIF_move(x, y-MIF_VCHAR/5);
  437.  
  438.         if (strlen(str) > 0) {
  439.  
  440.             /* Draw the text */
  441.             fprintf(outfile, "\t<TextLine <GroupID %d> %s %s %s\n",
  442.                      MIF_PEN_TO_GROUP(mif_pentype), mif_pen, mif_pen_width, mif_separation);
  443.             fprintf(outfile, "\t\t<TLOrigin  %.3f %.3f> %s <String `%s'>\n",
  444.                     mif_line.fpos_x, mif_line.fpos_y, mif_justify, str);
  445.             fprintf(outfile, "\t>\n");
  446.  
  447.             /* Register the used group ID */
  448.             proc_group_id(MIF_PEN_TO_GROUP(mif_pentype));
  449.  
  450.             /* Avoid to redraw this. The MIF system should remember it. */
  451.             mif_pen[0] = '\0';
  452.             mif_pen_width[0] = '\0';
  453.             mif_separation[0] = '\0';
  454.  
  455.             mif_justify[0] = '\0';  /* Independent of linetype */
  456.         }
  457.     } /* Text processed */
  458. }
  459.  
  460. /* Draw the pending line. Change current position. */
  461. static int put_mif_line()
  462. {
  463.     int np, i;
  464.     struct mif_line *tline;
  465.  
  466.     /* Process if inside a Frame */
  467.     if (mif_initialized != 0 && mif_in_frame != 0) {
  468.  
  469.         /* Count the number of available points */
  470.         for (tline = mif_line.next, np = 1; tline != &mif_line; tline = tline->next, np++)
  471.             ;
  472.  
  473.         /* Draw line (at least two points) */
  474.         if (np >= 2) {
  475.             /* Line preamble */
  476.             fprintf(outfile, "\t<PolyLine <GroupID %d> %s %s %s\n",
  477.                      MIF_PEN_TO_GROUP(mif_pentype), mif_pen, mif_pen_width, mif_separation);
  478.  
  479.             /* Draw the line elements */
  480.             fprintf(outfile, "\t\t<NumPoints %d> ", np);
  481.             for (i = 0, tline = &mif_line; i < np; i++, tline = tline->next) {
  482.                 if (i%4 == 0)
  483.                     fprintf(outfile, "\n\t\t");
  484.                 fprintf(outfile, "<Point  %.3f %.3f> ", tline->fpos_x, tline->fpos_y);
  485.             }
  486.  
  487.             /* Line post amble */
  488.             fprintf(outfile, "\n\t>\n");
  489.  
  490.             /* Register the used group ID */
  491.             proc_group_id(MIF_PEN_TO_GROUP(mif_pentype));
  492.  
  493.             /* Avoid to redraw this. The MIF system should remember it. */
  494.             mif_pen[0] = '\0';
  495.             mif_pen_width[0] = '\0';
  496.             mif_separation[0] = '\0';
  497.  
  498.             /* Move current position to end of line */
  499.             mif_line.fpos_x = mif_line.prev->fpos_x;
  500.             mif_line.fpos_y = mif_line.prev->fpos_y;
  501.  
  502.             /* Restore the line */
  503.             free_mif_line();
  504.         }
  505.  
  506.     } /* Line processed */
  507. }
  508.  
  509. /* Insert one point in the line */
  510. static int insert_mif_line(fx, fy)
  511. float fx, fy;
  512. {
  513.     int rval = TRUE;
  514.  
  515.     if ((mif_line.prev->next = (struct mif_line *) alloc(sizeof(struct mif_line),"MIF driver")) != (struct mif_line *) NULL) {
  516.         /* Link */
  517.         mif_line.prev->next->next = &mif_line;
  518.         mif_line.prev->next->prev = mif_line.prev;
  519.         mif_line.prev = mif_line.prev->next;
  520.  
  521.         /* Fill */
  522.         mif_line.prev->fpos_x = fx;
  523.         mif_line.prev->fpos_y = fy;
  524.  
  525.         rval = TRUE;
  526.     }
  527.     else { /* Failed to allocate */
  528.         /* Relink */
  529.         mif_line.prev->next = &mif_line;
  530.  
  531.         rval = FALSE;
  532.     }
  533.  
  534.     return(rval);
  535. }
  536.  
  537. /* Deallocate the used line structure elements */
  538. static int free_mif_line()
  539. {
  540.     struct mif_line *tline;
  541.  
  542.     while (mif_line.prev != &mif_line) {
  543.         /* Unlink */
  544.         tline = mif_line.prev;
  545.         mif_line.prev = mif_line.prev->prev;
  546.         mif_line.prev->next = &mif_line;
  547.  
  548.         /* Deallocate */
  549.         free(tline);
  550.     }
  551.  
  552.     /* Make sure that the list will be empty */
  553.     mif_line.prev = &mif_line;
  554.     mif_line.next = &mif_line;
  555. }
  556.  
  557. /* Register group ID. Update group ID existance. */
  558. /* Returns:     1       group_id belongs to a MIF group
  559.         0       group_id does not belong to a MIF group
  560.            -1       not inside a Frame
  561.            -2       group ID list is full
  562.  */
  563. static int proc_group_id(group_id)
  564. int group_id;
  565. {
  566.     int i, rval = 0;
  567.  
  568.     /* Process if inside a Frame */
  569.     if (mif_initialized != 0 && mif_in_frame != 0) {
  570.  
  571.         /* Find out the group ID, or a free group ID slot index. */
  572.         for (i = 0; i < MIF_NGROUP_ID &&
  573.                 mif_group_id[i].group_id != MIF_INVALID_GROUP_ID &&
  574.                 mif_group_id[i].group_id != group_id;
  575.                                         i++) {
  576.             /* Don't check the group_existance variable */
  577.         }
  578.  
  579.         if (i < MIF_NGROUP_ID) {
  580.             if (mif_group_id[i].group_id == MIF_INVALID_GROUP_ID) {
  581.                 /* Register as new group ID for eventual use as MIF group */
  582.                 mif_group_id[i].group_id = group_id;
  583.                 mif_group_id[i].group_existance = MIF_GROUP_NOT_EXISTS;
  584.             }
  585.             else {
  586.                 /* If second use of this group ID -> create a new MIF group */
  587.                 if (mif_group_id[i].group_id == group_id) {
  588.                     mif_group_id[i].group_existance = MIF_GROUP_EXISTS;
  589.                     /* NOTE: a group MUST have at least two members. */
  590.                     rval = 1;
  591.                 }
  592.             }
  593.         }
  594.         else {
  595.             rval = -2;      /* No place for this group ID in the list */
  596.         }
  597.  
  598.     } /* Group ID processed */
  599.     else {
  600.         rval = -1;      /* Not inside a Frame */
  601.     }
  602.  
  603.     /* Return MIF group status */
  604.     return(rval);
  605. }
  606.  
  607.