From 1f6143b4386b750ae9e732a6c591cdca73d2b2df Mon Sep 17 00:00:00 2001 From: Alan Coopersmith Date: Sun, 31 Mar 2013 09:36:14 -0700 Subject: Allow test programs to provide responses to selected QueryExtension calls Allows them to provide their own psuedo-implementations of Extensions. If the sequence in a response is set to XHIV_SEQ_MATCHDATA, then the new match_data field has a pointer to additional matching constraints. So far only X_QueryExtension will check those, and it expects a null terminated extension name string to match against the queried extension. Signed-off-by: Alan Coopersmith --- include/xhiv.h | 4 +++- src/server.c | 28 +++++++++++++++++++++------- 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/include/xhiv.h b/include/xhiv.h index 426918c..26b0036 100644 --- a/include/xhiv.h +++ b/include/xhiv.h @@ -31,7 +31,8 @@ #define XHIV_REQ_IGNORE 1024 /* Match only seq number, not req code */ #define XHIV_REQ_CONN_SETUP 1025 /* Initial handshake */ -#define XHIV_SEQ_IGNORE 0xFFFFFFFF /* Match only req code, not seq number */ +#define XHIV_SEQ_IGNORE 0xFFFFFFFF /* Match only req code, not seq number */ +#define XHIV_SEQ_MATCHDATA 0xFFFFFFFE /* Match only if match_data matches */ #define XHIV_NO_SET_SEQUENCE 0x01 /* Don't set sequence number in reply */ @@ -43,6 +44,7 @@ typedef struct xhiv_response { uint16_t reqType; /* Request code, extension number or XHIV_REQ constant */ uint16_t reqMinor; /* Extension minor request code */ uint32_t sequence; /* Sequence number, or XHIV_SEQ_IGNORE */ + const void *match_data; /* Additional data for matching requests */ uint32_t length; /* Total length of reply packet, in 4-byte words */ const void *response_data; /* Data to return */ uint32_t response_datalen; /* Length of response_data, in bytes */ diff --git a/src/server.c b/src/server.c index 24a9872..c1acfe0 100644 --- a/src/server.c +++ b/src/server.c @@ -521,7 +521,7 @@ HandleClientRequest(client_state *client, xhiv_response *responses) switch (req.reqType) { case X_QueryExtension: /* XOpenDisplay checks for BIG-REQUESTS & XKB extensions. - We only simulate BIG-REQUESTS for now */ + We only simulate BIG-REQUESTS here for now */ { int nbytes = client->req_len_remaining; char extension[32] = ""; @@ -533,11 +533,12 @@ HandleClientRequest(client_state *client, xhiv_response *responses) .first_event = 0, .first_error = 0 }; - xhiv_response qext_response = { + xhiv_response default_qext_response = { .length = bytes_to_int32(sz_xQueryExtensionReply), .response_data = &qext_reply, .response_datalen = sizeof(qext_reply) }; + xhiv_response *qext_response = &default_qext_response; if (nbytes > sizeof(extension)) nbytes = sizeof(extension); @@ -546,17 +547,30 @@ HandleClientRequest(client_state *client, xhiv_response *responses) if (rbytes > 0) { assert(client->req_len_remaining >= rbytes); client->req_len_remaining -= rbytes; - if (strncmp(extension + 4, XBigReqExtensionName, - sizeof(XBigReqExtensionName)) == 0) { - qext_reply.present = xTrue; - qext_reply.major_opcode = BIGREQ_REQTYPE; + /* Check to see if caller provided a match */ + for (r = responses; r != NULL ; r = r->next) { + if ((r->reqType == X_QueryExtension) && + (r->sequence == XHIV_SEQ_MATCHDATA) && + (strncmp(extension + 4, r->match_data, + sizeof(extension) - 4) == 0)) { + qext_response = r; + break; + } + } + /* If caller didn't, then handle ourselves */ + if (qext_response == &default_qext_response) { + if (strncmp(extension + 4, XBigReqExtensionName, + sizeof(XBigReqExtensionName)) == 0) { + qext_reply.present = xTrue; + qext_reply.major_opcode = BIGREQ_REQTYPE; + } } } else { assert(rbytes == 0); } client->crb = - AddResponseToBuffer(client->crb, &qext_response, + AddResponseToBuffer(client->crb, qext_response, client->sequence); } break; -- cgit v1.2.3