home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 8 / CDASC08.ISO / NEWS / 677 / TSRTOOLS / HOTKEY.C < prev    next >
C/C++ Source or Header  |  1993-10-07  |  11KB  |  523 lines

  1. /*
  2.     hotkey.C
  3.  
  4.     Version 1.5
  5.  
  6.     Hotkey Viewer and Changer
  7.  
  8.     Copyright (C) 1993, Geoff Friesen B.Sc.
  9.     All rights reserved.
  10.  
  11.     Developed with: Borland C++ 3.1
  12. */
  13.  
  14. /*
  15.     set ti=c:\borlandc\include
  16.     t hotkey -hh -x
  17.  
  18.     The BIOS memory location 0040:0084 is set to the number of
  19.     screen rows less one.  For example, if the screen has been
  20.     set to 25 lines then the value 24 would be stored here.  A
  21.     value of 49 would be stored if 50-line mode were in effect
  22.     (on VGA adaptors).  This address is used by recent adaptor
  23.     BIOSes.  Older BIOSes do not use it.  Therefore, assume it
  24.     to be valid if it returns a 24, 42, or 49.  The 42 is used
  25.     in EGA 43-line mode.
  26.  
  27.     This program assumes that the addresses for the signature,
  28.     hotkey letter, and hotkey scancode have not been changed.
  29.     These addresses are critical and should never be changed.
  30.  
  31.     HOTKEY LETTER ADDRESS   -> 0x0103 (single byte)
  32.     HOTKEY SCANCODE ADDRESS -> 0x0104 (single byte)
  33.     SIGNATURE ADDRESS START -> 0x010D (multiple bytes)
  34.  
  35.     The signature always begins with the characters "TSR:" and
  36.     is followed by one to eight ASCII characters which is fol-
  37.     lowed by an ASCII NULL byte terminator (ASCII 0).
  38.  
  39.     This TSR uses a GOTO statement in the main () function.  I
  40.     tend to use GOTOs in the area of exception handling.
  41. */
  42.  
  43. #pragma inline
  44.  
  45. #if !defined(__TINY__)
  46. #error Tiny Memory Model Expected
  47. #endif
  48.  
  49. #include "tsrlib.H"
  50.  
  51. char *title = "\r\n"
  52.  
  53. "╔═════════════════════════════════════════════════╗\r\n"
  54. "║ ▒   ▒  ▒▒▒  ▒▒▒▒▒ ▒   ▒ ▒▒▒▒▒ ▒   ▒             ║\r\n"
  55. "║ ▒   ▒ ▒   ▒   ▒   ▒  ▒  ▒     ▒   ▒             ║\r\n"
  56. "║ ▒   ▒ ▒   ▒   ▒   ▒ ▒   ▒     ▒   ▒             ║\r\n"
  57. "║ ▒▒▒▒▒ ▒   ▒   ▒   ▒▒    ▒▒▒▒   ▒▒▒  Version 1.5 ║\r\n"
  58. "║ ▒   ▒ ▒   ▒   ▒   ▒ ▒   ▒       ▒               ║\r\n"
  59. "║ ▒   ▒ ▒   ▒   ▒   ▒  ▒  ▒       ▒               ║\r\n"
  60. "║ ▒   ▒  ▒▒▒    ▒   ▒   ▒ ▒▒▒▒▒   ▒               ║\r\n"
  61. "║                                                 ║\r\n"
  62. "║ Copyright (C) 1993, Geoff Friesen B.Sc.         ║\r\n"
  63. "║ All rights reserved.                            ║\r\n"
  64. "╚═════════════════════════════════════════════════╝\r\n"
  65. "$";
  66.  
  67. int bw [] =
  68. {
  69.    WHITE,                /* border */
  70.    LIGHTGRAY << 4,            /* lightbar */
  71.    LIGHTGRAY                /* normal text */
  72. };
  73.  
  74. int color [] =
  75. {
  76.    GREEN,                /* border */
  77.    LIGHTGRAY << 4,            /* lightbar */
  78.    (BLUE << 4) | WHITE            /* normal text */
  79. };
  80.  
  81. #define NATTR   (sizeof(bw)/sizeof(bw [0]))
  82.  
  83. int attr [NATTR];
  84.  
  85. #define    FREEMCB    0
  86. #define    BLOCMCB    'M'
  87. #define    LASTMCB    'Z'
  88.  
  89. #define    KEYOFS    0x103
  90. #define    SIGOFS    0x10d
  91.  
  92. #define    MAXPSP    100
  93.  
  94. #define    NCOLS    18
  95. #define    NROWS    16
  96.  
  97. char buffer [(NCOLS+3)*(NROWS+3)*2];
  98.  
  99. int column = 1;
  100. int row;
  101. int srow = -1;                /* suggested row */
  102. int currow;
  103. int ctsr;
  104. int ntsr;
  105. int psps [MAXPSP];
  106.  
  107. void    change_key    (int key);
  108. void    down        (int nlines);
  109. void    end        (void);
  110. void    home        (void);
  111. char    *info        (int row);
  112. void    refresh        (void);
  113. int    scan        (void);
  114. void    up        (int nlines);
  115.  
  116. void main (void)
  117. {
  118.    int cshape, i, key, nrows, vmode, x, y;
  119.  
  120.    if ((vmode = v_getmode ()) != BW80 && vmode != C80 && vmode != MONO)
  121.        return;
  122.  
  123.    nrows = peekb(0x40, 0x84)+1;
  124.    if (nrows != 25 && nrows != 43 && nrows != 50)
  125.        nrows = 25;
  126.  
  127.    row = (srow == -1 || srow+NROWS+2 > nrows) ? 1 : srow;
  128.  
  129.    for (i = 0; i < NATTR; i++)
  130.     attr [i] = (vmode == C80) ? color [i] : bw [i];
  131.  
  132.    cshape = v_getshape ();
  133.    v_setshape (0x2000);         /* hide cursor */
  134.  
  135.    x = v_wherex ();
  136.    y = v_wherey ();
  137.  
  138.    v_screen (SCREEN_SAVE, column, row, NCOLS+3, NROWS+3, buffer);
  139.  
  140.    v_setattr (attr [0]);
  141.    v_border (BLOCK_LINE, column, row, NCOLS+2, NROWS+2);
  142.    v_shadow (column, row, NCOLS+2, NROWS+2);
  143.    v_setattr (attr [2]);
  144.    v_clear (column+1, row+1, NCOLS, NROWS);
  145.  
  146.    if (scan () == -1)
  147.    {
  148.        v_gotoxy (column+1, row+1);
  149.        v_cputs ("Scan unsuccessful.");
  150.  
  151.        v_gotoxy (column+1, row+3);
  152.        v_cputs ("  Press any key.");
  153.  
  154.        (void) k_fetch ();
  155.        goto main_exit;
  156.    }
  157.  
  158.    ctsr = 0;
  159.    currow = 1;
  160.    refresh ();
  161.  
  162.    do
  163.    {
  164.       if ((key = k_fetch ()) == ESC)
  165.       break;
  166.  
  167.       if (isalpha (key) || isdigit (key))
  168.       {
  169.       change_key (key);
  170.       continue;
  171.       }
  172.  
  173.       if (ntsr > 1)
  174.       switch (key)
  175.       {
  176.          case DOWN : down (1);
  177.              break;
  178.  
  179.          case END  : end ();
  180.              break;
  181.  
  182.          case HOME : home ();
  183.              break;
  184.  
  185.          case PGDN : down (16);
  186.              break;
  187.  
  188.          case PGUP : up (16);
  189.              break;
  190.  
  191.          case UP   : up (1);
  192.       }
  193.    }
  194.    while (1);
  195.  
  196. main_exit:
  197.  
  198.    v_screen (SCREEN_RESTORE, column, row, NCOLS+3, NROWS+3, buffer);
  199.    v_gotoxy (x, y);
  200.    v_setshape (cshape);
  201. }
  202.  
  203. void change_key (int key)
  204. {
  205.    static char scancodes [] =
  206.    {
  207.       30, 48, 46, 32, 18, 33, 34, 35, 23, 36, 37, 38, 50,    /* A-M */
  208.       49, 24, 25, 16, 19, 31, 20, 22, 47, 17, 45, 21, 44,    /* N-Z */
  209.       11,  2,  3,  4,  5,  6,  7,  8,  9, 10, 0            /* 0-9 */
  210.    };
  211.  
  212.    if (key >= 'Z')    /* convert to uppercase */
  213.        key -= 32;
  214.  
  215.    pokeb(psps [ctsr], KEYOFS, key);
  216.    pokeb(psps [ctsr], KEYOFS+1, isalpha (key) ? scancodes [key-'A'] :
  217.      scancodes [key-'0'+26]);
  218.  
  219.    v_gotoxy (column+5, row+currow);
  220.    v_setattr (attr [1]);
  221.    v_putch (key, 1);
  222. }
  223.  
  224. void down (int nlines)
  225. {
  226.    int i, dnlines;
  227.  
  228.    if (ctsr == ntsr-1)
  229.        return;
  230.  
  231.    v_setattr (attr [2]);
  232.    v_gotoxy (column+1, row+currow);
  233.    v_cputs (info (ctsr));
  234.  
  235.    dnlines = min(ntsr-1-ctsr, nlines);
  236.  
  237.    for (i = 1; i <= dnlines; i++)
  238.    {
  239.     if (currow != NROWS)
  240.         currow++;
  241.     else
  242.         v_scroll (column+1, row+1, NCOLS, NROWS, SCROLL_UP,
  243.               1, attr [2]);
  244.  
  245.     if (i == dnlines)
  246.         v_setattr (attr [1]);
  247.  
  248.     v_gotoxy (column+1, row+currow);
  249.     v_cputs (info (++ctsr));
  250.    }
  251. }
  252.  
  253. void end (void)
  254. {
  255.    if (ctsr == ntsr-1)
  256.        return;
  257.  
  258.    ctsr = ntsr-1;
  259.    currow = (ntsr < NROWS) ? ntsr : NROWS;
  260.    refresh ();
  261. }
  262.  
  263. void home (void)
  264. {
  265.    if (!ctsr)
  266.        return;
  267.  
  268.    ctsr = 0;
  269.    currow = 1;
  270.    refresh ();
  271. }
  272.  
  273. char *info (int row)
  274. {
  275.    int i;
  276.    static char buffer [NCOLS+1];
  277.    unsigned segment = psps [row];
  278.  
  279.    for (i = 0; i < NCOLS; i++)
  280.     buffer [i] = ' ';
  281.  
  282.    buffer [NCOLS] = '\0';
  283.  
  284.    buffer [0] = 'A';
  285.    buffer [1] = 'L';
  286.    buffer [2] = 'T';
  287.    buffer [3] = '-';
  288.    buffer [4] = peekb(segment, KEYOFS);
  289.  
  290.    buffer [6] = 'T';
  291.    buffer [7] = 'S';
  292.    buffer [8] = 'R';
  293.    buffer [9] = ':';
  294.  
  295.    i = SIGOFS+4;
  296.    while (peekb(segment, i))
  297.       buffer [6+i++-SIGOFS] = peekb(segment, i);
  298.  
  299.    return buffer;
  300. }
  301.  
  302. void refresh (void)
  303. {
  304.    int index, _min, _row;
  305.  
  306.    index = ctsr-currow+1;
  307.    _min = min(NROWS, ntsr);
  308.  
  309.    for (_row = 1; _row <= _min; _row++)
  310.    {
  311.     v_gotoxy (column+1, row+_row);
  312.     v_setattr (attr [(currow == _row) ? 1 : 2]);
  313.     v_cputs (info (index++));
  314.    }
  315. }
  316.  
  317. int scan (void)
  318. {
  319.    char typemcb = BLOCMCB;
  320.    unsigned segment = 0x40;
  321.  
  322.    do
  323.    {
  324.        if (peekb(segment, 0) == BLOCMCB)    /* Found first MCB?      */
  325.        if (peek(segment, 1) == segment+1)    /* First MCB owns ...    */
  326.            break;                /* ... following segment */
  327.  
  328.        if (++segment == 0xa000)            /* Goto 640K segment ... */
  329.        return -1;                /* ... even if less mem  */
  330.    }
  331.    while (1);
  332.  
  333.    ntsr = 0;
  334.  
  335.    do
  336.    {
  337.       if ((~peekb(segment+1, SIGOFS) == 'T') &&
  338.       (peekb(segment+1, SIGOFS+1) == 'S') &&
  339.       (peekb(segment+1, SIGOFS+2) == 'R') &&
  340.       peek(segment, 1) == segment+1)
  341.       psps [ntsr++] = segment+1;
  342.  
  343.       if (typemcb == LASTMCB || ntsr == MAXPSP)
  344.       break;
  345.  
  346.       segment += peek(segment, 3)+1;        /* Point to next MCB     */
  347.       typemcb = peekb(segment, 0);              /* Obtain MCB type       */
  348.  
  349.       if (typemcb != BLOCMCB && typemcb != LASTMCB)
  350.       return -1;
  351.    }
  352.    while (1);
  353.  
  354.    return (ntsr) ? 0 : -1;
  355. }
  356.  
  357. void up (int nlines)
  358. {
  359.    int i, uplines;
  360.  
  361.    if (!ctsr)
  362.        return;
  363.  
  364.    v_setattr (attr [2]);
  365.    v_gotoxy (column+1, row+currow);
  366.    v_cputs (info (ctsr));
  367.    uplines = min(ctsr, nlines);
  368.  
  369.    for (i = 1; i <= uplines; i++)
  370.    {
  371.     if (currow != 1)
  372.         currow--;
  373.     else
  374.         v_scroll (column+1, row+1, NCOLS, NROWS, SCROLL_DN,
  375.               1, attr [2]);
  376.  
  377.     if (i == uplines)
  378.         v_setattr (attr [1]);
  379.  
  380.     v_gotoxy (column+1, row+currow);
  381.     v_cputs (info (--ctsr));
  382.    }
  383. }
  384.  
  385. #ifndef INCL_ISALPHA
  386. #include "isalpha.C"
  387. #endif
  388.  
  389. #ifndef INCL_ISDIGIT
  390. #include "isdigit.C"
  391. #endif
  392.  
  393. #ifndef INCL_KFETCH
  394. #include "kfetch.C"
  395. #endif
  396.  
  397. #ifndef INCL_VBORDER
  398. #include "vborder.C"
  399. #endif
  400.  
  401. #ifndef INCL_VCPUTS
  402. #include "vcputs.C"
  403. #endif
  404.  
  405. #ifndef INCL_VGETMODE
  406. #include "vgetmode.C"
  407. #endif
  408.  
  409. #ifndef INCL_VGETSHAPE
  410. #include "vgetshap.C"
  411. #endif
  412.  
  413. #ifndef INCL_VPAINT
  414. #include "vpaint.C"
  415. #endif
  416.  
  417. #ifndef INCL_VSCROLL
  418. #include "vscroll.C"
  419. #endif
  420.  
  421. #ifndef INCL_VSETATTR
  422. #include "vsetattr.C"
  423. #endif
  424.  
  425. #ifndef INCL_VSETSHAPE
  426. #include "vsetshap.C"
  427. #endif
  428.  
  429. #ifndef INCL_VSHADOW
  430. #include "vshadow.C"
  431. #endif
  432.  
  433. #ifndef INCL_VWHEREX
  434. #include "vwherex.C"
  435. #endif
  436.  
  437. #ifndef INCL_VWHEREY
  438. #include "vwherey.C"
  439. #endif
  440.  
  441. int xparse (int option)
  442. {
  443.    int accum, digit;
  444.  
  445.    if (option == 'R')    /* RESET OPTION */
  446.    {
  447.        setrseg ();
  448.        column = 1;
  449.        srow = -1;
  450.        setcseg ();
  451.        return 0;
  452.    }
  453.  
  454.    if (option == 'X')    /* COLUMN OPTION */
  455.    {
  456.        if (!isdigit ((digit = parse ())))
  457.        {
  458.        _AH = 9;
  459.        _DX = FP_OFF("hotkey: digit expected after 'X'\r\n$");
  460.        geninterrupt(0x21);
  461.        return -1;
  462.        }
  463.  
  464.        accum = digit-'0';
  465.  
  466.        if (!isdigit ((digit = parse ())))
  467.        unparse ();
  468.        else
  469.        {
  470.        accum *= 10;
  471.        accum += (digit-'0');
  472.        }
  473.  
  474.        if (accum < 1 || accum > (80-NCOLS-2))
  475.        {
  476.        _AH = 9;
  477.        _DX = FP_OFF("hotkey: column out of range ...\r\n$");
  478.        geninterrupt(0x21);
  479.        return -1;
  480.        }
  481.  
  482.        setrseg ();
  483.        column = accum;
  484.        setcseg ();
  485.        return 0;
  486.    }
  487.  
  488.    if (option == 'Y')    /* ROW OPTION */
  489.    {
  490.        if (!isdigit ((digit = parse ())))
  491.        {
  492.        _AH = 9;
  493.        _DX = FP_OFF("hotkey: digit expected after 'Y'\r\n$");
  494.        geninterrupt(0x21);
  495.        return -1;
  496.        }
  497.  
  498.        accum = digit-'0';
  499.  
  500.        if (!isdigit ((digit = parse ())))
  501.        unparse ();
  502.        else
  503.        {
  504.        accum *= 10;
  505.        accum += (digit-'0');
  506.        }
  507.  
  508.        if (accum < 1 || accum > (50-NROWS-2))
  509.        {
  510.        _AH = 9;
  511.        _DX = FP_OFF("hotkey: row out of range ...\r\n$");
  512.        geninterrupt(0x21);
  513.        return -1;
  514.        }
  515.  
  516.        setrseg ();
  517.        srow = accum;
  518.        setcseg ();
  519.        return 0;
  520.    }
  521.  
  522.    return -1;
  523. }