home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-385-Vol-1of3.iso / x / xibm.zip / AIX / hftQueue.c < prev    next >
C/C++ Source or Header  |  1992-02-11  |  14KB  |  573 lines

  1. /*
  2.  * $Id: hftQueue.c,v 5.1 1992/02/12 00:21:36 jfc Exp $
  3.  *
  4.  * Copyright IBM Corporation 1987,1988,1989
  5.  *
  6.  * All Rights Reserved
  7.  *
  8.  * Permission to use, copy, modify, and distribute this software and its
  9.  * documentation for any purpose and without fee is hereby granted,
  10.  * provided that the above copyright notice appear in all copies and that 
  11.  * both that copyright notice and this permission notice appear in
  12.  * supporting documentation, and that the name of IBM not be
  13.  * used in advertising or publicity pertaining to distribution of the
  14.  * software without specific, written prior permission.
  15.  *
  16.  * IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  17.  * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
  18.  * IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
  19.  * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  20.  * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  21.  * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  22.  * SOFTWARE.
  23.  *
  24. */
  25. #include <fcntl.h>
  26. #include <signal.h>
  27.  
  28. #define    HFRDATA    8192
  29.  
  30. #include <sys/hft.h>
  31. #include <sys/time.h>
  32.  
  33. #include "ibmTrace.h"
  34.  
  35. #include "hftQueue.h"
  36.  
  37.     /*
  38.      * Defines to simplify dealing with AIX.
  39.      */
  40.  
  41. #define    HFWDCHARS(n)    (n)>>8&0xff, (n)&0xff
  42. #define    FLWDCHARS(n)    (n)>>24&0xff,(n)>>16&0xff,(n)>>8&0xff,(n)&0xff
  43. #define    VTD(n)    HFINTROESC, HFINTROLBR, HFINTROEX, FLWDCHARS(n)
  44.  
  45. #define    ringlen    sizeof(hftRing.buf)
  46. #define    RINGLEN    HFWDCHARS(ringlen)
  47. #define    RINGVTD    VTD(sizeof(hftRing) - 3)
  48. #define    RINGOFFSET    FLWDCHARS(sizeof(hftRing) - sizeof(hftRing.buf) -\
  49.                   sizeof(hftRing.req.hf_intro) - \
  50.                   sizeof(hftRing.req.hf_sublen) -\
  51.                   sizeof(hftRing.req.hf_subtype))
  52. #define RINGBASE    ((unsigned char *)&hftRing.buf.hf_rsvd[0])
  53. #define    RINGFIRST    32
  54. #define    RINGLAST    sizeof(hftRing.buf)
  55.  
  56. #define    HFT_ESC_KEYBOARD    0x77
  57. #define    HFT_ESC_LOCATOR        'y'
  58. #define    HFT_ESC_ADAPT        'r'
  59.  
  60.     /*
  61.      * Package global variables.
  62.      */
  63.  
  64.     unsigned    hftPending;
  65.     unsigned    hftGrantPending;
  66.     unsigned    hftRetractPending;
  67. static    int        hftSetInterrupts= 0;
  68. static    int        hftHaveScreen=    FALSE;
  69.     int        hftQFD=    -1;
  70.     int        hftNeedsReset=  FALSE;
  71.  
  72. static    hftEvHandler    hftHandlers[HFT_NEVENTS]= {
  73.                 HFT_IGNORE,
  74.                 HFT_IGNORE,
  75.                 HFT_IGNORE,
  76.                 HFT_IGNORE,
  77.                 HFT_IGNORE,
  78.                 HFT_IGNORE,
  79.                 HFT_IGNORE,
  80.                 HFT_IGNORE,
  81.                 HFT_IGNORE,
  82.                 HFT_IGNORE
  83.             };
  84.  
  85. static    int        hftEvSize[HFT_NEVENTS]= { 
  86.                 sizeof(hftKeyEv),
  87.                 sizeof(hftLocEv),
  88.                 sizeof(hftAdaptEv),
  89.                 sizeof(hftLocEv),
  90.                 sizeof(hftLPFKEv),
  91.                 sizeof(hftDialEv)
  92.             };
  93.  
  94. #define    HFT_N_LOC_STYPES    4
  95. static    int        hftLocatorSubtype[HFT_N_LOC_STYPES] = {
  96.             HFT_LOCATOR,    /* mouse report */
  97.             HFT_TABLET,    /* locator report */
  98.             HFT_LPFK,    /* LPFK report */
  99.             HFT_DIAL    /* Dial report */
  100. };
  101.  
  102. static    struct    hfprotocol    hftProtoReq= { 
  103.         VTD(sizeof(hftProtoReq)-3),    /* escape sequence introducer */
  104.         HFMOMPROH, HFMOMPROL, 2, 0    /* random garbage */
  105.     };
  106.  
  107. static    struct {
  108.     struct hfmomscreq    req;
  109.     struct     hfmomring    buf;
  110. } hftRing= {
  111.     RINGVTD,HFMOMREQH,HFMOMREQL,2,0,RINGLEN,RINGOFFSET,
  112.     0,0,0xff,0,RINGFIRST,RINGFIRST,0,0,0,0,0,
  113.      };
  114.  
  115. static    hftEvent    hftProtoArrived= { HFT_EVENT_ARRIVED };
  116. static    hftEvent    hftProtoGranted= { HFT_GRANTED };
  117. static    hftEvent    hftProtoRetracted= { HFT_RETRACTED };
  118. static    hftEvent    hftProtoBefore= { HFT_BEFORE_EVENTS };
  119. static    hftEvent    hftProtoAfter= { HFT_AFTER_EVENTS };
  120.  
  121. static    hftEvHandler    hftTimeoutHndlr;
  122. static    int        hftTimeoutCount;
  123.  
  124. /***====================================================================***/
  125.  
  126. void
  127. hftInterruptAlways()
  128. {
  129.     TRACE(("hftInterruptAlways()\n"));
  130.     hftRing.buf.hf_intreq= hftSetInterrupts= 0xff;
  131.     return;
  132. }
  133.  
  134. /***====================================================================***/
  135.  
  136. void
  137. hftInterruptOnFirst()
  138. {
  139.     TRACE(("hftInterruptOnFirst()\n"));
  140.     hftRing.buf.hf_intreq= hftSetInterrupts= 0;
  141.     return;
  142. }
  143.  
  144. /***====================================================================***/
  145.  
  146. #ifdef AIXrt
  147. #define    SIGTYPE int
  148. #else
  149. #define    SIGTYPE void
  150. #endif
  151.  
  152. static SIGTYPE
  153. hftIgnoreMsg()
  154. {
  155.     TRACE(("hftIgnoreMsg()\n"));
  156.     hftRing.buf.hf_intreq= hftSetInterrupts;
  157.     hftPending++;
  158.     if (hftHandlers[HFT_EVENT_ARRIVED])
  159.     (*hftHandlers[HFT_EVENT_ARRIVED])(&hftProtoArrived);
  160.     return;
  161. }
  162.  
  163. static SIGTYPE
  164. hftGrant()
  165. {
  166.     TRACE(("hftGrant()\n"));
  167.     hftGrantPending++;
  168.     hftPending++;
  169.     if (hftHandlers[HFT_EVENT_ARRIVED])
  170.     (*hftHandlers[HFT_EVENT_ARRIVED])(&hftProtoArrived);
  171.     return;
  172. }
  173.  
  174. static SIGTYPE
  175. hftRetract()
  176. {
  177.     TRACE(("hftRetract()\n"));
  178.     hftRetractPending++;
  179.     hftPending++;
  180.     if (hftHandlers[HFT_EVENT_ARRIVED])
  181.     (*hftHandlers[HFT_EVENT_ARRIVED])(&hftProtoArrived);
  182.     return;
  183. }
  184.  
  185. #ifdef AIXps2
  186.  typedef __SIGVOID (*sighandler_t)();
  187. #else
  188.  typedef void (*sighandler_t)();
  189. #endif
  190.  
  191. static void
  192. hftSetUpSignals(save)
  193.      int    save;
  194. {
  195. #ifndef AIXrt
  196.     struct  sigaction       svgrant;
  197.     struct  sigaction       svretract;
  198.     struct  sigaction       svmessage;
  199.     struct  sigaction       oldsig;
  200.  
  201.     TRACE(("hftSetUpSignals()\n"));
  202.  
  203.     svgrant.sa_handler=         (sighandler_t)hftGrant;
  204.     sigemptyset(&svgrant.sa_mask);
  205.     sigaddset(&svgrant.sa_mask,SIGGRANT);
  206.     sigaddset(&svgrant.sa_mask,SIGRETRACT);
  207.     svgrant.sa_flags= SA_RESTART ;
  208.  
  209.     svretract.sa_handler=       (sighandler_t)hftRetract;
  210.     sigemptyset(&svretract.sa_mask);
  211.     sigaddset(&svretract.sa_mask,SIGGRANT);
  212.     sigaddset(&svretract.sa_mask,SIGRETRACT);
  213.     svretract.sa_flags= SA_RESTART;
  214.  
  215.     svmessage.sa_handler=       (sighandler_t)hftIgnoreMsg;
  216.     sigemptyset(&svmessage.sa_mask);
  217.     sigaddset(&svmessage.sa_mask,SIGMSG);
  218.     svmessage.sa_flags= SA_RESTART ;
  219.  
  220.     sigaction(SIGGRANT,&svgrant,&oldsig);
  221.     if (save)
  222.     {
  223.     if ((oldsig.sa_handler!=SIG_DFL)&&(oldsig.sa_handler!=SIG_IGN))
  224.         hftHandlers[HFT_GRANTED]= oldsig.sa_handler;
  225.     }
  226.     sigaction(SIGRETRACT,&svretract,&oldsig);
  227.     if (save)
  228.     {
  229.     if ((oldsig.sa_handler!=SIG_DFL)&&(oldsig.sa_handler!=SIG_IGN))
  230.         hftHandlers[HFT_RETRACTED]= oldsig.sa_handler;
  231.     }
  232.     sigaction(SIGMSG,&svmessage,&oldsig);
  233.     if (save)
  234.     {
  235.     if ((oldsig.sa_handler!=SIG_DFL)&&(oldsig.sa_handler!=SIG_IGN))
  236.         hftHandlers[HFT_EVENT_ARRIVED]= oldsig.sa_handler;
  237.     }
  238. #else /* AIXrt */
  239.     struct  sigvec  svgrant;
  240.     struct  sigvec  svretract;
  241.     struct  sigvec  svmessage;
  242.     struct  sigvec  oldsig;
  243.  
  244.     TRACE(("Entering hftSetUpSignals()\n"));
  245.     svgrant.sv_handler=         hftGrant;
  246.     svgrant.sv_mask=            (1<<SIGGRANT)|(1<<SIGRETRACT);
  247.     svgrant.sv_onstack=         0;
  248.     svretract.sv_handler=       hftRetract;
  249.     svretract.sv_mask=          (1<<SIGGRANT)|(1<<SIGRETRACT);
  250.     svretract.sv_onstack=       0;
  251.     svmessage.sv_handler=       hftIgnoreMsg;
  252.     svmessage.sv_mask=          (1<<SIGMSG);
  253.     svmessage.sv_onstack=       0;
  254.     sigvec(SIGGRANT,&svgrant,&oldsig);
  255.     if (save) {
  256.     if ((oldsig.sv_handler!=SIG_DFL)&&(oldsig.sv_handler!=SIG_IGN))
  257.         hftHandlers[HFT_GRANTED]= oldsig.sv_handler;
  258.     }
  259.     sigvec(SIGRETRACT,&svretract,&oldsig);
  260.     if (save) {
  261.     if ((oldsig.sv_handler!=SIG_DFL)&&(oldsig.sv_handler!=SIG_IGN))
  262.         hftHandlers[HFT_RETRACTED]= oldsig.sv_handler;
  263.     }
  264.     sigvec(SIGMSG,&svmessage,&oldsig);
  265.     if (save) {
  266.     if ((oldsig.sv_handler!=SIG_DFL)&&(oldsig.sv_handler!=SIG_IGN))
  267.         hftHandlers[HFT_EVENT_ARRIVED]= oldsig.sv_handler;
  268.     }
  269.     TRACE(("Leaving hftSetUpSignals()\n"));
  270. #endif /* AIXrt */
  271.     return;
  272. }
  273.  
  274.     
  275. /***====================================================================***/
  276.  
  277.     /*
  278.      * defined in hftQueue.h
  279.      */
  280.  
  281. int
  282. hftInitQueue(deviceId,saveOldHandlers)
  283.      int    deviceId;
  284.      int    saveOldHandlers;
  285. {
  286.     struct    hfsmon    flags;
  287.     unsigned    offset;
  288.  
  289.     TRACE(("hftInitQueue()\n"));
  290.  
  291.     if (hftQFD<0)
  292.     {
  293.     if ( ( hftQFD = hftFindAScreen(deviceId) )<0 )
  294.     {
  295.         ErrorF("Fatal!      error opening /dev/hft\n");
  296.         ErrorF("            exiting\n");
  297.         exit(1);
  298.     }
  299.     }
  300.     hftSetUpSignals(saveOldHandlers);
  301.     flags.hf_momflags= HFSINGLE;
  302.  
  303.     /*
  304.      * once they fix hft.h this should be un-necessary, but will still work
  305.      */
  306. #ifndef MAX_MON_ADDRS
  307. # define MAX_MON_ADDRS 1
  308. #endif
  309.  
  310. #ifdef AIXps2
  311.     flags.hf_momscnt= MAX_MON_ADDRS;
  312. #endif    
  313.  
  314.     if (ioctl(hftQFD,HFSMON,&flags)!=0) {
  315.     ErrorF("Fatal!      error entering monitor mode\n");
  316.     ErrorF("            exiting\n");
  317.     exit(1);
  318.     }
  319.     hftProtoReq.hf_select[0] = HFXLATKBD;
  320.     hftProtoReq.hf_select[1] = HFLOCATOR | HFDIALS | HFLPFKS ;
  321.     hftProtoReq.hf_value[0]  = 0;
  322.     hftProtoReq.hf_value[1]  = HFLOCATOR | HFDIALS | HFLPFKS ;
  323.     if (write(hftQFD,&hftProtoReq,sizeof(hftProtoReq))!=sizeof(hftProtoReq))
  324.     {
  325.     ErrorF("Fatal!      protocol write failed\n");
  326.     ErrorF("            exiting\n");
  327.     exit(1);
  328.     }
  329.  
  330.     hftRing.buf.hf_intreq= hftSetInterrupts;
  331.     if (write(hftQFD,&hftRing,sizeof(hftRing))!=sizeof(hftRing))
  332.     {
  333.     ErrorF("Fatal!      request write failed\n");
  334.     ErrorF("            exiting\n");
  335.     exit(1);
  336.     }
  337.     hftPending= 0;
  338.  
  339. #ifdef AIXEXTENSIONS
  340.     hftQueryHardwareConfig(deviceId);
  341. #endif
  342.     return(TRUE);
  343. }
  344.  
  345. /***====================================================================***/
  346.  
  347. static    struct    hfprotocol    hftKSRProtoReq= { 
  348.         VTD(sizeof(hftProtoReq)-3),    /* escape sequence introducer */
  349.         HFKSRPROH, HFKSRPROL, 2, 0    /* random garbage */
  350.     };
  351.  
  352. static    struct    hfmomscrel    hftVTDRelease= {
  353.                     VTD(sizeof(hftVTDRelease)-3),
  354.                     HFMOMRELH,HFMOMRELL
  355.                 };
  356.  
  357. #include <stdio.h>
  358. void
  359. hftTermQueue()
  360. {
  361.     int    rtrn;
  362.  
  363.     TRACE(("hftTermQueue()\n"));
  364.     if (hftNeedsReset)
  365.     {
  366.     rtrn= write(hftQFD,&hftVTDRelease,sizeof(hftVTDRelease));
  367.  
  368.     if (rtrn!=sizeof(hftVTDRelease))
  369.         ErrorF("hftTermQueue release screen VTD failed (%d)\n", rtrn);
  370.  
  371.     hftKSRProtoReq.hf_select[0]= HFHOSTS|HFXLATKBD;
  372.     hftKSRProtoReq.hf_value[0]= HFXLATKBD;
  373.     hftKSRProtoReq.hf_select[1]= HFWRAP|HFLOCATOR|HFLPFKS|HFDIALS;
  374.     hftKSRProtoReq.hf_value[1]= HFWRAP;
  375.     rtrn= write(hftQFD,&hftKSRProtoReq,sizeof(hftKSRProtoReq));
  376.  
  377.     if (rtrn!=sizeof(hftKSRProtoReq))
  378.         ErrorF("hftTermQueue KSR protocol VTD failed (%d)\n", rtrn);
  379.  
  380.     rtrn= ioctl(hftQFD,HFCMON,0);
  381.  
  382.     if (rtrn!=0)
  383.         ErrorF("hftTermQueue CMON ioctl failed\n", rtrn);
  384.  
  385.     hftQFD= -1;
  386.     hftNeedsReset= 0;
  387.     }
  388.     return;
  389. }
  390.  
  391. /***====================================================================***/
  392.  
  393.     /*
  394.      * described in hftQueue.h
  395.      */
  396.  
  397. hftEvHandler
  398. hftInstallHandler(evType,pHandler)
  399.      int        evType;
  400.      hftEvHandler    pHandler;
  401. {
  402.     hftEvHandler    pOld;
  403.  
  404.     TRACE(("hftInstallHandler(%d,0x%x)\n",evType,pHandler));
  405.     if ((hftQFD==-1)||(evType<0)||(evType>=HFT_NEVENTS))
  406.     {
  407.     return(HFT_ERROR);
  408.     }
  409.     pOld= hftHandlers[evType];
  410.     hftHandlers[evType]= pHandler;
  411.     return(pOld);
  412. }
  413.  
  414.     /*
  415.      *  described in hftQueue.h
  416.      */
  417.  
  418. void
  419. hftAddTimeout(pHandler,count)
  420.      hftEvHandler    pHandler;
  421.      int        count;
  422. {
  423.     TRACE(("hftAddTimeout(0x%x,%d)\n",pHandler,count));
  424.  
  425.     if ((count>0)&&(pHandler!=NULL))
  426.     {
  427.     hftTimeoutHndlr=    pHandler;
  428.     hftTimeoutCount=    count;
  429.     }
  430.     else
  431.     {
  432.     hftTimeoutHndlr=    NULL;
  433.     hftTimeoutCount=    0;
  434.     }
  435.     return;
  436. }
  437.  
  438. #define    HFT_HEADERSIZE    3
  439. #define    HFT_BYTESLEFT    (source>sink?source-sink:source-sink+HFRDATA)
  440. #define    HFT_INCR(s)    (++s>=RINGLAST?s=RINGFIRST:0)
  441.  
  442. void
  443. hftDispatchEvents()
  444. {
  445.     char        *input = hftRing.buf.hf_rdata-RINGFIRST;
  446.     unsigned         source = hftRing.buf.hf_source;
  447.     unsigned         sink   = hftRing.buf.hf_sink;
  448.     unsigned char    *buf;
  449.     hftEvent           thisEvent;
  450.     int             nPending,tmp;
  451.     int              device;
  452.  
  453.     TRACE(("hftDispatchEvents()\n"));
  454.  
  455.     if ((hftPending)&&(hftHandlers[HFT_BEFORE_EVENTS]))
  456.     {
  457.     (*hftHandlers[HFT_BEFORE_EVENTS])(&hftProtoBefore);
  458.     }
  459.  
  460.     if (hftGrantPending)
  461.     {
  462.     if (hftHandlers[HFT_GRANTED])
  463.         (*hftHandlers[HFT_GRANTED])(&hftProtoGranted);
  464.     hftGrantPending= 0;
  465.     }
  466.     while (sink!=source)
  467.     {
  468.     if (HFT_BYTESLEFT<HFT_HEADERSIZE)
  469.     {
  470.         if (hftRing.buf.hf_ovflow)    goto incomplete;
  471.         else            break;
  472.     }
  473.     if (input[sink]!=27)    goto illegal; /* XXX -- UGLY!! */
  474.     HFT_INCR(sink);
  475.     if (input[sink]!='[')    goto illegal; /* XXX -- UGLY!! */
  476.     HFT_INCR(sink);
  477.     if    (input[sink]==HFT_ESC_KEYBOARD)        device=    HFT_KEYBOARD;
  478.     else if    (input[sink]==HFT_ESC_LOCATOR)        device=    HFT_LOCATOR;
  479.     else if    (input[sink]==HFT_ESC_ADAPT)        device=    HFT_ADAPT;
  480.     else                         goto illegal;
  481.     HFT_INCR(sink);
  482.     nPending= hftEvSize[device];
  483.  
  484.     if (HFT_BYTESLEFT<nPending)
  485.         goto incomplete;
  486.     buf= (unsigned char *)&thisEvent.hftEv;
  487.     while (nPending--)
  488.     {
  489.         *buf++= input[sink];
  490.         HFT_INCR(sink);
  491.     }
  492.     hftRing.buf.hf_sink= sink;
  493.  
  494.     if (device==HFT_LOCATOR)
  495.         device= hftLocatorSubtype[thisEvent.hftEv.hftLoc.leStype];
  496.  
  497.     if (hftHandlers[device]!=NULL)
  498.     {
  499.         (*hftHandlers[device])(&thisEvent);
  500.     }
  501.     }
  502.     if (hftRetractPending)
  503.     {
  504.     if (hftHandlers[HFT_RETRACTED]) 
  505.         (*hftHandlers[HFT_RETRACTED])(&hftProtoRetracted);
  506.     hftRetractPending= 0;
  507.     write(hftQFD,&hftVTDRelease,sizeof(hftVTDRelease));
  508.     }
  509.  
  510.     if (hftTimeoutCount>0)
  511.     {
  512.     if (--hftTimeoutCount==0)
  513.         (*hftTimeoutHndlr)();
  514.     }
  515.  
  516.     if ((sink==hftRing.buf.hf_source)&&(hftTimeoutCount<=0))
  517.     hftPending= 0;
  518.  
  519.  
  520.     if (hftHandlers[HFT_AFTER_EVENTS])
  521.     {
  522.     (*hftHandlers[HFT_AFTER_EVENTS])(&hftProtoAfter);
  523.     }
  524.  
  525.     return;
  526.     /*
  527.      * Called when a partial event is sitting on the queue.
  528.      * if there is an overflow, print a warning and reset the
  529.      * queue.  Could do some fancy attempts to parse event if
  530.      * we really wanted to.  If there is no overflow, just return.
  531.      */
  532.   incomplete:
  533.     if (hftRing.buf.hf_ovflow)
  534.     {
  535.     ErrorF("warning!    ring buffer overflow!\n");
  536.     ErrorF("            events may be lost\n");
  537.     hftRing.buf.hf_sink   = hftRing.buf.hf_source;
  538.     hftRing.buf.hf_ovflow = 0;
  539.     hftPending            = 0;
  540.     }
  541.     return;
  542.     /*
  543.      * called when an illegal character is found in a ring buffer
  544.      * structure header (or an illegal device is specified).
  545.      * prints a warning and finds the next legal header.
  546.      */
  547.   illegal:
  548.     ErrorF("internal error:  illegal character in ring buffer header\n");
  549.     ErrorF("                 events may be lost\n");
  550.     while (sink!=hftRing.buf.hf_source)
  551.     {
  552.     if (input[sink]==27)
  553.     {
  554.         hftRing.buf.hf_sink= sink;
  555.         HFT_INCR(sink);
  556.         if (input[sink]!='[')    continue;
  557.         HFT_INCR(sink);
  558.         if ((input[sink]==HFT_ESC_KEYBOARD) ||
  559.         (input[sink]==HFT_ESC_LOCATOR)  ||
  560.         (input[sink]==HFT_ESC_ADAPT))
  561.         {
  562.         break;
  563.         }
  564.     }
  565.     else HFT_INCR(sink);
  566.     }
  567.     hftRing.buf.hf_sink= sink;
  568.     if (sink==hftRing.buf.hf_source)
  569.     hftPending= 0;
  570.     return;
  571. }
  572.  
  573.