summaryrefslogtreecommitdiff
path: root/src/xcbext.h
blob: 7587513d7e4bcff3ad6aa1f0d359e83495d2b3d6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
/*
 * Copyright (C) 2001-2004 Bart Massey and Jamey Sharp.
 * All Rights Reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 * 
 * Except as contained in this notice, the names of the authors or their
 * institutions shall not be used in advertising or otherwise to promote the
 * sale, use or other dealings in this Software without prior written
 * authorization from the authors.
 */

#ifndef __XCBEXT_H
#define __XCBEXT_H

#include "xcb.h"

#ifdef __cplusplus
extern "C" {
#endif

/* xcb_ext.c */

struct xcb_extension_t {
    const char *name;
    int global_id;
};


/* xcb_out.c */

typedef struct {
    size_t count;
    xcb_extension_t *ext;
    uint8_t opcode;
    uint8_t isvoid;
} xcb_protocol_request_t;

enum xcb_send_request_flags_t {
    XCB_REQUEST_CHECKED = 1 << 0,
    XCB_REQUEST_RAW = 1 << 1,
    XCB_REQUEST_DISCARD_REPLY = 1 << 2,
    XCB_REQUEST_REPLY_FDS = 1 << 3
};

/**
 * @brief Send a request to the server.
 * @param c: The connection to the X server.
 * @param flags: A combination of flags from the xcb_send_request_flags_t enumeration.
 * @param vector: Data to send; must have two iovecs before start for internal use.
 * @param request: Information about the request to be sent.
 * @return The request's sequence number on success, 0 otherwise.
 *
 * This function sends a new request to the X server. The data of the request is
 * given as an array of @c iovecs in the @p vector argument. The length of that
 * array and the neccessary management information are given in the @p request
 * argument.
 *
 * When this function returns, the request might or might not be sent already.
 * Use xcb_flush() to make sure that it really was sent.
 *
 * Please note that this function is not the prefered way for sending requests.
 * It's better to use the generated wrapper functions.
 *
 * Please note that xcb might use index -1 and -2 of the @p vector array internally,
 * so they must be valid!
 */
unsigned int xcb_send_request(xcb_connection_t *c, int flags, struct iovec *vector, const xcb_protocol_request_t *request);

/**
 * @brief Send a file descriptor to the server in the next call to xcb_send_request.
 * @param c: The connection to the X server.
 * @param fd: The file descriptor to send.
 *
 * After this function returns, the file descriptor given is owned by xcb and
 * will be closed eventually.
 *
 * FIXME: How the heck is this supposed to work in a thread-safe way? There is a
 * race between two threads doing xcb_send_fd(); xcb_send_request(); at the same
 * time.
 */
void xcb_send_fd(xcb_connection_t *c, int fd);

/**
 * @brief Take over the write side of the socket
 * @param c: The connection to the X server.
 * @param return_socket: Callback function that will be called when xcb wants
 *                        to use the socket again.
 * @param closure: Argument to the callback function.
 * @param flags: A combination of flags from the xcb_send_request_flags_t enumeration.
 * @param sent: Location to the sequence number of the last sequence request.
 *              Must not be NULL.
 * @return 1 on success, else 0.
 *
 * xcb_take_socket allows external code to ask XCB for permission to
 * take over the write side of the socket and send raw data with
 * xcb_writev. xcb_take_socket provides the sequence number of the last
 * request XCB sent. The caller of xcb_take_socket must supply a
 * callback which XCB can call when it wants the write side of the
 * socket back to make a request. This callback synchronizes with the
 * external socket owner and flushes any output queues if appropriate.
 * If you are sending requests which won't cause a reply, please note the
 * comment for xcb_writev which explains some sequence number wrap issues.
 *
 * All replies that are generated while the socket is owned externally have
 * @p flags applied to them. For example, use XCB_REQUEST_CHECK if you don't
 * want errors to go to xcb's normal error handling, but instead having to be
 * picked up via xcb_wait_for_reply(), xcb_poll_for_reply() or
 * xcb_request_check().
 */
int xcb_take_socket(xcb_connection_t *c, void (*return_socket)(void *closure), void *closure, int flags, uint64_t *sent);

/**
 * @brief Send raw data to the X server.
 * @param c: The connection to the X server.
 * @param vector: Array of data to be sent.
 * @param count: Number of entries in @p vector.
 * @param requests: Number of requests that are being sent.
 * @return 1 on success, else 0.
 *
 * You must own the write-side of the socket (you've called
 * xcb_take_socket, and haven't returned from return_socket yet) to call
 * xcb_writev. Also, the iovec must have at least 1 byte of data in it.
 * You have to make sure that xcb can detect sequence number wraps correctly.
 * This means that the first request you send after xcb_take_socket must cause a
 * reply (e.g. just insert a GetInputFocus request). After every (1 << 16) - 1
 * requests without a reply, you have to insert a request which will cause a
 * reply. You can again use GetInputFocus for this. You do not have to wait for
 * any of the GetInputFocus replies, but can instead handle them via
 * xcb_discard_reply().
 */
int xcb_writev(xcb_connection_t *c, struct iovec *vector, int count, uint64_t requests);


/* xcb_in.c */

/**
 * @brief Wait for the reply of a given request.
 * @param c: The connection to the X server.
 * @param request: Sequence number of the request as returned by xcb_send_request().
 * @param e: Location to store errors in, or NULL. Ignored for unchecked requests.
 *
 * Returns the reply to the given request or returns null in the event of
 * errors. Blocks until the reply or error for the request arrives, or an I/O
 * error occurs.
 */
void *xcb_wait_for_reply(xcb_connection_t *c, unsigned int request, xcb_generic_error_t **e);

/**
 * @brief Poll for the reply of a given request.
 * @param c: The connection to the X server.
 * @param request: Sequence number of the request as returned by xcb_send_request().
 * @param reply: Location to store the reply in, must not be NULL.
 * @param e: Location to store errors in, or NULL. Ignored for unchecked requests.
 * @return 1 when the reply to the request was returned, else 0.
 *
 * Checks if the reply to the given request already received. Does not block.
 */
int xcb_poll_for_reply(xcb_connection_t *c, unsigned int request, void **reply, xcb_generic_error_t **error);

/**
 * @brief Don't use this, only needed by the generated code.
 * @param c: The connection to the X server.
 * @param reply: A reply that was received from the server
 * @param replylen: The size of the reply.
 * @return Pointer to the location where received file descriptors are stored.
 */
int *xcb_get_reply_fds(xcb_connection_t *c, void *reply, size_t replylen);


/* xcb_util.c */

/**
 * @param mask: The mask to check
 * @return The number of set bits in the mask
 */
int xcb_popcount(uint32_t mask);

/**
 * @param list: The base of an array
 * @param len: The length of the array
 * @return The sum of all entries in the array.
 */
int xcb_sumof(uint8_t *list, int len);

#ifdef __cplusplus
}
#endif

#endif