Home | History | Annotate | Line # | Download | only in src
      1 /* $XFree86$ */
      2 /*****************************************************************************
      3 Copyright 1987, 1988, 1989, 1990, 1991 by Digital Equipment Corp., Maynard, MA
      4 
      5 Permission to use, copy, modify, and distribute this software and its
      6 documentation for any purpose and without fee is hereby granted,
      7 provided that the above copyright notice appear in all copies and that
      8 both that copyright notice and this permission notice appear in
      9 supporting documentation, and that the name of Digital not be
     10 used in advertising or publicity pertaining to distribution of the
     11 software without specific, written prior permission.
     12 
     13 DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
     14 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
     15 DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
     16 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
     17 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
     18 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
     19 SOFTWARE.
     20 
     21 *****************************************************************************/
     22 #ifndef NO_DEC_ADDED_VALUE
     23 #ifdef SMT
     24 #define NEED_EVENTS
     25 #define NEED_REPLIES
     26 #endif
     27 #include <X11/Xlib.h>
     28 #define NEED_REPLIES
     29 #define NEED_EVENTS
     30 #include <X11/Xproto.h>
     31 #else /* NO_DEC_BUG_FIX */
     32 #include <X11/Xlib.h>
     33 #define NEED_REPLIES
     34 #define NEED_EVENTS
     35 #include <X11/Xproto.h>
     36 #endif /* NO_DEC_BUG_FIX */
     37 /* the following's a hack to support V3.1 protocol */
     38 #if defined(__STDC__) && !defined(UNIXCPP)
     39 #define GetOldReq(name, req, old_length) \
     40         WORD64ALIGN\
     41         if ((dpy->bufptr + SIZEOF(x##name##Req)) > dpy->bufmax)\
     42                 _XFlush(dpy);\
     43         req = (x##name##Req *)(dpy->last_req = dpy->bufptr);\
     44         req->reqType = X_##name;\
     45         req->length = old_length>>2;\
     46         dpy->bufptr += old_length;\
     47         dpy->request++
     48 
     49 #else  /* non-ANSI C uses empty comment instead of "##" for token concat */
     50 #define GetOldReq(name, req, old_length) \
     51         WORD64ALIGN\
     52         if ((dpy->bufptr + SIZEOF(x/**/name/**/Req)) > dpy->bufmax)\
     53                 _XFlush(dpy);\
     54         req = (x/**/name/**/Req *)(dpy->last_req = dpy->bufptr);\
     55         req->reqType = X_/**/name;\
     56         req->length = old_length>>2;\
     57         dpy->bufptr += old_length;\
     58         dpy->request++
     59 #endif
     60 
     61 #ifndef vms
     62 #include <X11/Xlibint.h>
     63 #else   /* vms */
     64 #define SyncHandle() \
     65     if (dpy->synchandler) (*dpy->synchandler)(dpy)
     66 /*
     67  * LockDisplay uses an undocumented feature in V5 of VMS that allows
     68  * disabling ASTs without calling $SETAST.  A bit is set in P1 space
     69  * that disables a user mode AST from being delivered to this process.
     70  *
     71  */
     72 #define LockDisplay(dis)             \
     73 {   globalref char ctl$gb_soft_ast_disable;    \
     74     globalref char ctl$gb_lib_lock;        \
     75     globalref short ctl$gw_soft_ast_lock_depth;    \
     76     if ( ctl$gb_soft_ast_disable == 0 ) {    \
     77     ctl$gb_soft_ast_disable = 1;        \
     78     ctl$gb_lib_lock = 1;            \
     79     ctl$gw_soft_ast_lock_depth = 1;        \
     80     }                        \
     81     else ctl$gw_soft_ast_lock_depth++;        \
     82 }
     83 
     84 /*
     85  * UnlockDisplay clears the AST disable bit, then checks to see if an
     86  * AST delivery attempt was made during the critical section.  If so,
     87  * reenable_ASTs is set, and $SETAST must be called to turn AST delivery
     88  * back on.
     89  *
     90  * Note that it assumed that LockDisplay and UnlockDisplay appear in
     91  * matched sets within a single routine.
     92  */
     93 #define UnlockDisplay(dis)             \
     94 {   globalref char ctl$gb_reenable_asts;    \
     95     globalref char ctl$gb_soft_ast_disable;    \
     96     globalref char ctl$gb_lib_lock;        \
     97     globalref short ctl$gw_soft_ast_lock_depth;    \
     98     if (!--ctl$gw_soft_ast_lock_depth)         \
     99     if ( ctl$gb_lib_lock ) {        \
    100         ctl$gb_lib_lock = 0;        \
    101             ctl$gb_soft_ast_disable = 0;    \
    102         if (ctl$gb_reenable_asts != 0)    \
    103         sys$setast(1);            \
    104         }                    \
    105 }
    106 
    107 #define WORD64ALIGN
    108 #if defined(__STDC__) && !defined(UNIXCPP)
    109 #define GetReq(name, req) \
    110         WORD64ALIGN\
    111         if ((dpy->bufptr + SIZEOF(x##name##Req)) > dpy->bufmax)\
    112                 _XFlush(dpy);\
    113         req = (x##name##Req *)(dpy->last_req = dpy->bufptr);\
    114         req->reqType = X_##name;\
    115         req->length = (SIZEOF(x##name##Req))>>2;\
    116         dpy->bufptr += SIZEOF(x##name##Req);\
    117         dpy->request++
    118 
    119 #else  /* non-ANSI C uses empty comment instead of "##" for token concat */
    120 #define GetReq(name, req) \
    121         WORD64ALIGN\
    122         if ((dpy->bufptr + SIZEOF(x/**/name/**/Req)) > dpy->bufmax)\
    123                 _XFlush(dpy);\
    124         req = (x/**/name/**/Req *)(dpy->last_req = dpy->bufptr);\
    125         req->reqType = X_/**/name;\
    126         req->length = (SIZEOF(x/**/name/**/Req))>>2;\
    127         dpy->bufptr += SIZEOF(x/**/name/**/Req);\
    128         dpy->request++
    129 #endif
    130 #endif /* vms */
    131 
    132 #include <X11/extensions/xtraplib.h>
    133 #include <X11/extensions/xtraplibp.h>
    134 
    135 /* Returns the all important protocol number to be used.
    136  * The only request guaranteed to be of the same request/reply
    137  * size is XEGetVersionRequest.  All others need the protocol
    138  * number to determine how to communicate.
    139  * Unfortunately, this was broken for V3.1 so GetAvailable will
    140  * have to be used to determine the protocol version.
    141  */
    142 int XEGetVersionRequest(XETC *tc, XETrapGetVersRep *ret)
    143 {
    144     int status = True;
    145     Display *dpy = tc->dpy;
    146     CARD32 X_XTrapGet = tc->extOpcode;
    147     xXTrapGetReq *reqptr;
    148     xXTrapGetVersReply rep;
    149     int numlongs = (SIZEOF(xXTrapGetVersReply) -
    150         SIZEOF(xReply) + SIZEOF(CARD32) -1 ) / SIZEOF(CARD32);
    151     LockDisplay(dpy);
    152     GetReq(XTrapGet,reqptr);
    153     reqptr->minor_opcode = XETrap_GetVersion;
    154     reqptr->protocol = XETrapProtocol;
    155     status = _XReply(dpy,(xReply *)&rep,numlongs,xTrue);
    156     UnlockDisplay(dpy);
    157     SyncHandle();
    158     memcpy((char *)ret,&(rep.data),sizeof(XETrapGetVersRep));
    159     return(status);
    160 }
    161 
    162 int XEGetAvailableRequest(XETC *tc, XETrapGetAvailRep *ret)
    163 {
    164     int status = True;
    165     Display *dpy = tc->dpy;
    166     CARD32 X_XTrapGet = tc->extOpcode;
    167     xXTrapGetReq *reqptr;
    168     xXTrapGetAvailReply rep;
    169     int numlongs = (SIZEOF(xXTrapGetAvailReply) -
    170         SIZEOF(xReply) + SIZEOF(CARD32) -1 ) / SIZEOF(CARD32);
    171     LockDisplay(dpy);
    172     GetReq(XTrapGet,reqptr);
    173     reqptr->minor_opcode = XETrap_GetAvailable;
    174     reqptr->protocol = XETrapProtocol;
    175     status = _XReply(dpy,(xReply *)&rep,numlongs,xTrue);
    176     UnlockDisplay(dpy);
    177     SyncHandle();
    178     memcpy((char *)ret,&(rep.data),sizeof(XETrapGetAvailRep));
    179     return(status);
    180 }
    181 
    182 /* should not be called directly by clients */
    183 static int XEConfigRequest(XETC *tc)
    184 {   /* protocol changed between V3.1 and V3.2! */
    185     int status = True;
    186     Display *dpy = tc->dpy;
    187     CARD32 X_XTrapConfig = tc->extOpcode;
    188     xXTrapConfigReq *reqptr;
    189     if (tc->protocol == 31)
    190     {   /* hack to allocate the old request length */
    191         GetOldReq(XTrapConfig,reqptr,276);
    192     }
    193     else
    194     {
    195         GetReq(XTrapConfig,reqptr);
    196     }
    197     reqptr->minor_opcode = XETrap_Config;
    198 
    199     memcpy((char *)reqptr->config_flags_valid,
    200         (char *)tc->values.v.flags.valid,4);
    201     memcpy((char *)reqptr->config_flags_data,
    202         (char *)tc->values.v.flags.data,4);
    203     memcpy((char *)reqptr->config_flags_req,
    204         (char *)tc->values.v.flags.req,XETrapMaxRequest);
    205     memcpy((char *)reqptr->config_flags_event,
    206         (char *)tc->values.v.flags.event,XETrapMaxEvent);
    207     reqptr->config_max_pkt_size=tc->values.v.max_pkt_size;
    208     reqptr->config_cmd_key=tc->values.v.cmd_key;
    209 
    210     XFlush(dpy);
    211     SyncHandle();
    212     tc->dirty = 0L; /* Configuration is no longer dirty */
    213     return(status);
    214 }
    215 
    216 /* Flush out any pending configuration */
    217 int XEFlushConfig(XETC *tc)
    218 {
    219     return((tc->dirty) ? XEConfigRequest(tc) : True);
    220 }
    221 int XEResetRequest(XETC *tc)
    222 {
    223     int status = True;
    224     Display *dpy = tc->dpy;
    225     CARD32 X_XTrap = tc->extOpcode;
    226     xXTrapReq *reqptr;
    227     status = XEFlushConfig(tc); /* Flushout any pending configuration first */
    228     if (status == True)
    229     {
    230         GetReq(XTrap,reqptr);
    231         reqptr->minor_opcode = XETrap_Reset;
    232         XFlush(dpy);
    233         SyncHandle();
    234     }
    235     return(status);
    236 }
    237 
    238 
    239 int XEGetLastInpTimeRequest(XETC *tc, XETrapGetLastInpTimeRep *ret)
    240 {   /* this was broken in V3.1! */
    241     int status = True;
    242     Display *dpy = tc->dpy;
    243     CARD32 X_XTrap = tc->extOpcode;
    244     xXTrapReq *reqptr;
    245     xXTrapGetLITimReply rep;
    246     int numlongs = (SIZEOF(xXTrapGetLITimReply) -
    247         SIZEOF(xReply) + SIZEOF(CARD32) - 1) / SIZEOF(CARD32);
    248     LockDisplay(dpy);
    249     GetReq(XTrap,reqptr);
    250     reqptr->minor_opcode = XETrap_GetLastInpTime;
    251     status = _XReply(dpy,(xReply *)&rep,numlongs,xTrue);
    252     UnlockDisplay(dpy);
    253     SyncHandle();
    254 
    255     ret->last_time=rep.data_last_time;
    256 
    257     return(status);
    258 }
    259 
    260 int XEStartTrapRequest(XETC *tc)
    261 {
    262     int status = True;
    263     Display *dpy = tc->dpy;
    264     CARD32 X_XTrap = tc->extOpcode;
    265     xXTrapReq *reqptr;
    266     status = XEFlushConfig(tc); /* Flushout any pending configuration first */
    267     if (status == True)
    268     {
    269         /* Add our event handler for the XLib transport */
    270         XETrapSetEventHandler(tc, XETrapData, XETrapDispatchXLib);
    271         GetReq(XTrap,reqptr);
    272         reqptr->minor_opcode = XETrap_StartTrap;
    273         XFlush(dpy);
    274         SyncHandle();
    275         BitTrue(tc->values.tc_flags, XETCTrapActive);
    276     }
    277     return(status);
    278 }
    279 int XEStopTrapRequest(XETC *tc)
    280 {
    281     int status = True;
    282     Display *dpy = tc->dpy;
    283     CARD32 X_XTrap = tc->extOpcode;
    284     xXTrapReq *reqptr;
    285     status = XEFlushConfig(tc); /* Flushout any pending configuration first */
    286     if (status == True)
    287     {
    288         GetReq(XTrap,reqptr);
    289         reqptr->minor_opcode = XETrap_StopTrap;
    290         XFlush(dpy);
    291         SyncHandle();
    292         BitFalse(tc->values.tc_flags, XETCTrapActive);
    293         /* Remove our event handler for the XLib transport */
    294 	XETrapSetEventHandler(tc, XETrapData, NULL);
    295     }
    296 
    297     return(status);
    298 }
    299 
    300 #ifndef _XINPUT
    301 int XESimulateXEventRequest(XETC *tc, CARD8 type, CARD8 detail,
    302     CARD16 x, CARD16 y, CARD8 screen)
    303 {
    304     int status = True;
    305     Display *dpy = tc->dpy;
    306     CARD32 X_XTrapInput = tc->extOpcode;
    307     xXTrapInputReq *reqptr;
    308     status = XEFlushConfig(tc); /* Flushout any pending configuration first */
    309     if (status == True)
    310     {   /* write out the input event */
    311         GetReq(XTrapInput,reqptr);
    312         reqptr->minor_opcode = XETrap_SimulateXEvent;
    313         reqptr->input.type   = type;
    314         reqptr->input.detail = detail;
    315         reqptr->input.x      = x;
    316         reqptr->input.y      = y;
    317         reqptr->input.screen = screen;
    318         XFlush(dpy);
    319     }
    320     return(status);
    321 }
    322 #endif
    323 int XEGetCurrentRequest(XETC *tc, XETrapGetCurRep *ret)
    324 {
    325     int status = True;
    326     Display *dpy = tc->dpy;
    327     CARD32 X_XTrap = tc->extOpcode;
    328     xXTrapReq *reqptr;
    329     xXTrapGetCurReply rep;
    330     int numlongs = (SIZEOF(xXTrapGetCurReply) -
    331         SIZEOF(xReply) + SIZEOF(CARD32) -1 ) / SIZEOF(CARD32);
    332     status = XEFlushConfig(tc); /* Flushout any pending configuration first */
    333     if (status == True)
    334     {
    335         LockDisplay(dpy);
    336         GetReq(XTrap,reqptr);
    337         reqptr->minor_opcode = XETrap_GetCurrent;
    338         /* to support comm. w/ V3.1 extensions */
    339         if (tc->protocol == 31)
    340         {
    341             char tmp[284];  /* need space for the big *old* reply */
    342             numlongs = (284-sizeof(xReply)+sizeof(long)-1)/sizeof(long);
    343             status = _XReply(dpy,(xReply *)tmp,numlongs,xTrue);
    344             memcpy(&rep,tmp,sizeof(rep));   /* move just what's needed */
    345         }
    346         else
    347         {
    348             status = _XReply(dpy,(xReply *)&rep,numlongs,xTrue);
    349         }
    350         UnlockDisplay(dpy);
    351         SyncHandle();
    352 
    353     memcpy((char *)ret->state_flags,rep.data_state_flags,2);
    354     memcpy((char *)ret->config.flags.valid,rep.data_config_flags_valid,4);
    355     memcpy((char *)ret->config.flags.data,rep.data_config_flags_data,4);
    356     memcpy((char *)ret->config.flags.req,rep.data_config_flags_req,
    357         XETrapMaxRequest);
    358     memcpy((char *)ret->config.flags.event,rep.data_config_flags_event,
    359         XETrapMaxEvent);
    360     ret->config.max_pkt_size=rep.data_config_max_pkt_size;
    361     ret->config.cmd_key=rep.data_config_cmd_key;
    362 
    363     }
    364     return(status);
    365 }
    366 
    367 int XEGetStatisticsRequest(XETC *tc, XETrapGetStatsRep *ret)
    368 {
    369     int status = True;
    370     Display *dpy = tc->dpy;
    371     CARD32 X_XTrap = tc->extOpcode;
    372     xXTrapReq *reqptr;
    373     xXTrapGetStatsReply rep;
    374     status = XEFlushConfig(tc); /* Flushout any pending configuration first */
    375     if (status == True)
    376     {
    377         LockDisplay(dpy);
    378         GetReq(XTrap,reqptr);
    379         reqptr->minor_opcode = XETrap_GetStatistics;
    380         /* to support comm. w/ V3.1 extensions */
    381 #ifndef CRAY
    382         if (tc->protocol == 31)
    383         {   /* this is the way we used to do it which breaks Cray's */
    384 #ifndef VECTORED_EVENTS
    385             int numlongs = (1060-sizeof(xReply)+sizeof(long)-1)/sizeof(long);
    386 #else
    387             int numlongs = (1544-sizeof(xReply)+sizeof(long)-1)/sizeof(long);
    388 #endif
    389             status = _XReply(dpy,(xReply *)&rep,numlongs,xTrue);
    390             if (status == True)
    391             {   /* need to shift it back into the data struct */
    392                 xXTrapGetStatsReply tmp;
    393                 tmp = rep;
    394                 memcpy(&(rep.data),&(tmp.pad0), sizeof(rep.data));
    395             }
    396         }
    397         else
    398 #endif /* CRAY */
    399         {   /* this is the way we do it for V3.2 */
    400             int numbytes = SIZEOF(xXTrapGetStatsReply) - SIZEOF(xReply);
    401             status = _XReply(dpy, (xReply *)&rep, 0, xFalse);
    402             if (status == True)
    403             {
    404                 status = _XRead(dpy, (char *)&rep.data, numbytes);
    405             }
    406         }
    407         UnlockDisplay(dpy);
    408         SyncHandle();
    409         memcpy(ret,&(rep.data),sizeof(XETrapGetStatsRep));
    410     }
    411     return(status);
    412 }
    413