1# Copyright 2014 Tycho Andersen
2# Copyright 2014 Sean Vig
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8#   http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15
16from cffi import FFI
17
18
19CONSTANTS = [
20    ("X_PROTOCOL", 11),
21    ("X_PROTOCOL_REVISION", 0),
22    ("X_TCP_PORT", 6000),
23
24    ("XCB_NONE", 0),
25    ("XCB_COPY_FROM_PARENT", 0),
26    ("XCB_CURRENT_TIME", 0),
27    ("XCB_NO_SYMBOL", 0),
28
29    ("XCB_CONN_ERROR", 1),
30    ("XCB_CONN_CLOSED_EXT_NOTSUPPORTED", 2),
31    ("XCB_CONN_CLOSED_MEM_INSUFFICIENT", 3),
32    ("XCB_CONN_CLOSED_REQ_LEN_EXCEED", 4),
33    ("XCB_CONN_CLOSED_PARSE_ERR", 5),
34    ("XCB_CONN_CLOSED_INVALID_SCREEN", 6),
35    ("XCB_CONN_CLOSED_FDPASSING_FAILED", 7),
36
37    ("XCB_REQUEST_CHECKED", 1 << 0)
38]
39
40
41# constants
42CDEF = '\n'.join("#define %s %d" % (c, v) for c, v in CONSTANTS)
43
44# types
45CDEF += """
46    // xcb.h
47    typedef struct {
48        uint8_t  response_type;  /**< Type of the response */
49        uint8_t  pad0;           /**< Padding */
50        uint16_t sequence;       /**< Sequence number */
51        uint32_t length;         /**< Length of the response */
52    } xcb_generic_reply_t;
53
54    typedef struct {
55        uint8_t  response_type;  /**< Type of the response */
56        uint8_t  pad0;           /**< Padding */
57        uint16_t sequence;       /**< Sequence number */
58        uint32_t pad[7];         /**< Padding */
59        uint32_t full_sequence;  /**< full sequence */
60    } xcb_generic_event_t;
61
62    typedef struct {
63        uint8_t  response_type;  /**< Type of the response */
64        uint8_t  error_code;     /**< Error code */
65        uint16_t sequence;       /**< Sequence number */
66        uint32_t resource_id;     /** < Resource ID for requests with side effects only */
67        uint16_t minor_code;      /** < Minor opcode of the failed request */
68        uint8_t  major_code;       /** < Major opcode of the failed request */
69        uint8_t  pad0;
70        uint32_t pad[5];         /**< Padding */
71        uint32_t full_sequence;  /**< full sequence */
72    } xcb_generic_error_t;
73
74    typedef struct {
75        unsigned int sequence;  /**< Sequence number */
76    } xcb_void_cookie_t;
77
78    typedef struct xcb_auth_info_t {
79        int   namelen;
80        char *name;
81        int   datalen;
82        char *data;
83    } xcb_auth_info_t;
84
85    typedef ... xcb_connection_t;
86
87    // xproto.h
88    typedef uint32_t xcb_colormap_t;
89    typedef uint32_t xcb_drawable_t;
90    typedef uint32_t xcb_pixmap_t;
91    typedef uint32_t xcb_visualid_t;
92    typedef uint32_t xcb_window_t;
93
94    typedef struct xcb_query_extension_reply_t {
95        uint8_t  response_type;
96        uint8_t  pad0;
97        uint16_t sequence;
98        uint32_t length;
99        uint8_t  present;
100        uint8_t  major_opcode;
101        uint8_t  first_event;
102        uint8_t  first_error;
103    } xcb_query_extension_reply_t;
104
105    typedef struct xcb_setup_t {
106        uint8_t       status; /**<  */
107        uint8_t       pad0; /**<  */
108        uint16_t      protocol_major_version; /**<  */
109        uint16_t      protocol_minor_version; /**<  */
110        uint16_t      length; /**<  */
111        uint32_t      release_number; /**<  */
112        uint32_t      resource_id_base; /**<  */
113        uint32_t      resource_id_mask; /**<  */
114        uint32_t      motion_buffer_size; /**<  */
115        uint16_t      vendor_len; /**<  */
116        uint16_t      maximum_request_length; /**<  */
117        uint8_t       roots_len; /**<  */
118        uint8_t       pixmap_formats_len; /**<  */
119        uint8_t       image_byte_order; /**<  */
120        uint8_t       bitmap_format_bit_order; /**<  */
121        uint8_t       bitmap_format_scanline_unit; /**<  */
122        uint8_t       bitmap_format_scanline_pad; /**<  */
123        uint8_t       min_keycode; /**<  */
124        uint8_t       max_keycode; /**<  */
125        uint8_t       pad1[4]; /**<  */
126    } xcb_setup_t;
127
128    typedef struct xcb_visualtype_t {
129        xcb_visualid_t visual_id; /**<  */
130        uint8_t        _class; /**<  */
131        uint8_t        bits_per_rgb_value; /**<  */
132        uint16_t       colormap_entries; /**<  */
133        uint32_t       red_mask; /**<  */
134        uint32_t       green_mask; /**<  */
135        uint32_t       blue_mask; /**<  */
136        uint8_t        pad0[4]; /**<  */
137    } xcb_visualtype_t;
138
139    typedef struct xcb_screen_t {
140        xcb_window_t   root; /**<  */
141        xcb_colormap_t default_colormap; /**<  */
142        uint32_t       white_pixel; /**<  */
143        uint32_t       black_pixel; /**<  */
144        uint32_t       current_input_masks; /**<  */
145        uint16_t       width_in_pixels; /**<  */
146        uint16_t       height_in_pixels; /**<  */
147        uint16_t       width_in_millimeters; /**<  */
148        uint16_t       height_in_millimeters; /**<  */
149        uint16_t       min_installed_maps; /**<  */
150        uint16_t       max_installed_maps; /**<  */
151        xcb_visualid_t root_visual; /**<  */
152        uint8_t        backing_stores; /**<  */
153        uint8_t        save_unders; /**<  */
154        uint8_t        root_depth; /**<  */
155        uint8_t        allowed_depths_len; /**<  */
156    } xcb_screen_t;
157
158    typedef struct xcb_screen_iterator_t {
159        xcb_screen_t *data; /**<  */
160        int           rem; /**<  */
161        int           index; /**<  */
162    } xcb_screen_iterator_t;
163
164    xcb_screen_iterator_t
165    xcb_setup_roots_iterator (const xcb_setup_t *R  /**< */);
166
167    void
168    xcb_screen_next (xcb_screen_iterator_t *i  /**< */);
169
170    // render.h
171    typedef uint32_t xcb_render_pictformat_t;
172
173    typedef struct xcb_render_directformat_t {
174        uint16_t red_shift; /**<  */
175        uint16_t red_mask; /**<  */
176        uint16_t green_shift; /**<  */
177        uint16_t green_mask; /**<  */
178        uint16_t blue_shift; /**<  */
179        uint16_t blue_mask; /**<  */
180        uint16_t alpha_shift; /**<  */
181        uint16_t alpha_mask; /**<  */
182    } xcb_render_directformat_t;
183
184    typedef struct xcb_render_pictforminfo_t {
185        xcb_render_pictformat_t   id; /**<  */
186        uint8_t                   type; /**<  */
187        uint8_t                   depth; /**<  */
188        uint8_t                   pad0[2]; /**<  */
189        xcb_render_directformat_t direct; /**<  */
190        xcb_colormap_t            colormap; /**<  */
191    } xcb_render_pictforminfo_t;
192
193    // xcbext.h
194    typedef struct xcb_extension_t {
195        const char *name;
196        int global_id;
197    } xcb_extension_t;
198
199    typedef struct {
200        size_t count;
201        xcb_extension_t *ext;
202        uint8_t opcode;
203        uint8_t isvoid;
204    } xcb_protocol_request_t;
205
206    // sys/uio.h
207    struct iovec
208    {
209      void *iov_base; /* BSD uses caddr_t (1003.1g requires void *) */
210      size_t iov_len; /* Must be size_t (1003.1g) */
211    };
212
213    // need to manually free some things that XCB allocates
214    void free(void *ptr);
215"""
216
217# connection manipulation, mostly generated with:
218# grep -v '^[ \/\}#]' xcb.h | grep -v '^typedef' | grep -v '^extern'
219CDEF += """
220    int xcb_flush(xcb_connection_t *c);
221    uint32_t xcb_get_maximum_request_length(xcb_connection_t *c);
222    void xcb_prefetch_maximum_request_length(xcb_connection_t *c);
223    xcb_generic_event_t *xcb_wait_for_event(xcb_connection_t *c);
224    xcb_generic_event_t *xcb_poll_for_event(xcb_connection_t *c);
225    const xcb_query_extension_reply_t *xcb_get_extension_data(xcb_connection_t *c, xcb_extension_t *ext);
226    const xcb_setup_t *xcb_get_setup(xcb_connection_t *c);
227    int xcb_get_file_descriptor(xcb_connection_t *c);
228    int xcb_connection_has_error(xcb_connection_t *c);
229    xcb_connection_t *xcb_connect_to_fd(int fd, xcb_auth_info_t *auth_info);
230    void xcb_disconnect(xcb_connection_t *c);
231    int xcb_parse_display(const char *name, char **host, int *display, int *screen);
232    xcb_connection_t *xcb_connect(const char *displayname, int *screenp);
233    xcb_connection_t *xcb_connect_to_display_with_auth_info(const char *display, xcb_auth_info_t *auth, int *screen);
234    uint32_t xcb_generate_id(xcb_connection_t *c);
235    xcb_generic_error_t *xcb_request_check(xcb_connection_t *c, xcb_void_cookie_t cookie);
236"""
237
238CDEF += """
239    unsigned int xcb_send_request(xcb_connection_t *c, int flags, struct iovec *vector, const xcb_protocol_request_t *request);
240    void *xcb_wait_for_reply(xcb_connection_t *c, unsigned int request, xcb_generic_error_t **e);
241    int xcb_poll_for_reply(xcb_connection_t *c, unsigned int request, void **reply, xcb_generic_error_t **error);
242    void xcb_discard_reply(xcb_connection_t *c, unsigned int sequence);
243"""
244
245
246ffi = FFI()
247if hasattr(ffi, 'set_source'):  # PyPy < 2.6 compatibility hack
248    ffi.set_source("xcffib._ffi", None, libraries=['xcb'])
249    do_compile = True
250else:
251    do_compile = False
252ffi.cdef(CDEF)
253
254
255if __name__ == "__main__" and do_compile:
256    ffi.compile()
257