home *** CD-ROM | disk | FTP | other *** search
/ ProfitPress Mega CDROM2 …eeware (MSDOS)(1992)(Eng) / ProfitPress-MegaCDROM2.B6I / COMM / MISC / SRC26_2.ZIP / SRC / KEYPC.C < prev    next >
Encoding:
C/C++ Source or Header  |  1990-07-13  |  16.9 KB  |  709 lines

  1. /*
  2.  * keypc.c: hterm keyboard decoder for IBM-PC, AX and J-3100
  3.  *
  4.  * Author: HIRANO Satoshi
  5.  * (C) 1989  Halca Computer Science Laboratory TM
  6.  *           University of Tokyo
  7.  *
  8.  * 2.2 89/05/16 Halca.Hirano remove all of kana char; V2.2 distribution
  9.  * 2.3 89/06/15 Halca.Hirano
  10.  *     1  remove #else
  11.  * 2.4 89/06/20 Halca.Hirano separate machine dependent
  12.  * 2.5 89/07/17 Halca.Hirano add key table.
  13.  * 2.6 89/07/20 Halca.Hirano save/load key table
  14.  *    ----- V2.3.-1.1 distribution ----
  15.  * 2.7 89/08/07 Halca.Hirano add mouse
  16.  * 2.8 89/09/14 Halca.Hirano fix mouse bug (cursor doesn't mode correctly.)
  17.  *    ---- V2.4.0 distribution ----
  18.  * 2.9 89/11/10 Tominaga@Titech ported to J3100
  19.  * ---- V2.4.2 distribution ----
  20.  * 3.0 89/12/03 Halca.Hirano
  21.  *    add BS key watcher
  22.  * ---- V2.5.1 distribution ----
  23.  * 3.1 89/12/16 Tominaga@Titech extend META-keys
  24.  *    Now META-CTRL-A generates ESC ^A
  25.  * 3.2 89/12/24 Halca.Hirano
  26.  *    fix key table loading bug. I made an attempt to WRITE APPLCursor 
  27.  *    and APPLPad!!
  28.  * 3.3 90/06/27 Zundoko@enterprise
  29.  *    generate '|' by SHIFT-\ key on J3100
  30.  *
  31.  *
  32.  * NOTE: for AX users
  33.  *    Scan code from ATOK japanese front end processor is defined below.
  34.  *    xxyy        xx < 0x81, xx is scan code, yy is ASCII code
  35.  *    00xx        xx >= 0x81, ((xx<<8)|nextchar) is shift JIS code
  36.  *    xx00        special key scan code (xx may be same as 
  37.  *            shift JIS upper byte)
  38.  *
  39.  * NOTE: for J-3100 users
  40.  *    Key code from BIOS thru ATOK japanese front end processor is as follows:
  41.  *    xxyy    if xx=0xf0, yy is a former byte of a shift-JIS character
  42.  *        if xx=0xf1, yy is a latter byte of a shift-JIS character
  43.  *        otherwise, xx is a scan code and yy is ASCII code
  44.  *
  45.  * $Header: keypc.cv  1.13  90/07/04 20:41:30  hirano  Exp $
  46.  */
  47.  
  48.  
  49. #include <stdio.h>
  50. #include <io.h>
  51. #include "option.h"
  52. #include "config.h"
  53. #include "hterm.h"
  54. #include "default.h"
  55. #include "keytabpc.h"
  56. #include "global.h"
  57.  
  58. #define S_SHIFT(p)    ((p) & 0x03)    /* left/right SHIFT is pressed    */
  59. #define S_CTRL(p)    ((p) & 0x04)    /* CTRL is pressed        */
  60. #define S_META(p)    ((p) & 0x08)    /* ALT is pressed        */
  61. #define S_NUMLOCK(p)    ((p) & 0x20)    /* NUMLOCK state        */
  62. #define SCAN_ESC    0x011b        /* scan code for ESC key    */
  63. #define SCAN_BS        0x0e08        /* scan code for SHIFT+BS key    */
  64. #define SCAN_CTRL_BS    0x0e7f        /* scan code for CTRL+BS key    */
  65. #define SCAN_ENTER    0x1c0d        /* scan code for ENTER        */
  66. #define SCAN_SPACE    0x3920        /* scan code for space        */
  67. #define SCAN_N_HENKAN    0xa700        /* scan code for henkan        */
  68. #define SCAN_C_HENKAN    0xa900        /* scan code for CTRL-henkan    */
  69. #define SCAN_M_HENKAN    0xaa00        /* scan code for META-henkan    */
  70. #define SCAN_N_MUHENKAN    0xab00        /* scan code for muhenkan    */
  71. #define SCAN_C_MUHENKAN    0xad00        /* scan code for CTRL-muhenkan    */
  72. #define SCAN_M_MUHENKAN    0xae00        /* scan code for META-muhenkan    */
  73.  
  74. #define MAX_KEYBUF (MAX_FUNKEY+3)
  75. static    u_short keyBuf[MAX_KEYBUF];    /* key data buffer    */
  76. static    int keyBufInPtr;
  77. static    int keyBufOutPtr;
  78. static    int keyBufLength;
  79.  
  80. void putBuf(unsigned short c);
  81. short putStrKeyBuf(char *s);
  82. void keyMode(void );
  83. void mouseSetHandler(int onOff);
  84. void mouseOnOff(int onOff);
  85. void mouseSetPosition(int x,int y);
  86. void far mouseEvent(int event,int x,int y);
  87.  
  88. void keyInit()
  89. /* iniz keyboard mode */
  90. {
  91.     clickFlag = DEFAULT_KEY_CLICK;
  92.     applKeypad = DEFAULT_APP_KEYBOARD;
  93.     applCursor = DEFAULT_CURSOR_KEY_MODE;
  94.     newline = DEFAULT_NEWLINE_MODE;
  95.     asckey = YES;            /* always ascii keyboard    */
  96.     mouseSpeed = DEFAULT_MOUSE_SPEED;
  97.     bsKeyCount = keyCount = 0;
  98.     bsKeyRatio = DEFAULT_BS_KEY_RATIO;
  99.     keyBufInPtr = keyBufOutPtr = keyBufLength = 0;
  100.     keyReInit();
  101. }
  102.  
  103. void keyReInit()
  104. {
  105.     mouseInit();
  106. }
  107.  
  108. void keySetup()
  109. /* setup keyboard mode */
  110. {}
  111.  
  112. void keyEnd()
  113. {
  114.     mouseEnd();
  115. }
  116.  
  117. int checkKey()
  118. /*
  119.  * return 0 if key buffer is empty
  120.  */
  121. {
  122.     if (checkBIOSKey())
  123.         return(YES);
  124.     /* check shift state */
  125.     rg.h.ah = 2;
  126.     int86(KEY_BIOS, &rg, &rg);
  127.     if (rg.h.al & 0x0f)    /* check right/left shift, ctrl, alt */
  128.         return(YES);
  129.     return(NO);
  130. }
  131.  
  132. short keyin()
  133. /* 
  134.  * check keyboard status and return key if available 
  135.  * return:
  136.  *    -1    key is not available
  137.  *    00xx    ASCII, kana
  138.  *    xxyy    hterm kanji code
  139.  *    xx00    special key code
  140.  */
  141. {
  142.     short        c, c2;
  143.     register u_char    scan;
  144.     u_char        shiftState;
  145.  
  146.     /*
  147.      *  if keyBuf is not empty, return char from it.
  148.      */
  149.     if (keyBufLength > 0) {
  150.         --keyBufLength;
  151.         c = keyBuf[keyBufOutPtr];
  152.         if (++keyBufOutPtr >= MAX_KEYBUF)
  153.             keyBufOutPtr = 0;
  154.         return(c);
  155.     }
  156.  
  157. #ifdef SOFT_FONT
  158.         if (softFont && blinkCursor && (blinkTimer <= 0)) {
  159.             blinkSoftCursor();
  160.         }
  161. #endif /* SOFT_FONT */
  162.  
  163.     if ((c = inputKey()) == -1)
  164.         return(-1);
  165.  
  166.     timerValue = timerLoadValue;
  167.     keyCount++;
  168.  
  169.     /* get shift state */
  170.     rg.h.ah = 2;
  171.     int86(KEY_BIOS, &rg, &rg);
  172.     shiftState = rg.h.al;
  173.  
  174.     if (clickFlag == YES)
  175.         click();
  176.  
  177.     switch (c) {            /* keys to be treated with care    */
  178.     case SCAN_ESC:
  179.         if (S_SHIFT(shiftState))
  180.             sendBreak(1);        /* short break    */
  181.         else if (S_CTRL(shiftState))
  182.             sendBreak(2);        /* long break    */
  183.         else
  184.             return(ESC);
  185.         return(-1);
  186.     case SCAN_BS:
  187.     case SCAN_CTRL_BS:
  188.         bsKeyCount++;
  189.         if (bsDel == BS_DEL)
  190.             return(DEL);
  191.         return(BS);
  192.     case SCAN_ENTER:
  193.         return(CR);
  194.     case SCAN_SPACE:
  195.     case SCAN_N_HENKAN:        /* AX henkan key    */
  196.     case SCAN_N_MUHENKAN:        /* AX muhenkan key    */
  197.         if (S_META(shiftState)) {    /* ALT    */
  198.             if (S_CTRL(shiftState)) {
  199.                 putBuf(0);
  200.             } else {
  201.                 putBuf(SPACE);
  202.             }
  203.             return(ESC);
  204.         } else if (S_CTRL(shiftState)) {
  205.             return(0);
  206.         }
  207.         return(SPACE);
  208.     case SCAN_C_HENKAN:
  209.     case SCAN_C_MUHENKAN:        /* ctrl space        */
  210.         return(0);
  211.     case SCAN_M_HENKAN:        /* alt space        */
  212.     case SCAN_M_MUHENKAN:
  213.         putBuf(SPACE);
  214.         return(ESC);
  215.     case 0x372a:            /* tenkey * key        */
  216.         if (applKeypad)        /* application keypad    */
  217.             return(putStrKeyBuf(APPLPad[0]));
  218.         else            /* ten key        */
  219.             return(c & 0xff);
  220. #ifdef AX
  221.     case 0x565c:
  222.     case 0x567c:
  223.     case 0x561c:            /* AX \| key        */
  224.         return(c & 0xff);
  225. #endif /* AX */
  226. #ifdef J3100
  227.     case 0x557c:            /* J-3100 SHIFT-\    Zundoko's patch */
  228.     case 0x555c:            /* J-3100 \ key        */
  229.     case 0x551c:            /* J-3100 CTRL-\    */
  230.         if (S_META(shiftState)) {
  231.             putBuf(c & 0xff);
  232.             return(ESC);
  233.         } else {
  234.             return(c & 0xff);
  235.         }
  236.     case 0x1a1d:            /* J-3100 CTRL-[ key    */
  237.         return(ESC);        /* adjust to ESC    */
  238.     case 0x1b1c:            /* J-3100 CTRL-] key    */
  239.         return(0x1d);        /* adjust to ^]        */
  240. #endif /* J3100 */
  241.     }
  242.  
  243.     scan = c >> 8;
  244.  
  245. #ifdef KANJI
  246. #ifndef J3100
  247.     if (scan == 0) {
  248.         if (isSJIS1(c)) {        /*if kanji start */
  249.             while ((c2 = inputKey()) == -1)
  250.                 ;
  251.             return(SJIStoJIS(c, c2));
  252.         } else if (scan == 0)
  253.             return((u_short)c);
  254.     }
  255. #else /* J3100 */
  256.     if (scan == 0 || scan == 0xf0 || scan == 0xf1) {
  257.         c &= 0xff;    /* adjust kanji code from FEP */
  258.         if (isSJIS1(c)) {        /*if kanji start */
  259.             while ((c2 = inputKey()) == -1)
  260.                 ;
  261.             c2 &= 0xff;    /* adjust this also */
  262.             return(SJIStoJIS(c, c2));
  263.         } else if (scan == 0) {
  264.             return((u_short)c);
  265.         }
  266.     }
  267. #endif /* J3100 */
  268. #endif /* KANJI */
  269.  
  270.     if (S_META(shiftState)) {            /* ALT pushed */
  271.         if (S_CTRL(shiftState)) {        /* ALT-CTRL */
  272.             if (0x78 <= scan && scan <= 0x83) {
  273.                 /*
  274.                  * number key with META-CTRL
  275.                  */
  276.                 if ((c = metaCtrlTable[scan - 0x78]) != -1) {
  277.                     putBuf(c);
  278.                     return(ESC);
  279.                 } else {
  280.                     return(-1);
  281.                 }
  282.             } else if (0x01 <= scan && scan <= 0x35) {
  283.                 /* 
  284.                  * typewriter key with META-CTRL
  285.                  */
  286.                 if ((c = metaCtrlTable[scan]) != -1) {
  287.                     putBuf(c);
  288.                     return(ESC);
  289.                 } else {
  290.                     return(-1);
  291.                 }
  292.             } else {
  293.                 /* no code assigned this key */
  294.                 return(-1);
  295.             }
  296.         } else if (S_SHIFT(shiftState)) {    /* ALT-SHIFT */
  297.             if (0x78 <= scan && scan <= 0x83) {
  298.                 /*
  299.                  * number key with META-SHIFT
  300.                  */
  301.                 if ((c = metaShiftTable[scan - 0x78]) != -1) {
  302.                     putBuf(c);
  303.                     return(ESC);
  304.                 } else {
  305.                     return(-1);
  306.                 }
  307.             } else if (0x01 <= scan && scan <= 0x35) {
  308.                 /* 
  309.                  * typewriter key with META-SHIFT
  310.                  */
  311.                 if ((c = metaShiftTable[scan]) != -1) {
  312.                     putBuf(c);
  313.                     return(ESC);
  314.                 } else {
  315.                     return(-1);
  316.                 }
  317.             } else {
  318.                 /* no code is assigned to this key */
  319.                 return(-1);
  320.             }
  321.         } else {                /* ALT only */
  322.             if (0x78 <= scan && scan <= 0x83) {
  323.                 /*
  324.                  * number key with META
  325.                  */
  326.                 if ((c = metaTable[scan - 0x78]) != -1) {
  327.                     putBuf(c);
  328.                     return(ESC);
  329.                 } else {
  330.                     return(-1);
  331.                 }
  332.             } else if (0x01 <= scan && scan <= 0x35) {
  333.                 /* 
  334.                  * typewriter key with META
  335.                  */
  336.                 if ((c = metaTable[scan]) != -1) {
  337.                     putBuf(c);
  338.                     return(ESC);
  339.                 } else {
  340.                     return(-1);
  341.                 }
  342.             } else if (SCAN_M_PF1 <= scan && scan <= SCAN_M_PF10) {
  343.                 /* 
  344.                  * ALT PF key
  345.                  */
  346.                 return(METAFunkey[scan - SCAN_M_PF1]);
  347.             } else {
  348.                 /* no META supported for this code */
  349.                 return(-1);
  350.             }
  351.         } /* with META, if "CTRL or SHIFT is pushed or not" */
  352.     } else {                    /* no ALT */
  353.         if (S_CTRL(shiftState)) {        /* CTRL */
  354.             if (SCAN_C_PF1 <= scan && scan <= SCAN_C_PF10) {
  355.                 /* 
  356.                  * CTRL PF key
  357.                  */
  358.                 return(CTRLFunkey[scan - SCAN_C_PF1]);
  359.             } else if (SCAN_C_PAD_BEGIN <= scan && scan <= SCAN_C_PAD_END) {
  360.                 /*
  361.                  * CTRL-pad/cursor key
  362.                  */
  363.                 c = CTRLCursor[scan-SCAN_C_PAD_BEGIN];
  364.                 return(c ? c : -1);
  365.             } else if (0x01 <= scan && scan <= 0x35) {
  366.                 /*
  367.                  * typewrite key with CTRL
  368.                  */
  369.                 return(c & 0xff);
  370.             } else {
  371.                 /*
  372.                  * no code
  373.                  */
  374.                 return(-1);
  375.             }
  376.         } else if (S_SHIFT(shiftState)) {    /* SHIFT */
  377.             if (SCAN_S_PF1 <= scan && scan <= SCAN_S_PF10) {
  378.                 /* 
  379.                  * SHIFT PF key 
  380.                  */
  381.                 return(putStrKeyBuf(SHIFTFunkey[scan - SCAN_S_PF1]));
  382.             } else if (SCAN_PF1 <= scan && scan <= SCAN_PF10) {
  383.                 /* 
  384.                  * normal PF key 
  385.                  */
  386.                 return(putStrKeyBuf(NORMALFunkey[scan - SCAN_PF1]));
  387.             } else if (SCAN_PAD_BEGIN <= scan && scan <= SCAN_PAD_END) {
  388.                 /*
  389.                  * normal pad key; non numlock (SHIFT should be ignored)
  390.                  */
  391.                 scan = scan - SCAN_PAD_BEGIN;
  392.                 if ((c & 0xff) && ((c & 0xff) != 0xe0)) { /* keypad is tenkey    */
  393.                     if (applKeypad && mode == M_COMM) /* application keypad    */
  394.                         return(putStrKeyBuf(APPLPad[scan+1 /* 1 means '*' key */]));
  395.                     else        /* number key        */
  396.                         return(c & 0xff);
  397.                 } else {
  398.                     if (mode != M_COMM)    /* in setup or history editor */
  399.                         return(SETUPCursor[scan]);
  400.                     else if (applCursor)    /* application cursor    */
  401.                         return(putStrKeyBuf(APPLCursor[scan]));
  402.                     else            /* normal cursor    */
  403.                         return(putStrKeyBuf(NORMALCursor[scan]));
  404.                 }
  405.             } else if (0x01 <= scan && scan <= 0x35) {
  406.                 /*
  407.                  * typewriter key with SHIFT
  408.                  */
  409.                 return(c & 0xff);
  410.             } else {
  411.                 /*
  412.                  * no code for this
  413.                  */
  414.                 return(-1);
  415.             }
  416.         } else {                /* normal */
  417.             if (SCAN_PF1 <= scan && scan <= SCAN_PF10) {
  418.                 /* 
  419.                  * normal PF key 
  420.                  */
  421.                 return(putStrKeyBuf(NORMALFunkey[scan - SCAN_PF1]));
  422.             } else if (SCAN_PAD_BEGIN <= scan && scan <= SCAN_PAD_END) {
  423.                 /*
  424.                  * normal pad key; non numlock 
  425.                  */
  426.                 scan = scan - SCAN_PAD_BEGIN;
  427.                 if ((c & 0xff) && ((c & 0xff) != 0xe0)) { /* keypad is tenkey    */
  428.                     if (applKeypad && mode == M_COMM) /* application keypad    */
  429.                         return(putStrKeyBuf(APPLPad[scan+1 /* 1 means '*' key */]));
  430.                     else        /* number key        */
  431.                         return(c & 0xff);
  432.                 } else {
  433.                     if (mode != M_COMM)    /* in setup or history editor */
  434.                         return(SETUPCursor[scan]);
  435.                     else if (applCursor)    /* application cursor    */
  436.                         return(putStrKeyBuf(APPLCursor[scan]));
  437.                     else            /* normal cursor    */
  438.                         return(putStrKeyBuf(NORMALCursor[scan]));
  439.                 }
  440.             } else if (0x01 <= scan && scan <= 0x35) {
  441.                 /*
  442.                  * typewriter key (return its ASCII code)
  443.                  */
  444.                 return(c & 0xff);
  445.             } else {
  446.                 /*
  447.                  * no code
  448.                  */
  449.                 return(-1);
  450.             }
  451.         } /* without META, if "CTRL or SHIFT is pushed or not" */
  452.     } /* if "META is pushed or not" */
  453.     
  454.     /* ignore if fallen down here, but it cannot! */
  455.     return(-1);
  456. }
  457.  
  458. static void putBuf(c)
  459. u_short c;
  460. {
  461.     if (keyBufLength >= MAX_KEYBUF) {
  462.         bell();        /* bell is more proper than click */
  463.         return;
  464.     }
  465.     keyBuf[keyBufInPtr] = c;
  466.     if (++keyBufInPtr >= MAX_KEYBUF)
  467.         keyBufInPtr = 0;
  468.     keyBufLength++;
  469.     if (c == DEL)
  470.         bsKeyCount++;        /* for BS key watcher        */
  471. }
  472.  
  473. static short putStrKeyBuf(s)
  474. register char *s;
  475. {
  476.     register char *p;
  477.  
  478.     if (*s == '\0')
  479.         return(-1);
  480.     for (p = s + 1; *p; p++)
  481.         putBuf(*p);
  482.     return(*s);
  483. }
  484.  
  485. void keyMode()
  486. {
  487.     /* nothing to do */
  488. }
  489.  
  490. void setBSDel(bsDelFlag)
  491. int bsDelFlag;
  492. {
  493.     /* not needed */
  494. }
  495.  
  496. #ifdef SETUP
  497. void editPFKey()
  498. {
  499.     editKeyTable(funkeyName, NORMALFunkey, NUM_FUNKEY, MAX_FUNKEY, FUNKEY_NAME_LEN);
  500. }
  501.  
  502. void editSPFKey()
  503. {
  504.     editKeyTable(funkeyName, SHIFTFunkey, NUM_FUNKEY, MAX_FUNKEY, FUNKEY_NAME_LEN);
  505. }
  506.  
  507. void editCursorKey()
  508. {
  509.     editKeyTable(&keypadName[1], NORMALCursor, NUM_PADKEY, MAX_FUNKEY, KEYPAD_NAME_LEN);
  510. }
  511.  
  512. void editAppCursorKey()
  513. {
  514.     editKeyTable(&keypadName[1], APPLCursor, NUM_PADKEY, MAX_FUNKEY, KEYPAD_NAME_LEN);
  515. }
  516.  
  517. void editAppKeyPad()
  518. {
  519.     editKeyTable(keypadName, APPLPad, NUM_PADKEY+1, MAX_FUNKEY, KEYPAD_NAME_LEN);
  520. }
  521.  
  522. void editNormalKeys(){}
  523. void editShiftKeys(){}
  524. void editCtrlKeys(){}
  525. void editKanaKeys(){}
  526. void editShKanaKeys(){}
  527.  
  528. void editBinding()
  529. {
  530.     editKeyTable(bindName, (u_char (*)[MAX_FUNKEY])bindTab, NUM_BIND, 1, BIND_NAME_LEN);
  531. }
  532.  
  533. void saveKey(fd)
  534. int fd;
  535. /*
  536.  * save key pad string, cursor key string, pf key string
  537.  */
  538. {
  539.     write(fd, (char *)NORMALFunkey, sizeof(NORMALFunkey));
  540.     write(fd, (char *)SHIFTFunkey, sizeof(SHIFTFunkey));
  541.     write(fd, (char *)NORMALCursor, sizeof(NORMALCursor));
  542.     write(fd, (char *)APPLCursor, sizeof(APPLCursor));
  543.     write(fd, (char *)APPLPad, sizeof(APPLPad));
  544.     write(fd, (char *)bindTab, sizeof(bindTab));
  545. }
  546. #endif /* SETUP */
  547.  
  548. void loadKey(fd)
  549. int fd;
  550. /*
  551.  * load key pad string, cursor key string, pf key string
  552.  */
  553. {
  554.     read(fd, (char *)NORMALFunkey, sizeof(NORMALFunkey));
  555.     read(fd, (char *)SHIFTFunkey, sizeof(SHIFTFunkey));
  556.     read(fd, (char *)NORMALCursor, sizeof(NORMALCursor));
  557.     read(fd, (char *)APPLCursor, sizeof(APPLCursor));
  558.     read(fd, (char *)APPLPad, sizeof(APPLPad));
  559.     read(fd, (char *)bindTab, sizeof(bindTab));
  560. }
  561.  
  562. #ifdef MOUSE
  563.  
  564. /*
  565.  *
  566.  * mouse related functions
  567.  *
  568.  */
  569. int mouseExists;
  570. int mouseOn;
  571. int mouseX, mouseY, mouseOriginX, mouseOriginY;
  572. int mouseLowX, mouseHighX, mouseLowY, mouseHighY;
  573. void (FAR *mouseHandler)();
  574. #define INT_MOUSE 0x33
  575.  
  576. void mouseInit()
  577. /*
  578.  * initialize mouse
  579.  */
  580. {
  581.     rg.x.ax = 0;
  582.     int86(INT_MOUSE, &rg, &rg);    /* check mouse environment    */
  583.     if (rg.x.ax == 0) 
  584.         return;            /* no mouse            */
  585.     /* get current position */
  586.     rg.x.ax = 3;
  587.     int86(INT_MOUSE, &rg, &rg);
  588.     mouseOriginX = mouseX = rg.x.cx;
  589.     mouseOriginY = mouseY = rg.x.dx;
  590.     mouseLowX = mouseOriginX - 100; mouseHighX = mouseOriginX + 100;
  591.     mouseLowY = mouseOriginY - 80; mouseHighY = mouseOriginY + 80;    
  592.     mouseSetHandler(YES);
  593. }
  594.  
  595. void mouseEnd()
  596. {
  597.     mouseSetHandler(NO);        /* remove handler        */
  598. }
  599.  
  600. void mouseSetHandler(onOff)
  601. int onOff;
  602. {
  603.     struct SREGS segRegs;
  604.  
  605.     mouseHandler = getMouseIntAddress();
  606.     segread(&segRegs);
  607.     rg.x.ax = 0x0c;
  608.     /*
  609.      * if onOff = YES, set move, left/right press handler
  610.      * else mask all event
  611.      */
  612.     rg.x.cx = onOff ? 0x0b : 0;
  613.     segRegs.es = FP_SEG(mouseHandler);
  614.     rg.x.dx = FP_OFF(mouseHandler);
  615.     int86x(INT_MOUSE, &rg, &rg, &segRegs);    /* set interrupt handler */
  616. }
  617.  
  618. void mouseOnOff(onOff)
  619. int onOff;
  620. {
  621.     rg.x.ax = onOff ? 1 : 2;
  622.     int86(INT_MOUSE, &rg, &rg);
  623. }
  624.  
  625. void mouseSetPosition(x, y)
  626. int x, y;
  627. {
  628.     rg.x.ax = 4;
  629.     rg.x.cx = x;
  630.     rg.x.dx = y;
  631.     int86(INT_MOUSE, &rg, &rg);
  632. }
  633.  
  634. void FAR mouseEvent(event, x, y)
  635. /*
  636.  * mouse event interrupt handler
  637.  */
  638. int event, x, y;
  639. {
  640.     u_short c = 0;
  641.     int dx = x - mouseX;
  642.     int dy = y - mouseY;
  643.     int thresh = (mouseSpeed + 1) * MOUSE_SPEED_BASE;
  644.  
  645.     spl7();
  646.     switch (event) {
  647.     case 1:    /* cursor is moved. */
  648.         if (mode != M_COMM) {
  649.             if (mode == M_SETUP)
  650.                 thresh *= 2;    /* for selecting menu */
  651.             if (dy > thresh)
  652.                 c = DOWN_KEY;
  653.             else if (dy < -thresh)
  654.                 c = UP_KEY;
  655.             if (c) {
  656.                 putBuf(c);
  657.                 mouseY = y;
  658.                 c = 0;
  659.             }
  660.             if (dx > thresh)
  661.                 c = RIGHT_KEY;
  662.             else if (dx < -thresh)
  663.                 c = LEFT_KEY;
  664.             if (c)
  665.                 mouseX = x;
  666.         }
  667.         if (x < mouseLowX || x > mouseHighX || y < mouseLowY || y > mouseHighY) {
  668.             /* recenter mouse position        */
  669.             mouseSetPosition(mouseOriginX, mouseOriginY);
  670.             mouseX = mouseOriginX;
  671.             mouseY = mouseOriginY;
  672.         }
  673.         break;
  674.     case 2:    /* left botton is pressed. */        
  675.         if (mode == M_HISTORY)
  676.             c = INS_KEY;
  677.         else if (mode == M_SETUP)
  678.             c = CR;
  679.         else /* communication mode */
  680.             c = PF_HIST_EDIT;    /* call history editor */
  681.         break;
  682.     case 8: /* right botton is pressed. */
  683.         if (mode == M_HISTORY)
  684.             c = CR;
  685.         else if (mode == M_SETUP)
  686.             c = ESC;
  687.         else /* communication mode */
  688.             c = SETUP_KEY;        /* call set-up    */
  689.         break;
  690.     }
  691.     /* 
  692.      * put emulated key into BIOS key buffer
  693.      */
  694.     if (c)
  695.         putBuf(c);
  696.     /*
  697.      * THIS may be bug!
  698.      */
  699.     splx();
  700. }
  701. #else
  702. void FAR mouseEvent() {}
  703. void mouseOnOff() {}
  704. void mouseSetPosition() {}
  705. void mouseEnd() {}
  706. void mouseInit() {}
  707. #endif /* MOUSE */
  708.  
  709.