home *** CD-ROM | disk | FTP | other *** search
/ Microsoft Programmer's Library 1.3 / Microsoft-Programers-Library-v1.3.iso / sampcode / prof_c / 05oslib / cursor.c next >
Encoding:
C/C++ Source or Header  |  1988-08-11  |  6.3 KB  |  255 lines

  1. /*
  2.  *    cursor -- interactively set cursor shape
  3.  */
  4.  
  5. #include <dos.h>
  6. #include <stdlib.h>
  7. #include <local\video.h>
  8. #include <local\keydefs.h>
  9.  
  10. /* additional drawing characters (others are defined in video.h) */
  11. #define DOT    254
  12. #define NO_DOT    196
  13. #define D_POINT    31
  14. #define R_POINT 16
  15. #define L_POINT 17
  16.  
  17. /* dimensions of the help frame */
  18. #define BOX_Y    6
  19. #define BOX_X    30
  20.  
  21. /* upper-left row and column of big cursor */
  22. int Ulr;
  23. int Ulc;
  24. int Mid;
  25.  
  26. /* cursor scan-line-selection modes */
  27. typedef enum { STARTSCAN, ENDSCAN } CMODE;
  28.  
  29. int
  30. main()
  31. {
  32.     int i, j;
  33.     int ch;
  34.     int start, end;
  35.     int height, width;
  36.     static char spoint[] = { "Start\020" }; /* contains right pointer */
  37.     static char epoint[] = { "\021Stop" };    /* contains left pointer */
  38.     static char title[] = { "CURSOR: Control cursor shape (V1.0)" };
  39.     unsigned char
  40.         oldattr,    /* video attribute upon entry */
  41.         headattr,    /* video attribute of header */
  42.         attr,         /* primary video attribute */
  43.         standout;    /* highlighting video attribute */
  44.     CMODE mode;
  45.  
  46.     static void drawdspy(int, int, int, int, int);
  47.     static void drawstart(int, char *);
  48.     static void drawend(int, int, char *);
  49.     static void drawactive(int, int, CMODE);
  50.     static void showhelp(int, int);
  51.  
  52.     /* get video information and initialize */
  53.     getstate();
  54.     Mid = Vwidth / 2;
  55.     readca(&ch, &oldattr, Vpage);    /* preserve user's video attribute */
  56.     getctype(&start, &end, Vpage);    /* and cursor shape */
  57.     headattr = (WHT << 4) | BLK;
  58.  
  59.     /* set parameters based on video mode (default = CGA) */
  60.     height = width = 8;    /* use an 8 by 8 block character cell */
  61.     attr = (BLU << 4) | CYAN | BRIGHT;
  62.     standout = YEL;
  63.     if (Vmode == MDA_M80) {
  64.         /* uses a 14 by 9 dot block character cell */
  65.         height = 14;
  66.         width = 9;
  67.         attr = NORMAL;
  68.         standout = BWHT;
  69.     }
  70.     setctype(height + 1, height + 1);    /* cursor off */
  71.  
  72.     /* basic text and layout */
  73.     Ulr = 2;
  74.     Ulc = Mid - width / 2;
  75.     clrscrn(attr);
  76.     putcur(0, 0, Vpage);
  77.     writeca(' ', headattr, Vwidth, Vpage);
  78.     putcur(0, Mid - strlen(title) / 2, Vpage);
  79.     writestr(title, Vpage);
  80.     showhelp(Ulr + height + 1, Mid - BOX_X / 2);
  81.  
  82.     /* interactively select cursor shape */
  83.     mode = STARTSCAN;
  84.     drawdspy(start, end, standout, width, height);
  85.     drawstart(start, spoint);
  86.     drawend(end, width, epoint);
  87.     drawactive(height, width, mode);
  88.     while (1) {
  89.         switch (ch = getkey()) {
  90.         case K_UP:
  91.             /* move up one scan line */
  92.             if (mode == STARTSCAN)
  93.                 drawstart(start--, "      ");
  94.             else
  95.                 drawend(end--, width, "     ");
  96.             break;
  97.         case K_DOWN:
  98.             /* move down one scan line */
  99.             if (mode == STARTSCAN)
  100.                 drawstart(start++, "      ");
  101.             else
  102.                 drawend(end++, width, "     ");
  103.             break;
  104.         case K_LEFT:
  105.             /* starting scan-line-selection mode */
  106.             mode = STARTSCAN;
  107.             drawactive(height, width, mode);
  108.             continue;
  109.         case K_RIGHT:
  110.             /* ending scan-line-selection mode */
  111.             mode = ENDSCAN;
  112.             drawactive(height, width, mode);
  113.             continue;
  114.         case K_RETURN:
  115.             /* set the new cursor shape */
  116.             setctype(start, end);
  117.             clrscrn(oldattr);
  118.             putcur(0, 0, Vpage);
  119.             exit(0);
  120.         }
  121.  
  122.         /* make corrections at cursor image boundaries */
  123.         if (start < 0)
  124.             start = 0;
  125.         else if (start > height)
  126.             start = height;
  127.         if (end < 0)
  128.             end = 0;
  129.         else if (end >= height)
  130.             end = height - 1;
  131.  
  132.         /* show updated cursor shape and pointers */
  133.         drawdspy(start, end, standout, width, height);
  134.         drawstart(start, spoint);
  135.         drawend(end, width, epoint);
  136.     }
  137.  
  138.     exit(0);
  139. } /* end main() */
  140.  
  141.  
  142. /*
  143.  *    drawdspy -- draw a magnified image of a cursor with the
  144.  *    currently active scan lines depicted as a sequence of dots
  145.  *    and inactive lines depicted as straight lines
  146.  */
  147.  
  148. static void
  149. drawdspy(s, e, a, w, h)
  150. int s;    /* starting scan line */
  151. int e;    /* ending scan line */
  152. int a;    /* video attribute */
  153. int w;    /* width */
  154. int h;    /* height */
  155. {
  156.     int i;
  157.  
  158.     /* display an exploded image of each scan line */
  159.     for (i = 0; i < h; ++i) {
  160.         putcur(Ulr + i, Ulc, Vpage);
  161.         if (s >= h)
  162.             /* cursor is effectively off */
  163.             writeca(NO_DOT, a, w, Vpage);
  164.         else if ((s <= e && i >= s && i <= e) || /* a full block */
  165.             (s > e && (i <= e || i >= s)))     /* a split block */
  166.             writeca(DOT, a, w, Vpage);
  167.         else
  168.             /* outside start/end range */
  169.             writeca(NO_DOT, a, w, Vpage);
  170.     }
  171. } /* end drawdspy() */
  172.  
  173.  
  174. /*
  175.  *    drawstart -- display a pointer to the displayed starting
  176.  *    scan line in the magnified cursor image
  177.  */
  178.  
  179. static void
  180. drawstart(s, sp)
  181. int s;        /* starting scan line number */
  182. char *sp;    /* visual pointer to the displayed starting scan line */
  183. {
  184.     putcur(Ulr + s, Ulc - strlen(sp), Vpage);
  185.     putstr(sp, Vpage);
  186. } /* end drawstart() */
  187.  
  188.  
  189. /*
  190.  *    drawend -- display a pointer to the displayed ending
  191.  *    scan line in the magnified cursor image
  192.  */
  193.  
  194. static void
  195. drawend(e, w, ep)
  196. int e;        /* ending scan line number */
  197. int w;        /* width of the cursor image */
  198. char *ep;    /* visual pointer to the displayed ending scan line */
  199. {
  200.     putcur(Ulr + e, Ulc + w, Vpage);
  201.     putstr(ep, Vpage);
  202. } /* end drawend() */
  203.  
  204. static void
  205. drawactive(h, w, m)
  206. int h, w;
  207. CMODE m;
  208. {
  209.     int col;
  210.  
  211.     /* clear active selector row */
  212.     putcur(Ulr - 1, Ulc, Vpage);
  213.     writec(' ', w, Vpage);
  214.  
  215.     /* point to active selector */
  216.     col = (m == STARTSCAN) ? 0 : w - 1;
  217.     putcur(Ulr - 1, Ulc + col, Vpage);
  218.     writec(D_POINT, 1, Vpage);
  219. } /* end drawactive() */
  220.  
  221. /*
  222.  *    showhelp -- display a set of instructions about the
  223.  *    use of the cursor program in a fine-ruled box
  224.  */
  225.  
  226. static void
  227. showhelp(r, c)
  228. int r, c;    /* upper-left corner of help frame */
  229. {
  230.     static char title[] = { " Instructions " };
  231.     extern int drawbox(int, int, int, int, int);
  232.  
  233.     /* fine-ruled box */
  234.     clrw(r, c, r + BOX_Y, c + BOX_X, (WHT << 4) | GRN | BRIGHT);
  235.     drawbox(r, c, r + BOX_Y, c + BOX_X, Vpage);
  236.  
  237.     /* centered title */
  238.     putcur(r, c + (BOX_X - strlen(title)) / 2, Vpage);
  239.     putstr(title, Vpage);
  240.  
  241.     /* display symbols and text using brute-force positioning */
  242.     putcur(r + 2, c + 2, Vpage);
  243.     put_ch(LEFTARROW, Vpage);
  244.     put_ch(RIGHTARROW, Vpage);
  245.     putstr("  Change selection mode", Vpage);
  246.     putcur(r + 3, c + 2, Vpage);
  247.     put_ch(UPARROW, Vpage);
  248.     put_ch(DOWNARROW, Vpage);
  249.     putstr("  Select scan lines", Vpage);
  250.     putcur(r + 4, c + 2, Vpage);
  251.     put_ch(L_POINT, Vpage);
  252.     put_ch(LRC11, Vpage);
  253.     putstr("  Set shape and exit", Vpage);
  254. } /* end showhelp() */
  255.