home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / PASCAL / TOOL_INC.ZIP / POPUP.INC < prev    next >
Encoding:
Text File  |  1988-01-29  |  8.3 KB  |  387 lines

  1.  
  2. (*
  3.  * popup - utility library for simple "pop-up" windows
  4.  *
  5.  * written by Samuel H. Smith, 7-Feb-86
  6.  *
  7.  *)
  8.  
  9. const
  10.    low_attr:  integer = 7;
  11.    norm_attr: integer = 15;
  12.    back_attr: integer = 0;
  13.  
  14.    slowdisplay:      boolean = false;
  15.    default_disp_seg: integer = $B800;
  16.  
  17. type
  18.    popup_string = string[255];
  19.  
  20.    screenloc =         record
  21.          character:          char;
  22.          attribute:          byte;
  23.    end;
  24.  
  25.    videoram =          array [0..1999] of screenloc;
  26.    videoptr =          ^videoram;
  27.  
  28.    window_rec = record
  29.       x1,y1,x2,y2: integer;
  30.       attr:        byte;
  31.    end;
  32.  
  33.    window_save_rec = record
  34.       win:      window_rec;
  35.       scr:      videoram;
  36.       cux,cuy:  integer;
  37.    end;
  38.  
  39.  
  40. var
  41.    cur_window:   window_rec;
  42.    saved_window: window_save_rec;
  43.    disp_mem:     videoptr;
  44.    disp_seg:     integer;
  45.  
  46.  
  47. procedure determine_video_ptr;     {determine video display area when
  48.                                     running under DESQview - also works
  49.                                     without DESQview}
  50. const
  51.    video_ptr_known: boolean = false;
  52. begin
  53.  
  54. {   if video_ptr_known then exit; }
  55.  
  56.    disp_seg := default_disp_seg;
  57.  
  58.    inline( $55/                    {push bp}
  59.            $a1/disp_seg/           {mov ax,[disp_seg]}
  60.            $8e/$c0/                {mov es,ax}
  61.            $bf/$00/$00/            {mov di,0}
  62.            $b4/$fe/                {mov ah,fe}
  63.            $cd/$10/                {int 10h}
  64.            $5d/                    {pop bp}
  65.            $8c/$06/disp_seg);      {mov [disp_seg],es}
  66.  
  67.    disp_mem := ptr(disp_seg,0);
  68.    video_ptr_known := true;
  69. end;
  70.  
  71.  
  72. procedure normvideo;
  73. begin
  74.    textcolor(norm_attr);
  75.    textbackground(back_attr);
  76.    cur_window.attr := norm_attr + back_attr shl 4;
  77. end;
  78.  
  79.  
  80. procedure lowvideo;
  81. begin
  82.    textcolor(low_attr);
  83.    textbackground(back_attr);
  84.    cur_window.attr := low_attr + back_attr shl 4;
  85. end;
  86.  
  87.  
  88.  
  89. procedure old_window(win: window_rec);   {redefine the old window
  90.                                           command so it can still be
  91.                                           used by other procs}
  92. begin
  93.    with win do
  94.       window(x1,y1,x2,y2);
  95. end;
  96.  
  97.  
  98.  
  99. procedure window(a1,b1,a2,b2: integer);    {make a new version of window
  100.                                             that saves the current state}
  101. begin
  102.    determine_video_ptr;
  103.  
  104.    with cur_window do
  105.    begin
  106.       x1 := a1;
  107.       y1 := b1;
  108.       x2 := a2;
  109.       y2 := b2;
  110.    end;
  111.  
  112.    old_window(cur_window);
  113. end;
  114.  
  115.  
  116.  
  117. function make_string(c: char; len: integer): popup_string;
  118.                                    {make a string by repeating
  119.                                     a character n times}
  120. var
  121.    i:  integer;
  122.    s:  popup_string;
  123. begin
  124.    for i := 1 to len do
  125.       s[i] := c;
  126.  
  127.    s[0] := chr(len);
  128.    make_string := s;
  129. end;
  130.  
  131.  
  132.  
  133. function invisible: boolean;   {is this the invisible program under doubledos?}
  134. var
  135.    reg:  registers;
  136.  
  137. begin
  138.    determine_video_ptr;
  139.  
  140.    reg.ax := $e400;   {doubledos return program status}
  141.    msdos(reg);
  142.  
  143.    if (lo(reg.ax) = 2) or slowdisplay then
  144.       invisible := true
  145.    else
  146.       invisible := false;
  147. end;
  148.  
  149.  
  150.  
  151. procedure disp (s:                  popup_string);
  152.                                      {very fast dma string display}
  153. var
  154.    index:              integer;
  155.    i:                  integer;
  156.    c:                  char;
  157.    len:                integer;
  158.    max_index:          integer;
  159.  
  160. begin
  161.  
  162.  
  163.    if invisible or (length(s) < 4) then
  164.                      {can't do dma screens if invisble under doubledos.
  165.                       this is slower than write for short strings}
  166.    begin
  167.       write(s);
  168.       exit;
  169.    end;
  170.  
  171.  
  172.    with cur_window do
  173.    begin
  174.       len := length (s);
  175.       index :=(wherey + y1 - 2)* 80 +(wherex + x1 - 2);
  176.       max_index := y2*80;
  177.  
  178.       for i := 1 to len do
  179.       begin
  180.          c := s [i];
  181.  
  182.          case c of
  183.             ^H:   index := index - 1;
  184.  
  185.             ^J:   begin
  186.                      index := index + 80;
  187.                      if index >= max_index then
  188.                      begin
  189.                         write(^J);
  190.                         index := index - 80;
  191.                      end;
  192.                   end;
  193.  
  194.             ^M:   index :=(index div 80)* 80 + x1 - 1;
  195.  
  196.             ^G:   write(^G);
  197.  
  198.             else  begin
  199.                      with disp_mem^[index] do
  200.                      begin
  201.                         character := c;
  202.                         attribute := attr;
  203.                      end;
  204.  
  205.                      index := index + 1;
  206.  
  207.                      if index >= max_index then
  208.                      begin
  209.                         index := index - 80;
  210.                         writeln;
  211.                      end;
  212.                   end;
  213.          end;
  214.       end;
  215.  
  216.  
  217. (* place cursor at end of displayed string *)
  218.  
  219.       gotoxy((index mod 80)- x1 + 2,(index div 80)- y1 + 2);
  220.    end;
  221. end;
  222.  
  223.  
  224.  
  225. procedure displn(s: popup_string);       {fast display and linefeed}
  226. begin
  227.    disp(s);
  228.    writeln;
  229. end;
  230.  
  231.  
  232.  
  233. procedure open_pop_up(x1,y1,x2,y2: integer; title: popup_string);
  234.                                             {open a titled pop up window
  235.                                              and save previous screen
  236.                                              state so it can be restored}
  237. const
  238.    topleft =           #213;
  239.    topright =          #184;
  240.    botleft =           #212;
  241.    botright =          #190;
  242.    sides =             #179;
  243.    tops =              #205;
  244.  
  245. var
  246.    i,
  247.    j:                  integer;
  248.    side:               popup_string;
  249.    top:                popup_string;
  250.    bottom:             popup_string;
  251.  
  252. begin
  253.  
  254. (* save the current window so it can be restored later *)
  255.    determine_video_ptr;
  256.    saved_window.scr := disp_mem^;
  257.    saved_window.win := cur_window;
  258.    saved_window.cux := wherex;
  259.    saved_window.cuy := wherey;
  260.    window(1,1,80,25);
  261.  
  262.  
  263. (* create window section strings *)
  264.    if title <> '' then
  265.       title := ' ' + title + ' ';
  266.                               {leave spaces around the title, if any}
  267.  
  268.  
  269. (* top of frame *)
  270.    top := make_string (tops, x2 - length (title)- x1 - 2) + topright;
  271.  
  272.  
  273. (* sides of frame *)
  274.    side := '';
  275.    j := 1;
  276.  
  277.    for i :=(y1 + 1) to (y2 - 1) do
  278.    begin
  279.       side[j]:= sides;
  280.       side[j + 1]:=^H;
  281.       side[j + 2]:=^J;
  282.       j := j + 3;
  283.    end;
  284.  
  285.    side[0]:= chr (j - 1);
  286.  
  287.  
  288. (* bottom of frame *)
  289.    bottom := botleft + make_string (tops, x2 - x1 - 1)+ botright;
  290.  
  291.  
  292. (* draw the frame *)
  293.    gotoxy(x1, y1);
  294.    disp(topleft + tops + title + top);
  295.  
  296.    gotoxy(x1, y1 + 1);
  297.    disp(side);
  298.  
  299.    gotoxy(x2, y1 + 1);
  300.    disp(side);
  301.  
  302.    gotoxy(x1, y2);
  303.    disp(bottom);
  304.  
  305. (* define the new window.  let the caller decide if it needs clearing *)
  306.    window(x1+1,y1+1,x2-1,y2-1);
  307.  
  308. end;
  309.  
  310.  
  311.  
  312. procedure remove_pop_up;        {restore the screen like it was
  313.                                  before the popup window was opened}
  314. begin
  315.  
  316. (* restore the windowing settings *)
  317.    cur_window := saved_window.win;
  318.    old_window(cur_window);
  319.  
  320. (* restore the cursor position *)
  321.    gotoxy(saved_window.cux,saved_window.cuy);
  322.  
  323. (* restore the display contents *)
  324.    disp_mem^ := saved_window.scr;
  325.  
  326. (* restore current video mode *)
  327.    if cur_window.attr = low_attr then
  328.       lowvideo
  329.    else
  330.       normvideo;
  331. end;
  332.  
  333.  
  334. procedure preserve_screen(name: popup_string);
  335.                                 {preserve contents in a named file}
  336. var
  337.    fd:  file of window_save_rec;
  338.  
  339. begin
  340.    if invisible then
  341.       exit;
  342.  
  343.    assign(fd,name);
  344. {$I-}
  345.    rewrite(fd);
  346. {$I+}
  347.    if ioresult = 0 then
  348.    begin
  349.       open_pop_up(1,1,5,5,'');
  350.       remove_pop_up;
  351.       write(fd,saved_window);
  352.       close(fd);
  353.    end;
  354. end;
  355.  
  356.  
  357. procedure restore_screen(name: popup_string);
  358.                                {restore a preserved screen from a file;
  359.                                 don't touch screen if file is missing}
  360. var
  361.    fd:  file of window_save_rec;
  362.  
  363. begin
  364.    if invisible then
  365.       exit;
  366.  
  367.    assign(fd,name);
  368. {$I-}
  369.    reset(fd);
  370. {$I+}
  371.    if ioresult = 0 then
  372.    begin
  373.       read(fd,saved_window);
  374.       close(fd);
  375.       remove_pop_up;
  376.    end;
  377.  
  378. end;
  379.  
  380.  
  381. procedure init_pop_up;   {call once before anything else in this library}
  382. begin
  383.    window(1,1,80,25);
  384.    normvideo;
  385. end;
  386.  
  387.