summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Coopersmith <alan.coopersmith@oracle.com>2013-03-17 17:08:07 -0700
committerAlan Coopersmith <alan.coopersmith@oracle.com>2013-03-30 20:31:13 -0700
commita100f5f5cd66c1baf91276834d0c1de9803856f3 (patch)
tree25b3462a2cdf0679d736285d9e8d2ab7cca1e232
parent9e1e383021c82a78c9c3a0c23b3f76016a5569ed (diff)
Expose sequence number setting "extension" to test programs
Allows setting specific sequeunce numbers for matching request patterns to avoid having to match exact sequences of calls Xlib may make behind the scenes to check for/use various extensions for you. Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
-rw-r--r--include/xhiv.h6
-rw-r--r--src/proto.h11
-rw-r--r--src/server.c19
-rw-r--r--src/xcb_client.c28
-rw-r--r--src/xlib_client.c16
5 files changed, 58 insertions, 22 deletions
diff --git a/include/xhiv.h b/include/xhiv.h
index 709afa0..0063cf3 100644
--- a/include/xhiv.h
+++ b/include/xhiv.h
@@ -51,16 +51,18 @@ typedef struct xhiv_response {
/* Fork a server process and return the string needed to connect to it. */
extern char *XhivOpenServer(xhiv_response *responses, pid_t *return_pid);
-/* Open a Xlib display connection to a new Xhiv server */
+/* Manage an Xlib display connection to a new Xhiv server */
#include <X11/Xlib.h>
extern Display *XhivOpenDisplay(xhiv_response *responses);
extern int XhivCloseDisplay(Display *dpy);
+extern void XhivSequenceSync(Display *dpy, uint32_t sequence);
#ifdef HAVE_XCB
-/* Open an xcb display connection to a new Xhiv server */
+/* Manage an xcb display connection to a new Xhiv server */
#include <xcb/xcb.h>
extern xcb_connection_t *xhiv_connect(xhiv_response *responses);
extern int xhiv_disconnect(xcb_connection_t *conn);
+extern void xhiv_sequence_sync(xcb_connection_t *conn, uint32_t sequence);
#endif
#endif /* XHIV_H */
diff --git a/src/proto.h b/src/proto.h
index 8534d26..56899d6 100644
--- a/src/proto.h
+++ b/src/proto.h
@@ -25,6 +25,8 @@
# include "config.h"
#endif
+/* Fake extension protocol between xhiv client & server */
+
#include <inttypes.h>
/* Major op code (reqType) */
@@ -33,11 +35,16 @@
/* Minor op code (reqMinor) */
#define XhivSeqStart 0 /* start sequence counting */
-/* Fake extension protocol between xhiv client setup & server */
+/*
+ * Force the sequence number used for matching canned request replies
+ * to be set to the value specified in this request. (i.e. if this
+ * request has sequence 0, the next one will be treated as 1 & so on).
+ */
typedef struct {
uint8_t reqType; /* XHIV_PROTO_REQTYPE */
uint8_t reqMinor; /* XHIV_PROTO_SEQSTART */
- uint16_t length; /* 1 - no more data needed */
+ uint16_t length; /* 2 - no more data needed */
+ uint32_t sequence; /* treat this request as having this seq no. */
} xXhivSeqStartReq;
#define sz_xXhivSeqStartReq 4
diff --git a/src/server.c b/src/server.c
index d9bb996..38fa584 100644
--- a/src/server.c
+++ b/src/server.c
@@ -492,6 +492,11 @@ HandleClientRequest(client_state *client, xhiv_response *responses)
else
length = req.length;
+#ifdef DEBUG
+ printf("Request %d (match seq %d): %d/%d\n", client->sequence,
+ client->match_sequence, req.reqType, req.data);
+#endif
+
/* X11 packets count the initial header as part of their length */
client->req_len_remaining = (length << 2) - sizeof(req);
@@ -588,8 +593,18 @@ HandleClientRequest(client_state *client, xhiv_response *responses)
break;
case X_XHIV_PROTO_REQTYPE: /* our fake extension */
- if (req.data == XhivSeqStart)
- client->match_sequence = 0;
+ if (req.data == XhivSeqStart) {
+ uint32_t newseq;
+ rbytes = _XSERVTransRead(client->conn, (char *)&newseq,
+ sizeof(uint32_t));
+ assert(rbytes == sizeof(uint32_t));
+ client->req_len_remaining -= rbytes;
+
+ client->match_sequence = newseq;
+#ifdef DEBUG
+ printf("Set match sequence to %d\n", newseq);
+#endif
+ }
break;
case BIGREQ_REQTYPE: /* our fake BIG-REQUESTS extension */
diff --git a/src/xcb_client.c b/src/xcb_client.c
index 9587ddd..e4f7f33 100644
--- a/src/xcb_client.c
+++ b/src/xcb_client.c
@@ -44,21 +44,11 @@ static const xcb_protocol_request_t xcb_req = {
.isvoid = 1
};
-static xXhivSeqStartReq xssreq = {
- .reqType = X_XHIV_PROTO_REQTYPE,
- .reqMinor = XhivSeqStart,
- .length = 1 /* no more data needed */
-};
-
xcb_connection_t *
xhiv_connect(xhiv_response *responses) {
char *displayname;
xcb_connection_t *conn;
int screen;
- struct iovec xcb_parts[4] = {
- [2] = { .iov_base = &xssreq, .iov_len = sizeof(xssreq) },
- [3] = { .iov_base = 0, .iov_len = 0 /* no padding needed */ }
- };
displayname = XhivOpenServer(responses, &server_pid);
assert(displayname != NULL);
@@ -67,11 +57,27 @@ xhiv_connect(xhiv_response *responses) {
assert(conn != NULL);
assert(screen == 0);
- xcb_send_request(conn, XCB_REQUEST_RAW, xcb_parts + 2, &xcb_req);
+ xhiv_sequence_sync(conn, 0);
return conn;
}
+void
+xhiv_sequence_sync(xcb_connection_t *conn, uint32_t seq) {
+ xXhivSeqStartReq xssreq = {
+ .reqType = X_XHIV_PROTO_REQTYPE,
+ .reqMinor = XhivSeqStart,
+ .length = 2,
+ .sequence = seq
+ };
+ struct iovec xcb_parts[4] = {
+ [2] = { .iov_base = &xssreq, .iov_len = sizeof(xssreq) },
+ [3] = { .iov_base = 0, .iov_len = 0 /* no padding needed */ }
+ };
+
+ xcb_send_request(conn, XCB_REQUEST_RAW, xcb_parts + 2, &xcb_req);
+}
+
int
xhiv_disconnect(xcb_connection_t *conn) {
pid_t waitfor;
diff --git a/src/xlib_client.c b/src/xlib_client.c
index 03b56c8..a612910 100644
--- a/src/xlib_client.c
+++ b/src/xlib_client.c
@@ -36,7 +36,6 @@ Display *
XhivOpenDisplay(xhiv_response *responses) {
char *dpyname;
Display *dpy;
- xReq *xssreq;
dpyname = XhivOpenServer(responses, &server_pid);
assert(dpyname != NULL);
@@ -44,13 +43,20 @@ XhivOpenDisplay(xhiv_response *responses) {
dpy = XOpenDisplay(dpyname);
assert(dpy != NULL);
+ XhivSequenceSync(dpy, 0);
+
+ return dpy;
+}
+
+void
+XhivSequenceSync(Display *dpy, uint32_t sequence) {
+ xResourceReq *xssreq;
+
LockDisplay(dpy);
- GetEmptyReq(XHIV_PROTO_REQTYPE, xssreq);
- xssreq->data = XhivSeqStart;
+ GetResReq(XHIV_PROTO_REQTYPE, sequence, xssreq);
+ ((xXhivSeqStartReq *)xssreq)->reqMinor = XhivSeqStart;
UnlockDisplay(dpy);
SyncHandle();
-
- return dpy;
}
int