home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / alib / d1xx / d114 / vt100.lha / Vt100 / window.c < prev    next >
C/C++ Source or Header  |  1987-11-22  |  17KB  |  649 lines

  1. /****************************************************
  2.  * vt100 emulator - window/keyboard support
  3.  *
  4.  *    v2.7 870825 ACS - Provide an info/status window rather than using
  5.  *              req().  Better error handling.
  6.  *    v2.6 870227 DBW - bug fixes for all the stuff in v2.5
  7.  *    v2.5 870214 DBW - more additions (see readme file)
  8.  *    v2.4 861214 DBW - lots of fixes/additions (see readme file)
  9.  *    v2.3 861101 DBW - minor bug fixes
  10.  *    v2.2 861012 DBW - more of the same
  11.  *    v2.1 860915 DBW - new features (see README)
  12.  *         860823 DBW - Integrated and rewrote lots of code
  13.  *    v2.0 860809 DBW - Major rewrite
  14.  *    v1.1 860720 DBW    - Switches, 80 cols, colors, bug fixes
  15.  *    v1.0 860712 DBW    - First version released
  16.  *
  17.  ****************************************************/
  18.  
  19. #include "vt100.h"
  20.  
  21. /* keyboard definitions for toasc() */
  22. static char keys[75] = {
  23.     '`','1','2','3','4','5','6','7','8','9','0','-' ,
  24.     '=','\\', 0, '0','q','w','e','r','t','y','u','i','o' ,
  25.     'p','[',']', 0, '1','2','3','a','s','d','f','g','h' ,
  26.     'j','k','l',';','\'', 0, 0, '4','5','6', 0, 'z','x','c','v',
  27.     'b','n','m',44,'.','/', 0, '.','7','8','9',' ',8,
  28.     '\t',13,13,27,127,0,0,0,'-' } ;
  29.     
  30. /* For InfoMsg...may be changed by a NEWSIZE msg in vt100.c */
  31. int reqminx,    /* Min value for x in reqwindow (pixels) */
  32.     reqmaxx,    /* Max value for x in reqwindow (pixels) */
  33.     reqmaxlen,    /* Max # chars in reqwindow */
  34.     reqminy,    /* Min value for y in reqwindow (scan lines) */    
  35.     reqmaxy,    /* Max value for y in reqwindow (scan lines) */
  36.     reqfudge;    /* Clear space between border and start of 1st char */
  37. int reqy;    /* Current pixel location in reqwindow */
  38.  
  39. void ReqNewSize(), OpenReqWindow();
  40.  
  41. /***************************************************
  42.  *  function to swap the use of backspace and delete
  43.  ***************************************************/
  44.  
  45. void swap_bs_del()
  46.     {
  47.     if (p_bs_del)   p_bs_del = 0;
  48.     else        p_bs_del = 1;
  49.  
  50.     keys[0x41] =    p_bs_del ? 127 : 8;
  51.     keys[0x46] =    p_bs_del ? 8 : 127;
  52.     }
  53.  
  54. /*************************************************
  55.  *  function to get file name (via a requestor)
  56.  *************************************************/
  57. void req(prmpt,name,getinp)
  58. char *prmpt,*name;
  59. int  getinp;
  60.     {
  61.     ULONG class;
  62.     USHORT position, RemoveGadget();
  63.     unsigned int code, qual;
  64.     int  lprmpt, lname;
  65.     struct IntuiMessage *Msg;
  66.  
  67.     if(reqwinup == 0)
  68.     OpenReqWindow();
  69.     
  70.     if(!getinp) {
  71.         InfoMsg2Line(prmpt, name);
  72.         return;
  73.     }
  74.  
  75.     lprmpt = strlen(prmpt);
  76.     lname = strlen(name);
  77.  
  78.     /* Don't use strings longer than what we've provided space for. */
  79.     if(lprmpt > (MAXGADSTR-1)) {
  80.     emits("Prompt too long - truncated.\n");
  81.     lprmpt = MAXGADSTR-1;
  82.     }
  83.     if(lname > (MAXGADSTR-1)) {
  84.     emits("Name too long - truncated.\n");
  85.     lname = MAXGADSTR-1;
  86.     }
  87.  
  88.     if (Msg = (struct IntuiMessage *)GetMsg(reqwindow->UserPort)) {
  89.     class = Msg->Class;
  90.     ReplyMsg(Msg);
  91.     if(class == REQCLEAR)
  92.         numreqs = 0;
  93.     if(class == NEWSIZE)
  94.         ReqNewSize(reqwindow->Height, reqwindow->Width);
  95.     }
  96.  
  97.     /* Make sure the prompt gets updated */
  98.     if (numreqs == 1 && strcmp(Prompt,prmpt) != 0) {
  99.     EndRequest(&myrequest,reqwindow);
  100.     do {
  101.         Wait(1L << reqwindow->UserPort->mp_SigBit);
  102.         while (Msg = (struct IntuiMessage *)GetMsg(reqwindow->UserPort)) {
  103.             class = Msg->Class;
  104.             ReplyMsg(Msg);
  105.             if(class == NEWSIZE)
  106.                 ReqNewSize(reqwindow->Height, reqwindow->Width);
  107.         }
  108.     } while (class != REQCLEAR);
  109.     numreqs = 0;
  110.     }
  111.  
  112.     /* copy in a prompt and a default */
  113.     strncpy(Prompt,prmpt,lprmpt); Prompt[lprmpt+1] = '\0';
  114.     strncpy(InpBuf,name,lname); InpBuf[lname+1] = '\0';
  115.  
  116.     if (numreqs == 1) {        /* If there is a requester... reuse it */
  117.         RefreshGadgets(&mystrgad, reqwindow, &myrequest);
  118.         Delay(2L);
  119.     }
  120.     else {            /* otherwise create it */
  121.     while(numreqs != 1) {
  122.             if (Request(&myrequest, reqwindow) == 0) {
  123.         emits("ERROR - CAN'T CREATE REQUESTOR FOR:\n");
  124.         emits(Prompt); emit('\n'); emits(InpBuf); emit('\n');
  125.         return;
  126.         }
  127.         else numreqs = 1;
  128.  
  129.         do {
  130.         Wait(1L << reqwindow->UserPort->mp_SigBit);
  131.         while (Msg = (struct IntuiMessage *)GetMsg(reqwindow->UserPort)) {
  132.             class = Msg->Class;
  133.             ReplyMsg(Msg);
  134.             if(class == REQCLEAR)
  135.             numreqs = 0;
  136.             if(class == NEWSIZE)
  137.             ReqNewSize(reqwindow->Height, reqwindow->Width);
  138.         }
  139.         } while (class != REQSET);
  140.     } /* end while numreqs != 0 */
  141.     } /* end else */
  142.  
  143.     /* if we don't want input, we're done */
  144.     if (getinp == 0 || numreqs == 0) return;
  145.  
  146.     if((reqwindow->Flags & WINDOWACTIVE) != WINDOWACTIVE) {
  147.         WindowToFront(reqwindow);
  148.     ActivateWindow(reqwindow);
  149.     do {
  150.         Wait(1L << reqwindow->UserPort->mp_SigBit);
  151.         while(Msg = (struct IntuiMessage *)GetMsg(reqwindow->UserPort)) {
  152.         class = Msg->Class;
  153.         ReplyMsg(Msg);
  154.         if(class == NEWSIZE)
  155.             ReqNewSize(reqwindow->Height, reqwindow->Width);
  156.         }
  157.     } while (class != ACTIVEWINDOW);
  158.     }
  159.     
  160.     /* here is where we pre-select the gadget   */
  161.     if (!ActivateGadget(&mystrgad,reqwindow,&myrequest)) {
  162.  
  163.     /* wait for his/her hands to get off the keyboard (Amiga-key) */
  164.     Delay(20L);
  165.     while (Msg = (struct IntuiMessage *)GetMsg(reqwindow->UserPort)) {
  166.         ReplyMsg(Msg);
  167.         if(class == NEWSIZE)
  168.         ReqNewSize(reqwindow->Height, reqwindow->Width);
  169.     }
  170.  
  171.     /* try once more before giving up... */
  172.     ActivateGadget(&mystrgad,reqwindow,&myrequest);
  173.     }
  174.  
  175.     /* wait for input to show up */
  176.     while (1) {
  177.     if ((NewMessage = (struct IntuiMessage *)
  178.         GetMsg(reqwindow->UserPort)) == FALSE) {
  179.         Wait(1L<<reqwindow->UserPort->mp_SigBit);
  180.         continue;
  181.         }
  182.     class = NewMessage->Class;
  183.     ReplyMsg(NewMessage);
  184.  
  185.     /* the requestor got terminated... yea!! */
  186.     if (class == REQCLEAR) break;
  187.  
  188.     if(class == NEWSIZE)
  189.         ReqNewSize(reqwindow->Height, reqwindow->Width);
  190.         
  191.     /* maybe this is a menu item to handle */
  192. /*    if (class == MENUPICK) handle_menupick(class,code); */
  193.     }
  194.  
  195.     /* all done, so return the result */
  196.     numreqs = 0;
  197.     strcpy(name,InpBuf);
  198.     }
  199.  
  200. /*************************************************
  201. *  function to print a string
  202. *************************************************/
  203. void emits(string)
  204. char string[];
  205.     {
  206.     int i;
  207.     char c;
  208.  
  209.     i=0;
  210.     while (string[i] != 0)
  211.     {
  212.     c=string[i];
  213.     if (c == 10) emit(13);
  214.     emit(c);
  215.     i += 1;
  216.     }
  217.     }
  218.  
  219. /*************************************************
  220. *  function to output ascii chars to window
  221. *************************************************/
  222. void emit(c)
  223. char c;
  224.     {
  225.     static char wrap_flag = 0;    /* are we at column 80? */
  226.  
  227.     c &= 0x7F;
  228.     switch( c )
  229.     {
  230.     case '\t':
  231.     x += 64 - ((x-MINX) % 64);
  232.     break;
  233.  
  234.     case 10:  /* lf */
  235.     y += 8;
  236.     break;
  237.  
  238.     case 13:  /* cr */
  239.     x = MINX;
  240.     break;
  241.  
  242.     case 8:   /* backspace */
  243.     x -= 8;
  244.     if (x < MINX) x = MINX;
  245.     break;
  246.  
  247.     case 12:     /* page */
  248.     x = MINX;
  249.     y = MINY;
  250.     SetAPen(mywindow->RPort,0L);
  251.     RectFill(mywindow->RPort,(long)MINX,
  252.         (long)(MINY-7),(long)(MAXX+7),(long)(MAXY+1));
  253.     SetAPen(mywindow->RPort,1L);
  254.     break;
  255.  
  256.     case 7:     /* bell */
  257.     if (p_volume == 0) DisplayBeep(NULL);
  258.     else {
  259.         BeginIO(&Audio_Request);
  260.         WaitIO(&Audio_Request);
  261.         }
  262.     break;
  263.  
  264.     default:
  265.     if (c < ' ' || c > '~') break;
  266.     if (p_wrap && wrap_flag && x >= MAXX) {
  267.         x = MINX;
  268.         y += 8;
  269.         if (y > MAXY) {
  270.         y = MAXY;
  271.         ScrollRaster(mywindow->RPort,0L,8L,(long)MINX,
  272.             (long)(MINY-6),(long)(MAXX+7),(long)(MAXY+1));
  273.         }
  274.         }
  275.     Move(mywindow->RPort,(long)x,(long)y);
  276.  
  277.     if (curmode&FSF_BOLD) {
  278.         if (p_depth > 1) {
  279.         SetAPen(mywindow->RPort,(long)(2+(1^p_screen)));
  280.         SetSoftStyle(mywindow->RPort,(long)curmode,253L);
  281.         }
  282.         else SetSoftStyle(mywindow->RPort,(long)curmode,255L);
  283.         }
  284.     else SetSoftStyle(mywindow->RPort,(long)curmode,255L);
  285.  
  286.     if (curmode&FSF_REVERSE) {
  287.         SetDrMd(mywindow->RPort,(long)(JAM2+INVERSVID));
  288.         Text(mywindow->RPort,&c,1L);
  289.         SetDrMd(mywindow->RPort,(long)JAM2);
  290.         }
  291.     else Text(mywindow->RPort,&c,1L);
  292.  
  293.     if (curmode&FSF_BOLD) SetAPen(mywindow->RPort,1L);
  294.     x += 8;
  295.     } /* end of switch */
  296.  
  297.     if (y > MAXY) {
  298.     y = MAXY;
  299.     x = MINX;
  300.     ScrollRaster(mywindow->RPort,0L,8L,(long)MINX,
  301.         (long)(MINY-6),(long)(MAXX+7),(long)(MAXY+1));
  302.     }
  303.     if (x > MAXX) {
  304.     wrap_flag = 1;
  305.     x = MAXX;
  306.     }
  307.     else wrap_flag = 0;
  308.     }
  309.  
  310. /*************************************************
  311. *  function to output ascii chars to window (batched)
  312. *************************************************/
  313. void emitbatch(la,lookahead)
  314. int la;
  315. char *lookahead;
  316.     {
  317.     int i;
  318.  
  319.     Move(mywindow->RPort,(long)x,(long)y);
  320.     i = x / 8;
  321.     if (i+la >= maxcol) {
  322.     if (p_wrap == 0) la = maxcol - i;
  323.     else {
  324.         lookahead[la] = 0;
  325.         emits(lookahead);
  326.         return;
  327.         }
  328.     }
  329.     if (curmode&FSF_BOLD) {
  330.     if (p_depth > 1) {
  331.         SetAPen(mywindow->RPort,(long)(2+(1^p_screen)));
  332.         SetSoftStyle(mywindow->RPort,(long)curmode,253L);
  333.         }
  334.     else SetSoftStyle(mywindow->RPort,(long)curmode,255L);
  335.     }
  336.     else SetSoftStyle(mywindow->RPort,(long)curmode,255L);
  337.  
  338.     if (curmode&FSF_REVERSE) {
  339.     SetDrMd(mywindow->RPort,(long)(JAM2+INVERSVID));
  340.     Text(mywindow->RPort,lookahead,(long)la);
  341.     SetDrMd(mywindow->RPort,(long)JAM2);
  342.     }
  343.     else Text(mywindow->RPort,lookahead,(long)la);
  344.     if (curmode&FSF_BOLD) SetAPen(mywindow->RPort,1L);
  345.     x += (8 * la);
  346.     }
  347.  
  348. /******************************
  349. * Manipulate cursor
  350. ******************************/
  351. void cursorflip()
  352.     {
  353.     SetDrMd(mywindow->RPort,(long)COMPLEMENT);
  354.     SetAPen(mywindow->RPort,3L);
  355.     RectFill(mywindow->RPort,
  356.     (long)(x-1),(long)(y-6),(long)(x+8),(long)(y+1));
  357.     SetAPen(mywindow->RPort,1L);
  358.     SetDrMd(mywindow->RPort,(long)JAM2);
  359.     }
  360.  
  361. /************************************************
  362. *  function to take raw key data and convert it
  363. *  into ascii chars
  364. **************************************************/
  365. int toasc(code,qual,local)
  366. unsigned int code,qual;
  367. int local;
  368.     {
  369.     unsigned int ctrl,shift,capsl,amiga,alt;
  370.     char c = 0, keypad = 0;
  371.     char *ptr;
  372.  
  373.     ctrl    = qual & IEQUALIFIER_CONTROL;
  374.     capsl   = qual & IEQUALIFIER_CAPSLOCK;
  375.     amiga   = qual & (IEQUALIFIER_LCOMMAND | IEQUALIFIER_RCOMMAND);
  376.     shift   = qual & (IEQUALIFIER_LSHIFT   | IEQUALIFIER_RSHIFT);
  377.     alt        = qual & (IEQUALIFIER_LALT     | IEQUALIFIER_RALT);
  378.  
  379.     switch ( code )
  380.     {
  381.     case 98:
  382.     case 226:
  383.     case 99:
  384.     case 227:
  385.     case 96:
  386.     case 97:
  387.     case 224:
  388.     case 225:
  389.     case 100:
  390.     case 101:
  391.     case 228:
  392.     case 229:
  393.     case 102:
  394.     case 103:
  395.     case 230:
  396.     case 231:   c = 0; break; /* ctrl, shift, capsl, amiga, or alt */
  397.  
  398.     case 0x50:
  399.     case 0x51:
  400.     case 0x52:
  401.     case 0x53:
  402.     case 0x54:
  403.     case 0x55:
  404.     case 0x56:
  405.     case 0x57:
  406.     case 0x58:
  407.     case 0x59:  c = 0;
  408.             if (shift)    ptr = p_F[code - 0x50];
  409.             else    ptr = p_f[code - 0x50];
  410.             if (!script_on && *ptr == p_keyscript)
  411.                 script_start(++ptr);
  412.             else    sendstring(ptr);
  413.             break;
  414.     case 0x0f: c = (p_keyapp) ? 'p' : '0'; keypad = TRUE; break;
  415.     case 0x1d: c = (p_keyapp) ? 'q' : '1'; keypad = TRUE; break;
  416.     case 0x1e: c = (p_keyapp) ? 'r' : '2'; keypad = TRUE; break;
  417.     case 0x1f: c = (p_keyapp) ? 's' : '3'; keypad = TRUE; break;
  418.     case 0x2d: c = (p_keyapp) ? 't' : '4'; keypad = TRUE; break;
  419.     case 0x2e: c = (p_keyapp) ? 'u' : '5'; keypad = TRUE; break;
  420.     case 0x2f: c = (p_keyapp) ? 'v' : '6'; keypad = TRUE; break;
  421.     case 0x3d: c = (p_keyapp) ? 'w' : '7'; keypad = TRUE; break;
  422.     case 0x3e: c = (p_keyapp) ? 'x' : '8'; keypad = TRUE; break;
  423.     case 0x3f: c = (p_keyapp) ? 'y' : '9'; keypad = TRUE; break;
  424.     case 0x43: c = (p_keyapp) ? 'M' : 13 ; keypad = TRUE; break;
  425.     case 0x4a: c = (p_keyapp) ? 'l' : '-'; keypad = TRUE; break;
  426.     case 0x5f: sendstring("\033Om") ;break;
  427.     case 0x3c: c = (p_keyapp) ? 'n' : '.'; keypad = TRUE; break;
  428.     case 0x4c:
  429.     case 0x4d:
  430.     case 0x4e:
  431.     case 0x4f: sendchar(27);            /* cursor keys */
  432.            if (p_curapp) sendchar('O');
  433.            else sendchar('[');
  434.            sendchar(code - 11);
  435.            break;
  436.  
  437.     default:
  438.     if (code < 75) c = keys[code];
  439.     else c = 0;
  440.     }
  441.  
  442.     if (keypad) {
  443.     if (p_keyapp) sendstring("\033O");
  444.     sendchar(c);
  445.     return(0);
  446.     }
  447.  
  448.     /* add modifiers to the keys */
  449.  
  450.     if (c != 0) {
  451.     if (shift) {
  452.         if ((c <= 'z') && (c >= 'a')) c -= 32;
  453.         else
  454.         switch( c ) {
  455.         case '[':  c = '{'; break;
  456.         case ']':  c = '}'; break;
  457.         case '\\': c = '|'; break;
  458.         case '\'': c = '"'; break;
  459.         case ';':  c = ':'; break;
  460.         case '/':  c = '?'; break;
  461.         case '.':  c = '>'; break;
  462.         case ',':  c = '<'; break;
  463.         case '`':  c = '~'; break;
  464.         case '=':  c = '+'; break;
  465.         case '-':  c = '_'; break;
  466.         case '1':  c = '!'; break;
  467.         case '2':  c = '@'; break;
  468.         case '3':  c = '#'; break;
  469.         case '4':  c = '$'; break;
  470.         case '5':  c = '%'; break;
  471.         case '6':  c = '^'; break;
  472.         case '7':  c = '&'; break;
  473.         case '8':  c = '*'; break;
  474.         case '9':  c = '('; break;
  475.         case '0':  c = ')'; break;
  476.         default:            break;
  477.         }
  478.         }
  479.     else if (capsl && (c <= 'z') && (c >= 'a')) c -= 32;
  480.     }
  481.     if (ctrl) {
  482.     if (c > '`' && c <= 127) c -= 96;
  483.     else if (c > '@' && c <= '_') c -= 64;
  484.     else if (c == '6') c = 30;
  485.     else if (c == '-' || c == '?') c = 31;
  486.     }
  487.     if (ctrl && (c == '@' || c == '2' || c == ' ')) {
  488.     if (!local) sendchar(alt?128:0);
  489.     c = 0;
  490.     }
  491.     else if (c != 0 && (!local)) sendchar(alt?c+128:c);
  492.     return((int)c);
  493.     }
  494.  
  495. void
  496. KillReq()
  497. {
  498.     struct IntuiMessage *Msg;
  499.     ULONG class;
  500.     
  501.     if(numreqs != 0) {
  502.     EndRequest(&myrequest,reqwindow);
  503.     do {
  504.         Wait(1L << reqwindow->UserPort->mp_SigBit);
  505.         while (Msg = (struct IntuiMessage *)GetMsg(reqwindow->UserPort)) {
  506.             class = Msg->Class;
  507.             ReplyMsg(Msg);
  508.         }
  509.     } while (class != REQCLEAR);
  510.     numreqs = 0;
  511.     }
  512.  
  513.     if(reqwinup) {
  514.         /* First, clear out all pending messages */
  515.     while (Msg = (struct IntuiMessage *)GetMsg(reqwindow->UserPort)) {
  516.         class = Msg->Class;
  517.         ReplyMsg(Msg);
  518.     }
  519.     NewReqWindow.LeftEdge = reqwindow->LeftEdge;    /* Remember ...      */
  520.     NewReqWindow.TopEdge = reqwindow->TopEdge;    /* ...where...      */
  521.     NewReqWindow.Width = reqwindow->Width;        /* ...the user... */
  522.     NewReqWindow.Height = reqwindow->Height;    /* ...put it.      */
  523.     CloseWindow(reqwindow); /* Now we can close the window */
  524.     reqwinup = 0;
  525.     }
  526. }
  527.  
  528. void
  529. InfoMsg2Line(header, msg)
  530. char *header, *msg;
  531. {
  532.     ScrollInfoMsg(1);
  533.     InfoMsgNoScroll(header);
  534.     ScrollInfoMsg(1);
  535.     InfoMsgNoScroll(msg);
  536.     ScrollInfoMsg(1);
  537. }
  538.  
  539. void
  540. InfoMsg1Line(msg)
  541. char *msg;
  542. {
  543.     ScrollInfoMsg(1);
  544.     InfoMsgNoScroll(msg);
  545.     ScrollInfoMsg(1);
  546. }
  547.  
  548. /*   Output the specified data to the "info" window  */
  549. void
  550. ScrollInfoMsg(lines)
  551. int lines;
  552. {
  553. /*  ULONG class;
  554.     struct IntuiMessage *Msg; */
  555.     int pixels = lines << 3;
  556.     
  557.     if(!reqwinup)
  558.     OpenReqWindow();
  559.  
  560. /*  if(Msg=(struct IntuiMessage *)GetMsg(reqwindow->UserPort)) {
  561.     class = Msg->Class;
  562.     ReplyMsg(Msg);
  563.     if(class == NEWSIZE)
  564.         ReqNewSize(reqwindow->Height, reqwindow->Width);
  565.     } */
  566.  
  567.     if ( (reqy += pixels) > reqmaxy) {
  568.     reqy = reqmaxy;
  569.     if(pixels > 0)
  570.         ScrollRaster(reqwindow->RPort, 0L, (LONG)pixels,
  571.         (LONG)reqminx,
  572.         (LONG)reqminy,
  573.         (LONG)(reqmaxx+7),
  574.         (LONG)(reqmaxy+7));
  575. /* Was:        (LONG)(wp->Width - wp->BorderRight),
  576.         (LONG)(wp->Height - wp->BorderBottom)); */
  577.     }
  578. }
  579.  
  580. void
  581. InfoMsgNoScroll(msg)
  582. char *msg;
  583. {
  584.     LONG msglen = strlen(msg);
  585.  
  586.     if(msglen > reqmaxlen)
  587.     msglen = reqmaxlen;
  588.  
  589.     ScrollInfoMsg(0);    /* Ensure that the msg willbe visible */
  590.  
  591.     /*  Position the pen at the baseline of the character (7 scan lines
  592.     ** into it). */
  593.     Move(reqwindow->RPort, (LONG)reqminx, (LONG)(reqy+6));
  594.     Text(reqwindow->RPort, msg, msglen);
  595. }
  596.  
  597. void
  598. ReqNewSize(height, width)
  599. SHORT height, width;
  600. {
  601.     register struct Window *wp = reqwindow;
  602.     int oldmaxy;
  603.  
  604.     /*   Compute min and max for x and y coordinates.  Note that for y the
  605.     ** value is for the *top* of the character, not the baseline.  Text()
  606.     ** uses a baseline value and so it must be adjusted prior to the call
  607.     ** (characters are assumed to occupy an 8x8 matrix with the baseline at
  608.     ** 7).  When computing the max values, calculate them so that we will
  609.     ** sufficient room for an entire character. */
  610.     oldmaxy = reqmaxy;
  611.     reqminy = wp->BorderTop + reqfudge;
  612.     reqmaxy = (((height - reqminy - wp->BorderBottom) >> 3) << 3)
  613.         + (reqminy-8);
  614.     reqminx = wp->BorderLeft + reqfudge;
  615.     reqmaxx = (((width - reqminx - wp->BorderRight) >> 3) << 3)
  616.         + (reqminx-8);
  617.     reqmaxlen = (reqmaxx+7) / 8;
  618.     if(oldmaxy > reqmaxy) { /* Clean up the bottom of the window */
  619.     int temp = height - wp->BorderBottom - reqmaxy;
  620.     
  621.     ScrollRaster(wp->RPort, 0L, (LONG)temp,
  622.     (LONG)reqminx,
  623.     (LONG)reqmaxy,
  624.     (LONG)(width - wp->BorderRight),
  625.     (LONG)(height - wp->BorderBottom));
  626.     }
  627. }
  628.  
  629. void
  630. OpenReqWindow()
  631. {
  632.     struct IntuiMessage *Msg;
  633.     ULONG class;
  634.     void ReqNewSize();
  635.     
  636.     reqwindow = OpenWindow(&NewReqWindow);
  637.     do {
  638.     Wait(1L << reqwindow->UserPort->mp_SigBit);
  639.     while(Msg = (struct IntuiMessage *)GetMsg(reqwindow->UserPort)) {
  640.         class = Msg->Class;
  641.         ReplyMsg(Msg);
  642.     }
  643.     } while (class != ACTIVEWINDOW);
  644.     reqfudge = 0;    /* Leave 0 pixels/scan lines between border and char */
  645.     ReqNewSize(reqwindow->Height, reqwindow->Width);
  646.     reqy = reqminy;    /* Top of character set by ReqNewSize() */
  647.     reqwinup = 1;
  648. }
  649.