XERqsts.c revision 9384b2f3
1/* $XFree86$ */ 2/***************************************************************************** 3Copyright 1987, 1988, 1989, 1990, 1991 by Digital Equipment Corp., Maynard, MA 4 5Permission to use, copy, modify, and distribute this software and its 6documentation for any purpose and without fee is hereby granted, 7provided that the above copyright notice appear in all copies and that 8both that copyright notice and this permission notice appear in 9supporting documentation, and that the name of Digital not be 10used in advertising or publicity pertaining to distribution of the 11software without specific, written prior permission. 12 13DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 14ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL 15DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR 16ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 17WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 18ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 19SOFTWARE. 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 */ 142int 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 162int 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 */ 183static 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 */ 217int XEFlushConfig(XETC *tc) 218{ 219 return((tc->dirty) ? XEConfigRequest(tc) : True); 220} 221int 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 239int 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 260int 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} 279int 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 301int 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 323int 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 367int 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