home *** CD-ROM | disk | FTP | other *** search
/ PC Extra Super CD 1998 January / PCPLUS131.iso / DJGPP / V2 / DJLSR201.ZIP / src / debug / fsdb / screen.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-10-01  |  17.8 KB  |  682 lines

  1. /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <ctype.h>
  6. #include <bios.h>
  7. #include <dos.h>
  8. #include <dpmi.h>
  9. #include <go32.h>
  10. #include <keys.h>
  11. #include <setjmp.h>
  12. #include "ed.h"
  13. #include "screen.h"
  14. void *xmalloc (size_t);
  15. /* ------------------------------------------------------------------------- */
  16. static char *colours[] = {
  17.   "black",        "blue",         "green",        "cyan",
  18.   "red",          "purple",       "brown",        "grey",
  19.   "darkgrey",     "lightblue",    "lightgreen",   "lightcyan",
  20.   "lightred",     "lightmagenta", "yellow",       "white"};
  21. /* ------------------------------------------------------------------------- */
  22. /* At position (X,Y) place TXT in the debugger screen.  */
  23.  
  24. inline void
  25. put (int x, int y, unsigned char *txt)
  26. {
  27.   unsigned char *p
  28.     = (unsigned char *)(debug_screen_save + 3) + 2 * (cols * y + x);
  29.   while (*txt)
  30.     *p++ = *txt++,
  31.     *p++ = screen_attr;
  32. }
  33. /* ------------------------------------------------------------------------- */
  34. /* At position (X,Y) left-justify to width L this TXT in the debugger
  35.    screen.  */
  36.  
  37. inline void
  38. putl (int x, int y, int l, unsigned char *txt)
  39. {
  40.   unsigned char *p
  41.     = (unsigned char *)(debug_screen_save + 3) + 2 * (cols * y + x);
  42.   while (*txt && l > 0)
  43.     *p++ = *txt++,
  44.     *p++ = screen_attr,
  45.     l--;
  46.   while (l-- > 0)
  47.     *p++ = ' ',
  48.     *p++ = screen_attr;
  49. }
  50. /* ------------------------------------------------------------------------- */
  51. /* At position (X,Y) place CHAR.  Add DELTA to the screen address and repeat
  52.    COUNT times.  This is mainly used to draw frames.  */
  53.  
  54. inline void
  55. draw (int x, int y, unsigned char ch, int delta, int count)
  56. {
  57.   short unsigned *p
  58.     = (short unsigned *)(debug_screen_save + 3) + (cols * y + x);
  59.   short unsigned attrch = ((unsigned)screen_attr << 8) + ch;
  60.   while (count--)
  61.     *p = attrch,
  62.     p += delta;
  63. }
  64. /* ------------------------------------------------------------------------- */
  65. /* Highlight the text at (X,Y) length LEN by updating the attribute.  */
  66.  
  67. void
  68. highlight (int x, int y, int len)
  69. {
  70.   unsigned short *p
  71.     = (unsigned short *)(debug_screen_save + 4) + (cols * y + x);
  72.   while (len--)
  73.     *(unsigned char *)p = screen_attr,
  74.     p++;
  75. }
  76. /* ------------------------------------------------------------------------- */
  77. /* Draw a frame with its corners at (X1,Y1) and (X2,Y2).  */
  78.  
  79. void
  80. frame (int x1, int y1, int x2, int y2)
  81. {
  82.   draw (x1 + 1, y1, '─', 1,    x2 - x1 - 1);
  83.   draw (x1 + 1, y2, '─', 1,    x2 - x1 - 1);
  84.   draw (x1, y1 + 1, '│', cols, y2 - y1 - 1);
  85.   draw (x2, y1 + 1, '│', cols, y2 - y1 - 1);
  86.   put (x1, y1, "┌");
  87.   put (x2, y1, "┐");
  88.   put (x1, y2, "└");
  89.   put (x2, y2, "┘");
  90. }
  91. /* ------------------------------------------------------------------------- */
  92. /* Display (on the physical screen) some virtual SCREEN.  */
  93.  
  94. void
  95. put_screen (char *screen)
  96. {
  97.   int addr;
  98.  
  99.   switch (*screen++)
  100.     {
  101.     case 0:
  102.       /* Text screen, primary display.  */
  103.       ScreenSetCursor (screen[0], screen[1]);
  104.       ScreenUpdate (screen + 2);
  105.       break;
  106.     case 1:
  107.       /* Text screen, secondary display.  */
  108.       addr = (screen[0] * cols + screen[1]) * 2;
  109.       outportb (0x3b4, 0xf); outportb (0x3b5, addr & 0xff);
  110.       outportb (0x3b4, 0xe); outportb (0x3b5, addr >> 8);
  111.       movedata (_go32_my_ds (), (unsigned) (screen + 2),
  112.         _go32_conventional_mem_selector (), 0xb0000,
  113.         cols * rows * 2);
  114.       break;
  115.     }
  116. }
  117. /* ------------------------------------------------------------------------- */
  118. /* Return a (malloc'ed) virtual copy of the currently displayed screen.  */
  119.  
  120. char *
  121. get_screen (void)
  122. {
  123.   char *p;
  124.   int r, c, addr;
  125.  
  126.   p = xmalloc (cols * rows * 2 + 3);
  127.   if (dual_monitor_p)
  128.     {
  129.       /* Get the secondary display's contents.  */
  130.  
  131.       p[0] = 1;
  132.       addr = (outportb (0x3b4, 0xf), inportb (0x3b5))
  133.     + (outportb (0x3b4, 0xe), inportb (0x3b5) << 8);
  134.       p[1] = (addr / 2) / cols;
  135.       p[2] = (addr / 2) % cols;
  136.       movedata (_go32_conventional_mem_selector (), 0xb0000,
  137.         _go32_my_ds (), (unsigned) (p + 3),
  138.         cols * rows * 2);
  139.     }
  140.   else
  141.     {
  142.       /* Get the primary display's contents.  */
  143.       ScreenGetCursor (&r, &c);
  144.       p[0] = 0;
  145.       p[1] = r;
  146.       p[2] = c;
  147.       ScreenRetrieve (p + 3);
  148.     }
  149.   return p;
  150. }
  151. /* ------------------------------------------------------------------------- */
  152. /* Display the debugger screen (if not already displayed).  */
  153.  
  154. void
  155. debug_screen (void)
  156. {
  157.   if (!debug_screen_p)
  158.     {
  159.       if (!dual_monitor_p)
  160.     {
  161.       user_screen_save = get_screen ();
  162.       put_screen (debug_screen_save);
  163.     }
  164.       debug_screen_p = 1;
  165.     }
  166. }
  167. /* ------------------------------------------------------------------------- */
  168. /* Display the user screen (if not already displayed).  */
  169.  
  170. void
  171. user_screen (void)
  172. {
  173.   if (debug_screen_p)
  174.     {
  175.       if (!dual_monitor_p)
  176.     {
  177.       put_screen (user_screen_save);
  178.       free (user_screen_save);
  179.     }
  180.       debug_screen_p = 0;
  181.     }
  182. }
  183. /* ------------------------------------------------------------------------- */
  184. /* Reportedly, `sleep' & `gettimeofday' are buggy under Dpmi -- emulate.
  185.    Anyway, this means that we can make a keypress abort the sleeping.  */
  186.  
  187. static int
  188. mysleep (int secs)
  189. {
  190.   struct time now;
  191.   unsigned now100, then100;
  192.  
  193.   gettime (&now);
  194.   then100
  195.     = ((now.ti_hour * 60 + now.ti_min) * 60 + now.ti_sec + secs) * 100
  196.       + now.ti_hund;
  197.   do
  198.     {
  199.       gettime (&now);
  200.       now100 = ((now.ti_hour * 60 + now.ti_min) * 60 + now.ti_sec) * 100
  201.     + now.ti_hund;
  202.       if (now100 < 100 || kbhit ())
  203.     break; /* Day turnover or key pressed.  */
  204.     }
  205.   while (now100 < then100);
  206.   return 0;
  207. }
  208. /* ------------------------------------------------------------------------- */
  209. void
  210. message (CL_TYPE class, char *fmt, ...)
  211. {
  212.   char *save, *buf = alloca (cols);
  213.   unsigned char saveattr = screen_attr;
  214.   int len, y = rows / 2;
  215.  
  216.   vsprintf (buf, fmt, (&fmt) + 1);
  217.   len = strlen (buf);
  218.   save = debug_screen_save;
  219.   debug_screen_save = get_screen ();
  220.   switch (class)
  221.     {
  222.     case CL_Error:
  223.       screen_attr = screen_attr_error;
  224.       break;
  225.     default:
  226.       screen_attr = screen_attr_message;
  227.     }
  228.   frame (1, y - 1, cols - 2, y + 1);
  229.   draw (2, y, ' ', 1, cols - 4);
  230.   put ((cols - len) / 2, y, buf);
  231.   screen_attr = saveattr;
  232.   put_screen (debug_screen_save);
  233.   switch (class)
  234.     {
  235.     case CL_Info:
  236.       mysleep (2);
  237.       break;
  238.     case CL_Msg:
  239.     case CL_Error:
  240.       (void) getxkey ();
  241.     }
  242.   free (debug_screen_save);
  243.   debug_screen_save = save;
  244.   put_screen (debug_screen_save);
  245. }
  246. /* ------------------------------------------------------------------------- */
  247. /* Read a string from the keyboard to `read_buffer'.  The entry is started
  248.    with STARTTEXT.  This function uses an obscene amount of redrawing, but
  249.    who cares?  */
  250.  
  251. int
  252. read_string (char *starttext)
  253. {
  254.   char *save;
  255.   int key, esc = 0, pos, leave = 0, y = rows / 2;
  256.  
  257.   save = debug_screen_save;
  258.   debug_screen_save = get_screen ();
  259.   strcpy (read_buffer, starttext);
  260.   pos = strlen (read_buffer);
  261.  
  262.   frame (1, y - 1, cols - 2, y + 1);
  263.   do
  264.     {
  265.       draw (2, y, ' ', 1, cols - 4);
  266.       put (3, y, read_buffer);
  267.       pos = strlen (read_buffer);
  268.       put_screen (debug_screen_save);
  269.       ScreenSetCursor (y, 3 + pos);
  270.       key = getxkey ();
  271.       switch (key)
  272.     {
  273.     case K_Return:
  274.       leave = 1;
  275.       break;
  276.     case K_Escape:
  277.       leave = 1;
  278.       esc = 1;
  279.       read_buffer[0] = '\0';
  280.       break;
  281.     case K_BackSpace:
  282.       if (pos > 0)
  283.         read_buffer[--pos] = '\0';
  284.       break;
  285.     default:
  286.       if (key >= ' ' && key <= 0xff && pos <= cols - 7)
  287.         {
  288.           read_buffer[pos++] = key & 0xff;
  289.           read_buffer[pos] = '\0';
  290.         }
  291.     }
  292.     }
  293.   while (!leave);
  294.   free (debug_screen_save);
  295.   debug_screen_save = save;
  296.   put_screen (debug_screen_save);
  297.   return esc;
  298. }
  299. /* ------------------------------------------------------------------------- */
  300. void
  301. init_screen (void)
  302. {
  303.   if (dual_monitor_p)
  304.     rows = 25, cols = 80;
  305.   else
  306.     {
  307.       cols = ScreenCols ();
  308.       rows = ScreenRows ();
  309.       if (cols < 80 || rows < 25)
  310.     {
  311.       fprintf (stderr, "\n\
  312. Debugger error:\n\
  313. There are only %d columns and %d rows\n\
  314. in this display mode.\n\
  315. The debugger needs at least\n\
  316. 80 columns and 25 rows.\n",
  317.            cols, rows);
  318.       exit (1);
  319.     }
  320.     }
  321.   toplines = (rows / 2) + 4;
  322.   bottomlines = rows - 3 - toplines;
  323. }
  324. /* ------------------------------------------------------------------------- */
  325. /* Set the default colours.  */
  326.  
  327. void
  328. init_colours (void)
  329. {
  330.   switch (dual_monitor_p ? 7 : ScreenMode ())
  331.     {
  332.     case 2:
  333.     case 7:
  334.       /* Mono */
  335.       screen_attr_normal    = (A_black << 4) + A_grey;
  336.       screen_attr_source    = screen_attr_normal;
  337.       screen_attr_focus        = (A_grey  << 4) + A_black;
  338.       screen_attr_break        = (A_black << 4) + A_white;
  339.       screen_attr_message   = (A_grey  << 4) + A_white;
  340.       screen_attr_error        = (A_grey  << 4) + A_white;
  341.       screen_attr_menu      = (A_grey  << 4) + A_black;
  342.       screen_attr_menufocus = (A_black << 4) + A_white;
  343.       screen_attr_editframe = (A_grey  << 4) + A_black;
  344.       screen_attr_edittxt   = (A_grey  << 4) + A_black;
  345.       screen_attr_editfield = (A_grey  << 4) + A_black;
  346.       screen_attr_editfocus = (A_black << 4) + A_white;
  347.       break;
  348.     default:
  349.       /* Colour */
  350.       screen_attr_normal    = (A_cyan  << 4) + A_blue;
  351.       screen_attr_source    = (A_cyan  << 4) + A_black;
  352.       screen_attr_focus        = (A_blue  << 4) + A_white;
  353.       screen_attr_break        = (A_red   << 4) + A_white;
  354.       screen_attr_message   = (A_green << 4) + A_white;
  355.       screen_attr_error        = (A_red   << 4) + A_white;
  356.       screen_attr_menu      = (A_grey  << 4) + A_black;
  357.       screen_attr_menufocus = (A_black << 4) + A_white;
  358.       screen_attr_editframe = (A_blue  << 4) + A_grey;
  359.       screen_attr_edittxt   = (A_blue  << 4) + A_grey;
  360.       screen_attr_editfield = (A_blue  << 4) + A_white;
  361.       screen_attr_editfocus = (A_red   << 4) + A_white;
  362.     }
  363. }
  364. /* ------------------------------------------------------------------------- */
  365. void
  366. screen_mode (int rows)
  367. {
  368.   union REGS regs;
  369.   int font, cursor;
  370.  
  371.   switch (rows)
  372.     {
  373.     case 43:
  374.     case 50:
  375.       font = 0x1112;
  376.       cursor = 0x0607;
  377.       break;
  378.     case 25:
  379.     case 28:
  380.     default:
  381.       font = 0x1111;
  382.       cursor = 0x0607;
  383.     }
  384.   regs.w.ax = 0x0003;
  385.   int86 (0x10, ®s, ®s);
  386.   regs.w.ax = font;
  387.   regs.h.bl = 0;
  388.   int86 (0x10, ®s, ®s);
  389.   regs.w.ax = 0x1200;
  390.   regs.h.bl = 32;
  391.   int86 (0x10, ®s, ®s);
  392.   if (rows == 25)
  393.     {
  394.       regs.w.ax = 0x0003;
  395.       int86 (0x10, ®s, ®s);
  396.     }
  397.   regs.w.ax = 0x0100;
  398.   regs.w.cx = cursor;
  399.   int86 (0x10, ®s, ®s);
  400. }
  401. /* ------------------------------------------------------------------------- */
  402. int
  403. menu (char *title, MENU_ITEM *m, int *focus)
  404. {
  405.   char *save;
  406.   int width, i, count, state;
  407.   unsigned char saveattr = screen_attr;
  408.   int x0, y0;
  409.  
  410.   save = debug_screen_save;
  411.   debug_screen_save = get_screen ();
  412.  
  413.   width = title ? strlen (title) : 0;
  414.   for (count = 0; m[count].txt; count++)
  415.     {
  416.       i = strlen (m[count].txt);
  417.       if (i > width) width = i;
  418.     }
  419.   width += 2;
  420.   x0 = cols / 2 - width / 2;
  421.   y0 = rows / 2 - count / 2;
  422.  
  423.   screen_attr = screen_attr_menu;
  424.   frame (x0 - 1, y0 - 1, x0 + width, y0 + count);
  425.   if (title)
  426.     put (cols / 2 - strlen (title) / 2, y0 - 1, title);
  427.  
  428.   state = 0;
  429.   while (state == 0)
  430.     {
  431.       for (i = 0; i < count; i++)
  432.     {
  433.       screen_attr
  434.         = (i == *focus) ? screen_attr_menufocus : screen_attr_menu;
  435.       putl (x0 + 1, y0 + i, width - 1, m[i].txt);
  436.       put (x0, y0 + i, " ");
  437.     }
  438.       put_screen (debug_screen_save);
  439.       switch (getxkey ())
  440.     {
  441.     case K_Escape:
  442.       state = 1;
  443.       break;
  444.     case K_Return:
  445.       state = 2;
  446.       break;
  447.     case K_Up:
  448.     case K_EUp:
  449.     case K_Left:
  450.     case K_ELeft:
  451.       if (*focus) (*focus)--;
  452.       break;
  453.     case K_Down:
  454.     case K_EDown:
  455.     case K_Right:
  456.     case K_ERight:
  457.       if (*focus < count - 1) (*focus)++;
  458.       break;
  459.     case K_Home:
  460.     case K_EHome:
  461.       *focus = 0;
  462.       break;
  463.     case K_End:
  464.     case K_EEnd:
  465.       *focus = count - 1;
  466.       break;
  467.     }
  468.     }
  469.   screen_attr = saveattr;
  470.   free (debug_screen_save);
  471.   debug_screen_save = save;
  472.   put_screen (debug_screen_save);
  473.   if (state == 2)
  474.     {
  475.       if (m[*focus].handler)
  476.     m[*focus].handler (m[*focus].info);
  477.       return *focus;
  478.     }
  479.   else
  480.     return -1;
  481. }
  482. /* ------------------------------------------------------------------------- */
  483. int
  484. edit (char *title, EDIT_ITEM *fields, int focus)
  485. {
  486.   char *save;
  487.   unsigned char saveattr = screen_attr;
  488.   int i, leave, esc = 0, count, key = 0, width, *length;
  489.   int x0, y0, x, y, len;
  490.   char *data;
  491.  
  492.   save = debug_screen_save;
  493.   debug_screen_save = get_screen ();
  494.  
  495.   for (count = 0; fields[count].txt; count++)
  496.     /* Nothing.  */;
  497.   x0 = 3;
  498.   y0 = rows / 2 - count / 2;
  499.   screen_attr = screen_attr_editframe;
  500.   length = alloca (count * sizeof (int));
  501.   frame (x0 - 1, y0 - 1, cols - x0, y0 + count);
  502.   if (title)
  503.     put (cols / 2 - strlen (title) / 2, y0 - 1, title);
  504.  
  505.   screen_attr = screen_attr_edittxt;
  506.   for (i = 0; i < count; i++)
  507.     {
  508.       put (x0, y0 + i, " ");
  509.       put (x0 + 1, y0 + i, fields[i].txt);
  510.       length[i] = strlen (fields[i].txt);
  511.     }
  512.  
  513.   leave = 0;
  514.   while (!leave)
  515.     {
  516.       for (i = 0; i < count; i++)
  517.     {
  518.       screen_attr = screen_attr_editfield;
  519.       width = cols - 8 - length[i];
  520.       x = x0 + length[i] + 1, y = y0 + i;
  521.       put (x - 1, y, " ");
  522.       putl (x, y, 1 + width, fields[i].data);
  523.     }
  524.       data = fields[focus].data;
  525.       screen_attr = screen_attr_editfocus;
  526.       width = cols - 8 - length[focus];
  527.       x = x0 + length[focus] + 1, y = y0 + focus;
  528.       put (x - 1, y, " ");
  529.       len = strlen (data);
  530.       while (!leave)
  531.     {
  532.       putl (x, y, 1 + width, data);
  533.       put_screen (debug_screen_save);
  534.       ScreenSetCursor (y, x + len);
  535.       switch ((key = getxkey ()))
  536.         {
  537.         case K_Left:
  538.         case K_ELeft:
  539.         case K_BackSpace:
  540.           if (len)
  541.         data[--len] = 0;
  542.           break;
  543.         case ' ' ... '~':
  544.           if (len < width)
  545.         data[len++] = key, data[len] = 0;
  546.           break;
  547.         default:
  548.           leave = 1;
  549.           break;
  550.         }
  551.     }
  552.       leave = 0;
  553.       switch (key)
  554.     {
  555.     case K_Escape:
  556.       leave = esc = 1;
  557.       break;
  558.     case K_Up:
  559.     case K_EUp:
  560.       focus = focus ? focus - 1 : count - 1;
  561.       break;
  562.     case K_Return:
  563.       leave = (focus == count - 1);
  564.       /* Fall through.  */
  565.     case K_Down:
  566.     case K_EDown:
  567.       focus = (focus == count - 1) ? 0 : focus + 1;
  568.       break;
  569.     case K_Home:
  570.     case K_EHome:
  571.       focus = 0;
  572.       break;
  573.     case K_End:
  574.     case K_EEnd:
  575.       focus = count - 1;
  576.       break;
  577.     }
  578.     }
  579.  
  580.   screen_attr = saveattr;
  581.   free (debug_screen_save);
  582.   debug_screen_save = save;
  583.   put_screen (debug_screen_save);
  584.   return !esc;
  585. }
  586. /* ------------------------------------------------------------------------- */
  587. static void
  588. attr2text (char *buf, unsigned char attr)
  589. {
  590.   sprintf (buf, "%s on %s%s", 
  591.        colours[attr & 15], colours[(attr >> 4) & 7], \
  592.        (attr & 128) ? ", blinking" : "");
  593.   buf[0] = toupper (buf[0]);
  594. }
  595.  
  596. static int
  597. text2attr (char *s)
  598. {
  599.   char *s1, *s2, *cs;
  600.   int f, b, l;
  601.  
  602.   l = strlen (s) + 1;
  603.   s = strcpy (alloca (l), s);
  604.   s1 = alloca (l);
  605.   s2 = alloca (l);
  606.   if ((cs = strchr (s, ',')))
  607.     if (stricmp (cs, ", blinking"))
  608.       return -1;
  609.     else
  610.       *cs = 0;
  611.   if (sscanf (s, "%s on %s", s1, s2) == 2)
  612.     {
  613.       for (f = 0; f < 16; f++)
  614.     if (stricmp (colours[f], s1) == 0)
  615.       break;
  616.       for (b = 0; b < 8; b++)
  617.     if (stricmp (colours[b], s2) == 0)
  618.       break;
  619.       if (f < 16 && b < 8)
  620.     return (cs ? 128 : 0) | (b << 4) | f;
  621.     }
  622.   return -1;
  623. }
  624.  
  625. void
  626. edit_colours (int dummy)
  627. {
  628.   int i, focus;
  629.   static EDIT_ITEM form[] = {
  630.     {"Normal ..............: ", 0},
  631.     {"Source Code .........: ", 0},
  632.     {"Foci ................: ", 0},
  633.     {"Breakpoints .........: ", 0},
  634.     {"Messages ............: ", 0},
  635.     {"Errors ..............: ", 0},
  636.     {"Menus ...............: ", 0},
  637.     {"Menu Foci ...........: ", 0},
  638.     {"Form Frames .........: ", 0},
  639.     {"Form Legends ........: ", 0},
  640.     {"Form Fields .........: ", 0},
  641.     {"Form Foci ...........: ", 0},
  642.     {0, 0}};
  643.  
  644.   for (i = 0; form[i].txt; i++) form[i].data = alloca (cols);
  645.   attr2text (form[ 0].data, screen_attr_normal);
  646.   attr2text (form[ 1].data, screen_attr_source);
  647.   attr2text (form[ 2].data, screen_attr_focus);
  648.   attr2text (form[ 3].data, screen_attr_break);
  649.   attr2text (form[ 4].data, screen_attr_message);
  650.   attr2text (form[ 5].data, screen_attr_error);
  651.   attr2text (form[ 6].data, screen_attr_menu);
  652.   attr2text (form[ 7].data, screen_attr_menufocus);
  653.   attr2text (form[ 8].data, screen_attr_editframe);
  654.   attr2text (form[ 9].data, screen_attr_edittxt);
  655.   attr2text (form[10].data, screen_attr_editfield);
  656.   attr2text (form[11].data, screen_attr_editfocus);
  657.   focus = 0;
  658.   while (edit ("Edit Colour Scheme", form, focus))
  659.     {
  660.       for (focus = 0; form[focus].txt; focus++)
  661.     if (text2attr (form[focus].data) == -1)
  662.       break;
  663.       if (form[focus].txt == 0)
  664.     {
  665.       screen_attr_normal    = text2attr (form[ 0].data);      
  666.       screen_attr_source    = text2attr (form[ 1].data);
  667.       screen_attr_focus     = text2attr (form[ 2].data);
  668.       screen_attr_break     = text2attr (form[ 3].data);
  669.       screen_attr_message   = text2attr (form[ 4].data);
  670.       screen_attr_error     = text2attr (form[ 5].data);
  671.       screen_attr_menu      = text2attr (form[ 6].data);
  672.       screen_attr_menufocus = text2attr (form[ 7].data);
  673.       screen_attr_editframe = text2attr (form[ 8].data);
  674.       screen_attr_edittxt   = text2attr (form[ 9].data);
  675.       screen_attr_editfield = text2attr (form[10].data);
  676.       screen_attr_editfocus = text2attr (form[11].data);
  677.       return;
  678.     }
  679.     }
  680. }
  681. /* ------------------------------------------------------------------------- */
  682.