home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / X / mit / server / ddx / ibm / AIX / hftQueue.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-07-21  |  18.7 KB  |  652 lines

  1. /*
  2.  * $XConsortium: hftQueue.c,v 1.5 91/09/09 13:24:12 rws Exp $
  3.  *
  4.  * Copyright IBM Corporation 1987,1988,1989,1990,1991
  5.  *
  6.  * All Rights Reserved
  7.  *
  8.  * License 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, FITNESS, AND 
  18.  * NONINFRINGEMENT OF THIRD PARTY RIGHTS, IN NO EVENT SHALL
  19.  * IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
  20.  * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  21.  * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  22.  * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  23.  * SOFTWARE.
  24.  *
  25. */
  26.  
  27. #include <signal.h>
  28. #define HFRDATA 8912         /* override HFRDATA in hft.h */
  29. #include <sys/hft.h>
  30. #include <fcntl.h>           /* cals */
  31.  
  32. #define NEED_EVENTS
  33. #include "X.h"
  34. #include "Xproto.h"
  35. #include "input.h"
  36. #include "scrnintstr.h"
  37. #include "cursorstr.h"
  38. #include "miscstruct.h"
  39. #include "aixCursor.h"
  40. #include "ibmScreen.h"
  41.  
  42. #include "ibmTrace.h"
  43. #include "aixError.h"
  44. #include "hftQueue.h"
  45.  
  46.     /*
  47.      * Defines to simplify dealing with AIX.
  48.      */
  49.  
  50. #define HFWDCHARS(n)    (n)>>8&0xff, (n)&0xff
  51. #define FLWDCHARS(n)    (n)>>24&0xff,(n)>>16&0xff,(n)>>8&0xff,(n)&0xff
  52. #define VTD(n)  HFINTROESC, HFINTROLBR, HFINTROEX, FLWDCHARS(n)
  53.  
  54. #ifdef AIXV3  /* fix version 2 bug */
  55. #define ringlen sizeof(hftRingbuf)
  56. #define RINGLEN HFWDCHARS(ringlen)
  57. #define RINGVTD VTD(sizeof(hftRingreq) - 3)
  58. #define RINGOFFSET      FLWDCHARS(sizeof(hftRing) - sizeof(hftRingbuf) -\
  59.                               sizeof(hftRingreq.hf_intro) - \
  60.                               sizeof(hftRingreq.hf_sublen) -\
  61.                               sizeof(hftRingreq.hf_subtype))
  62. #define RINGBASE        ((unsigned char *)&hftRingbuf.hf_rsvd[0])
  63. #define RINGFIRST       32
  64. #define RINGLAST        sizeof(hftRingbuf)
  65. #else
  66.  
  67. #define ringlen sizeof(hftRingbuf)
  68. #define RINGLEN HFWDCHARS(ringlen)
  69. #define RINGVTD VTD(sizeof(hftRing) - 3)
  70. #define RINGOFFSET      FLWDCHARS(sizeof(hftRing) - sizeof(hftRingbuf) -\
  71.                               sizeof(hftRingreq.hf_intro) - \
  72.                               sizeof(hftRingreq.hf_sublen) -\
  73.                               sizeof(hftRingreq.hf_subtype))
  74. #define RINGBASE        ((unsigned char *)&hftRingbuf.hf_rsvd[0])
  75. #define RINGFIRST       32
  76. #define RINGLAST        sizeof(hftRingbuf)
  77. #endif
  78.  
  79. #define HFT_ESC_KEYBOARD        0x77
  80. #define HFT_ESC_LOCATOR         'y'
  81. #define HFT_ESC_ADAPT           'r'
  82. #define HFT_ESC_FOCUSIN         'z'
  83.  
  84.     /*
  85.      * Package global variables.
  86.      */
  87.  
  88.     unsigned        hftPending;
  89.     unsigned        hftGrantPending;
  90.     unsigned        hftRetractPending;
  91.  
  92. static  int             hftSetInterrupts= 0;
  93. static  int             hftHaveScreen=  FALSE;
  94.     int             hftQFD= -1;
  95.     int             hftNeedsReset=  FALSE;
  96.  
  97. static  hftEvHandler    hftHandlers[HFT_NEVENTS]= {
  98.                             HFT_IGNORE,
  99.                             HFT_IGNORE,
  100.                             HFT_IGNORE,
  101.                             HFT_IGNORE,
  102.                             HFT_IGNORE,
  103.                             HFT_IGNORE,
  104.                             HFT_IGNORE,
  105.                             HFT_IGNORE,
  106.                             HFT_IGNORE,
  107.                             HFT_IGNORE
  108.                     };
  109.  
  110. static  int             hftEvSize[HFT_NEVENTS]= {
  111.                             sizeof(hftKeyEv),
  112.                             sizeof(hftLocEv),
  113.                             sizeof(hftAdaptEv),
  114.                             sizeof(hftLocEv),
  115.                             sizeof(hftLPFKEv),
  116.                             sizeof(hftDialEv)
  117.                     };
  118.  
  119. #define HFT_N_LOC_STYPES        4
  120. static  int             hftLocatorSubtype[HFT_N_LOC_STYPES] = {
  121.                     HFT_LOCATOR,    /* mouse report */
  122.                     HFT_TABLET,     /* locator report */
  123.                     HFT_LPFK,       /* LPFK report */
  124.                     HFT_DIAL        /* Dial report */
  125. };
  126.  
  127. static  struct  hfprotocol      hftProtoReq= {
  128.             VTD(sizeof(hftProtoReq)-3),     /* escape sequence introducer */
  129.             HFMOMPROH, HFMOMPROL, 2, 0      /* random garbage */
  130.     };
  131.  
  132. struct hfmomscreq       hftRingreq;
  133. struct {
  134.      char hf_rsvd[2];
  135.      char hf_intreq;
  136.      char hf_ovflow;
  137.      unsigned hf_source;
  138.      unsigned hf_sink;
  139.      int hf_unused[5];
  140.      char hf_rdata[HFRDATA];
  141. } hftRingbuf ;
  142. /*
  143.       = {
  144.     RINGVTD,HFMOMREQH,HFMOMREQL,2,0,RINGLEN,RINGOFFSET,
  145.     0,0,0xff,0,RINGFIRST,RINGFIRST,0,0,0,0,0,
  146.     };
  147. */
  148. #ifdef AIXV3
  149. #define INT_TO_ARRAY(a,i)       *((char *)      (a))       = (i) >> 24 ; \
  150.                             *((char *)      (a) + 1)   = (i) >> 16 ; \
  151.                             *((char *)      (a) + 2)   = (i) >> 8 ; \
  152.                             *((char *)      (a) + 3)   = (i) ;
  153. #define SHORT_TO_ARRAY(a,i)     *((char *)      (a))       = (i) >> 8 ; \
  154.                             *((char *)      (a) + 1 )  = (i) ;
  155. #endif
  156.  
  157. static  hftEvent        hftProtoArrived= { HFT_EVENT_ARRIVED };
  158. static  hftEvent        hftProtoGranted= { HFT_GRANTED };
  159. static  hftEvent        hftProtoRetracted= { HFT_RETRACTED };
  160. static  hftEvent        hftProtoBefore= { HFT_BEFORE_EVENTS };
  161. static  hftEvent        hftProtoAfter= { HFT_AFTER_EVENTS };
  162.  
  163. static  hftEvHandler    hftTimeoutHndlr;
  164. static  int             hftTimeoutCount;
  165. extern  int             AIXDefaultDisplay ;    /* cals */
  166.  
  167. /***====================================================================***/
  168.  
  169. void
  170. hftInterruptAlways()
  171. {
  172.     TRACE(("hftInterruptAlways()\n"));
  173.     hftRingbuf.hf_intreq= hftSetInterrupts= 0xff;
  174.     return;
  175. }
  176.  
  177. /***====================================================================***/
  178.  
  179. void
  180. hftInterruptOnFirst()
  181. {
  182.     TRACE(("hftInterruptOnFirst()\n"));
  183.     hftRingbuf.hf_intreq= hftSetInterrupts= 0;
  184.     return;
  185. }
  186.  
  187.  
  188. static void
  189. hftQuitMsg()
  190. {
  191.     TRACE(("hftQuit()\n"));
  192.     return ;
  193. }
  194. static void
  195. hftIgnoreMsg()
  196. {
  197.     TRACE(("hftIgnoreMsg()\n"));
  198.     hftRingbuf.hf_intreq= hftSetInterrupts;
  199.     hftPending++;
  200.     if (hftHandlers[HFT_EVENT_ARRIVED])
  201.     (*hftHandlers[HFT_EVENT_ARRIVED])(&hftProtoArrived);
  202.     return ;
  203. }
  204.  
  205. static void
  206. hftGrant()
  207. {
  208.     TRACE(("hftGrant() hftGrantPending=%d, hftRetractPending=%d, hftPending=%d\n", hftGrantPending, hftRetractPending, hftPending));
  209.     hftGrantPending++;
  210.     hftPending++;
  211.     if (hftHandlers[HFT_EVENT_ARRIVED])
  212.     (*hftHandlers[HFT_EVENT_ARRIVED])(&hftProtoArrived);
  213.     return ;
  214. }
  215.  
  216. static void
  217. hftRetract()
  218. {
  219.     TRACE(("hftRetract() hftGrantPending=%d, hftRetractPending=%d, hftPending=%d\n", hftGrantPending, hftRetractPending, hftPending));
  220.     hftRetractPending++;
  221.     hftPending++;
  222.     if (hftHandlers[HFT_EVENT_ARRIVED])
  223.     (*hftHandlers[HFT_EVENT_ARRIVED])(&hftProtoArrived);
  224.     return ;
  225. }
  226.  
  227. static void
  228. hftSetUpSignals(save)
  229. int     save;
  230. {
  231. struct  sigaction       svquit;
  232. struct  sigaction       svgrant;
  233. struct  sigaction       svretract;
  234. struct  sigaction       svmessage;
  235. struct  sigaction       oldsig;
  236.  
  237.     TRACE(("hftSetUpSignals()\n"));
  238.  
  239.     svgrant.sa_handler=         hftGrant;
  240.     SIGINITSET(svgrant.sa_mask);
  241.     SIGADDSET(svgrant.sa_mask,SIGGRANT);
  242.     SIGADDSET(svgrant.sa_mask,SIGRETRACT);
  243.     svgrant.sa_flags=   SA_RESTART ;
  244.  
  245.     svretract.sa_handler=       hftRetract;
  246.  
  247.     SIGINITSET(svretract.sa_mask);
  248.     SIGADDSET(svretract.sa_mask,SIGGRANT);
  249.     SIGADDSET(svretract.sa_mask,SIGRETRACT);
  250.     svretract.sa_flags= SA_RESTART;
  251.  
  252.     svmessage.sa_handler=       hftIgnoreMsg;
  253.     SIGINITSET(svmessage.sa_mask);
  254.     SIGADDSET(svmessage.sa_mask,SIGMSG);
  255.     svmessage.sa_flags= SA_RESTART ;
  256.  
  257.     svquit.sa_handler=  hftQuitMsg;
  258.     SIGINITSET(svquit.sa_mask);
  259.     SIGADDSET(svquit.sa_mask,SIGQUIT);
  260.     svquit.sa_flags=    SA_RESTART ;
  261.  
  262.     sigaction(SIGQUIT,&svquit,&oldsig);
  263.     sigaction(SIGGRANT,&svgrant,&oldsig);
  264.     if (save) {
  265.     if ((oldsig.sa_handler!=SIG_DFL)&&(oldsig.sa_handler!=SIG_IGN))
  266.         hftHandlers[HFT_GRANTED]= oldsig.sa_handler;
  267.     }
  268.     sigaction(SIGRETRACT,&svretract,&oldsig);
  269.     if (save) {
  270.     if ((oldsig.sa_handler!=SIG_DFL)&&(oldsig.sa_handler!=SIG_IGN))
  271.         hftHandlers[HFT_RETRACTED]= oldsig.sa_handler;
  272.     }
  273.     sigaction(SIGMSG,&svmessage,&oldsig);
  274.     if (save) {
  275.     if ((oldsig.sa_handler!=SIG_DFL)&&(oldsig.sa_handler!=SIG_IGN))
  276.         hftHandlers[HFT_EVENT_ARRIVED]= oldsig.sa_handler;
  277.     }
  278.  
  279.     return ;
  280. }
  281.  
  282.     /*
  283.      * defined in hftQueue.h
  284.      */
  285.  
  286. int
  287. hftInitQueue(deviceId,saveOldHandlers)
  288. int     deviceId;
  289. int     saveOldHandlers;
  290. {
  291.     unsigned    offset;
  292.  
  293.     TRACE(("hftInitQueue() hftQFD is %d\n",hftQFD));
  294.  
  295.     if (hftQFD<0) {
  296.     errFatal(("NO OUTPUT DEVICE"));
  297.       /**
  298.     hftQFD = open("/dev/hft",O_WRONLY);
  299.     if (hftQFD<0)
  300.         ErrorF("hftInitQueue: Cannot open /dev/hft to query device ids\n");
  301.     return(TRUE);
  302.        **/
  303.     }
  304.  
  305.     TRACE(("hftInitQueue: After FindAScreen hftQFD is %d\n",hftQFD));
  306.  
  307.     hftSetUpSignals(saveOldHandlers);
  308.  
  309.     hftPutAllIntoMonitorMode(&hftRingbuf);
  310.     aixConnectScreens();
  311.     hftActivateVT(hftQFD);
  312.     hftPending= 0;
  313.  
  314. #ifdef AIXEXTENSIONS
  315.     hftQueryHardwareConfig(deviceId);
  316. #endif
  317.  
  318.     return(TRUE);
  319. }
  320.  
  321. /***====================================================================***/
  322.  
  323. static  struct  hfprotocol      hftKSRProtoReq= {
  324.             VTD(sizeof(hftProtoReq)-3),     /* escape sequence introducer */
  325.             HFKSRPROH, HFKSRPROL, 2, 0      /* random garbage */
  326.     };
  327.  
  328. static  struct  hfmomscrel      hftVTDRelease= {
  329.                                     VTD(sizeof(hftVTDRelease)-3),
  330.                                     HFMOMRELH,HFMOMRELL
  331.                             };
  332. /* file descriptor to send the Release to after a Retract has been received */
  333. extern int  RetractFD;
  334.  
  335. #include <stdio.h>
  336. void
  337. hftTermQueue()
  338. {
  339. int     rtrn;
  340.  
  341.    TRACE(("hftTermQueue()\n"));
  342.  
  343.    if (hftNeedsReset) {
  344.     rtrn= write(hftQFD,&hftVTDRelease,sizeof(hftVTDRelease));
  345.     if (rtrn!=sizeof(hftVTDRelease)) {
  346.         ErrorF("hftTermQueue release screen VTD failed (%d)\n",
  347.                                                                     rtrn);
  348.     }
  349.     hftKSRProtoReq.hf_select[0]= HFHOSTS|HFXLATKBD;
  350.     hftKSRProtoReq.hf_value[0]= HFXLATKBD;
  351.     hftKSRProtoReq.hf_select[1]= HFWRAP|HFMOUSE|HFTABLET|HFLPFKS|HFDIALS;
  352.     hftKSRProtoReq.hf_value[1]= HFWRAP;
  353.     rtrn= write(hftQFD,&hftKSRProtoReq,sizeof(hftKSRProtoReq));
  354.     if (rtrn!=sizeof(hftKSRProtoReq)) {
  355.         ErrorF("hftTermQueue KSR protocol VTD failed (%d)\n",
  356.                                                                     rtrn);
  357.     }
  358.     rtrn= ioctl(hftQFD,HFCMON,0);
  359.     if (rtrn!=0) {
  360.         ErrorF("hftTermQueue CMON ioctl failed\n",rtrn);
  361.     }
  362.     hftQFD= -1;
  363.     hftNeedsReset= 0;
  364.    }
  365.    return;
  366. }
  367.  
  368. /***====================================================================***/
  369.  
  370.     /*
  371.      * described in hftQueue.h
  372.      */
  373.  
  374. hftEvHandler
  375. hftInstallHandler(evType,pHandler)
  376. int     evType;
  377. hftEvHandler    pHandler;
  378. {
  379. hftEvHandler    pOld;
  380.  
  381.     TRACE(("hftInstallHandler(%d,0x%x)\n",evType,pHandler));
  382.     if ((hftQFD==-1)||(evType<0)||(evType>=HFT_NEVENTS)) {
  383.     return(HFT_ERROR);
  384.     }
  385.     pOld= hftHandlers[evType];
  386.     hftHandlers[evType]= pHandler;
  387.     return(pOld);
  388. }
  389.  
  390.     /*
  391.      *  described in hftQueue.h
  392.      */
  393.  
  394. void
  395. hftAddTimeout(pHandler,count)
  396. hftEvHandler    pHandler;
  397. int             count;
  398. {
  399.     TRACE(("hftAddTimeout(0x%x,%d)\n",pHandler,count));
  400.  
  401.     if ((count>0)&&(pHandler!=NULL)) {
  402.     hftTimeoutHndlr=        pHandler;
  403.     hftTimeoutCount=        count;
  404.     }
  405.     else {
  406.     hftTimeoutHndlr=        NULL;
  407.     hftTimeoutCount=        0;
  408.     }
  409.     return;
  410. }
  411.  
  412. #define HFT_HEADERSIZE  3
  413. #define HFT_BYTESLEFT   (source>sink?source-sink:source-sink+HFRDATA)
  414. #define HFT_INCR(s)     (++s>=RINGLAST?s=RINGFIRST:0)
  415.  
  416. void
  417. hftDispatchEvents()
  418. {
  419.      char            *input= hftRingbuf.hf_rdata-RINGFIRST;
  420.      unsigned        source= hftRingbuf.hf_source;
  421.      unsigned        sink= hftRingbuf.hf_sink;
  422.      unsigned char   *buf;
  423.      hftEvent        thisEvent;
  424.      int             nPending,tmp;
  425.      int             device;
  426.  
  427.     TRACE(("hftDispatchEvents()\n"));
  428.  
  429.     if ((hftPending)&&(hftHandlers[HFT_BEFORE_EVENTS])) {
  430.     (*hftHandlers[HFT_BEFORE_EVENTS])(&hftProtoBefore);
  431.     }
  432.  
  433.     if (hftGrantPending) {
  434.     if (hftHandlers[HFT_GRANTED])
  435.         (*hftHandlers[HFT_GRANTED])(&hftProtoGranted);
  436.     hftGrantPending= 0;
  437.  
  438.     /* make sure the VT we get input from is active */
  439.     /* (after a grant it will be visible, but it may */
  440.     /* not be active) */
  441.     hftActivateVT(hftQFD);
  442.  
  443.     }
  444.     while (sink!=source) {
  445.     if (HFT_BYTESLEFT<HFT_HEADERSIZE)  {
  446.         if (hftRingbuf.hf_ovflow)   goto incomplete;
  447.         else                        break;
  448.     }
  449.     if (input[sink]!=27)
  450.             goto illegal;
  451.     HFT_INCR(sink);
  452.     if (input[sink]!='[')
  453.             goto illegal;
  454.     HFT_INCR(sink);
  455.     if      (input[sink]==HFT_ESC_KEYBOARD)         device= HFT_KEYBOARD;
  456.     else if (input[sink]==HFT_ESC_LOCATOR)          device= HFT_LOCATOR;
  457.     else if (input[sink]==HFT_ESC_ADAPT)            device= HFT_ADAPT;
  458.     else if (input[sink]==HFT_ESC_FOCUSIN) {
  459.       TRACE(("new HFT_ESC_FOCUSIN\n"));
  460.           HFT_INCR(sink);
  461.           hftRingbuf.hf_sink= sink;
  462.           continue;   /* with while loop */
  463.       }
  464.     else                                            goto illegal;
  465.     HFT_INCR(sink);
  466.     nPending= hftEvSize[device];
  467.  
  468.     if (HFT_BYTESLEFT<nPending)
  469.         goto incomplete;
  470.     buf= (unsigned char *)&thisEvent.hftEv;
  471.     while (nPending--) {
  472.         *buf++= input[sink];
  473.         HFT_INCR(sink);
  474.     }
  475.     hftRingbuf.hf_sink= sink;
  476.  
  477.     if (device==HFT_LOCATOR)
  478.         device= hftLocatorSubtype[thisEvent.hftEv.hftLoc.leStype];
  479.  
  480.     if (hftHandlers[device]!=NULL) {
  481.         (*hftHandlers[device])(&thisEvent);
  482.     }
  483.     }
  484.     if (hftRetractPending) {
  485.     if (hftHandlers[HFT_RETRACTED])
  486.         (*hftHandlers[HFT_RETRACTED])(&hftProtoRetracted);
  487.     hftRetractPending= 0;
  488.     write(RetractFD,&hftVTDRelease,sizeof(hftVTDRelease));
  489.     }
  490.  
  491.     if (hftTimeoutCount>0) {
  492.     if (--hftTimeoutCount==0)
  493.         (*hftTimeoutHndlr)();
  494.     }
  495.  
  496.     if ((sink==hftRingbuf.hf_source)&&(hftTimeoutCount<=0))
  497.     hftPending= 0;
  498.  
  499.  
  500.     if (hftHandlers[HFT_AFTER_EVENTS]) {
  501.     (*hftHandlers[HFT_AFTER_EVENTS])(&hftProtoAfter);
  502.     }
  503.  
  504.     return;
  505.     /*
  506.      * Called when a partial event is sitting on the queue.
  507.      * if there is an overflow, print a warning and reset the
  508.      * queue.  Could do some fancy attempts to parse event if
  509.      * we really wanted to.  If there is no overflow, just return.
  510.      */
  511. incomplete:
  512.     if (hftRingbuf.hf_ovflow) {
  513.         errWarning(("ring buffer overflow! events lost"));
  514.         hftRingbuf.hf_sink= hftRingbuf.hf_source;
  515.         hftRingbuf.hf_ovflow= 0;
  516.         hftPending= 0;
  517.     }
  518.     return;
  519.     /*
  520.      * called when an illegal character is found in a ring buffer
  521.      * structure header (or an illegal device is specified).
  522.      * prints a warning and finds the next legal header.
  523.      */
  524. illegal:
  525.     TRACE((" sink is %d  input char is %d \n",sink, input[sink]));
  526.     ErrorF("Illegal character in ring buffer header - ");
  527.     ErrorF("sink is %02x  input char is %02x \n",sink, input[sink]);
  528.     while (sink!=hftRingbuf.hf_source) {
  529.         if (input[sink]==27) {
  530.             hftRingbuf.hf_sink= sink;
  531.             HFT_INCR(sink);
  532.             if (input[sink]!='[')   continue;
  533.             HFT_INCR(sink);
  534.             if ((input[sink]==HFT_ESC_KEYBOARD)||
  535.                                     (input[sink]==HFT_ESC_LOCATOR)||
  536.                                     (input[sink]==HFT_ESC_ADAPT)) {
  537.                 break;
  538.             }
  539.         }
  540.         else HFT_INCR(sink);
  541.     }
  542.     hftRingbuf.hf_sink= sink;
  543.     if (sink==hftRingbuf.hf_source)
  544.         hftPending= 0;
  545.     return;
  546. }
  547.  
  548. /*
  549. struct hfmomring {                      * monitor mode ring status, ptrs *
  550.    char  hf_rsvd[2];                    * reserved *
  551.    char  hf_intreq;                     * intr request, send a SIGMSG:
  552.                                          0x00 = when buffer becomes empty
  553.                                          0xFF = for each input event *
  554.    char  hf_ovflow;                     * overflow:  0x00=normal,
  555.                                                   0xFF=overflow *
  556.    ulong hf_source;                     * current sys ptr (offset=32+) *
  557.    ulong hf_sink;                       * current user ptr (offset=32+) *
  558.    long  hf_unused[5];                  * reserved *
  559.    char  hf_rdata[HFRDATA];             * data goes here *
  560. };
  561. */
  562.  
  563. void
  564. hftEnterMonitorMode(fd, rptr)
  565.     int  fd;
  566.     struct hfmomring  *rptr;
  567. {
  568.     struct hfsmon  flags;
  569.     extern unsigned  hftGrantPending;
  570.  
  571.     TRACE(("hftEnterMonitorMode(fd=%d) #1\n",fd));
  572.     TRACE(("hftEnterMonitorMode()  hftGrantPending=%d\n",hftGrantPending));
  573.     hftGrantPending = 0;
  574.     flags.hf_momflags= HFSINGLE;
  575.     if (ioctl(fd,HFSMON,&flags)!=0) {
  576.     errFatal(("error entering monitor mode"));
  577.     exit(1);
  578.     }
  579.  
  580.     hftProtoReq.hf_select[0]=   HFXLATKBD;
  581.     hftProtoReq.hf_select[1]=   HFMOUSE | HFTABLET | HFDIALS | HFLPFKS ;
  582.     hftProtoReq.hf_value[0]=    0;
  583.     hftProtoReq.hf_value[1]=    HFMOUSE | HFTABLET | HFDIALS | HFLPFKS ;
  584.  
  585.     if (write(fd,&hftProtoReq,sizeof(hftProtoReq))!=sizeof(hftProtoReq)) {
  586.     errFatal(("protocol write failed"));
  587.     }
  588.  
  589. /*-----------------------------------------------------------*/
  590.  
  591.  
  592.     if( fd == hftQFD ){
  593.     rptr->hf_intreq= hftSetInterrupts;
  594.  
  595.     hftRingreq.hf_intro[0] = 0x1b ;
  596.     hftRingreq.hf_intro[1] = '[' ;
  597.     hftRingreq.hf_intro[2] = 'x' ;
  598.     INT_TO_ARRAY(&(hftRingreq.hf_intro[3]),sizeof(hftRingreq)- 3);
  599.     hftRingreq.hf_intro[7] = HFMOMREQH ;
  600.     hftRingreq.hf_intro[8] = HFMOMREQL ;
  601.     hftRingreq.hf_sublen = 2 ;
  602.     hftRingreq.hf_subtype = 0 ;
  603.     SHORT_TO_ARRAY(&(hftRingreq.hf_ringlen[0]),sizeof(struct hfmomring));
  604.     INT_TO_ARRAY(&(hftRingreq.hf_ringoffset[0]), ((char *)rptr) - (char *)&(hftRingreq.hf_ringlen[0]));
  605.     rptr->hf_intreq = 0 ;
  606.     rptr->hf_ovflow = 0 ;
  607.     rptr->hf_source = 32 ;
  608.     rptr->hf_sink = 32 ;
  609.  
  610.     if (write(fd,&(hftRingreq),sizeof(hftRingreq))!=sizeof(hftRingreq)) {
  611.         errFatal(("request write failed"));
  612.     }
  613.     TRACE(("AFTER 1 write Ring ADDR is %x hftRing source is %d dstis %d \n",&(hftRingreq),rptr->hf_source,rptr->hf_sink));
  614.     TRACE(("size = %d\n", sizeof(hftRingreq)));
  615.     }
  616.     else{
  617.     TRACE(("HFINTROSZ=%d\n",HFINTROSZ));
  618.     hftRingreq.hf_intro[0] = 0x1b ;
  619.     hftRingreq.hf_intro[1] = '[' ;
  620.     hftRingreq.hf_intro[2] = 'x' ;
  621.     INT_TO_ARRAY(&(hftRingreq.hf_intro[3]), HFINTROSZ-3);
  622.     hftRingreq.hf_intro[7] = HFMOMREQH ;
  623.     hftRingreq.hf_intro[8] = HFMOMREQL ;
  624.  
  625.     if (write(fd,&(hftRingreq),HFINTROSZ)!=HFINTROSZ) {
  626.         errFatal(("request write failed"));
  627.     }
  628.     }
  629.  
  630. /*-----------------------------------------------------------*/
  631.  
  632.     TRACE(("hftEnterMonitorMode() waiting for grant #1\n"));
  633.     while( ! hftGrantPending ){
  634.     }
  635.     TRACE(("hftEnterMonitorMode() waiting for grant #2\n"));
  636.     TRACE(("hftEnterMonitorMode() got a grant  hftGrantPending=%d\n",hftGrantPending));
  637.     hftGrantPending = 0;
  638.     TRACE(("hftEnterMonitorMode(fd=%d) #2\n",fd));
  639. }
  640.  
  641. hftPutAllIntoMonitorMode(rptr)
  642.     struct hfmomring  *rptr;
  643. {
  644.     int  i;
  645.  
  646.     TRACE(("hftPutAllIntoMonitorMode()\n"));
  647.     for(i=0;i<ibmNumScreens;i++){
  648.     hftActivateVT(ibmScreenFD(i));
  649.     hftEnterMonitorMode(ibmScreenFD(i), rptr);
  650.     }
  651. }
  652.