home *** CD-ROM | disk | FTP | other *** search
/ Current Shareware 1994 January / SHAR194.ISO / catalogs / mtchplay.zip / WINDOW.C < prev    next >
Text File  |  1992-09-20  |  9KB  |  415 lines

  1. /* -------------- window.c ----------------------- */
  2. /* From DDJ, September 1988 */
  3.  
  4. #include <stdio.h>
  5. #include <alloc.h>
  6. #include <string.h>
  7. #include <conio.h>
  8. #include <mem.h>
  9. #include <dos.h>
  10. #include <stdlib.h>
  11. #include "window.h"
  12.  
  13.  
  14. /* ------------ window border characters --------- */
  15. #define NW   '\332'
  16. #define NE   '\277'
  17. #define SE   '\331'
  18. #define SW   '\300'
  19. #define SIDE '\263'
  20. #define LINE '\304'
  21.  
  22. int editing;
  23. static union REGS rg;
  24.  
  25. /* -------------- window definition structure --------- */
  26. struct wn wdo[MAX_WINDOWS];
  27. int curr_wnd;                     /* current window */
  28. struct wn wkw;                    /* a working window structure */
  29.  
  30. static void upline(void);
  31. static void downline(void);
  32. static void firstline(void);
  33. static void lastline(void);
  34. static void dline(int,int,int);
  35.  
  36. /* ---------------- establish a new window --------------- */
  37. void establish_window(left,top,right,bottom,foreg,backg,save)
  38. {
  39.   if (curr_wnd < MAX_WINDOWS)
  40.     {
  41.      if (curr_wnd)
  42.         wdo[curr_wnd-1] = wkw;
  43.      setmem(&wkw, sizeof(wkw), 0);
  44.      wkw.lf = left;
  45.      wkw.tp = top;
  46.      wkw.rt = right;
  47.      wkw.bt = bottom;
  48.      wkw.fg = foreg;
  49.      wkw.bg = backg;
  50.      wkw.wd = right+1-left;
  51.      wkw.ht = bottom-top-1;
  52.      if (save)
  53.        {
  54.         if ((wkw.wsave=malloc((wkw.ht+2)*wkw.wd*2)) == NULL)
  55.            return;
  56.         gettext(left,top,right,bottom,wkw.wsave);
  57.        }
  58.      wdo[curr_wnd++] = wkw;
  59.      current_window();
  60.      clear_window();
  61.     }
  62. }
  63.  
  64. /* -------- initialize the working window as current ------- */
  65. void current_window()
  66. {
  67.   window(wkw.lf,wkw.tp,wkw.rt,wkw.bt);
  68.   hidecursor();
  69.   if (wkw.fg || wkw.bg)
  70.     {
  71.      textcolor(wkw.fg);
  72.      textbackground(wkw.bg);
  73.     }
  74. }
  75.  
  76. /* -------------- set a window's title -------------------- */
  77. void window_title(char *ttl)
  78. {
  79.   writeline((wkw.wd-strlen(ttl))/2, 1, ttl);
  80. }
  81.  
  82. /* --------------- remove a window -------------------------- */
  83. void delete_window()
  84. {
  85.   if (curr_wnd)
  86.     {
  87.      if (wkw.wsave)
  88.        {
  89.         puttext(wkw.lf,wkw.tp,wkw.rt,wkw.bt,wkw.wsave);
  90.         free(wkw.wsave);
  91.        }
  92.      setmem(wdo+curr_wnd-1,sizeof(struct wn),0);
  93.      --curr_wnd;
  94.      if (curr_wnd)
  95.        {
  96.         wkw = wdo[curr_wnd-1];
  97.         current_window();
  98.        }
  99.      }
  100. }
  101.  
  102. /* --------- clear window area, display border -------------------- */
  103. void clear_window()
  104. {
  105.   int height,width,y=1;
  106.   char line1[81],line2[81];
  107.  
  108.   height = wkw.ht;
  109.   width = wkw.wd;
  110.   setmem(line1 + 1,width - 1,LINE);
  111.   setmem(line2 + 1,width - 1,' ');
  112.   *line1 = NW;
  113.   line1[width-1] = NE;
  114.   line1[width] = '\0';
  115.   *line2 = SIDE;
  116.   line2[width-1] = SIDE;
  117.   line2[width] = '\0';
  118.   line1[width] = line2[width] = '\0';
  119.   writeline(1,y++,line1);
  120.   while (height--)
  121.      writeline(1,y++,line2);
  122.   *line1 = SW;
  123.   line1[width-1] = SE;
  124.   writeline(1,y,line1);
  125. }
  126.  
  127. /* ---------- scroll the window; d:  1 = up, 0 = dn ------------ */
  128. void scroll_window(d)
  129. {
  130.   if (_video.snow == 0)
  131.      movetext(wkw.lf+1,wkw.tp+1,wkw.rt-1,wkw.bt-2+d,wkw.lf+1,wkw.tp+2-d);
  132.   else
  133.     {
  134.      rg.h.ah = d ? 6 : 7;
  135.      rg.h.bh = _video.attribute;
  136.      rg.h.cl = wkw.lf;
  137.      rg.h.ch = wkw.tp;
  138.      rg.h.dl = wkw.rt-2;
  139.      rg.h.dh = wkw.bt-2;
  140.      int86(16,&rg,&rg);
  141.     }
  142. }
  143.  
  144. /* ----------- display text in window -------------------- */
  145. void text_window(char *txt[],int ln)
  146. {
  147.   int height = wkw.ht;
  148.  
  149.   wkw.wtext = txt;
  150.   wkw.wtop = ln;
  151.   wkw.wy = 1;
  152.   while (height-- && txt[ln-1])
  153.      dline(ln++,wkw.fg,wkw.bg);
  154.   wkw.wlines = 0;
  155.   while (*txt++)
  156.      wkw.wlines++;
  157. }
  158.  
  159.  
  160. static int lineno;
  161. /* ----------- page and scroll through window of text -------- */
  162. int select_window(int ln,int foreg,int backg,int (*func)(int,int))
  163. {
  164.   int c=0;
  165.   int frtn;
  166.   int height,dln,ptop;
  167.  
  168.   if (ln > wkw.wtop + wkw.ht - 1 || ln < wkw.wtop)
  169.      text_window(wkw.wtext,ln);
  170.   else
  171.      wkw.wy = ln - wkw.wtop + 1;
  172.   while (TRUE)
  173.     {
  174.      lineno = wkw.wtop + wkw.wy -1;
  175.      ptop = wkw.wtop;
  176.      dline(lineno,foreg,backg);
  177.      if (wkw.wx == 0)
  178.         hidecursor();
  179.      else gotoxy(wkw.wx,wkw.wy+1);
  180.      c = get_key();
  181.      if (c == '\r' || c == ESC)
  182.         break;
  183.      switch(c)
  184.        {
  185.         case CTRL_HOME:
  186.           firstline();
  187.           break;
  188.         case CTRL_END:
  189.           lastline();
  190.           break;
  191.         case PGUP:
  192.           wkw.wtop -= wkw.ht;
  193.           if (wkw.wtop < 1)
  194.              wkw.wtop = 1;
  195.           break;
  196.         case PGDN:
  197.           wkw.wtop +=wkw.ht;
  198.           if (wkw.wtop > wkw.wlines - (wkw.ht-1))
  199.             {
  200.              wkw.wtop = wkw.wlines - (wkw.ht-1);
  201.              if (wkw.wtop < 1)
  202.                 wkw.wtop = 1;
  203.             }
  204.           break;
  205.         case Up:
  206.           upline();
  207.           break;
  208.         case Dn:
  209.           downline();
  210.           break;
  211.         default:
  212.           if (!editing && wkw.wlines <= wkw.ht)
  213.             {
  214.              if (c == HOME)
  215.                {
  216.                 firstline();
  217.                 break;
  218.                }
  219.              if (c == End)
  220.                {
  221.                 lastline();
  222.                 break;
  223.                }
  224.             }
  225.           if (func)
  226.             {
  227.              frtn
  228.               = (*func)(c,lineno);
  229.              if (frtn == ERROR)
  230.                 putch(BELL);
  231.              else
  232.              if (frtn)
  233.                {
  234.                 wkw.wy = frtn;
  235.                 return frtn;
  236.                }
  237.              c = 0;
  238.             }
  239.          break;
  240.        }
  241.      switch(c)
  242.        {
  243.         case HOME:
  244.         case CTRL_HOME:
  245.         case End:
  246.         case CTRL_END:
  247.         case PGUP:
  248.         case PGDN:
  249.           if (wkw.wtop != ptop)
  250.             {
  251.              height = wkw.ht;
  252.              dln = wkw.wtop;
  253.              while (height-- && wkw.wtext[dln-1])
  254.                 dline(dln++,wkw.fg,wkw.bg);
  255.              break;
  256.             }
  257.         default:
  258.           dline(lineno,wkw.fg,wkw.bg);
  259.           break;
  260.        }
  261.     }
  262.   return c == ESC ? 0 : lineno;
  263. }
  264.  
  265. /* ------------------- move up one line ------------------- */
  266. static void upline()
  267. {
  268.   if (lineno > 1)
  269.     {
  270.      if (wkw.wy == 1)
  271.        {
  272.         if (wkw.wtop >1)
  273.           {
  274.            --wkw.wtop;
  275.            scroll_window(0);
  276.           }
  277.        }
  278.      else
  279.         --wkw.wy;
  280.     }
  281.   else
  282.   if (wkw.wlines <= wkw.ht)
  283.         lastline();
  284. }
  285.  
  286.  
  287. /* ------------------- move down one line ----------------------- */
  288. static void downline()
  289. {
  290.   if (lineno < wkw.wlines)
  291.     {
  292.      if (wkw.wy == wkw.ht)
  293.        {
  294.         scroll_window(1);
  295.         wkw.wtop++;
  296.        }
  297.      else
  298.         wkw.wy++;
  299.     }
  300.   else
  301.   if (wkw.wlines <= wkw.ht)
  302.      firstline();
  303. }
  304.  
  305. /* --------------------- move to first line ------------------------- */
  306. static void firstline()
  307. {
  308.   wkw.wtop = wkw.wy = 1;
  309. }
  310.  
  311. /* ---------------------- move to last line -------------------------- */
  312. static void lastline()
  313. {
  314.   wkw.wtop = wkw.wlines - (wkw.ht-1);
  315.   if (wkw.wtop < 1)
  316.      wkw.wtop = 1;
  317.   wkw.wy = wkw.ht;
  318.   if (wkw.wy > wkw.wlines)
  319.      wkw.wy = wkw.wlines;
  320. }
  321.  
  322. char spaces[80] =
  323. "                                                                             ";
  324.  
  325. /* ------------- display a line of text, highlight or normal ----------- */
  326. static void dline(ln,foreg,backg)
  327. {
  328.   if (foreg || backg)
  329.     {
  330.      textcolor(foreg);
  331.      textbackground(backg);
  332.      --ln;
  333.      writeline(2,ln-wkw.wtop+3, *(wkw.wtext + ln));
  334.      if (strlen(*(wkw.wtext + ln)) < wkw.wd-2)
  335.         writeline(2+strlen(*(wkw.wtext + ln)), ln-wkw.wtop+3,spaces+79-wkw.wd+
  336.                  + strlen(*(wkw.wtext + ln)) + 2);
  337.     }
  338. }
  339.  
  340. /* --------------- write a line of text to video window ------------------ */
  341. void writeline(int x,int y,char *str)
  342. {
  343.   int c1[80], *cp = c1;
  344.   while (*str)
  345.      *cp++ = (*str++ & 255) | (_video.attribute << 8);
  346.   __vram(__vptr(x+wkw.lf-1,y+wkw.tp-1),(int far *)c1,
  347.          (unsigned)((int far *)cp-(int far *)c1));
  348. }
  349.  
  350. /* ---------------- hide the cursor ----------------- */
  351. void hidecursor()
  352. {
  353.   rg.h.ah = 2;
  354.   rg.x.dx = 0x1900;
  355.   rg.h.bh = 0;
  356.   int86(0x10,&rg,&rg);
  357. }
  358.  
  359. /* ----------------- set cursor type ------------------ */
  360. void set_cursor_type(unsigned t)
  361. {
  362.   rg.x.ax = 0x0100;
  363.   rg.x.bx = 0;
  364.   rg.x.cx = t;
  365.   int86(0x10,&rg,&rg);
  366. }
  367.  
  368. /* ------------------ clear screen ----------------------- */
  369. void clear_screen()
  370. {
  371.   window(1,1,80,25);
  372.   gotoxy(1,1);
  373.   rg.h.al = ' ';
  374.   rg.h.ah = 9;
  375.   rg.x.bx = 7;
  376.   rg.x.cx = 2000;
  377.   int86(0x10,&rg,&rg);
  378. }
  379.  
  380. void (*helpfunc)(void);
  381. int helpkey;
  382.  
  383. /* ------------------- read keyboard ----------------------- */
  384. int get_key()
  385. {
  386.   int c;
  387.  
  388.   if ((c=getch()) == 0)
  389.      c = getch() | 128;
  390.   if (c == helpkey && helpfunc)
  391.     {
  392.      (*helpfunc)();
  393.      c = get_key();
  394.     }
  395.     return c;
  396. }
  397.  
  398. /* -------------------- write error message -------------------- */
  399. void error_message(char *errmsg)
  400. {
  401.   int lf = (80-strlen(errmsg)+2)/2;
  402.   int rt = lf + max(strlen(errmsg)+2,15);
  403.   establish_window(lf,11,rt,14,ERRORFG,ERRORBG,TRUE);
  404.   gotoxy(2,2);
  405.   cputs(errmsg);
  406.   gotoxy(2,3);
  407.   cputs("(Press [Esc])");
  408.   hidecursor();
  409.   putch(BELL);
  410.   while (get_key() != ESC)
  411.      ;
  412.   delete_window();
  413. }
  414.  
  415.