Compare commits

...

153 Commits

Author SHA1 Message Date
Frederik Hertzum 93e6da2e2e added wrap file 2025-08-12 22:52:42 +02:00
Samuel Thibault 6a7661f60a Get rid of PATH_MAX
There could be no upper limit on the length of a path according
to POSIX, therefore these macros may not be defined at all on
some systems (such as GNU Hurd). There is however a limit on
sizeof(struct sockaddr_un.sun_path), so use it.

Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
Part-of: <https://gitlab.freedesktop.org/xorg/lib/libxcb/-/merge_requests/65>
2025-07-08 23:05:34 +02:00
Alan Coopersmith daf2c53976 add pure & const function attributes suggested by gcc -Wsuggest-attribute
This only covers the ones in the pre-written code.  There are many more
suggested in the generated code, which will require changing the generator
and will thus be handled separately.

Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
Part-of: <https://gitlab.freedesktop.org/xorg/lib/libxcb/-/merge_requests/64>
2024-12-15 10:17:22 -08:00
Alan Coopersmith 021e887de9 xcb.h: use __has_attribute to check for attribute((__packed__)) support
Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
Part-of: <https://gitlab.freedesktop.org/xorg/lib/libxcb/-/merge_requests/64>
2024-12-15 10:17:22 -08:00
Alan Coopersmith 124690ba63 xcb.h: remove __solaris__ ifdef
Nothing was defining __solaris__ on Solaris in current build setup, and
it's not needed on Solaris 10 (released 2005) and later, which has
stdint.h.  (Solaris 2.6 - 9 had inttypes.h, but no stdint.h.)

Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
Part-of: <https://gitlab.freedesktop.org/xorg/lib/libxcb/-/merge_requests/64>
2024-12-15 10:17:22 -08:00
Xi Ruoyao ebea71700f c_client.py: Always open output files in UTF-8
The UTF-8 quotes can appear in man pages etc as well, not only C code.
For example, in xcb_composite_redirect_subwindows.3:

    xcb_composite_redirect_subwindows - Redirect all current and future
    children of ‘window’

Note that window is quoted by a pair of UTF-8 single quotes.

Closes: #72
Signed-off-by: Xi Ruoyao <xry111@xry111.site>
Part-of: <https://gitlab.freedesktop.org/xorg/lib/libxcb/-/merge_requests/60>
2024-06-06 03:11:02 +08:00
Matt Turner 622152ee42 libxcb 1.17.0 2024-04-15 14:53:31 +00:00
Matt Turner 4574ab269b configure.ac: Require xcb-proto >= 1.17.0
Signed-off-by: Matt Turner <mattst88@gmail.com>
2024-04-15 14:53:31 +00:00
Uli Schlachter b78d304531 Always write C code in UTF-8
Some people apparently use non-utf8 locales and this caused errors when
xcb-proto started using some "fancy" quote marks. Fix this by always
using utf8 encoding.

Fixes: https://gitlab.freedesktop.org/xorg/lib/libxcb/-/issues/72
Signed-off-by: Uli Schlachter <psychon@znc.in>
2024-04-15 14:40:41 +00:00
Erik Kurzinger 389f22d1cb Add xcb-dri3 dependency to xcb-present.pc.in
Present version 1.4 introduces a dependency on DRI3 for the DRI3Syncobj
protocol type.

Signed-off-by: Erik Kurzinger <ekurzinger@nvidia.com>
2024-03-20 07:06:12 -07:00
Alan Coopersmith 86a478032b xcb_popcount: Use __builtin_popcount if compiler supports it
If the compiler knows of a better implementation for counting the number
of bits set in a word for the target CPU, let it use that, instead of the
classic algorithm optimized for PDP-6.

Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
2024-03-08 22:11:43 +00:00
Alan Coopersmith c268499c30 tests: fix -Werror=discarded-qualifiers errors in check_public.c
check_public.c: In function ‘parse_display_pass’:
check_public.c:32:32: error: passing argument 1 of ‘putenv’ discards ‘const’ qualifier from pointer target type [-Werror=discarded-qualifiers]
   32 |                         putenv("DISPLAY=");
      |                                ^~~~~~~~~~
In file included from check_public.c:4:
/usr/include/stdlib.h:148:19: note: expected ‘char *’ but argument is of type ‘const char *’
  148 | extern int putenv(char *);
      |                   ^~~~~~
check_public.c:57:16: error: passing argument 1 of ‘putenv’ discards ‘const’ qualifier from pointer target type [-Werror=discarded-qualifiers]
   57 |         putenv("DISPLAY=");
      |                ^~~~~~~~~~
/usr/include/stdlib.h:148:19: note: expected ‘char *’ but argument is of type ‘const char *’
  148 | extern int putenv(char *);
      |                   ^~~~~~
check_public.c: In function ‘parse_display_fail’:
check_public.c:73:32: error: passing argument 1 of ‘putenv’ discards ‘const’ qualifier from pointer target type [-Werror=discarded-qualifiers]
   73 |                         putenv("DISPLAY=");
      |                                ^~~~~~~~~~
/usr/include/stdlib.h:148:19: note: expected ‘char *’ but argument is of type ‘const char *’
  148 | extern int putenv(char *);
      |                   ^~~~~~
check_public.c:99:16: error: passing argument 1 of ‘putenv’ discards ‘const’ qualifier from pointer target type [-Werror=discarded-qualifiers]
   99 |         putenv("DISPLAY=");
      |                ^~~~~~~~~~
/usr/include/stdlib.h:148:19: note: expected ‘char *’ but argument is of type ‘const char *’
  148 | extern int putenv(char *);
      |                   ^~~~~~
check_public.c: In function ‘public_suite’:
check_public.c:244:16: error: passing argument 1 of ‘putenv’ discards ‘const’ qualifier from pointer target type [-Werror=discarded-qualifiers]
  244 |         putenv("DISPLAY=");
      |                ^~~~~~~~~~
/usr/include/stdlib.h:148:19: note: expected ‘char *’ but argument is of type ‘const char *’
  148 | extern int putenv(char *);
      |                   ^~~~~~
cc1: all warnings being treated as errors

Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
2024-03-02 11:47:47 -08:00
Alan Coopersmith c671b9b30a
libxcb 1.16.1
Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
2024-03-02 11:13:37 -08:00
Fergus Dall 3c946010c8 Enable large file support
Signed-off-by: Fergus Dall <sidereal@google.com>
2023-11-07 17:42:42 +11:00
Peter Williams 02a7bbed39 Fix compilation on Windows
Merge request !30 broke compilation on Windows by introducing unbalanced
curly braces. This change restores the previous behavior on Windows:
only TCP is supported.
2023-08-28 18:01:39 +00:00
Alan Coopersmith 18c3f055e7 gitlab CI: use latest xcbproto from git to build against
Closes issue #70

Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
2023-08-20 11:36:40 -07:00
Thomas Klausner 453115f7ee configure.ac: drop `pthread-stubs` dependency on NetBSD 2023-08-20 17:38:39 +00:00
Alan Coopersmith f11691a098 gitlab CI: regenerate container used for builds
This updates the included xcb-proto to the newly required 1.16.
As explained in issue #70, this is a quick workaround, not the
long-term fix for this problem.

Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
2023-08-20 10:30:11 -07:00
Matt Turner cc4b93c9cd libxcb 1.16
Signed-off-by: Matt Turner <mattst88@gmail.com>
2023-08-16 16:18:09 -04:00
Matt Turner 1519334652 configure.ac: Require xcb-proto >= 1.16.0
Signed-off-by: Matt Turner <mattst88@gmail.com>
2023-08-16 16:18:09 -04:00
Ilya Pominov 038636786a c_client: Fix crash in xcb_randr_set_monitor
Take into account c_need_sizeof when evaluating
xcb_protocol_request_t.count

Incorrect xcb_protocol_request_t.count causes a segmentation fault when
calling functions:
- xcb_randr_set_monitor{_checked}
- xcb_input_change_feedback_control{_checked}
- xcb_input_change_device_control{_unchecked}

Steps to reproduce:
Call xcb_randr_set_monitor() with valid arguments

OBSERVED RESULT
Segmentation fault
```
Process terminating with default action of signal 11 (SIGSEGV)
  Access not within mapped region at address 0x780
    at 0x4852925: memmove (in /usr/libexec/valgrind/vgpreload_memcheck-
amd64-linux.so)
    by 0x486967C: memcpy (string_fortified.h:29)
    by 0x486967C: send_request (xcb_out.c:59)
    by 0x486967C: send_request (xcb_out.c:46)
    by 0x486967C: xcb_send_request_with_fds64 (xcb_out.c:338)
    by 0x48699FC: xcb_send_request (xcb_out.c:359)
    by 0x4891F11: xcb_randr_set_monitor_checked (randr.c:5350)
```

EXPECTED RESULT
Function returns cookie

Amend: 77b594f958

Signed-off-by: Ilya Pominov <ipominov@astralinux.ru>
2023-04-10 20:06:52 +03:00
Demi Marie Obenour 8935793f1f Add tests for unix socket parsing
Signed-off-by: Demi Marie Obenour <demiobenour@gmail.com>
2023-03-25 15:27:50 -04:00
Demi Marie Obenour 095255531b DISPLAY starting with / or unix: is always a socket path
If DISPLAY starts with / or unix:, do not check for anything but a full
filesystem socket path.  In particular, abstract AF_UNIX sockets and TCP
sockets will not be used in this case.   Also be stricter about parsing
the screen part of /path.screen displays, and bail out after all stat()
errors other than ENOENT.

Signed-off-by: Demi Marie Obenour <demiobenour@gmail.com>
2023-03-25 13:15:08 -04:00
Demi Marie Obenour ccdef1a8a5 Allow full paths to sockets on non-macOS
When combined with xorg/lib/libxtrans!7, this allows CVE-2020-25697 to
be mitigated by placing the AF_UNIX socket in a secure directory on the
filesystem.

This enables HAVE_LAUNCHD unconditionally and deletes the configure
switch.

Signed-off-by: Demi Marie Obenour <demiobenour@gmail.com>
2023-03-25 13:15:08 -04:00
Matthieu Herrb 18e109d755 Fix xcb_connect() call with a custom xcb_auth_info_t
If the function implementing xcb_connect is called directly with a
custom xcb_auth_info_t then checking that the screen in $DISPLAY
is valid is skipped.

Reported by chohag AT jtan DOT com

Signed-off-by: Matthieu Herrb <matthieu@herrb.eu>
2023-02-28 14:21:07 +01:00
Jan Beich fd04ab24a5 configure.ac: drop `pthread-stubs` dependency on DragonFly and FreeBSD
All `pthread_*` symbols used by libxcb have stubs in libc. So, stop
linking against libpthread.
2023-02-11 18:15:23 +00:00
Alan Coopersmith 4d1a578dd5 Raise minimum required version of Python from 2.6 to 3.0
Trying to build with Python 2.7.14 fails with:
  File "./c_client.py", line 2270
    key = (*self.name[:-1], field.enum)
           ^
SyntaxError: invalid syntax

Fixes: 33f3dbe ("Fix handling of documented enum parameters")
Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
2023-02-09 14:58:12 -08:00
Alan Coopersmith e2a3e80eb8 configure.ac: Remove obsolete AC_HEADER_STDC
Nothing checks for the STDC_HEADERS flag this set, and all supported
systems have C89 compatible headers now.

Clears autoconf warnings of:
configure.ac:93: warning: The macro `AC_HEADER_STDC' is obsolete.
configure.ac:93: You should run autoupdate.
./lib/autoconf/headers.m4:704: AC_HEADER_STDC is expanded from...
configure.ac:93: the top level

Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
2023-02-06 15:55:23 -08:00
Daniel G 3333d5bde8 Fix indentation. 2023-01-09 16:21:35 +00:00
Daniel G 973b510e95 Fix windows build. 2023-01-07 19:35:47 +00:00
Jeremy Huddleston Sequoia cb8c70f5a6
xcb_conn: Add a check for NULL to silence a UBSan runtime error
xcb_conn.c:314:60: runtime error: applying zero offset to null pointer

Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu@apple.com>
2022-11-26 22:48:00 -08:00
Demi Marie Obenour 33f3dbe369 Fix handling of documented enum parameters
Previously this would crash the code generator.

Signed-off-by: Demi Marie Obenour <demiobenour@gmail.com>
2022-10-16 15:44:42 -04:00
Demi Marie Obenour c9513aac2d Fix a compiler warning
The warning is harmless but annoying.

Signed-off-by: Demi Marie Obenour <demiobenour@gmail.com>
2022-10-16 01:55:30 -04:00
Alan Coopersmith 06e1ef43bb configure.ac: drop dependency `pthread-stubs` on Solaris
On Solaris 10 and later, the pthread functions are directly in libc,
and libpthread only has metadata to redirect calls from it to the
libc functions.

On Solaris 9 and older (no longer supported), libc contained its own
thread stubs that libpthread then overrode.

Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
2022-10-04 11:30:09 -07:00
PaperChalice d53ad60d77 configure.ac: drop dependency `pthread-stubs` on macOS
`libpthread.dylib` on macOS is an alias of `libSystem.B.dylib`,
every program should link against `libSystem.B.dylib`.
2022-09-28 22:55:38 +00:00
Uli Schlachter e2ee5aabe9 Improve tutorial example
This tutorial example only handles XCB_EXPOSURE and XCB_KEY_RELEASE
events and ignores everything else. Thus, there is no point in asking
for more kinds of events.

A while ago, I ported this tutorial to x11rb [1]. Recently, I received a
pull request [2] removing these unnecessary event masks. This commit is
thus only partially by me and the 'issue' was originally found by the
author of [2].

[1]: https://github.com/psychon/x11rb/blob/master/x11rb/examples/tutorial.rs
[2]: https://github.com/psychon/x11rb/pull/754

Signed-off-by: Uli Schlachter <psychon@znc.in>
2022-09-28 22:39:32 +00:00
Mihail Konev 9dcb081708 autogen: add default patch prefix
Signed-off-by: Mihail Konev <k.mvc@ya.ru>
Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
2022-07-24 14:26:03 -07:00
Emil Velikov 7d798d3ccb autogen.sh: use quoted string variables
Place quotes around the $srcdir, $ORIGDIR and $0 variables to prevent
fall-outs, when they contain space.

Signed-off-by: Emil Velikov <emil.l.velikov@gmail.com>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
2022-07-24 14:25:54 -07:00
Peter Hutterer 7071b4a13c autogen.sh: use exec instead of waiting for configure to finish
Syncs the invocation of configure with the one from the server.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Emil Velikov <emil.velikov@collabora.com>
Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
2022-07-24 14:25:53 -07:00
Alan Coopersmith ee60239b73 gitlab CI: add a basic build test
Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
2022-07-18 17:55:43 -07:00
Mike Sharov 3123dfe723 Require xcb-proto >= 1.15.1, which has Dbe
Signed-off-by: Mike Sharov <msharov@users.sourceforge.net>
2022-06-22 10:56:37 -04:00
Mike Sharov 816407655f Build DOUBLE-BUFFER extension.
Signed-off-by: Mike Sharov <msharov@users.sourceforge.net>
2022-06-02 13:27:48 -04:00
Matt Turner c2c4a2cd19 libxcb 1.15
Signed-off-by: Matt Turner <mattst88@gmail.com>
2022-05-03 15:09:54 -07:00
Hodong ddafdba11f Fix a memory leak
Signed-off-by: Hodong <hodong@yozmos.com>
2022-01-15 02:32:04 +09:00
Demi Marie Obenour 43fbf03e54 Fix integer overflows in xcb_in.c
This fixes an integer overflow security vulnerability in xcb_in.c, which
may allow for memory corruption.
2021-11-17 12:09:02 -05:00
Thomas Anderson 233d7b7f1f Fix hang in xcb_request_check()
This fixes https://gitlab.freedesktop.org/xorg/lib/libxcb/-/issues/53

The issue was that libxcb expected to get a reply based on the request_expected
variable, but a reply would never arrive because the request was never actually
written.  To resolve this, a separate request_expected_written variable is
added.
2021-09-30 23:32:35 +00:00
Ran Benita dc28118747 Avoid request counter truncation in replies map after 2**32 requests
The c->in request counters are uint64_t, and can realistically go over
2**32 over a lifetime of a client. The c->in->replies map however uses
unsigned int keys and the passed request numbers are silently truncated.

I haven't analyzed in depth what happens what it wraps around but it's
probably nothing good.

The only user of the xcb_list.c map code is c->in->replies, so just
change it to use uint64_t keys.

Reviewed-by: Uli Schlachter <psychon@znc.in>
Signed-off-by: Ran Benita <ran@unusedvar.com>
2021-09-30 17:22:06 +00:00
Julien Cristau 26396bf156 Add newline when printing auth/connection failure string to stderr
The reason strings returned by the server don't all include a newline,
so make sure we add one to avoid confusing clients.  Xlib used to do
this before it delegated that work to libxcb.

Fixes #34

Signed-off-by: Julien Cristau <jcristau@debian.org>
2021-09-30 17:18:18 +00:00
Uli Schlachter a503167f75 Improve/fix docs for reply fds functions
Fixes: https://gitlab.freedesktop.org/xorg/lib/libxcb/-/issues/56
Signed-off-by: Uli Schlachter <psychon@znc.in>
2021-09-20 18:40:08 +00:00
Povilas Kanapickas 3c76c0579f c_client.py: Implement handling of <length> element
Signed-off-by: Povilas Kanapickas <povilas@radix.lt>
2021-07-30 22:58:47 +03:00
Povilas Kanapickas bdc3f21a52 c_client: Extract _c_get_field_mapping_for_expr() 2021-07-30 22:58:46 +03:00
Povilas Kanapickas 068af21cb3 c_client.py: Use get_expr_field_names directly to resolve list fields
Using get_expr_fields() is only needed in case we are doing things that
can span multiple types easily, e.g. when deciding what data to pass via
function parameters and so on.

In _c_serialize_helper_list_field() we are building function body, so
acquiring field names via get_expr_field_names() is enough.

Signed-off-by: Povilas Kanapickas <povilas@radix.lt>
2021-07-30 22:58:45 +03:00
Povilas Kanapickas 4d678b162b c_client.py: Extract get_expr_field_names()
Signed-off-by: Povilas Kanapickas <povilas@radix.lt>
2021-07-30 22:58:44 +03:00
Peter Harris 21414e7c44 Fix writev emulation on Windows
There are at least two bugs in the previous implementation:

- If an early iovec is partially written, there can be a gap of missing
  data (as a later iovec will be started before the early iovec is
  completed).
- If a late iovec returns WSAEWOULDBLOCK, *vector and *count are not
  updated, leading to a re-send of the entire request.

Move the *vector update into the send() loop to update piecemeal as
individual iovecs are sent.

Example program that demonstrates the issue (this program should run
forever after these bugs have been fixed):

#include <stdio.h>
#include <stdlib.h>
#include "xcb.h"

// Non-cryptographic random number generator from http://burtleburtle.net/bob/rand/smallprng.html
// because Microsoft's random number generators either have a too small RAND_MAX or are too slow
typedef struct ranctx { uint32_t a; uint32_t b; uint32_t c; uint32_t d; } ranctx;

static uint32_t ranval(ranctx *x);
static void raninit(ranctx *x, uint32_t seed);


#define MAX_PROP_LEN (128 * 1024)

int main(int argc, char *argv[]) {
    uint32_t seed = 0x12345678;
    if (argc > 1) {
        seed = strtoul(argv[1], NULL, 0);
    }
    ranctx ran;
    raninit(&ran, seed);

    xcb_connection_t *c = xcb_connect(NULL, NULL);
    if (!c || xcb_connection_has_error(c)) {
        printf("Cannot connect to $DISPLAY\n");
        return 1;
    }
    const xcb_setup_t *setup = xcb_get_setup(c);
    char *buf = malloc(MAX_PROP_LEN + 8); // plus a bit of slack so we can run random values off the end
    if (!buf) {
        printf("oom\n");
        return 1;
    }
    for (uint32_t i=0; i < (MAX_PROP_LEN + 3) / 4; i++) {
        ((uint32_t *)buf)[i] = ranval(&ran);
    }

    xcb_window_t win = xcb_generate_id(c);
    xcb_create_window(c, 0, win, xcb_setup_roots_iterator(setup).data[0].root, 0, 0, 1, 1, 0,
            XCB_WINDOW_CLASS_INPUT_ONLY, 0, 0, NULL);
    printf("Created window 0x%X\n", win);

    for (;;) {
        xcb_flush(c);
        xcb_generic_event_t *ev = xcb_poll_for_event(c);
        if (ev) {
            if (ev->response_type == 0) {
                xcb_generic_error_t *err = (xcb_generic_error_t *)ev;
                printf("Unexpected X Error %d\n", err->error_code);
                printf("   Sequence %d\n", err->sequence);
                printf("   Resource ID 0x%X\n", err->resource_id);
                printf("   Opcode: %d.%d\n", err->major_code, err->minor_code);
                return 1;
            }
            printf("Unexpected X Event %d\n", ev->response_type);
            return 1;
        }

        uint32_t siz = ranval(&ran) % MAX_PROP_LEN + 1;
        xcb_change_property(c, XCB_PROP_MODE_REPLACE, win, XCB_ATOM_STRING, XCB_ATOM_STRING, 8, siz, buf);
    }

    return 0;
}


#define rot(x,k) (((x)<<(k))|((x)>>(32-(k))))
static uint32_t ranval(ranctx *x) {
    uint32_t e = x->a - rot(x->b, 27);
    x->a = x->b ^ rot(x->c, 17);
    x->b = x->c + x->d;
    x->c = x->d + e;
    x->d = e + x->a;
    return x->d;
}

static void raninit(ranctx *x, uint32_t seed) {
    uint32_t i;
    x->a = 0xf1ea5eed, x->b = x->c = x->d = seed;
    for (i = 0; i<20; ++i) {
        (void)ranval(x);
    }
}

Signed-off-by: Peter Harris <pharris@opentext.com>
2021-06-04 14:31:13 +00:00
Peter Harris 4b0d9d3868 Fix build on Windows
Notable changes: Protect include of unistd.h (and other POSIX headers).
Use SOCKET (which is larger than int) and closesocket (because close is
not compatible) for sockets. Use <stdint.h>'s intptr_t instead of the
non-portable ssize_t.

Signed-off-by: Peter Harris <pharris@opentext.com>
2021-06-04 14:31:13 +00:00
Alan Coopersmith cd0fba98a2 xcb_auth: Quiet -Wimplicit-fallthrough warning in get_authptr()
xcb_auth.c:135:14: warning: this statement may fall through [-Wimplicit-fallthrough=]
         addr += 12;
         ~~~~~^~~~~
xcb_auth.c:138:5: note: here
     case AF_INET:
     ^~~~

Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
2021-06-01 18:40:59 -07:00
Julien Cristau 2ef8655987 Increment libtool version info for libxcb-dri3
Somewhat belatedly given the last update was in xcb-proto 1.13 in 2017...

Quoting @smcv from https://bugs.debian.org/921069:
>>>
libxcb-dri3 version 1.13 appears to have added new symbols without increasing
the minor ABI version in its -version-info. This will break anything that
compares libraries by their version info to decide which one is newer.

The Steam Runtime uses libraries' major/minor/micro ABI version info (in this
case 0.0.0) to decide whether to use the system copy of a library or the copy
in the Steam Runtime, depending on which one is newer (#921026). We can
work around this by adding a versioned dependency on libxcb-dri3-0 and
deleting the copy from the Steam Runtime, but this isn't a particularly
scalable solution.
>>>
2021-02-02 10:00:23 +01:00
Ran Benita 4cbcac4eca gitignore: add files generated by make check
Signed-off-by: Ran Benita <ran@unusedvar.com>
2020-11-18 23:06:32 -05:00
Ran Benita f01f3c378e tests: don't use deprecated fail_unless check API
It causes errors like this when running make check:

check_public.c:40:24: error: too many arguments for format [-Werror=format-extra-args]
   40 |   fail_unless(success, "unexpected parse failure %sfor '%s'", test_string[test_type], name);

Closes: https://gitlab.freedesktop.org/xorg/lib/libxcb/-/issues/49
Tested-by: Matt Turner <mattst88@gmail.com>
Signed-off-by: Ran Benita <ran@unusedvar.com>
2020-11-18 23:06:05 -05:00
Eduardo Sánchez Muñoz 704e0a91b1 Use the 'present' field to properly check that the XC-MISC
extension is available in xcb_generate_id.

Also document the returned value when xcb_generate_id fails.
2020-03-02 19:01:41 +01:00
Matt Turner 4b40b44cb6 Release libxcb 1.14
Signed-off-by: Matt Turner <mattst88@gmail.com>
2020-02-22 12:20:08 -08:00
Matt Turner 78c492deaa Build xz tarballs instead of bzip2
Signed-off-by: Matt Turner <mattst88@gmail.com>
2020-02-22 12:20:08 -08:00
Matt Turner 8f7e4c4e9f configure.ac: Depend on pthread-stubs only on not-Linux
Signed-off-by: Matt Turner <mattst88@gmail.com>
2020-02-22 11:35:44 -08:00
Sam Varshavchik f9f4b00aad Implement xcb_total_read() and xcb_total_written().
Returns raw byte counts that have been read or written to the
xcb_connection_t.

I found it very useful when developing a high level widget toolkit, to
track down inefficient/sub-optimum code that generates a lot of X
protocol traffic.

Signed-off-by: Sam Varshavchik <mrsam@courier-mta.com>
2020-02-22 19:12:51 +00:00
A. Wilcox 59e271e15b tests: Support Check 0.13.0 API
[mattst88]: Keep compatibility 	with old API via preprocessor

Fixes: #43
2020-02-22 11:02:09 -08:00
Martin Dørum 21324989b7 Handle EINTR from recvmsg in _xcb_in_read
I have a GTK application which occasionally crashes with an "interrupted
system call" g_message from gdk. After a lot of debugging, I've found
that the call to recvmsg in _xcb_in_read occasionally fails with EINTR,
and instead of retrying the system call, xcb would just shut down the
connection.

This change makes _xcb_in_read treat EINTR the same as it would treat
EAGAIN; it returns 1 and libX11 ends up calling xcb_poll_for_event
again (from what I have understood).

I have spoken with a few people who think recvmsg failing with EINTR in
this case shouldn't ever happen, and I don't know enough to agree or
disagree with that. In case anyone wants to dig further and try to
figure out why the recvmsg call sometimes fails with EINTR, here's the
backtrace from inside of _xcb_in_read where that happened:

Thread 1 "beanbar" hit Breakpoint 1, _xcb_in_read (c=c@entry=0x55ecbe4aba80) at xcb_in.c:1059
1059                fprintf(stderr, "Hello World am %s:%i, errno is %s\n", __FILE__, __LINE__, strerror(errno));
(gdb) bt
0  0x00007fa48fa48639 in _xcb_in_read (c=c@entry=0x55ecbe4aba80) at xcb_in.c:1059
1  0x00007fa48fa489d8 in poll_for_next_event (c=0x55ecbe4aba80, queued=queued@entry=0) at xcb_in.c:352
2  0x00007fa48fa48a3d in poll_for_next_event (queued=0, c=<optimized out>) at xcb_in.c:722
3  0x00007fa48fa48a3d in xcb_poll_for_event (c=<optimized out>) at xcb_in.c:722
4  0x00007fa4908d1b7e in poll_for_event (dpy=dpy@entry=0x55ecbe4a9730, queued_only=queued_only@entry=0) at xcb_io.c:245
5  0x00007fa4908d1cf0 in poll_for_response (dpy=dpy@entry=0x55ecbe4a9730) at xcb_io.c:303
6  0x00007fa4908d1fed in _XEventsQueued (mode=2, dpy=0x55ecbe4a9730) at xcb_io.c:363
7  0x00007fa4908d1fed in _XEventsQueued (dpy=dpy@entry=0x55ecbe4a9730, mode=mode@entry=2) at xcb_io.c:344
8  0x00007fa4908c3d47 in XPending (dpy=0x55ecbe4a9730) at Pending.c:55
9  0x00007fa493cadbc7 in  () at /usr/lib/libgdk-3.so.0
10 0x00007fa49234d08a in g_main_context_prepare () at /usr/lib/libglib-2.0.so.0
11 0x00007fa49234d6e6 in  () at /usr/lib/libglib-2.0.so.0
12 0x00007fa49234d8ae in g_main_context_iteration () at /usr/lib/libglib-2.0.so.0
13 0x00007fa4938b920e in g_application_run () at /usr/lib/libgio-2.0.so.0
14 0x000055ecbc820af4 in main (argc=1, argv=0x7ffd06238098) at src/main.c:190

Signed-off-by: Martin Dørum <martid0311@gmail.com>
2019-05-19 16:05:08 +02:00
Jon Turney 656c08c542
Include time.h before using time()
Signed-off-by: Jon Turney <jon.turney@dronecode.org.uk>
2019-04-25 17:30:16 +01:00
Alan Coopersmith be1745c8eb Add README.md to EXTRA_DIST
Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
2019-02-17 12:23:17 -08:00
Eduardo Sánchez Muñoz 58f37377c8 Add "ge.*" to src/.gitignore 2019-02-17 13:33:12 +01:00
Alan Coopersmith 7bac366953 Update README for gitlab migration
Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
2019-02-16 13:41:28 -08:00
Alan Coopersmith 02ff3eadf4 Update configure.ac bug URL for gitlab migration
Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
2019-02-16 13:35:06 -08:00
Alan Coopersmith 542befe40a c_client: fix "adress" typo
Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
2019-01-07 14:42:53 -08:00
Uli Schlachter 8287ebd7b7 Release libxcb 1.13.1 2018-09-27 14:04:17 +02:00
Erik Kurzinger bbda345a71 don't flag extra reply in xcb_take_socket
If any flags are specified in a call to xcb_take_socket,
they should only be applied to replies for requests sent
after that function returns (and until the socket is
re-acquired by XCB).

Previously, they would also be incorrectly applied to the
reply for the last request sent before the socket was taken.
For instance, in this example program the reply for the
GetInputFocus request gets discarded, even though it was
sent before the socket was taken. This results in the
call to retrieve the reply hanging indefinitely.

static void return_socket(void *closure) {}

int main(void)
{
    Display *dpy = XOpenDisplay(NULL);
    xcb_connection_t *c = XGetXCBConnection(dpy);

    xcb_get_input_focus_cookie_t cookie = xcb_get_input_focus_unchecked(c);
    xcb_flush(c);

    uint64_t seq;
    xcb_take_socket(c, return_socket, dpy, XCB_REQUEST_DISCARD_REPLY, &seq);

    xcb_generic_error_t *err;
    xcb_get_input_focus_reply(c, cookie, &err);
}

In practice, this has been causing intermittent KWin crashes when
used in combination with the proprietary NVIDIA driver such as
https://bugs.kde.org/show_bug.cgi?id=386370 since when Xlib fails to
retrieve one of these incorrectly discarded replies it triggers
an IO error.

Signed-off-by: Erik Kurzinger <ekurzinger@nvidia.com>
Signed-off-by: Uli Schlachter <psychon@znc.in>
2018-08-21 18:57:01 +02:00
Daniel Stone 7e0f166579 Release libxcb 1.13
Signed-off-by: Daniel Stone <daniels@collabora.com>
2018-02-28 17:24:53 +00:00
Daniel Stone a3e9821bec c_client: Add support for lists of FDs
Matching xcbgen changes, add support having a ListType which contains
file descriptors. Use this to send a variable number of FDs to the
server, including when the list size is not fixed.

Signed-off-by: Daniel Stone <daniels@collabora.com>
2017-06-05 20:36:50 +01:00
Daniel Stone c7aa4e682f c_client: Don't serialise non-wire fields
For when we have a variable-sized field followed by a fixed field, make
sure we do not serialise non-wire fields.

Signed-off-by: Daniel Stone <daniels@collabora.com>
2017-06-05 20:36:50 +01:00
Christian Linhart d10194a321 enable xinput by default
Support for the xinput extension is complete now,
as far as I can tell.

According to our discussion on the list, we enable it now.

Signed-off-by: Christian Linhart <chris@demorecorder.com>
2017-05-13 10:56:24 +02:00
David McFarland fad81b6342 read from connection when polling special events and replies
Using the mesa vulkan driver, if you acquire an image from a
swapchain using a finite timeout (x11_acquire_next_image_poll_x11),
it will occasionally lock, calling xcb_poll_for_special_event in
a loop until the timeout expires.

Call _xcb_in_read() once from the polling functions for special
events and replies, in the same way as xcb_poll_for_event.

Signed-off-by: David McFarland <corngood@gmail.com>
Signed-off-by: Uli Schlachter <psychon@znc.in>
2017-05-13 09:34:31 +02:00
Tobias Stoeckmann f830eb93c9 Check strdup for NULL return value.
_xcb_open does not check strdup's return value for NULL if launchd suport
was configured.

Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
Signed-off-by: Uli Schlachter <psychon@znc.in>
2017-04-01 11:50:09 +02:00
Christian Linhart ee9dfc9a76 add support for eventstruct
eventstruct allows to use events as part of requests.
This is, e.g., needed by xcb_input_send_extension_event.

Signed-off-by: Christian Linhart <chris@demorecorder.com>
2017-03-11 10:51:50 +01:00
Christian Linhart 0c2c5d50f8 optionally build the GE extension
xcb contains an xml-definition for the GenericEvent extension
but this extension was neither generated nor built.

This patch enables optional building of the GenericEvent extension
with configure option --enable-ge

By default, the GenericEvent extension is not built.
Normally this is not needed by application programs
because there is implicit support for the GE-extension
for the specific events built with this extension.

But it may be useful for X-protocol analyzers and stuff like that.

Signed-off-by: Christian Linhart <chris@demorecorder.com>
2017-03-11 10:51:33 +01:00
Christian Linhart 9bce1f72e3 move symbol lookup of sumof expr to the parser
replace the complicated symboltable lookup for sumof expr
by accessing the lenfield of the expr-object.

This requires the corresponding patch for xcb/proto
which sets the lenfield accordingly.

This should be OK because for official releases we define
that dependency in the build system.

For getting versions off the HEAD of the git repo, it should
be obvious that xcb/proto and xcb/libxcb have to be updated together.

I have tested this patch and it generates exactly the same code
as before.

Tested-by: Christian Linhart <chris@demorecorder.com>
Signed-off-by: Christian Linhart <chris@demorecorder.com>
2017-03-11 10:51:11 +01:00
Alan Coopersmith 65b298c7ca Correct @param "e" to "error" in xcb_poll_for_reply*()
Found by clang -Wdocumentation:

./xcbext.h:271:11: warning: parameter 'e' not found in the function
      declaration [-Wdocumentation]
 * @param e Location to store errors in, or NULL. Ignored for un...
          ^
./xcbext.h:271:11: note: did you mean 'error'?
 * @param e Location to store errors in, or NULL. Ignored for un...
          ^
          error

./xcbext.h:283:11: warning: parameter 'e' not found in the function
      declaration [-Wdocumentation]
 * @param e Location to store errors in, or NULL. Ignored for un...
          ^
./xcbext.h:283:11: note: did you mean 'error'?
 * @param e Location to store errors in, or NULL. Ignored for un...
          ^
          error

Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
Signed-off-by: Uli Schlachter <psychon@znc.in>
2016-05-29 15:56:25 +02:00
Alan Coopersmith 32a9084546 Remove : from @param names in manually written headers
Makes style match the @param names in autogenerated headers and makes
clang -Wdocumentation stop complaining about all of them:

./xcb.h:523:11: warning: parameter 'display:' not found in the function
      declaration [-Wdocumentation]
 * @param display: A pointer to the display number.
          ^~~~~~~~
./xcb.h:523:11: note: did you mean 'display'?
 * @param display: A pointer to the display number.
          ^~~~~~~~
          display

Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
Signed-off-by: Uli Schlachter <psychon@znc.in>
2016-05-29 15:56:07 +02:00
Thomas Klausner 8740a288ca Fix inconsistent use of tabs vs. space.
Needed for at least python-3.5.x.

Signed-off-by: Thomas Klausner <wiz@NetBSD.org>
Signed-off-by: Uli Schlachter <psychon@znc.in>
2016-05-28 12:20:59 +02:00
Uli Schlachter d34785a34f Release libxcb 1.12
Signed-off-by: Uli Schlachter <psychon@znc.in>
2016-05-18 18:43:38 +02:00
Uli Schlachter b11fca06f7 Bump xcb-proto requirement to 1.12
This is needed due to various changes that were done to the XML schema.

Signed-off-by: Uli Schlachter <psychon@znc.in>
2016-05-14 10:33:54 +02:00
Mark Kettenis 095353ff1a Increase unix socket send buffer to at least 64KB
Some systems (e.g. OpenBSD) have a rather small default socket send buffer
size of 4KB.  The result is that sending requests with a largish payload
requires serveral writev(2) system calls.  Make sure the socket send buffer
is at least 64KB such that we're likely to succeed with a single system
call for most requests.  A similar change was made to the xtrans code
some time ago.

Signed-off-by: Mark Kettenis <kettenis@openbsd.org>
Reviewed-by: Matthieu Herrb <matthieu@herrb.eu>
2016-02-01 09:10:04 +01:00
Christian Linhart b3516102b4 do not serialize pads by default anymore
Pads should not be serialized/deserialized to maintain
ABI compatibility when adding explicit align pads.

Therefore this pad switches off serialization of pads
unless it is enforced by serialize=true in the xml-definition
of that pad

Signed-off-by: Christian Linhart <chris@demorecorder.com>
2016-02-01 07:53:28 +01:00
Jaya Tiwari c03388ff9e calculate lengthless list
Some rework done by Christian Linhart

Signed-off-by: Jaya Tiwari <tiwari.jaya18@gmail.com>
Signed-off-by: Christian Linhart <chris@demorecorder.com>
2016-01-06 02:34:28 +01:00
Christian Linhart 7758257567 Fix handling of align-pads in end-iterators
If a list is preceded by an align-pad, then
accessor for the end-iterator returned a wrong
value.

Reason: the length of the align-iterator was added
to a pointer of list-member type. Therefore, the length
was multiplied by the size of the list-member type,
due to C pointer arithmetic rules.

This has looked like the following, e.g., in
xcb_randr_get_crtc_transform_pending_params_end:

i.data = ((xcb_render_fixed_t *) prev.data) + ((-prev.index) & (4 - 1)) + (R->pending_nparams);

This bug was introduced with the following commit:
http://cgit.freedesktop.org/xcb/libxcb/commit/?id=4033d39d4da21842bb1396a419dfc299591c3b1f

The fix handles this by casting to char* before adding the align,
and then casting the result to the member type.

Signed-off-by: Christian Linhart <chris@demorecorder.com>
2016-01-06 02:23:28 +01:00
Christian Linhart 32a2189183 set the align-offset as provided by proto
instead of using the lower bits of the pointer address.
This fixes a bug reported by Peter Hutterer in off-list communication
back in June 2015.

This requires the alignment-checker patches in xcb/proto.

Signed-off-by: Christian Linhart <chris@demorecorder.com>
2016-01-06 02:09:56 +01:00
Adam Jackson 6e0378ebbf Bump version to 1.11.90
We've released 1.11.1 and new libX11 wants that or better.  git master
will suffice, so bump the version number ahead of 1.11 branch.

Signed-off-by: Adam Jackson <ajax@redhat.com>
2015-09-21 15:27:52 -04:00
Christian Linhart 4033d39d4d make lists after align-pads work
Handle align-pads when generating an end-function
in the same way as handling them when generating
an accessor or iterator function.

Signed-off-by: Christian Linhart <chris@demorecorder.com>
2015-08-13 18:06:43 +02:00
Christian Linhart b15c96f950 make support for server side stuff optional
and make it disabled by default with an EXPERIMENTAL warning

reason: this feature is unfinished and we want to have flexibility for
ABI/API changes, while still being able to make a release soon

Signed-off-by: Christian Linhart <chris@demorecorder.com>
2015-07-04 16:25:23 +02:00
Jon TURNEY c5d923d8ff Link with winsock library for socket functions on MinGW
Signed-off-by: Jon TURNEY <jon.turney@dronecode.org.uk>
2015-07-04 16:14:05 +02:00
Uli Schlachter 5b40681c88 Fix a thread hang with xcb_wait_for_special_event()
Consider the following:

- Two threads are calling xcb_wait_for_special_event() and xcb_wait_for_reply()
  concurrently.
- The thread doing xcb_wait_for_reply() wins the race and poll()s the socket for
  readability.
- The other thread will be put to sleep on the special_event_cond of the special
  event (this is done in _xcb_conn_wait() via the argument
  xcb_wait_for_special_event() gives it).
- The first thread gets its reply, but does not yet receive any special event.

In this case, the first thread will return to its caller. On its way out, it
will call _xcb_in_wake_up_next_reader(), but that function cannot wake up
anything since so far it did not handle xcb_wait_for_special_event().

Thus, the first thread stays blocked on the condition variable and no thread
tries to read from the socket.

A test case demonstrating this problem is available at the bug report.

Fix this similar to how we handle this with xcb_wait_for_reply():

The function wait_for_reply() adds an entry into a linked list of threads that
wait for a reply. Via this list, _xcb_in_wake_up_next_reader() can wake up this
thread so that it can call _xcb_conn_wait() again and then poll()s the socket.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=84252
Signed-off-by: Uli Schlachter <psychon@znc.in>
Tested-by: Michel Dänzer <michel.daenzer@amd.com>
2015-06-25 20:38:48 +02:00
Michel Dänzer f85661c3bc Call _xcb_wake_up_next_reader from xcb_wait_for_special_event
All functions calling _xcb_conn_wait() must make sure that waiting
readers are woken up when we read a reply or event that they are waiting
for. xcb_wait_for_special_event() did not do so. This adds the missing
call to_xcb_in_wake_up_next_reader().

Fixes deadlock when waiting for a special event and concurrently
processing the display connection queue in another thread.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=84252
Tested-by: Thomas Daede <bztdlinux@gmail.com>
Tested-by: Clément Guérin <geecko.dev@free.fr>
Reviewed-by: Uli Schlachter <psychon@znc.in>
Signed-off-by: Michel Dänzer <michel@daenzer.net>
Signed-off-by: Uli Schlachter <psychon@znc.in>
2015-06-12 09:45:16 +02:00
Uli Schlachter 8584c0e095 send_fds(): Handle too many outstanding FDs to send
Before this patch, the following code caused an endless loop in send_fds(),
because the queue of FDs to send was eventually full, but _xcb_out_flush_to()
didn't make any progress, since there was no request to send:

   while (1) { xcb_send_fd(conn, dup(some_fd)); }

Fix this by sending a sync when flushing didn't make any progress. That way we
actually have something to send and can attach the pending FDs.

Because send_fds() can now send requests, the code in
xcb_send_request_with_fds64() has to be changed. It has to call send_fds()
before it establishes a good sequence number for the request it wants to send.

Signed-off-by: Uli Schlachter <psychon@znc.in>
2015-06-12 09:39:13 +02:00
Uli Schlachter 658fb4a5f0 Code generator: Use xcb_send_request_with_fds()
Signed-off-by: Uli Schlachter <psychon@znc.in>
2015-06-12 09:39:13 +02:00
Uli Schlachter b15aa6bd4e Add xcb_send_request_with_fds() and *_with_fds64()
Doing xcb_send_fd(), xcb_send_request() is racy. If two threads do this at the
same time, they could mix up their file descriptors. This commit makes it
possibly to fix this race by providing a single function which does everything
that is needed.

Signed-off-by: Uli Schlachter <psychon@znc.in>
2015-06-12 09:39:12 +02:00
Uli Schlachter cc04cfb41b send_fds(): Make sure no other thread interrupts us
Two threads trying to send fds at the same time could interfere. To guarantee a
correct ordering, we have to use correct locking. The code in send_fds() missed
one case: If there was another thread already writing requests, we slept on the
"done with writing" condition variable (c->out.cond). This would allow other
threads to re-acquire the iolock before us and could cause fds to be sent out of
order.

To fix this, at the beginning of send_fds() we now make sure that no other
thread is already writing requests. This is what prepare_socket_request() does.
Additionally, it gets the socket back in case xcb_take_socket() was called,
which is a good thing, too, since fds are only sent with corresponding requests.
2015-06-12 09:39:12 +02:00
Uli Schlachter 25f9e7e45a xcb_send_fd(): Always close fds
The API docs for xcb_send_fd() says "After this function returns, the file
descriptor given is owned by xcb and will be closed eventually".

Let the implementation live up to its documentation. We now also close fds if fd
passing is unavailable (!HAVE_SENDMSG) and when the connection is in an error
state.

(This also does sneak in some preparatory functions for follow-up commits and
thus does things in a more complicated way than really necessary.)

Signed-off-by: Uli Schlachter <psychon@znc.in>
2015-06-12 09:39:12 +02:00
Ran Benita bbdf1d133f c_client.py: don't generate useless empty /** < */ comments
(This does not change doxygen's output or warnings).

Signed-off-by: Ran Benita <ran234@gmail.com>
Reviewed-by: Christian Linhart <chris@demorecorder.com>
2015-05-30 11:36:13 +02:00
Ran Benita ff6cb3913b c_client.py: use pattern matching with enumerate()
Signed-off-by: Ran Benita <ran234@gmail.com>
2015-05-30 11:16:43 +02:00
Christian Linhart cb621341a6 expose 64-bit sequence numbers for XLib
While XCB uses 64-bit sequence number internally, it only exposes
"unsigned int" so that, on 32-bit architecture, Xlib based applications
may see their sequence number wrap which causes the connection to the X
server to be lost.

Expose 64-bit sequence number from XCB API so that Xlib and others can
use it even on 32-bit environment.

This implies the following API addition:

  xcb_send_request64()
  xcb_discard_reply64()
  xcb_wait_for_reply64()
  xcb_poll_for_reply64()

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=71338

Reviewed-by: Uli Schlachter <psychon@znc.in>
Signed-off-by: Christian Linhart <chris@demorecorder.com>
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
2015-04-08 11:55:48 +02:00
Alan Coopersmith c49aa98594 Escape \n to display properly in xcb-requests man page
In nroff, \n is a macro that "Interpolates number register x" (where x
is the character following the \n sequence), thus the man page currently
prints 0 instead of \n" in several lines, leading to output such as:

 printf("The _NET_WM_NAME atom has ID %u0, reply-⁠>atom);

It needs to be escaped here, as \\n, as is done in other examples in
this man page already.

https://bugs.freedesktop.org/show_bug.cgi?id=90231

Reported-by: Stefan Merettig
Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
2015-04-29 23:23:05 -07:00
Ran Benita a90be9955d c_client.py: make condition easier to follow in _c_complex()
Signed-off-by: Ran Benita <ran234@gmail.com>
Reviewed-by: Christian Linhart <chris@demorecorder.com>
2015-03-15 12:25:58 +01:00
Ran Benita f9f925107e c_client.py: don't add /* <name> */ before references to 'S'
The name can be understood from the type of S already.

For examples, look for 'S->' in xkb.c or xinput.c.

Signed-off-by: Ran Benita <ran234@gmail.com>
Reviewed-by: Christian Linhart <chris@demorecorder.com>
Reviewed-by: Rémi Cardona <remi@gentoo.org>
2015-03-15 12:22:32 +01:00
Ran Benita 17f9bda6c2 c_client.py: remove duplicated `cookie_type` argument for requests
It is implied already inside the function by the `void` argument.

Signed-off-by: Ran Benita <ran234@gmail.com>
Reviewed-by: Christian Linhart <chris@demorecorder.com>
2015-03-15 12:19:07 +01:00
Ran Benita c65005e9d0 c_client.py: spell out keyword arguments in c_request() for clarity
Signed-off-by: Ran Benita <ran234@gmail.com>
Reviewed-by: Christian Linhart <chris@demorecorder.com>
2015-03-15 12:11:59 +01:00
Ran Benita 6872e92582 c_client.py: simplify _c_reply_has_fds()
Signed-off-by: Ran Benita <ran234@gmail.com>
Reviewed-by: Christian Linhart <chris@demorecorder.com>
2015-03-15 12:05:37 +01:00
Ran Benita 8bf8b62316 c_client.py: remove commented debug statements
Signed-off-by: Ran Benita <ran234@gmail.com>
Reviewed-by: Christian Linhart <chris@demorecorder.com>
2015-03-15 12:03:27 +01:00
Ran Benita ec435aebd6 c_client.py: use C99 initializers instead of comments
Signed-off-by: Ran Benita <ran234@gmail.com>
Reviewed-by: Christian Linhart <chris@demorecorder.com>
2015-03-15 11:52:38 +01:00
Ran Benita 89498d1d45 c_client.py: remove end-of-function comments
Signed-off-by: Ran Benita <ran234@gmail.com>
Reviewed-by: Christian Linhart <chris@demorecorder.com>
2015-03-15 11:42:16 +01:00
Ran Benita 2871d4b1b8 c_client.py: no need to compare bools to True/False
Signed-off-by: Ran Benita <ran234@gmail.com>
Reviewed-by: Christian Linhart <chris@demorecorder.com>
2015-03-15 11:39:00 +01:00
Ran Benita 30976e5255 c_client.py: use "foo".join() instead of reduce
Signed-off-by: Ran Benita <ran234@gmail.com>
Reviewed-by: Christian Linhart <chris@demorecorder.com>
2015-03-15 11:36:23 +01:00
Ran Benita 0ab52cbcc6 c_client.py: fix indentation
(Also remove unnecessary parens around the condition).

Signed-off-by: Ran Benita <ran234@gmail.com>
Reviewed-by: Christian Linhart <chris@demorecorder.com>
2015-03-15 11:23:30 +01:00
Ran Benita 80341d5df3 c_client.py: use comprehensions instead of map/filter
Signed-off-by: Ran Benita <ran234@gmail.com>
Reviewed-by: Christian Linhart <chris@demorecorder.com>
2015-03-15 10:42:32 +01:00
Ran Benita 86ea6645d9 c_client.py: use print as a function for python3 compatibility
This works for all python>=2.6, which is what configure requires.

Signed-off-by: Ran Benita <ran234@gmail.com>
Reviewed-by: Christian Linhart <chris@demorecorder.com>
2015-03-15 10:27:39 +01:00
Ran Benita 70d32ce7d8 c_client.py: fix pyflakes errors
c_client.py:2: 'from xml.etree.cElementTree import *' used; unable to detect undefined names
c_client.py:3: 'basename' imported but unused
c_client.py:9: 'time' imported but unused
c_client.py:1437: local variable 'list_obj' is assigned to but never used
c_client.py:1745: local variable 'varfield' is assigned to but never used
c_client.py:2050: local variable 'length' is assigned to but never used
c_client.py:2416: local variable 'R_obj' is assigned to but never used
c_client.py:2441: local variable 'S_obj' is assigned to but never used

Signed-off-by: Ran Benita <ran234@gmail.com>
Reviewed-by: Christian Linhart <chris@demorecorder.com>
2015-03-15 10:22:38 +01:00
Ran Benita 12d23b934f c_client.py: simplify maximum expression
Signed-off-by: Ran Benita <ran234@gmail.com>
Reviewed-by: Christian Linhart <chris@demorecorder.com>
2015-03-15 10:09:39 +01:00
Ran Benita 1b37d6ad3a c_client.py: remove unneeded call to get_serialize_params()
The results are not used, and the function doesn't have side effects.

Signed-off-by: Ran Benita <ran234@gmail.com>
Reviewed-by: Christian Linhart <chris@demorecorder.com>
2015-03-15 10:03:12 +01:00
Jaya Tiwari e3ec1f7463 Adding accessors for requests
Added accessor functions for requests the same way they were added for
structs,events and replies.
Lists for replies have accessor functions now.

Signed-off-by: Jaya Tiwari <tiwari.jaya18@gmail.com>
Reviewed-by: Christian Linhart <chris@demorecorder.com>

Comment from the Reviewer Christian Linhart:
I have tested your patch after fixing the issues with the patch-format.
It looks good:
* only adds new functions, and does not modify existing functions.
  Therefore it is API and ABI compatible.

* adds accessors for varsized-stuff in requests.
  This is needed for server-side XCB and may be useful for implementing X11-protocol proxies.
2015-02-22 11:56:04 +01:00
Christian Linhart 5353c0216e Merge http://git.demorecorder.com/git/free-sw/xcb/libxcb
branch 'ParametrizedStruct-V7'
2015-02-10 10:13:04 +01:00
Christian Linhart c6f3fb2529 generator: support parametrized structs
Parametrized structs contain paramref expressions which
refer to the value of a field defined in the context
where the struct is used.

Implementing the parametrized structs turned out
to be somewhat easier than previously thought
because the generator already had some support for type-parametrization
because this is needed when case or bitcase refers to fields outside
of the switch.

So I decided to go with the flow and to implement the solution
which best fits the current implementation.

I did the following:
* I provided a way to specify fieldref with an explicitely given type:
  This resulted in <paramref type="CARD8>fieldname</paramref>
  A paramref is just a fieldref with an explicit type.
  The type is necessary because there is no local field of that
  name where the type can be derived from.

* then I tested it and made several changes in the generator
  such that it really works.

Basically the generated code is as follows:
* The parameter appears on the parameter list of the
  sizeof-function of the parametrized struct.
  When that function gets called, an appropriate argument is supplied.

* The parameter also appears as an additional member of the iterator-struct
  for the iterator of lists of that parametrized struct.
  This way, the next-function can get the value of that parameter from the iterator.
  When the iterator is created, this iterator-member is set accordingly.

* When the paramref appears in the length-expression of a list, then
  the parameter appears on the parameterlist of the "length" and "end" functions.
  When these functions get called, an appropriate argument is supplied.

Some comments:
* I did not implement inline structs.
  This would probably have been more complicated, and at least some additional effort.
  But that can be implemented later if needed.
  (Inline structs could probably use some code from switch-case/bitcase which is already kind of
  an inlined struct but one has to be careful not to break the functionality
  of switch-case/bitcase. Support for inline structs inside lists must probably
  be implemented from scratch...)

* The paramref expression refers to a field of the same name in the struct/request/...
  where it is used.
  So it is not possible to pass the value of arbitrary fields or even expressions
  to the parametrized struct.
  This would have been possible with the previously discussed <typearg>.
  That can be added later, if needed.
  ( Wont be too complicated )

* So this is pretty much like the proposal from Ran Benita.

changes for V2 of this patch, according to suggestions from Ran Benita:
* replace map with list comprehension
  because map returns an iterator instead of a list from Python 3 on,
  so it cannot be added to a list anymore.

* removed "self" parameter of function additional_params_to_str
  and accessed the variable additional_params from the outer
  function directly.

changes for V2 of this patch:
* adapt to revision 2 of patchset ListInputDevices
* style fixes for similar things that Ran Benita has found in my previous patches

Message-ID: <54574397.4060000@DemoRecorder.com>
Patch-Thread-Subject: [Xcb] parametrized structs implemented
Patch-Set: ParametrizedStruct
Patch-Number: libxcb 1/1
Patch-Version: V3
Signed-off-by: Christian Linhart <chris@DemoRecorder.com>
2014-11-03 11:23:17 +01:00
Christian Linhart 912cd97a6d generator: support listelement-ref
Support for listelement-ref needs the following three changes
(in the order as they appear in the patch):

* making the current list-element accessible with the variable
  xcb_listelement which is a pointer to the list-element

* supporting lists of simple-type for sumof with a nested expression

* using the variable for resolving a listelement-ref expression

Changes for V2 of this patch:
- adapt to removal of patch "libxcb 2/6" from patchset "ListInputDevices".

Changes for V3 of this patch:
- adapt to V2 of patch "libxcb 5/6" from patchset "ListInputDevices"

Changes for V4 of this patch:
- adapt to revision 2 of the patchset "ListInputDevices"

Message-ID: <545743A0.50907@DemoRecorder.com>
Patch-Thread-Subject: [Xcb] support popcount of a list and associated xml changes
Patch-Set: PopcountList
Patch-Number: libxcb 4/4
Patch-Version: V4
Signed-off-by: Christian Linhart <chris@DemoRecorder.com>
2014-11-03 11:23:17 +01:00
Christian Linhart 422458b663 generator: _c_accessor_get_length: remove buggy special case
The function _c_accessor_get_length had a special case handling
for intermixed var and fixed size fields.

However:
* The implementation of that special case was buggy:
  It tried to call a python-dict as a function which causes
  Python to abort the program with a stacktrace and error message.
  So this code was never used.

* The case it tried to handle is handeled elsewhere in the
  meantime: in _c_helper_absolute_name by previous patches
  made by me.

Message-ID: <1409845851-38950-3-git-send-email-chris@demorecorder.com>
Patch-Thread-Subject: [Xcb] support popcount of a list and associated xml changes
Patch-Set: PopcountList
Patch-Number: libxcb 3/4
Patch-Version: V1
Signed-off-by: Christian Linhart <chris@DemoRecorder.com>
2014-11-03 11:23:17 +01:00
Christian Linhart b1e4a3bbd8 generator: generate accessors for events, too
Accessors are generally needed for var-sized fields
and fields after var-sized fields.

Generic events can have ver-sized fields.
Therefore they need accessors.

Message-ID: <1409845851-38950-2-git-send-email-chris@demorecorder.com>
Patch-Thread-Subject: [Xcb] support popcount of a list and associated xml changes
Patch-Set: PopcountList
Patch-Number: libxcb 2/4
Patch-Version: V1
Signed-off-by: Christian Linhart <chris@DemoRecorder.com>
2014-11-03 11:23:16 +01:00
Christian Linhart 6234225b4b generator: no type-setup for eventcopies anymore
_c_type_setup is not called for eventcopies anymore:
Reasons:
* the type-setup of an eventcopy would overwrite members of the original
  event object such as c_type, ...
* it is needed for the next patch, i.e., generating accessors:
  type_setup would create sizeof-etc funtions which called
  undefined accessor functions.

Sizeof-functions are generated for compatibility:
Reason:
* Type-setup of eventcopies has previously generated
  sizeof-functions for eventcopies.
  So, we still need to generate these functions.
  These new sizeof-functions simply call the sizeof-function
  of the defining event of the eventcopy.

Message-ID: <1409845851-38950-1-git-send-email-chris@demorecorder.com>
Patch-Thread-Subject: [Xcb] support popcount of a list and associated xml changes
Patch-Set: PopcountList
Patch-Number: libxcb 1/4
Patch-Version: V1
Signed-off-by: Christian Linhart <chris@DemoRecorder.com>
2014-11-03 11:23:16 +01:00
Christian Linhart 18ff453edd _c_helper_fieldaccess_expr: remove handling for empty sep
The loop-variable "sep" is never empty in function
"_c_helper_fieldaccess_expr", after a fix elsewhere.
Therefore I removed the handling of the case of "sep" being empty.

Thanks to Ran Benita for the hint that this can be removed.

Signed-off-by: Christian Linhart <chris@demorecorder.com>
Reviewed-by: Ran Benita <ran234@gmail.com>

Message-ID: <545627C2.3050608@DemoRecorder.com>
Patch-Thread-Subject: [Xcb] [PATCHSET] ListInputDevices revision 2
Patch-Set: ListInputDevices
Patch-Number: libxcb 9/9
Patch-Version: V1
2014-11-03 11:23:16 +01:00
Christian Linhart d905b88618 function _c_helper_fieldaccess_expr: improve description
Signed-off-by: Christian Linhart <chris@demorecorder.com>
Reviewed-by: Ran Benita <ran234@gmail.com>

Message-ID: <545627BA.1000909@DemoRecorder.com>
Patch-Thread-Subject: [Xcb] [PATCHSET] ListInputDevices revision 2
Patch-Set: ListInputDevices
Patch-Number: libxcb 8/9
Patch-Version: V1
2014-11-03 11:23:16 +01:00
Christian Linhart 17f6e04493 rename _c_helper_absolute_name to _c_helper_fieldaccess_expr
The function _c_helper_absolute_name was named in
a misleading way.
It computes a C-expression for accessing a field of an xcb-type.

Therefore the name _c_helper_fieldaccess_expr is more appropriate.

Note: Patch 6 of this series has been removed during the review process.

Signed-off-by: Christian Linhart <chris@demorecorder.com>
Reviewed-by: Ran Benita <ran234@gmail.com>

Message-ID: <545627AE.2040200@DemoRecorder.com>
Patch-Thread-Subject: [Xcb] [PATCHSET] ListInputDevices revision 2
Patch-Set: ListInputDevices
Patch-Number: libxcb 7/9
Patch-Version: V1
2014-11-03 11:23:16 +01:00
Christian Linhart 51a0d57acc generator: sumof with nested expression
Support sumof with a nested expression.
The nested expression is computed for every list-element
and the result of the computation is added to the sum.

This way, sumof can be applied to a list of structs,
and, e.g., compute the sum of a specific field of that struct.

example:
<struct name="SumofTest_Element">
   <field type="CARD16" name="foo" />
   <field type="CARD16" name="bar" />
</struct>

<struct name="SumofTest_FieldAccess">
   <field type="CARD32" name="len" />
   <list type="SumofTest_Element" name="mylist1">
	   <fieldref>len</fieldref>
   </list>
   <list type="CARD16" name="mylist2">
	<sumof ref="mylist1">
		<fieldref>bar</fieldref>
	</sumof>
   </list>
</struct>

generated tmpvar:
    int xcb_pre_tmp_1; /* sumof length */
    int xcb_pre_tmp_2; /* sumof loop counter */
    int64_t xcb_pre_tmp_3; /* sumof sum */
    const xcb_input_sumof_test_element_t* xcb_pre_tmp_4; /* sumof list ptr */

generated code:
    /* mylist2 */
    /* sumof start */
    xcb_pre_tmp_1 = _aux->len;
    xcb_pre_tmp_3 = 0;
    xcb_pre_tmp_4 = xcb_input_sumof_test_field_access_mylist_1(_aux);
    for ( xcb_pre_tmp_2 = 0; xcb_pre_tmp_2 < xcb_pre_tmp_1; xcb_pre_tmp_2++) {
        xcb_pre_tmp_3 += xcb_pre_tmp_4->bar;
        xcb_pre_tmp_4++;
    }
    /* sumof end. Result is in xcb_pre_tmp_3 */
    xcb_block_len += xcb_pre_tmp_3 * sizeof(uint16_t);

changes for V2 of this patch:
* explicitely set the member access operator in the prefix-tuple
  passed to function _c_helper_field_mapping.
  This enables us to simplify function "_c_helper_absolute_name"
  (which will be renamed "_c_helper_fieldaccess_expr" soon)

V3: Changed style and formatting according to suggestions from Ran Benita

Signed-off-by: Christian Linhart <chris@DemoRecorder.com>
Reviewed-by: Ran Benita <ran234@gmail.com>

Message-ID: <54562798.8040500@DemoRecorder.com>
Patch-Thread-Subject: [Xcb] [PATCHSET] ListInputDevices revision 2
Patch-Set: ListInputDevices
Patch-Number: libxcb 5/9
Patch-Version: V3
2014-11-03 11:23:16 +01:00
Christian Linhart 4a915c0dba generator: sumof: support any type, generate explicit code
A sumof-expression now generates explicit code ( for-loop etc )
instead of calling xcb_sumof.

This way, it supports any type which can be added.
Previously, only uint_8 was supported.

Here's an example and the generated code:

xml:
<struct name="SumofTest">
   <field type="CARD32" name="len" />
   <list type="CARD16" name="mylist1">
	   <fieldref>len</fieldref>
   </list>
   <list type="CARD8" name="mylist2">
	   <sumof ref="mylist1"/>
   </list>
</struct>

declaration of tempvars at the start of enclosing function:
    int xcb_pre_tmp_1; /* sumof length */
    int xcb_pre_tmp_2; /* sumof loop counter */
    int64_t xcb_pre_tmp_3; /* sumof sum */
    const uint16_t* xcb_pre_tmp_4; /* sumof list ptr */

code:
    /* mylist2 */
    /* sumof start */
    xcb_pre_tmp_1 = _aux->len;
    xcb_pre_tmp_3 = 0;
    xcb_pre_tmp_4 = xcb_input_sumof_test_mylist_1(_aux);
    for ( xcb_pre_tmp_2 = 0; xcb_pre_tmp_2 < xcb_pre_tmp_1; xcb_pre_tmp_2++) {
        xcb_pre_tmp_3 += *xcb_pre_tmp_4;
        xcb_pre_tmp_4++;
    }
    /* sumof end. Result is in xcb_pre_tmp_3 */
    xcb_block_len += xcb_pre_tmp_3 * sizeof(uint8_t);

This patch is also a preparation for sumof which can access
fields of lists of struct, etc.

V2: Changed style and formatting according to suggestions from Ran Benita

Signed-off-by: Christian Linhart <chris@DemoRecorder.com>
Reviewed-by: Ran Benita <ran234@gmail.com>

Message-ID: <54562774.8030306@DemoRecorder.com>
Patch-Thread-Subject: [Xcb] [PATCHSET] ListInputDevices revision 2
Patch-Set: ListInputDevices
Patch-Number: libxcb 4/9
Patch-Version: V2
2014-11-03 11:23:16 +01:00
Christian Linhart fda1fb4ed4 generator: expressions can generate pre-code
This patch provides a mechanism for generating
preparatory code for expressions.

This is e.g. necessary when an expression needs computations
which cannot be done in a C-Expression, like for-loops.

This will be used for sumof expressions but may be useful
elsewhere.

Note: Patch 2 of this series has been removed during the review process.

V2: adapt to changes in previous patches

V3: some style and formatting changes according to suggestions from Ran Benita.

Signed-off-by: Christian Linhart <chris@DemoRecorder.com>
Reviewed-by: Ran Benita <ran234@gmail.com>

Message-ID: <54562769.3090405@DemoRecorder.com>
Patch-Thread-Subject: [Xcb] [PATCHSET] ListInputDevices revision 2
Patch-Set: ListInputDevices
Patch-Number: libxcb 3/9
Patch-Version: V3
2014-11-03 11:23:16 +01:00
Christian Linhart 265d38882c generator: fix absname for fields with only accessor function
Fix _c_helper_absolute_name for fields which cannot be accessed
as a struct/union member but which can be accessed by an
accessor function.

The fix generates calls to the accessor function in these cases.

Example:
<struct name="AbsnameTest">
<field type="CARD32" name="len" />
<list type="CARD8" name="mylist1">
   <fieldref>len</fieldref>
</list>
<list type="CARD8" name="mylist2">
   <sumof ref="mylist1"/>
</list>
</struct>

The sumof-expression ( <sumof ref="mylist1"/> ) refers to mylist1
which is only acessible by an accessor function.

Previously, sumof was only used inside bitcases,
where such lists are accessible by members of the
deserialized parent struct.
(there is a difference between deserialization of switches
and structs.)

V2 of this patch:
* replaced "!= None" with "is not None" because that's more pythonic.
(according to suggestion from Ran Benita)

V3 of this patch: simplification:
* fixed the recursion in _c_type_setup
  so that _c_helper_absolute_name does not need check
  a gazillion things as a workaround anymore.

* simplified _c_helper_absolute_name
  - remove unneeded check for empty string before
    append of last_sep to prefix_str

  - removed those if-conditions which are not
    needed anymore after fixing the recursion
    in _c_type_setup.

  - extract functionality for checking whether a field
    needs an accessor ( and which type of accessor )
    in functions.
    (also extracted from _c_accessors)

  - rearrange the condition branches and actions for
    more readability.

V3 generates exactly the same *.c and *.h files as V2.

V4 of this patch:
* improve formatting as per suggestions of Ran

Signed-off-by: Christian Linhart <chris@DemoRecorder.com>
Reviewed-by: Ran Benita <ran234@gmail.com>

Message-ID: <54562758.5090107@DemoRecorder.com>
Patch-Thread-Subject: [Xcb] [PATCHSET] ListInputDevices revision 2
Patch-Set: ListInputDevices
Patch-Number: libxcb 1/9
Patch-Version: V4
2014-11-03 11:23:16 +01:00
Peter Harris bbca7b82f8 Merge branch 'NestedStructTypenames-V5' of http://infra-srv1.demorecorder.com/git/free-sw/xcb/libxcb 2014-10-30 11:51:57 -04:00
Christian Linhart fdb291b414 no typename for nested structs
Nested structs which are generated for named case and bitcase
do not get a typename anymore, i.e., they are anonymous structs.

Reasons for this change:
* Prior typenames have caused nameclashes
* Prior typenames introduced names in the global namespace which
  did not start with the xcb prefix.

This change is safe with respect to API compatibility because:
I have searched for instances of named bitcases and there's only one place
where they are used, and that's in xkb.xml: reply GetKbdByName.
( no need to search for <case> because it was introduced after the last release )

The reply GetKbdByName is broken in its current form in the xkb.xml anyways,
so it is most probably not used anywhere.

So, my conclusion is that we can safely omit named types for nested structs.
No need for an attribute.

Message-ID: <1409731849-51897-1-git-send-email-chris@demorecorder.com>
Patch-Thread-Subject: Re: [Xcb] names of nested structs of named bitcase/case are prone to nameclashes. Solution?
Patch-Set: NestedStructTypenames
Patch-Number: libxcb 1/1
Patch-Version: V1
Signed-off-by: Christian Linhart <chris@DemoRecorder.com>
Reviewed-By: Ran Benita <ran234@gmail.com>
2014-10-20 12:21:21 +02:00
Christian Linhart a7c75be5b1 generator: fix align-pads for switches which start at unaligned pos
Fix the alignment computation inside switches which start at
an unaligned pos.
This affects both explicit and implicit align pads.

The alignment offset is derived from the lowest 3 bits of
the pointer to the protocol-data at the start of the switch.
This is sufficient for correcting all alignments up to 8-byte alignment.
As far as I know there is no bigger alignment than 8-byte for the
X-protocol.

Example:
struct InputState, where the switch starts after two 1-byte fields,
which is a 2 byte offset for 4-byte and 8-byte alignment.

The previous problem can be demonstrated when adding a
<pad align="4"/> at the end of case "key".

(Or when finding a testcase which reports the case "valuator" not
at the last position of the QueryDeviceState-reply.
I didn't find such a testcase, so I have used the pad align
as described above.)

V2: patch modified in order to fix bugs which I found when working on the
next issue:
* xcb_padding_offset has to be set 0 when xcb_block_len is set 0
* xcb_padding_offset cannot be "const" therefore
* for unpack and unserialize, the padding_offset must computed
  from _buffer instead of from the aux_var.

V3: patch revised according to suggestion by Ran Benita:
* only create and use xcb_padding_offset for switch

Message-ID: <1410298000-24734-1-git-send-email-chris@demorecorder.com>
Patch-Thread-Subject: [Xcb] xinput:QueryDeviceState: full-support: generator and xml-changes
Patch-Set: QueryDeviceState
Patch-Number: libxcb 4/4
Patch-Version: V3
Signed-off-by: Christian Linhart <chris@DemoRecorder.com>
Reviewed-By: Ran Benita <ran234@gmail.com>
2014-10-20 12:21:21 +02:00
Christian Linhart 277ea629de generator: support lists of structs which contain a switch
This essentially requires to have a correct sizeof-function
for the struct.
This in turn requires a sizeof-function for the switch, too.

Making a sizeof-function for the switch is triggered by
replacing "elif" by "if" in the first change of this patch.
This way, c_need_sizeof is also set to True for switches if appropriate.

The _c_serialize_helper_switch_field function has to support
the context "sizeof":
This is done in the second change of this patch

The third change of this patch fixes an alignment error:
It does not make sense to base the padding on the struct-type
which is generated for switch because this struct does not
represent the protocol. Rather it is the output of deserialization.
( The implicit padding for var-sized fields has other issues, IMHO,
but I am not touching these now...)

The effect on the generated code for the current xml-files
is as follows:
* several additional sizeof-functions are generated
* the fix of the alignment error only changes one place
  in the XKB-extension for the GetKbdByName-reply.
  This is no problem because that reply in its current form
  is broken/unfinished anyways.

Note:
This patch also fixes a problem in the generator when
a fixed-size list is the last field of a case or bitcase.

Message-ID: <1408653356-21191-2-git-send-email-chris@demorecorder.com>
Patch-Thread-Subject: [Xcb] xinput:QueryDeviceState: full-support: generator and xml-changes
Patch-Set: QueryDeviceState
Patch-Number: libxcb 2/3
Patch-Version: V1
Signed-off-by: Christian Linhart <chris@DemoRecorder.com>
Reviewed-By: Ran Benita <ran234@gmail.com>
2014-10-20 12:21:21 +02:00
Emil Velikov 382d306d6c Move internal/private dependencies to Requires.private
Program using the xcb sub-modules has indirect compile and runtime
dependency of core xcb. To ensure this out we currently list xcb in
the Requires field of the pkg-config files. While this provides all
the required dependencies for successful compilation this causes
over-linking and hides potential linking miss-use against the xcb modules.

By moving to Requires.private we retain the compilation and runtime
compatibility and avoids any runtime problems.

Cc: Keith Packard <keithp@keithp.com>
Cc: Alan Coopersmith <alan.coopersmith@oracle.com>
References: http://people.freedesktop.org/~dbn/pkg-config-guide.html#faq
References: https://wiki.mageia.org/en/Overlinking_issues_in_packaging
References: http://err.no/personal/blog/2008/Mar/25
Signed-off-by: Emil Velikov <emil.l.velikov@gmail.com>
Reviewed-by: Julien Cristau <jcristau@debian.org>
Signed-off-by: Uli Schlachter <psychon@znc.in>
2014-10-03 23:53:54 +02:00
Christian Linhart d74d066949 generator: support fixed size lists in var-sized structs
V2: patch revised according to suggestions from Ran Benita:
* removed blanks before an after parentheses of function-calls or tuples
* replaced if by elif in "if field.type.is_list". ( this fixes old code )

Message-ID: <540B4D17.1080908@DemoRecorder.com>
Patch-Thread-Subject: [Xcb] xinput:QueryDeviceState: full-support: generator and xml-changes
Patch-Set: QueryDeviceState
Patch-Number: libxcb 1/3
Patch-Version: V2
Signed-off-by: Christian Linhart <chris@DemoRecorder.com>
Reviewed-By: Ran Benita <ran234@gmail.com>
2014-09-09 23:54:41 +02:00
Uli Schlachter b0e6c2de09 xcb_get_setup(): Never return NULL
The documentation doesn't mention it and it's unlikely that a lot of code out
there handles this case correctly. So, instead of returning NULL, let
xcb_get_setup() return a pointer to a static, invalid, all-zero setup
information structure.

Signed-off-by: Uli Schlachter <psychon@znc.in>
2014-08-25 19:15:34 -04:00
Uli Schlachter c4e40f646b Make some functions also work on error connections
There is no technical reason why xcb_get_setup() and xcb_get_file_descriptor()
shouldn't work on non-static error connections. They cannot be used for many
useful things, but at least they work.

This works around bugs in lots of programs out there which assume that
xcb_get_setup() does not return NULL and which just happily dereference the
results. Since xcb_connect() never returns NULL, it's a bit weird that
xcb_get_setup() can do so. xcb_get_file_descriptor() is just modified since this
can be done here equally easily and because the fd isn't closed until the final
xcb_disconnect() on the error connection.

Non-static error connections are connections which entered an error state after
xcb_connect() succeeded. If something goes wrong in establishing a connection,
xcb_connect() will return a static error connection which doesn't have the
fields used here.

Signed-off-by: Uli Schlachter <psychon@znc.in>
2014-08-25 19:15:34 -04:00
Christian Linhart 355d4d6ab9 support switch case in the generator
The implementation is rather simple:
When a <case> is used instead of a <bitcase>
then operator "==" is used instead of "&" in the if-condition.

So it creates a series of "if" statements
(instead of a switch-case statement in C )

In practice this does not matter because a good
optimizing compiler will create the same code
as for a switch-case.

With this simple implementation we get additional
flexibility in the following forms:
* a case value may appear in multiple case branches.
  for example:
	case C1 will be selected by values 1, 4, or 5
	case C2 will be selected by values 3, 4, or 7

* mixing of bitcase and case is possible
	(this will usually make no sense but there may
	be protocol specs where this is needed)

details of the impl:
* replaced "is_bitcase" with "is_case_or_bitcase" in all places
  so that cases are treated like bitcases.

* In function "_c_serialize_helper_switch": write operator "=="
  instead of operator "&" if it is a case.
2014-08-20 11:59:04 -04:00
Daniel Martin 966fba6ba4 Disable Xevie and Xprint by default
Both extensions have been dropped from the X-Server in 2008:
    http://cgit.freedesktop.org/xorg/xserver/commit/?id=1c8bd31
    http://cgit.freedesktop.org/xorg/xserver/commit/?id=f4036f6

Don't build them by default.

Reviewed-by: Julien Cristau <jcristau@debian.org>
Signed-off-by: Daniel Martin <consume.noise@gmail.com>
Signed-off-by: Uli Schlachter <psychon@znc.in>
2014-08-06 13:32:50 +02:00
Gaetan Nadon a5e90ae6a1 help text: do not report the insanly long list of Warning flags.
Originally there was just one. Now that XCB has been integrated with X and
uses the same compiler flags, it is a different story.

  Used CFLAGS:
    CPPFLAGS............:
    CFLAGS..............: -g -O2
    Warning CFLAGS......:  -Wall -Wpointer-arith AND SO ON FOR 8 lines...

It completely defaces the otherwise excellent output.

Reviewed-by: Josh Triplett <josh@joshtriplett.org>
Signed-off-by: Gaetan Nadon <memsize@videotron.ca>
Signed-off-by: Uli Schlachter <psychon@znc.in>
2014-08-06 13:29:16 +02:00
Gaetan Nadon 529e3bfc20 Add ChangeLog and INSTALL using xorg macros
Same as all other X modules. The one in libxcb git is removed.

Those files are created during 'make dist'

Reviewed-by: Josh Triplett <josh@joshtriplett.org>
Signed-off-by: Gaetan Nadon <memsize@videotron.ca>
Signed-off-by: Uli Schlachter <psychon@znc.in>
2014-08-06 13:29:16 +02:00
Gaetan Nadon 74f552c1b3 sendmsg: remove --enable-sendfds as it is superceeded by --enable-dri3
DRI3 requires sendmsg support which is auto-detected. A builder can enable
or disable dri3 feature. If sendmsg function is not available, dri3 cannot
be enabled.

This reverts af8067cbf4 which was done at a time where --enable-dri3
had not been added yet.

Reviewed-by: Josh Triplett <josh@joshtriplett.org>
Signed-off-by: Gaetan Nadon <memsize@videotron.ca>
Signed-off-by: Uli Schlachter <psychon@znc.in>
2014-08-06 13:26:08 +02:00
Gaetan Nadon 23f57ac8bf config: issue an error if DRI3 is requested, but sendfds is not available
When a user issues the --enable-dri3 option and sendfds is not available
on the system, the configuration will abort with an error message.

Reviewed-by: Josh Triplett <josh@joshtriplett.org>
Signed-off-by: Gaetan Nadon <memsize@videotron.ca>
Signed-off-by: Uli Schlachter <psychon@znc.in>
2014-08-06 13:26:08 +02:00
Gaetan Nadon 7f07b57be5 config: default option for enable-dri3 is not implemented
The first symptom is the help text:

  --enable-dri3     Build XCB DRI3 Extension (default: "$sendfds")

The implementation variable $sendfds leaked into the user interface.
Testing the various user inputs:
  <nothing>                DRI3 is enabled     PASS
  --enable-dri3		   DRI3 is enabled     PASS
  --enable-dri3=yes        DRI3 is enabled     PASS
  --enable-dri3=no         DRI3 is disabled    PASS
  --disable-dri3           DRI3 is disabled    PASS
  --enable-dri3=$sendfds   DRI3 is disabled    FAIL

This patch implements the usual idiom for features that are enabled by
default if the various conditions are met (sendfds is available).
New help text:

  --enable-dri3     Build XCB DRI3 Extension (default: auto)

With the additional user input:

  --enable-dri3=auto

which is equivalent to providing no input at all.

Reviewed-by: Josh Triplett <josh@joshtriplett.org>
Signed-off-by: Gaetan Nadon <memsize@videotron.ca>
Signed-off-by: Uli Schlachter <psychon@znc.in>
2014-08-06 13:26:08 +02:00
57 changed files with 1948 additions and 846 deletions

5
.gitignore vendored
View File

@ -21,3 +21,8 @@ libtool
m4/l*.m4
mkinstalldirs
stamp-h1
ChangeLog
INSTALL
check-pc-requires.log
check-pc-requires.trs
test-suite.log

123
.gitlab-ci.yml Normal file
View File

@ -0,0 +1,123 @@
# vim: set expandtab shiftwidth=2 tabstop=8 textwidth=0 filetype=yaml:
#
# This CI uses the freedesktop.org ci-templates.
# Please see the ci-templates documentation for details:
# https://freedesktop.pages.freedesktop.org/ci-templates/
.templates_sha: &template_sha b791bd48996e3ced9ca13f1c5ee82be8540b8adb # see https://docs.gitlab.com/ee/ci/yaml/#includefile
include:
# Arch container builder template
- project: 'freedesktop/ci-templates'
ref: *template_sha
file: '/templates/arch.yml'
- project: 'freedesktop/ci-templates'
ref: *template_sha
file: '/templates/ci-fairy.yml'
- template: Security/SAST.gitlab-ci.yml
stages:
- prep # prep work like rebuilding the container images if there is a change
- install xcbproto
- build # for actually building and testing things in a container
- test
- deploy
variables:
FDO_UPSTREAM_REPO: 'xorg/lib/libxcb'
# The tag should be updated each time the list of packages is updated.
# Changing a tag forces the associated image to be rebuilt.
# Note: the tag has no meaning, we use a date format purely for readability
FDO_DISTRIBUTION_TAG: '2023-08-21.0'
FDO_DISTRIBUTION_PACKAGES: 'git gcc pkgconf autoconf automake libtool make xorg-util-macros python doxygen graphviz check libxslt libxau libxdmcp'
#
# Verify that commit messages are as expected
#
check-commits:
extends:
- .fdo.ci-fairy
stage: prep
script:
- ci-fairy check-commits --junit-xml=results.xml
except:
- master@xorg/lib/libxcb
variables:
GIT_DEPTH: 100
artifacts:
reports:
junit: results.xml
#
# Verify that the merge request has the allow-collaboration checkbox ticked
#
check-merge-request:
extends:
- .fdo.ci-fairy
stage: deploy
script:
- ci-fairy check-merge-request --require-allow-collaboration --junit-xml=results.xml
artifacts:
when: on_failure
reports:
junit: results.xml
allow_failure: true
#
# Build a container with the given tag and the packages pre-installed.
# This only happens if/when the tag changes, otherwise the existing image is
# re-used.
#
container-prep:
extends:
- .fdo.container-build@arch
stage: prep
variables:
GIT_STRATEGY: none
#
# Build latest xcbproto from git, instead of relying on the container
# to package a new enough version.
#
xcbproto-build:
extends:
- .fdo.distribution-image@arch
stage: install xcbproto
script:
- export INSTDIR="$PWD/_inst"
- git clone --depth=1 https://gitlab.freedesktop.org/xorg/proto/xcbproto
- pushd xcbproto > /dev/null
- mkdir _builddir
- pushd _builddir > /dev/null
- ../autogen.sh --disable-silent-rules --prefix="$INSTDIR"
- make -j${FDO_CI_CONCURRENT:-4} install
- popd > /dev/null
- popd > /dev/null
variables:
artifacts:
paths:
- _inst
#
# The default build, runs on the image built above.
#
build:
stage: build
extends:
- .fdo.distribution-image@arch
script:
- export INSTDIR="$PWD/_inst"
- export PKG_CONFIG_PATH=$(find $INSTDIR/ -name '*.pc' -printf "%h:")
- autoreconf -ivf
- mkdir _builddir
- pushd _builddir > /dev/null
- ../configure --disable-silent-rules --enable-devel-docs --with-doxygen
- make
- make check
- make distcheck
- popd > /dev/null

229
INSTALL
View File

@ -1,229 +0,0 @@
Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002 Free Software
Foundation, Inc.
This file is free documentation; the Free Software Foundation gives
unlimited permission to copy, distribute and modify it.
Basic Installation
==================
These are generic installation instructions.
The `configure' shell script attempts to guess correct values for
various system-dependent variables used during compilation. It uses
those values to create a `Makefile' in each directory of the package.
It may also create one or more `.h' files containing system-dependent
definitions. Finally, it creates a shell script `config.status' that
you can run in the future to recreate the current configuration, and a
file `config.log' containing compiler output (useful mainly for
debugging `configure').
It can also use an optional file (typically called `config.cache'
and enabled with `--cache-file=config.cache' or simply `-C') that saves
the results of its tests to speed up reconfiguring. (Caching is
disabled by default to prevent problems with accidental use of stale
cache files.)
If you need to do unusual things to compile the package, please try
to figure out how `configure' could check whether to do them, and mail
diffs or instructions to the address given in the `README' so they can
be considered for the next release. If you are using the cache, and at
some point `config.cache' contains results you don't want to keep, you
may remove or edit it.
The file `configure.ac' (or `configure.in') is used to create
`configure' by a program called `autoconf'. You only need
`configure.ac' if you want to change it or regenerate `configure' using
a newer version of `autoconf'.
The simplest way to compile this package is:
1. `cd' to the directory containing the package's source code and type
`./configure' to configure the package for your system. If you're
using `csh' on an old version of System V, you might need to type
`sh ./configure' instead to prevent `csh' from trying to execute
`configure' itself.
Running `configure' takes awhile. While running, it prints some
messages telling which features it is checking for.
2. Type `make' to compile the package.
3. Optionally, type `make check' to run any self-tests that come with
the package.
4. Type `make install' to install the programs and any data files and
documentation.
5. You can remove the program binaries and object files from the
source code directory by typing `make clean'. To also remove the
files that `configure' created (so you can compile the package for
a different kind of computer), type `make distclean'. There is
also a `make maintainer-clean' target, but that is intended mainly
for the package's developers. If you use it, you may have to get
all sorts of other programs in order to regenerate files that came
with the distribution.
Compilers and Options
=====================
Some systems require unusual options for compilation or linking that
the `configure' script does not know about. Run `./configure --help'
for details on some of the pertinent environment variables.
You can give `configure' initial values for configuration parameters
by setting variables in the command line or in the environment. Here
is an example:
./configure CC=c89 CFLAGS=-O2 LIBS=-lposix
*Note Defining Variables::, for more details.
Compiling For Multiple Architectures
====================================
You can compile the package for more than one kind of computer at the
same time, by placing the object files for each architecture in their
own directory. To do this, you must use a version of `make' that
supports the `VPATH' variable, such as GNU `make'. `cd' to the
directory where you want the object files and executables to go and run
the `configure' script. `configure' automatically checks for the
source code in the directory that `configure' is in and in `..'.
If you have to use a `make' that does not support the `VPATH'
variable, you have to compile the package for one architecture at a
time in the source code directory. After you have installed the
package for one architecture, use `make distclean' before reconfiguring
for another architecture.
Installation Names
==================
By default, `make install' will install the package's files in
`/usr/local/bin', `/usr/local/man', etc. You can specify an
installation prefix other than `/usr/local' by giving `configure' the
option `--prefix=PATH'.
You can specify separate installation prefixes for
architecture-specific files and architecture-independent files. If you
give `configure' the option `--exec-prefix=PATH', the package will use
PATH as the prefix for installing programs and libraries.
Documentation and other data files will still use the regular prefix.
In addition, if you use an unusual directory layout you can give
options like `--bindir=PATH' to specify different values for particular
kinds of files. Run `configure --help' for a list of the directories
you can set and what kinds of files go in them.
If the package supports it, you can cause programs to be installed
with an extra prefix or suffix on their names by giving `configure' the
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
Optional Features
=================
Some packages pay attention to `--enable-FEATURE' options to
`configure', where FEATURE indicates an optional part of the package.
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
is something like `gnu-as' or `x' (for the X Window System). The
`README' should mention any `--enable-' and `--with-' options that the
package recognizes.
For packages that use the X Window System, `configure' can usually
find the X include and library files automatically, but if it doesn't,
you can use the `configure' options `--x-includes=DIR' and
`--x-libraries=DIR' to specify their locations.
Specifying the System Type
==========================
There may be some features `configure' cannot figure out
automatically, but needs to determine by the type of machine the package
will run on. Usually, assuming the package is built to be run on the
_same_ architectures, `configure' can figure that out, but if it prints
a message saying it cannot guess the machine type, give it the
`--build=TYPE' option. TYPE can either be a short name for the system
type, such as `sun4', or a canonical name which has the form:
CPU-COMPANY-SYSTEM
where SYSTEM can have one of these forms:
OS KERNEL-OS
See the file `config.sub' for the possible values of each field. If
`config.sub' isn't included in this package, then this package doesn't
need to know the machine type.
If you are _building_ compiler tools for cross-compiling, you should
use the `--target=TYPE' option to select the type of system they will
produce code for.
If you want to _use_ a cross compiler, that generates code for a
platform different from the build platform, you should specify the
"host" platform (i.e., that on which the generated programs will
eventually be run) with `--host=TYPE'.
Sharing Defaults
================
If you want to set default values for `configure' scripts to share,
you can create a site shell script called `config.site' that gives
default values for variables like `CC', `cache_file', and `prefix'.
`configure' looks for `PREFIX/share/config.site' if it exists, then
`PREFIX/etc/config.site' if it exists. Or, you can set the
`CONFIG_SITE' environment variable to the location of the site script.
A warning: not all `configure' scripts look for a site script.
Defining Variables
==================
Variables not defined in a site shell script can be set in the
environment passed to `configure'. However, some packages may run
configure again during the build, and the customized values of these
variables may be lost. In order to avoid this problem, you should set
them in the `configure' command line, using `VAR=value'. For example:
./configure CC=/usr/local2/bin/gcc
will cause the specified gcc to be used as the C compiler (unless it is
overridden in the site shell script).
`configure' Invocation
======================
`configure' recognizes the following options to control how it
operates.
`--help'
`-h'
Print a summary of the options to `configure', and exit.
`--version'
`-V'
Print the version of Autoconf used to generate the `configure'
script, and exit.
`--cache-file=FILE'
Enable the cache: use and save the results of the tests in FILE,
traditionally `config.cache'. FILE defaults to `/dev/null' to
disable caching.
`--config-cache'
`-C'
Alias for `--cache-file=config.cache'.
`--quiet'
`--silent'
`-q'
Do not print messages saying which checks are being made. To
suppress all normal output, redirect it to `/dev/null' (any error
messages will still be shown).
`--srcdir=DIR'
Look for the package's source code in directory DIR. Usually
`configure' can determine that directory automatically.
`configure' also accepts some other, not widely useful, options. Run
`configure --help' for more details.

View File

@ -12,6 +12,9 @@ endif
if BUILD_DAMAGE
pkgconfig_DATA += xcb-damage.pc
endif
if BUILD_DBE
pkgconfig_DATA += xcb-dbe.pc
endif
if BUILD_DPMS
pkgconfig_DATA += xcb-dpms.pc
endif
@ -84,6 +87,9 @@ endif
if BUILD_XVMC
pkgconfig_DATA += xcb-xvmc.pc
endif
if BUILD_GE
pkgconfig_DATA += xcb-ge.pc
endif
AM_TESTS_ENVIRONMENT = \
@ -96,4 +102,17 @@ tools/README \
tools/api_conv.pl \
tools/constants \
autogen.sh \
README.md \
$(TESTS)
MAINTAINERCLEANFILES = ChangeLog INSTALL
.PHONY: ChangeLog INSTALL
INSTALL:
$(INSTALL_CMD)
ChangeLog:
$(CHANGELOG_CMD)
dist-hook: ChangeLog INSTALL

52
NEWS
View File

@ -1,3 +1,55 @@
Release 1.14 (2020-02-22)
=========================
* Add xcb_total_read() and xcb_total_written() API
* Support check >= 0.13 API (for make check)
* Bug fix to handle EINTR from recvmsg
* Only require pthread-stubs on non-Linux platforms
Release 1.13.1 (2018-09-27)
===========================
* Don't flag extra reply in xcb_take_socket
Release 1.13 (2018-02-28)
=========================
* Add support for variable-sized lists of FDs
* Poll for events when blocking waiting for special events
* xinput: Enable XInput extension by default
* ge: Add explicit support for GenericEvent extension
* Fix documentation warnings from clang
* Cosmetic cleanups
Release 1.12 (2016-05-18)
=========================
* configure: Various fixes for dri3 and FD passing support
* configure: Don't report all the warning CFLAGS
* configure: Disable Xevie and Xprint by default
* Add support for various new constructs in the XML schema
* Make some functions also accept connections in an error state
* Never return NULL from xcb_get_setup()
* Use Requires.private in .pc files to avoid overlinking
* Fix align-pads for switches which start at unaligned positions
* Use anonymous structs for some nested structs
* Also generate accessors for variable-sized events and requests
* Improved python3 compatibility
* Generate C99 initializers instead of comments
* Various simplifications to the python code
* Fix line breaks in xcb-requests manual page
* Always close FDs in xcb_send_fd()
* Fix thread-safety issues with FD passing
* Add xcb_send_request_with_fds() and xcb_send_request_with_fds64()
* Fix endless loop with too many outstanding FDs to send
* Link with winsock library on MinGW
* Disable some unfinished API for some server-side code by default
* Use align-offsets computed by xcb-proto instead of low bits of pointers
* Fix iterator interaction with align padding
* Stop serializing padding by default
* Increase unix socket send buffer to at least 64KiB
Release 1.11.1 (2015-09-06)
===========================
* Expose 64-bit sequence numbers for XLib
* Fix some hangs related to xcb_wait_for_special_event()
Release 1.11 (2014-08-01)
=========================
* Force structures with 64-bit fields to be packed

View File

@ -2,7 +2,7 @@ About libxcb
============
libxcb provides an interface to the X Window System protocol, which
replaces the current Xlib interface. It has several advantages over
replaces the traditional Xlib interface. It has several advantages over
Xlib, including:
- size: small, simple library, and lower memory footprint
- latency hiding: batch several requests and wait for the replies later
@ -10,27 +10,32 @@ Xlib, including:
- proven thread support: transparently access XCB from multiple threads
- easy extension implementation: interfaces auto-generated from XML-XCB
Xlib can also use XCB as a transport layer, allowing software to make
Xlib also uses XCB as a transport layer, allowing software to make
requests and receive responses with both, which eases porting to XCB.
However, client programs, libraries, and toolkits will gain the most
benefit from a native XCB port.
More information about xcb is available from our website:
Please report any issues you find to the freedesktop.org bug tracker,
at:
https://xcb.freedesktop.org/
<https://bugs.freedesktop.org/enter_bug.cgi?product=XCB>
Please report any issues you find to the freedesktop.org bug tracker at:
https://gitlab.freedesktop.org/xorg/lib/libxcb/issues
Discussion about XCB occurs on the XCB mailing list:
<mailto:xcb at lists.freedesktop.org>
<http://lists.freedesktop.org/mailman/listinfo/xcb>
https://lists.freedesktop.org/mailman/listinfo/xcb
You can obtain the latest development versions of XCB using GIT.
For anonymous checkouts, use:
You can obtain the latest development versions of XCB using GIT from
the libxcb code repository at:
git clone git://anongit.freedesktop.org/git/xcb/libxcb
https://gitlab.freedesktop.org/xorg/lib/libxcb
For developers, use:
For anonymous checkouts, use:
git clone git+ssh://git.freedesktop.org/git/xcb/libxcb
git clone https://gitlab.freedesktop.org/xorg/lib/libxcb.git
For developers, use:
git clone git@gitlab.freedesktop.org:xorg/lib/libxcb.git

View File

@ -1,14 +1,17 @@
#! /bin/sh
srcdir=`dirname $0`
srcdir=`dirname "$0"`
test -z "$srcdir" && srcdir=.
ORIGDIR=`pwd`
cd $srcdir
cd "$srcdir"
autoreconf -v --install || exit 1
cd $ORIGDIR || exit $?
cd "$ORIGDIR" || exit $?
git config --local --get format.subjectPrefix >/dev/null 2>&1 ||
git config --local format.subjectPrefix "PATCH libxcb"
if test -z "$NOCONFIGURE"; then
$srcdir/configure "$@"
exec "$srcdir"/configure "$@"
fi

View File

@ -23,7 +23,7 @@ for inc in src/*.h; do
included=`grep '# *include' $inc |
sed -e 's/[^<"]*[<"]//' -e 's/[>"]//' |
grep -v 'xcb.h\|xproto.h'`
requires=`grep '^Requires:' $pcin`
requires=`grep '^Requires.private:' $pcin`
missing=""
for i in $included; do
ibase=`basename $i .h`
@ -58,7 +58,7 @@ for inc in src/*.h; do
*)
if [ "$fix" = "y" ]; then
echo $package adding dependency on $missing
sed -i '/^Requires:/s/$/ '"$missing"'/' $pcin
sed -i '/^Requires.private:/s/$/ '"$missing"'/' $pcin
else
echo $package missing $missing
status=1

View File

@ -2,8 +2,8 @@ dnl Process this file with autoconf to produce a configure script.
# Initialize Autoconf
AC_PREREQ([2.60])
AC_INIT([libxcb],[1.11],
[https://bugs.freedesktop.org/enter_bug.cgi?product=xcb],
AC_INIT([libxcb],[1.17.0],
[https://gitlab.freedesktop.org/xorg/lib/libxcb/-/issues],
[libxcb])
AC_CONFIG_AUX_DIR([build-aux])
AC_CONFIG_MACRO_DIR([m4])
@ -11,13 +11,14 @@ AC_CONFIG_SRCDIR([xcb.pc.in])
AC_CONFIG_HEADERS([src/config.h])
# Initialize Automake
AM_INIT_AUTOMAKE([foreign dist-bzip2])
AM_PATH_PYTHON([2.6])
AM_INIT_AUTOMAKE([foreign dist-xz])
AM_PATH_PYTHON([3.0])
# Set common system defines for POSIX extensions, such as _GNU_SOURCE
# Must be called before any macros that run the compiler (like AC_PROG_LIBTOOL)
# to avoid autoconf errors.
AC_USE_SYSTEM_EXTENSIONS
AC_SYS_LARGEFILE
# Initialize libtool
LT_PREREQ([2.2])
@ -36,7 +37,7 @@ if test x"$HAVE_DOT" = xno; then
AC_MSG_WARN([dot not found - doxygen targets will be skipped])
fi
PKG_CHECK_MODULES(CHECK, [check >= 0.9.4], [HAVE_CHECK=yes], [HAVE_CHECK=no])
PKG_CHECK_MODULES(CHECK, [check >= 0.9.6], [HAVE_CHECK=yes], [HAVE_CHECK=no])
AM_CONDITIONAL(HAVE_CHECK, test x$HAVE_CHECK = xyes)
XSLTPROC=no
@ -50,8 +51,12 @@ fi
AC_SUBST(HTML_CHECK_RESULT)
# Checks for pkg-config packages
PKG_CHECK_MODULES(XCBPROTO, xcb-proto >= 1.11)
NEEDED="pthread-stubs xau >= 0.99.2"
PKG_CHECK_MODULES(XCBPROTO, xcb-proto >= 1.17.0)
NEEDED="xau >= 0.99.2"
case $host_os in
linux*|darwin*|solaris*|dragonfly*|freebsd*|netbsd*) ;;
*) NEEDED="$NEEDED pthread-stubs" ;;
esac
PKG_CHECK_MODULES(NEEDED, $NEEDED)
have_xdmcp="no"
@ -86,18 +91,11 @@ XCBPROTO_XCBPYTHONDIR=`$PKG_CONFIG --variable=pythondir xcb-proto`
AC_MSG_RESULT($XCBPROTO_XCBPYTHONDIR)
AC_SUBST(XCBPROTO_XCBPYTHONDIR)
AC_HEADER_STDC
AC_SEARCH_LIBS(getaddrinfo, socket)
AC_SEARCH_LIBS(connect, socket)
AC_ARG_ENABLE(sendfds, AS_HELP_STRING([--disable-sendfds], [Support FD passing (default: auto)]),
[sendfds=$enableval], [sendfds=auto])
case x$sendfds in
xauto)
AC_SEARCH_LIBS(sendmsg, socket, [sendfds="yes"], [sendfds="no"])
;;
esac
# Find support for sending a message from a socket
AC_SEARCH_LIBS(sendmsg, socket, [have_sendmsg="yes"], [have_sendmsg="no"])
# XPG4v2/UNIX95 added msg_control - check to see if we need to define
# _XOPEN_SOURCE to get it (such as on Solaris)
@ -126,14 +124,14 @@ if test "x$ac_cv_member_struct_msghdr_msg_control" = xno; then
AC_CHECK_MEMBER([struct msghdr.msg_control],
[AC_DEFINE([_XOPEN_SOURCE], [500],
[Defined if needed to expose struct msghdr.msg_control])
], [sendfds="no"], [
], [have_sendmsg="no"], [
#define _XOPEN_SOURCE 500
AC_INCLUDES_DEFAULT
#include <sys/socket.h>
])
fi
case x$sendfds in
case x$have_sendmsg in
xyes)
AC_DEFINE([HAVE_SENDMSG],1,[Define if your platform supports sendmsg])
;;
@ -212,42 +210,47 @@ case $host_os in
;;
esac
XCB_EXTENSION(Composite, "yes")
XCB_EXTENSION(Damage, "yes")
XCB_EXTENSION(DPMS, "yes")
XCB_EXTENSION(DRI2, "yes")
XCB_EXTENSION(DRI3, "$sendfds")
XCB_EXTENSION(GLX, "yes")
XCB_EXTENSION(Present, "yes")
XCB_EXTENSION(RandR, "yes")
XCB_EXTENSION(Record, "yes")
XCB_EXTENSION(Render, "yes")
XCB_EXTENSION(Resource, "yes")
XCB_EXTENSION(Screensaver, "yes")
XCB_EXTENSION(Shape, "yes")
XCB_EXTENSION(Shm, "yes")
XCB_EXTENSION(Sync, "yes")
XCB_EXTENSION(Xevie, "yes")
XCB_EXTENSION(XFixes, "yes")
XCB_EXTENSION(XFree86-DRI, "yes")
XCB_EXTENSION(Xinerama, "yes")
XCB_EXTENSION(XInput, "no")
XCB_EXTENSION(XKB, "yes")
XCB_EXTENSION(Xprint, "yes")
XCB_EXTENSION(SELinux, "no")
XCB_EXTENSION(XTest, "yes")
XCB_EXTENSION(Xv, "yes")
XCB_EXTENSION(XvMC, "yes")
dnl Link with winsock for socket functions on MinGW
case $host_os in
*mingw*)
AC_CHECK_LIB([ws2_32],[main])
;;
*)
;;
esac
AC_ARG_WITH(launchd, AS_HELP_STRING([--with-launchd], [Build with support for Apple's launchd (default: auto)]), [LAUNCHD=$withval], [LAUNCHD=auto])
if test "x$LAUNCHD" = xauto; then
unset LAUNCHD
AC_CHECK_PROG(LAUNCHD, [launchd], [yes], [no], [$PATH$PATH_SEPARATOR/sbin])
fi
XCB_EXTENSION(Composite, yes)
XCB_EXTENSION(Damage, yes)
XCB_EXTENSION(Dbe, yes)
XCB_EXTENSION(DPMS, yes)
XCB_EXTENSION(DRI2, yes)
XCB_EXTENSION(DRI3, $have_sendmsg)
XCB_EXTENSION(GE, no)
XCB_EXTENSION(GLX, yes)
XCB_EXTENSION(Present, yes)
XCB_EXTENSION(RandR, yes)
XCB_EXTENSION(Record, yes)
XCB_EXTENSION(Render, yes)
XCB_EXTENSION(Resource, yes)
XCB_EXTENSION(Screensaver, yes)
XCB_EXTENSION(Shape, yes)
XCB_EXTENSION(Shm, yes)
XCB_EXTENSION(Sync, yes)
XCB_EXTENSION(Xevie, no)
XCB_EXTENSION(XFixes, yes)
XCB_EXTENSION(XFree86-DRI, yes)
XCB_EXTENSION(Xinerama, yes)
XCB_EXTENSION(XInput, yes)
XCB_EXTENSION(XKB, yes)
XCB_EXTENSION(Xprint, no)
XCB_EXTENSION(SELinux, no)
XCB_EXTENSION(XTest, yes)
XCB_EXTENSION(Xv, yes)
XCB_EXTENSION(XvMC, yes)
if test "x$LAUNCHD" = xyes ; then
AC_DEFINE(HAVE_LAUNCHD, 1, [launchd support available])
fi
AC_ARG_WITH(serverside-support, AS_HELP_STRING([--with-serverside-support], [Build with support for server-side usage of xcb. This is still EXPERIMENTAL! ABI/API may change! (default: no)]), [XCB_SERVERSIDE_SUPPORT=$withval], [XCB_SERVERSIDE_SUPPORT=no])
AM_CONDITIONAL(XCB_SERVERSIDE_SUPPORT, test "x$XCB_SERVERSIDE_SUPPORT" = "xyes")
AC_CONFIG_FILES([
Makefile
@ -261,9 +264,11 @@ AC_CONFIG_FILES([
xcb.pc
xcb-composite.pc
xcb-damage.pc
xcb-dbe.pc
xcb-dpms.pc
xcb-dri2.pc
xcb-dri3.pc
xcb-ge.pc
xcb-glx.pc
xcb-present.pc
xcb-randr.pc
@ -300,7 +305,7 @@ echo " Package: ${PACKAGE_NAME} ${PACKAGE_VERSION}"
echo ""
echo " Configuration"
echo " XDM support.........: ${have_xdmcp}"
echo " sendmsg fd passing..: ${sendfds}"
echo " sendmsg fd passing..: ${have_sendmsg}"
echo " Build unit tests....: ${HAVE_CHECK}"
echo " with html results.: ${HTML_CHECK_RESULT}"
echo " XCB buffer size.....: ${xcb_queue_buffer_size}"
@ -308,9 +313,11 @@ echo ""
echo " X11 extensions"
echo " Composite...........: ${BUILD_COMPOSITE}"
echo " Damage..............: ${BUILD_DAMAGE}"
echo " Dbe.................: ${BUILD_DBE}"
echo " Dpms................: ${BUILD_DPMS}"
echo " Dri2................: ${BUILD_DRI2}"
echo " Dri3................: ${BUILD_DRI3}"
echo " GenericEvent........: ${BUILD_GE}"
echo " Glx.................: ${BUILD_GLX}"
echo " Randr...............: ${BUILD_RANDR}"
echo " Record..............: ${BUILD_RECORD}"
@ -335,7 +342,6 @@ echo ""
echo " Used CFLAGS:"
echo " CPPFLAGS............: ${CPPFLAGS}"
echo " CFLAGS..............: ${CFLAGS}"
echo " Warning CFLAGS......: ${BASE_CFLAGS}"
echo ""
echo " Installation:"
echo " Prefix..............: ${prefix}"

View File

@ -2297,9 +2297,7 @@ int main ()
values[0] = screen->white_pixel;
values[1] =
XCB_EVENT_MASK_KEY_RELEASE |
XCB_EVENT_MASK_BUTTON_PRESS |
XCB_EVENT_MASK_EXPOSURE |
XCB_EVENT_MASK_POINTER_MOTION;
XCB_EVENT_MASK_EXPOSURE;
cookie_window = xcb_create_window_checked (c,
screen->root_depth,
window, screen->root,

4
libxcb.wrap Normal file
View File

@ -0,0 +1,4 @@
[wrap-git]
url = https://gitea.gigo-games.dk/frederik/libxcb.git
revision = HEAD
depth = 1

View File

@ -38,15 +38,32 @@ dnl XCB_EXTENSION(name, default)
dnl set the X extension
dnl
AC_DEFUN([XCB_EXTENSION],
[
[dnl
pushdef([UP], translit([$1], [-a-z], [_A-Z]))dnl
pushdef([DOWN], translit([$1], [A-Z], [a-z]))dnl
dnl
m4_if([$2], [yes], [m4_define([xcb_defopt], [yes])],
[$2], [no], [m4_define([xcb_defopt], [no])],
m4_define([xcb_defopt], [auto]))dnl
AC_ARG_ENABLE(DOWN,
[AS_HELP_STRING([--enable-[]DOWN], [Build XCB $1 Extension (default: $2)])],
[AS_HELP_STRING([--enable-[]DOWN],
[Build XCB $1 Extension (default: ]xcb_defopt[)])],
[BUILD_[]UP=$enableval],
[BUILD_[]UP=$2])
[BUILD_[]UP=xcb_defopt])
dnl
m4_if(xcb_defopt, [auto], [
# This extension has a default value of "auto" and depends on the value of $2
if test "x$BUILD_[]UP" = "xauto" ; then
BUILD_[]UP=$2
fi
if test "x$BUILD_[]UP" = "xyes" ; then
if test "x$2" = "xno" ; then
AC_MSG_ERROR([Extension []UP requested, but dependencies are not met])
fi
fi])
m4_undefine([xcb_defopt])dnl
AM_CONDITIONAL(BUILD_[]UP, [test "x$BUILD_[]UP" = "xyes"])
])

View File

@ -36,7 +36,7 @@ void my_example(xcb_connection *conn) {
cookie = xcb_intern_atom(conn, 0, strlen("_NET_WM_NAME"), "_NET_WM_NAME");
/* ... do other work here if possible ... */
if ((reply = xcb_intern_atom_reply(conn, cookie, NULL))) {
printf("The _NET_WM_NAME atom has ID %u\n", reply->atom);
printf("The _NET_WM_NAME atom has ID %u\\n", reply->atom);
}
free(reply);
}
@ -118,7 +118,7 @@ void my_example(xcb_connection *conn, xcb_window_t window) {
cookie = xcb_intern_atom(c, 0, strlen("_NET_WM_NAME"), "_NET_WM_NAME");
/* ... do other work here if possible ... */
if ((reply = xcb_intern_atom_reply(c, cookie, &error))) {
printf("The _NET_WM_NAME atom has ID %u\n", reply->atom);
printf("The _NET_WM_NAME atom has ID %u\\n", reply->atom);
free(reply);
} else {
fprintf(stderr, "X11 Error %d\\n", error->error_code);
@ -138,7 +138,7 @@ void my_example(xcb_connection *conn, xcb_window_t window) {
"_NET_WM_NAME");
/* ... do other work here if possible ... */
if ((reply = xcb_intern_atom_reply(c, cookie, NULL))) {
printf("The _NET_WM_NAME atom has ID %u\n", reply->atom);
printf("The _NET_WM_NAME atom has ID %u\\n", reply->atom);
free(reply);
}

2
src/.gitignore vendored
View File

@ -1,9 +1,11 @@
bigreq.*
composite.*
damage.*
dbe.*
dpms.*
dri2.*
dri3.*
ge.*
glx.*
present.*
randr.*

View File

@ -40,6 +40,14 @@ libxcb_damage_la_LIBADD = $(XCB_LIBS)
nodist_libxcb_damage_la_SOURCES = damage.c damage.h
endif
EXTSOURCES += dbe.c
if BUILD_DBE
lib_LTLIBRARIES += libxcb-dbe.la
libxcb_dbe_la_LDFLAGS = -version-info 0:0:0 -no-undefined @lt_enable_auto_import@
libxcb_dbe_la_LIBADD = $(XCB_LIBS)
nodist_libxcb_dbe_la_SOURCES = dbe.c dbe.h
endif
EXTSOURCES += dpms.c
if BUILD_DPMS
lib_LTLIBRARIES += libxcb-dpms.la
@ -59,7 +67,7 @@ endif
EXTSOURCES += dri3.c
if BUILD_DRI3
lib_LTLIBRARIES += libxcb-dri3.la
libxcb_dri3_la_LDFLAGS = -version-info 0:0:0 -no-undefined @lt_enable_auto_import@
libxcb_dri3_la_LDFLAGS = -version-info 1:0:1 -no-undefined @lt_enable_auto_import@
libxcb_dri3_la_LIBADD = $(XCB_LIBS)
nodist_libxcb_dri3_la_SOURCES = dri3.c dri3.h
endif
@ -232,6 +240,13 @@ libxcb_xvmc_la_LIBADD = $(XCB_LIBS)
nodist_libxcb_xvmc_la_SOURCES = xvmc.c xvmc.h
endif
EXTSOURCES += ge.c
if BUILD_GE
lib_LTLIBRARIES += libxcb-ge.la
libxcb_ge_la_LDFLAGS = -version-info 0:0:0 -no-undefined @lt_enable_auto_import@
libxcb_ge_la_LIBADD = $(XCB_LIBS)
nodist_libxcb_ge_la_SOURCES = ge.c ge.h
endif
EXTHEADERS=$(EXTSOURCES:.c=.h)
xcbinclude_HEADERS = xcb.h xcbext.h
@ -248,9 +263,15 @@ libman_DATA = $(BUILT_MAN_PAGES)
BUILT_SOURCES = $(EXTSOURCES) $(BUILT_MAN_PAGES)
CLEANFILES = $(EXTSOURCES) $(EXTHEADERS) $(BUILT_MAN_PAGES)
C_CLIENT_PY_EXTRA_ARGS =
if XCB_SERVERSIDE_SUPPORT
C_CLIENT_PY_EXTRA_ARGS += --server-side
endif
$(EXTSOURCES): c_client.py $(XCBPROTO_XCBINCLUDEDIR)/$(@:.c=.xml)
$(AM_V_GEN)$(PYTHON) $(srcdir)/c_client.py -c "$(PACKAGE_STRING)" -l "$(XORG_MAN_PAGE)" \
-s "$(LIB_MAN_SUFFIX)" -p $(XCBPROTO_XCBPYTHONDIR) \
$(C_CLIENT_PY_EXTRA_ARGS) \
$(XCBPROTO_XCBINCLUDEDIR)/$(@:.c=.xml)
$(BUILT_MAN_PAGES): $(EXTSOURCES)

File diff suppressed because it is too large Load Diff

158
src/xcb.h
View File

@ -29,11 +29,7 @@
#define __XCB_H__
#include <sys/types.h>
#if defined(__solaris__)
#include <inttypes.h>
#else
#include <stdint.h>
#endif
#ifndef _WIN32
#include <sys/uio.h>
@ -51,7 +47,35 @@ extern "C" {
* @file xcb.h
*/
#ifndef __has_attribute
# define __has_attribute(x) 0 /* Compatibility with older compilers. */
#endif
/*
* For the below checks, we currently assume that __GNUC__ indicates
* gcc 3.0 (released 2001) or later, as we require support for C99.
*/
/* Supported in gcc 2.5 and later */
#if defined(__GNUC__) || __has_attribute(__const__)
#define XCB_CONST_FUNCTION __attribute__((__const__))
#else
#define XCB_CONST_FUNCTION XCB_PURE_FUNCTION
#endif
/* Supported in gcc 2.7 and later */
#if defined(__GNUC__) || __has_attribute(__packed__)
#define XCB_PACKED __attribute__((__packed__))
#else
#define XCB_PACKED
#endif
/* Supported in gcc 2.96 and later */
#if defined(__GNUC__) || __has_attribute(__pure__)
#define XCB_PURE_FUNCTION __attribute__((__pure__))
#else
#define XCB_PURE_FUNCTION
#endif
/**
* @defgroup XCB_Core_API XCB Core API
@ -142,6 +166,18 @@ typedef struct {
uint32_t full_sequence; /**< full sequence */
} xcb_generic_event_t;
/**
* @brief Raw Generic event.
*
* A generic event structure as used on the wire, i.e., without the full_sequence field
*/
typedef struct {
uint8_t response_type; /**< Type of the response */
uint8_t pad0; /**< Padding */
uint16_t sequence; /**< Sequence number */
uint32_t pad[7]; /**< Padding */
} xcb_raw_generic_event_t;
/**
* @brief GE event
*
@ -225,7 +261,7 @@ typedef struct xcb_auth_info_t {
/**
* @brief Forces any buffered output to be written to the server.
* @param c: The connection to the X server.
* @param c The connection to the X server.
* @return > @c 0 on success, <= @c 0 otherwise.
*
* Forces any buffered output to be written to the server. Blocks
@ -235,7 +271,7 @@ int xcb_flush(xcb_connection_t *c);
/**
* @brief Returns the maximum request length that this server accepts.
* @param c: The connection to the X server.
* @param c The connection to the X server.
* @return The maximum request length field.
*
* In the absence of the BIG-REQUESTS extension, returns the
@ -252,7 +288,7 @@ uint32_t xcb_get_maximum_request_length(xcb_connection_t *c);
/**
* @brief Prefetch the maximum request length without blocking.
* @param c: The connection to the X server.
* @param c The connection to the X server.
*
* Without blocking, does as much work as possible toward computing
* the maximum request length accepted by the X server.
@ -274,7 +310,7 @@ void xcb_prefetch_maximum_request_length(xcb_connection_t *c);
/**
* @brief Returns the next event or error from the server.
* @param c: The connection to the X server.
* @param c The connection to the X server.
* @return The next event from the server.
*
* Returns the next event or error from the server, or returns null in
@ -285,7 +321,7 @@ xcb_generic_event_t *xcb_wait_for_event(xcb_connection_t *c);
/**
* @brief Returns the next event or error from the server.
* @param c: The connection to the X server.
* @param c The connection to the X server.
* @return The next event from the server.
*
* Returns the next event or error from the server, if one is
@ -298,7 +334,7 @@ xcb_generic_event_t *xcb_poll_for_event(xcb_connection_t *c);
/**
* @brief Returns the next event without reading from the connection.
* @param c: The connection to the X server.
* @param c The connection to the X server.
* @return The next already queued event from the server.
*
* This is a version of xcb_poll_for_event that only examines the
@ -346,8 +382,8 @@ void xcb_unregister_for_special_event(xcb_connection_t *c,
/**
* @brief Return the error for a request, or NULL if none can ever arrive.
* @param c: The connection to the X server.
* @param cookie: The request cookie.
* @param c The connection to the X server.
* @param cookie The request cookie.
* @return The error for the request, or NULL if none can ever arrive.
*
* The xcb_void_cookie_t cookie supplied to this function must have resulted
@ -364,8 +400,8 @@ xcb_generic_error_t *xcb_request_check(xcb_connection_t *c, xcb_void_cookie_t co
/**
* @brief Discards the reply for a request.
* @param c: The connection to the X server.
* @param sequence: The request sequence number from a cookie.
* @param c The connection to the X server.
* @param sequence The request sequence number from a cookie.
*
* Discards the reply for a request. Additionally, any error generated
* by the request is also discarded (unless it was an _unchecked request
@ -378,13 +414,33 @@ xcb_generic_error_t *xcb_request_check(xcb_connection_t *c, xcb_void_cookie_t co
*/
void xcb_discard_reply(xcb_connection_t *c, unsigned int sequence);
/**
* @brief Discards the reply for a request, given by a 64bit sequence number
* @param c The connection to the X server.
* @param sequence 64-bit sequence number as returned by xcb_send_request64().
*
* Discards the reply for a request. Additionally, any error generated
* by the request is also discarded (unless it was an _unchecked request
* and the error has already arrived).
*
* This function will not block even if the reply is not yet available.
*
* Note that the sequence really does have to come from xcb_send_request64();
* the cookie sequence number is defined as "unsigned" int and therefore
* not 64-bit on all platforms.
* This function is not designed to operate on socket-handoff replies.
*
* Unlike its xcb_discard_reply() counterpart, the given sequence number is not
* automatically "widened" to 64-bit.
*/
void xcb_discard_reply64(xcb_connection_t *c, uint64_t sequence);
/* xcb_ext.c */
/**
* @brief Caches reply information from QueryExtension requests.
* @param c: The connection.
* @param ext: The extension data.
* @param c The connection.
* @param ext The extension data.
* @return A pointer to the xcb_query_extension_reply_t for the extension.
*
* This function is the primary interface to the "extension cache",
@ -401,8 +457,8 @@ const struct xcb_query_extension_reply_t *xcb_get_extension_data(xcb_connection_
/**
* @brief Prefetch of extension data into the extension cache
* @param c: The connection.
* @param ext: The extension data.
* @param c The connection.
* @param ext The extension data.
*
* This function allows a "prefetch" of extension data into the
* extension cache. Invoking the function may cause a call to
@ -417,7 +473,7 @@ void xcb_prefetch_extension_data(xcb_connection_t *c, xcb_extension_t *ext);
/**
* @brief Access the data returned by the server.
* @param c: The connection.
* @param c The connection.
* @return A pointer to an xcb_setup_t structure.
*
* Accessor for the data returned by the server when the xcb_connection_t
@ -433,21 +489,23 @@ void xcb_prefetch_extension_data(xcb_connection_t *c, xcb_extension_t *ext);
*
* The result must not be freed.
*/
XCB_PURE_FUNCTION
const struct xcb_setup_t *xcb_get_setup(xcb_connection_t *c);
/**
* @brief Access the file descriptor of the connection.
* @param c: The connection.
* @param c The connection.
* @return The file descriptor.
*
* Accessor for the file descriptor that was passed to the
* xcb_connect_to_fd call that returned @p c.
*/
XCB_PURE_FUNCTION
int xcb_get_file_descriptor(xcb_connection_t *c);
/**
* @brief Test whether the connection has shut down due to a fatal error.
* @param c: The connection.
* @param c The connection.
* @return > 0 if the connection is in an error state; 0 otherwise.
*
* Some errors that occur in the context of an xcb_connection_t
@ -463,12 +521,13 @@ int xcb_get_file_descriptor(xcb_connection_t *c);
* @return XCB_CONN_CLOSED_PARSE_ERR, error during parsing display string.
* @return XCB_CONN_CLOSED_INVALID_SCREEN, because the server does not have a screen matching the display.
*/
XCB_PURE_FUNCTION
int xcb_connection_has_error(xcb_connection_t *c);
/**
* @brief Connects to the X server.
* @param fd: The file descriptor.
* @param auth_info: Authentication data.
* @param fd The file descriptor.
* @param auth_info Authentication data.
* @return A newly allocated xcb_connection_t structure.
*
* Connects to an X server, given the open socket @p fd and the
@ -486,7 +545,7 @@ xcb_connection_t *xcb_connect_to_fd(int fd, xcb_auth_info_t *auth_info);
/**
* @brief Closes the connection.
* @param c: The connection.
* @param c The connection.
*
* Closes the file descriptor and frees all memory associated with the
* connection @c c. If @p c is @c NULL, nothing is done.
@ -498,10 +557,10 @@ void xcb_disconnect(xcb_connection_t *c);
/**
* @brief Parses a display string name in the form documented by X(7x).
* @param name: The name of the display.
* @param host: A pointer to a malloc'd copy of the hostname.
* @param display: A pointer to the display number.
* @param screen: A pointer to the screen number.
* @param name The name of the display.
* @param host A pointer to a malloc'd copy of the hostname.
* @param display A pointer to the display number.
* @param screen A pointer to the screen number.
* @return 0 on failure, non 0 otherwise.
*
* Parses the display string name @p display_name in the form
@ -517,8 +576,8 @@ int xcb_parse_display(const char *name, char **host, int *display, int *screen);
/**
* @brief Connects to the X server.
* @param displayname: The name of the display.
* @param screenp: A pointer to a preferred screen number.
* @param displayname The name of the display.
* @param screenp A pointer to a preferred screen number.
* @return A newly allocated xcb_connection_t structure.
*
* Connects to the X server specified by @p displayname. If @p
@ -536,9 +595,9 @@ xcb_connection_t *xcb_connect(const char *displayname, int *screenp);
/**
* @brief Connects to the X server, using an authorization information.
* @param display: The name of the display.
* @param auth: The authorization information.
* @param screen: A pointer to a preferred screen number.
* @param display The name of the display.
* @param auth The authorization information.
* @param screen A pointer to a preferred screen number.
* @return A newly allocated xcb_connection_t structure.
*
* Connects to the X server specified by @p displayname, using the
@ -558,8 +617,8 @@ xcb_connection_t *xcb_connect_to_display_with_auth_info(const char *display, xcb
/**
* @brief Allocates an XID for a new object.
* @param c: The connection.
* @return A newly allocated XID.
* @param c The connection.
* @return A newly allocated XID, or -1 on failure.
*
* Allocates an XID for a new object. Typically used just prior to
* various object creation functions, such as xcb_create_window.
@ -567,6 +626,35 @@ xcb_connection_t *xcb_connect_to_display_with_auth_info(const char *display, xcb
uint32_t xcb_generate_id(xcb_connection_t *c);
/**
* @brief Obtain number of bytes read from the connection.
* @param c The connection
* @return Number of bytes read from the server.
*
* Returns cumulative number of bytes received from the connection.
*
* This retrieves the total number of bytes read from this connection,
* to be used for diagnostic/monitoring/informative purposes.
*/
uint64_t
xcb_total_read(xcb_connection_t *c);
/**
*
* @brief Obtain number of bytes written to the connection.
* @param c The connection
* @return Number of bytes written to the server.
*
* Returns cumulative number of bytes sent to the connection.
*
* This retrieves the total number of bytes written to this connection,
* to be used for diagnostic/monitoring/informative purposes.
*/
uint64_t
xcb_total_written(xcb_connection_t *c);
/**
* @}
*/

View File

@ -31,9 +31,8 @@
#include <assert.h>
#include <X11/Xauth.h>
#include <sys/param.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>
#ifdef __INTERIX
/* _don't_ ask. interix has INADDR_LOOPBACK in here. */
@ -48,6 +47,8 @@
#endif
#include "xcb_windefs.h"
#else
#include <sys/param.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>
@ -72,7 +73,7 @@ enum auth_protos {
#define AUTH_PROTO_XDM_AUTHORIZATION "XDM-AUTHORIZATION-1"
#define AUTH_PROTO_MIT_MAGIC_COOKIE "MIT-MAGIC-COOKIE-1"
static char *authnames[N_AUTH_PROTOS] = {
static const char *authnames[N_AUTH_PROTOS] = {
#ifdef HASXDMAUTH
AUTH_PROTO_XDM_AUTHORIZATION,
#endif
@ -133,6 +134,7 @@ static Xauth *get_authptr(struct sockaddr *sockname, int display)
}
addr += 12;
/* if v4-mapped, fall through. */
XCB_ALLOW_FALLTHRU
#endif
case AF_INET:
if(!addr)
@ -163,7 +165,7 @@ static Xauth *get_authptr(struct sockaddr *sockname, int display)
return XauGetBestAuthByAddr (family,
(unsigned short) addrlen, addr,
(unsigned short) dispbuflen, dispbuf,
N_AUTH_PROTOS, authnames, authnameslen);
N_AUTH_PROTOS, (char **)authnames, authnameslen);
}
#ifdef HASXDMAUTH
@ -269,10 +271,17 @@ static int compute_auth(xcb_auth_info_t *info, Xauth *authptr, struct sockaddr *
to the value returned by either getpeername() or getsockname()
(according to POSIX, applications should not assume a particular
length for `sockaddr_un.sun_path') */
#ifdef _WIN32
static struct sockaddr *get_peer_sock_name(int(_stdcall *socket_func)(SOCKET,
struct sockaddr *,
socklen_t *),
int fd)
#else
static struct sockaddr *get_peer_sock_name(int (*socket_func)(int,
struct sockaddr *,
socklen_t *),
int fd)
#endif
{
socklen_t socknamelen = sizeof(struct sockaddr) + INITIAL_SOCKNAME_SLACK;
socklen_t actual_socknamelen = socknamelen;

View File

@ -32,7 +32,6 @@
#include <assert.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>
@ -48,7 +47,9 @@
#ifdef _WIN32
#include "xcb_windefs.h"
#include <io.h>
#else
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#endif /* _WIN32 */
@ -64,6 +65,26 @@ typedef struct {
uint16_t length;
} xcb_setup_generic_t;
static const xcb_setup_t xcb_error_setup = {
0, /* status: failed (but we wouldn't have a xcb_setup_t in this case) */
0, /* pad0 */
0, 0, /* protocol version, should be 11.0, but isn't */
0, /* length, invalid value */
0, /* release_number */
0, 0, /* resource_id_{base,mask} */
0, /* motion_buffer_size */
0, /* vendor_len */
0, /* maximum_request_length */
0, /* roots_len */
0, /* pixmap_formats_len */
0, /* image_byte_order */
0, /* bitmap_format_bit_order */
0, /* bitmap_format_scanline_unit */
0, /* bitmap_format_scanline_pad */
0, 0, /* {min,max}_keycode */
{ 0, 0, 0, 0 } /* pad1 */
};
/* Keep this list in sync with is_static_error_conn()! */
static const int xcb_con_error = XCB_CONN_ERROR;
static const int xcb_con_closed_mem_er = XCB_CONN_CLOSED_MEM_INSUFFICIENT;
@ -149,6 +170,8 @@ static int write_setup(xcb_connection_t *c, xcb_auth_info_t *auth_info)
static int read_setup(xcb_connection_t *c)
{
const char newline = '\n';
/* Read the server response */
c->setup = malloc(sizeof(xcb_setup_generic_t));
if(!c->setup)
@ -174,6 +197,7 @@ static int read_setup(xcb_connection_t *c)
{
xcb_setup_failed_t *setup = (xcb_setup_failed_t *) c->setup;
write(STDERR_FILENO, xcb_setup_failed_reason(setup), xcb_setup_failed_reason_length(setup));
write(STDERR_FILENO, &newline, 1);
return 0;
}
@ -181,6 +205,7 @@ static int read_setup(xcb_connection_t *c)
{
xcb_setup_authenticate_t *setup = (xcb_setup_authenticate_t *) c->setup;
write(STDERR_FILENO, xcb_setup_authenticate_reason(setup), xcb_setup_authenticate_reason_length(setup));
write(STDERR_FILENO, &newline, 1);
return 0;
}
}
@ -191,33 +216,47 @@ static int read_setup(xcb_connection_t *c)
/* precondition: there must be something for us to write. */
static int write_vec(xcb_connection_t *c, struct iovec **vector, int *count)
{
#ifndef _WIN32
int n;
#endif
assert(!c->out.queue_len);
#ifdef _WIN32
int i = 0;
int ret = 0,err = 0;
struct iovec *vec;
n = 0;
/* Could use the WSASend win32 function for scatter/gather i/o but setting up the WSABUF struct from
an iovec would require more work and I'm not sure of the benefit....works for now */
vec = *vector;
while(i < *count)
while (*count)
{
ret = send(c->fd,vec->iov_base,vec->iov_len,0);
if(ret == SOCKET_ERROR)
{
err = WSAGetLastError();
if(err == WSAEWOULDBLOCK)
{
return 1;
}
}
n += ret;
*vec++;
i++;
struct iovec *vec = *vector;
if (vec->iov_len)
{
int ret = send(c->fd, vec->iov_base, vec->iov_len, 0);
if (ret == SOCKET_ERROR)
{
int err = WSAGetLastError();
if (err == WSAEWOULDBLOCK)
{
return 1;
}
}
if (ret <= 0)
{
_xcb_conn_shutdown(c, XCB_CONN_ERROR);
return 0;
}
c->out.total_written += ret;
vec->iov_len -= ret;
vec->iov_base = (char *)vec->iov_base + ret;
}
if (vec->iov_len == 0) {
(*vector)++;
(*count)--;
}
}
if (!*count)
*vector = 0;
#else
n = *count;
if (n > IOV_MAX)
@ -259,28 +298,32 @@ static int write_vec(xcb_connection_t *c, struct iovec **vector, int *count)
return 1;
}
#endif /* _WIN32 */
if(n <= 0)
{
_xcb_conn_shutdown(c, XCB_CONN_ERROR);
return 0;
}
c->out.total_written += n;
for(; *count; --*count, ++*vector)
{
int cur = (*vector)->iov_len;
if(cur > n)
cur = n;
(*vector)->iov_len -= cur;
(*vector)->iov_base = (char *) (*vector)->iov_base + cur;
n -= cur;
if(cur) {
(*vector)->iov_len -= cur;
(*vector)->iov_base = (char *) (*vector)->iov_base + cur;
n -= cur;
}
if((*vector)->iov_len)
break;
}
if(!*count)
*vector = 0;
assert(n == 0);
#endif /* _WIN32 */
return 1;
}
@ -288,15 +331,15 @@ static int write_vec(xcb_connection_t *c, struct iovec **vector, int *count)
const xcb_setup_t *xcb_get_setup(xcb_connection_t *c)
{
if(c->has_error)
return 0;
if(is_static_error_conn(c))
return &xcb_error_setup;
/* doesn't need locking because it's never written to. */
return c->setup;
}
int xcb_get_file_descriptor(xcb_connection_t *c)
{
if(c->has_error)
if(is_static_error_conn(c))
return -1;
/* doesn't need locking because it's never written to. */
return c->fd;
@ -324,7 +367,11 @@ xcb_connection_t *xcb_connect_to_fd(int fd, xcb_auth_info_t *auth_info)
c = calloc(1, sizeof(xcb_connection_t));
if(!c) {
#ifdef _WIN32
closesocket(fd);
#else
close(fd);
#endif
return _xcb_conn_ret_error(XCB_CONN_CLOSED_MEM_INSUFFICIENT) ;
}
@ -357,7 +404,11 @@ void xcb_disconnect(xcb_connection_t *c)
/* disallow further sends and receives */
shutdown(c->fd, SHUT_RDWR);
#ifdef _WIN32
closesocket(c->fd);
#else
close(c->fd);
#endif
pthread_mutex_destroy(&c->iolock);
_xcb_in_destroy(&c->in);
@ -508,3 +559,30 @@ int _xcb_conn_wait(xcb_connection_t *c, pthread_cond_t *cond, struct iovec **vec
return ret;
}
uint64_t xcb_total_read(xcb_connection_t *c)
{
uint64_t n;
if (xcb_connection_has_error(c))
return 0;
pthread_mutex_lock(&c->iolock);
n = c->in.total_read;
pthread_mutex_unlock(&c->iolock);
return n;
}
uint64_t xcb_total_written(xcb_connection_t *c)
{
uint64_t n;
if (xcb_connection_has_error(c))
return 0;
pthread_mutex_lock(&c->iolock);
n = c->out.total_written;
pthread_mutex_unlock(&c->iolock);
return n;
}

View File

@ -32,7 +32,6 @@
#include <assert.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
@ -40,6 +39,7 @@
#include <poll.h>
#endif
#ifndef _WIN32
#include <unistd.h>
#include <sys/select.h>
#include <sys/socket.h>
#endif
@ -97,6 +97,11 @@ typedef struct reader_list {
struct reader_list *next;
} reader_list;
typedef struct special_list {
xcb_special_event_t *se;
struct special_list *next;
} special_list;
static void remove_finished_readers(reader_list **prev_reader, uint64_t completed)
{
while(*prev_reader && XCB_SEQUENCE_COMPARE((*prev_reader)->request, <=, completed))
@ -234,9 +239,15 @@ static int read_packet(xcb_connection_t *c)
if(pend && pend->workaround == WORKAROUND_GLX_GET_FB_CONFIGS_BUG)
{
uint32_t *p = (uint32_t *) c->in.queue;
genrep.length = p[2] * p[3] * 2;
uint64_t new_length = ((uint64_t)p[2]) * ((uint64_t)p[3]);
if(new_length >= (UINT32_MAX / UINT32_C(16)))
{
_xcb_conn_shutdown(c, XCB_CONN_CLOSED_MEM_INSUFFICIENT);
return 0;
}
genrep.length = (uint32_t)(new_length * UINT64_C(2));
}
length += genrep.length * 4;
length += genrep.length * UINT64_C(4);
/* XXX a bit of a hack -- we "know" that all FD replys place
* the number of fds in the pad0 byte */
@ -246,7 +257,7 @@ static int read_packet(xcb_connection_t *c)
/* XGE events may have sizes > 32 */
if ((genrep.response_type & 0x7f) == XCB_XGE_EVENT)
eventlength = genrep.length * 4;
eventlength = genrep.length * UINT64_C(4);
bufsize = length + eventlength + nfd * sizeof(int) +
(genrep.response_type == XCB_REPLY ? 0 : sizeof(uint32_t));
@ -360,7 +371,7 @@ static void free_reply_list(struct reply_list *head)
}
}
static int read_block(const int fd, void *buf, const ssize_t len)
static int read_block(const int fd, void *buf, const intptr_t len)
{
int done = 0;
while(done < len)
@ -475,6 +486,26 @@ static void remove_reader(reader_list **prev_reader, reader_list *reader)
}
}
static void insert_special(special_list **prev_special, special_list *special, xcb_special_event_t *se)
{
special->se = se;
special->next = *prev_special;
*prev_special = special;
}
static void remove_special(special_list **prev_special, special_list *special)
{
while(*prev_special)
{
if(*prev_special == special)
{
*prev_special = (*prev_special)->next;
break;
}
prev_special = &(*prev_special)->next;
}
}
static void *wait_for_reply(xcb_connection_t *c, uint64_t request, xcb_generic_error_t **e)
{
void *ret = 0;
@ -523,6 +554,20 @@ void *xcb_wait_for_reply(xcb_connection_t *c, unsigned int request, xcb_generic_
return ret;
}
void *xcb_wait_for_reply64(xcb_connection_t *c, uint64_t request, xcb_generic_error_t **e)
{
void *ret;
if(e)
*e = 0;
if(c->has_error)
return 0;
pthread_mutex_lock(&c->iolock);
ret = wait_for_reply(c, request, e);
pthread_mutex_unlock(&c->iolock);
return ret;
}
int *xcb_get_reply_fds(xcb_connection_t *c, void *reply, size_t reply_size)
{
return (int *) (&((char *) reply)[reply_size]);
@ -595,6 +640,20 @@ void xcb_discard_reply(xcb_connection_t *c, unsigned int sequence)
pthread_mutex_unlock(&c->iolock);
}
void xcb_discard_reply64(xcb_connection_t *c, uint64_t sequence)
{
if(c->has_error)
return;
/* If an error occurred when issuing the request, fail immediately. */
if(!sequence)
return;
pthread_mutex_lock(&c->iolock);
discard_reply(c, sequence);
pthread_mutex_unlock(&c->iolock);
}
int xcb_poll_for_reply(xcb_connection_t *c, unsigned int request, void **reply, xcb_generic_error_t **error)
{
int ret;
@ -608,6 +667,27 @@ int xcb_poll_for_reply(xcb_connection_t *c, unsigned int request, void **reply,
assert(reply != 0);
pthread_mutex_lock(&c->iolock);
ret = poll_for_reply(c, widen(c, request), reply, error);
if(!ret && c->in.reading == 0 && _xcb_in_read(c)) /* _xcb_in_read shuts down the connection on error */
ret = poll_for_reply(c, widen(c, request), reply, error);
pthread_mutex_unlock(&c->iolock);
return ret;
}
int xcb_poll_for_reply64(xcb_connection_t *c, uint64_t request, void **reply, xcb_generic_error_t **error)
{
int ret;
if(c->has_error)
{
*reply = 0;
if(error)
*error = 0;
return 1; /* would not block */
}
assert(reply != 0);
pthread_mutex_lock(&c->iolock);
ret = poll_for_reply(c, request, reply, error);
if(!ret && c->in.reading == 0 && _xcb_in_read(c)) /* _xcb_in_read shuts down the connection on error */
ret = poll_for_reply(c, request, reply, error);
pthread_mutex_unlock(&c->iolock);
return ret;
}
@ -662,11 +742,16 @@ xcb_generic_error_t *xcb_request_check(xcb_connection_t *c, xcb_void_cookie_t co
return 0;
pthread_mutex_lock(&c->iolock);
request = widen(c, cookie.sequence);
if(XCB_SEQUENCE_COMPARE(request, >=, c->in.request_expected)
&& XCB_SEQUENCE_COMPARE(request, >, c->in.request_completed))
if (XCB_SEQUENCE_COMPARE(request, >, c->in.request_completed))
{
_xcb_out_send_sync(c);
_xcb_out_flush_to(c, c->out.request);
if(XCB_SEQUENCE_COMPARE(request, >=, c->in.request_expected))
{
_xcb_out_send_sync(c);
}
if (XCB_SEQUENCE_COMPARE(request, >=, c->out.request_expected_written))
{
_xcb_out_flush_to(c, c->out.request);
}
}
reply = wait_for_reply(c, request, &ret);
assert(!reply);
@ -698,6 +783,8 @@ xcb_generic_event_t *xcb_poll_for_special_event(xcb_connection_t *c,
return 0;
pthread_mutex_lock(&c->iolock);
event = get_special_event(c, se);
if(!event && c->in.reading == 0 && _xcb_in_read(c)) /* _xcb_in_read shuts down the connection on error */
event = get_special_event(c, se);
pthread_mutex_unlock(&c->iolock);
return event;
}
@ -705,17 +792,23 @@ xcb_generic_event_t *xcb_poll_for_special_event(xcb_connection_t *c,
xcb_generic_event_t *xcb_wait_for_special_event(xcb_connection_t *c,
xcb_special_event_t *se)
{
special_list special;
xcb_generic_event_t *event;
if(c->has_error)
return 0;
pthread_mutex_lock(&c->iolock);
insert_special(&c->in.special_waiters, &special, se);
/* get_special_event returns 0 on empty list. */
while(!(event = get_special_event(c, se)))
if(!_xcb_conn_wait(c, &se->special_event_cond, 0, 0))
break;
remove_special(&c->in.special_waiters, &special);
_xcb_in_wake_up_next_reader(c);
pthread_mutex_unlock(&c->iolock);
return event;
}
@ -843,6 +936,8 @@ void _xcb_in_wake_up_next_reader(xcb_connection_t *c)
int pthreadret;
if(c->in.readers)
pthreadret = pthread_cond_signal(c->in.readers->data);
else if(c->in.special_waiters)
pthreadret = pthread_cond_signal(&c->in.special_waiters->se->special_event_cond);
else
pthreadret = pthread_cond_signal(&c->in.event_cond);
assert(pthreadret == 0);
@ -874,8 +969,20 @@ void _xcb_in_replies_done(xcb_connection_t *c)
pend = container_of(c->in.pending_replies_tail, struct pending_reply, next);
if(pend->workaround == WORKAROUND_EXTERNAL_SOCKET_OWNER)
{
pend->last_request = c->out.request;
pend->workaround = WORKAROUND_NONE;
if (XCB_SEQUENCE_COMPARE(pend->first_request, <=, c->out.request)) {
pend->last_request = c->out.request;
pend->workaround = WORKAROUND_NONE;
} else {
/* The socket was taken, but no requests were actually sent
* so just discard the pending_reply that was created.
*/
struct pending_reply **prev_next = &c->in.pending_replies;
while (*prev_next != pend)
prev_next = &(*prev_next)->next;
*prev_next = NULL;
c->in.pending_replies_tail = prev_next;
free(pend);
}
}
}
}
@ -929,6 +1036,7 @@ int _xcb_in_read(xcb_connection_t *c)
}
}
#endif
c->in.total_read += n;
c->in.queue_len += n;
}
while(read_packet(c))
@ -955,7 +1063,7 @@ int _xcb_in_read(xcb_connection_t *c)
}
#endif
#ifndef _WIN32
if((n > 0) || (n < 0 && errno == EAGAIN))
if((n > 0) || (n < 0 && (errno == EAGAIN || errno == EINTR)))
#else
if((n > 0) || (n < 0 && WSAGetLastError() == WSAEWOULDBLOCK))
#endif /* !_WIN32 */

View File

@ -36,7 +36,7 @@
typedef struct node {
struct node *next;
unsigned int key;
uint64_t key;
void *data;
} node;
@ -73,7 +73,7 @@ void _xcb_map_delete(_xcb_map *list, xcb_list_free_func_t do_free)
free(list);
}
int _xcb_map_put(_xcb_map *list, unsigned int key, void *data)
int _xcb_map_put(_xcb_map *list, uint64_t key, void *data)
{
node *cur = malloc(sizeof(node));
if(!cur)
@ -86,7 +86,7 @@ int _xcb_map_put(_xcb_map *list, unsigned int key, void *data)
return 1;
}
void *_xcb_map_remove(_xcb_map *list, unsigned int key)
void *_xcb_map_remove(_xcb_map *list, uint64_t key)
{
node **cur;
for(cur = &list->head; *cur; cur = &(*cur)->next)

View File

@ -31,7 +31,11 @@
#include <assert.h>
#include <stdlib.h>
#ifdef _WIN32
#include <io.h>
#else
#include <unistd.h>
#endif
#include <string.h>
#include "xcb.h"
@ -177,15 +181,59 @@ uint32_t xcb_get_maximum_request_length(xcb_connection_t *c)
return c->out.maximum_request_length.value;
}
unsigned int xcb_send_request(xcb_connection_t *c, int flags, struct iovec *vector, const xcb_protocol_request_t *req)
static void close_fds(int *fds, unsigned int num_fds)
{
for (unsigned int index = 0; index < num_fds; index++)
close(fds[index]);
}
static void send_fds(xcb_connection_t *c, int *fds, unsigned int num_fds)
{
#if HAVE_SENDMSG
/* Calling _xcb_out_flush_to() can drop the iolock and wait on a condition
* variable if another thread is currently writing (c->out.writing > 0).
* This call waits for writers to be done and thus _xcb_out_flush_to() will
* do the work itself (in which case we are a writer and
* prepare_socket_request() will wait for us to be done if another threads
* tries to send fds, too). Thanks to this, we can atomically write out FDs.
*/
prepare_socket_request(c);
while (num_fds > 0) {
while (c->out.out_fd.nfd == XCB_MAX_PASS_FD && !c->has_error) {
/* XXX: if c->out.writing > 0, this releases the iolock and
* potentially allows other threads to interfere with their own fds.
*/
_xcb_out_flush_to(c, c->out.request);
if (c->out.out_fd.nfd == XCB_MAX_PASS_FD) {
/* We need some request to send FDs with */
_xcb_out_send_sync(c);
}
}
if (c->has_error)
break;
c->out.out_fd.fd[c->out.out_fd.nfd++] = fds[0];
fds++;
num_fds--;
}
#endif
close_fds(fds, num_fds);
}
uint64_t xcb_send_request_with_fds64(xcb_connection_t *c, int flags, struct iovec *vector,
const xcb_protocol_request_t *req, unsigned int num_fds, int *fds)
{
uint64_t request;
uint32_t prefix[2];
int veclen = req->count;
enum workarounds workaround = WORKAROUND_NONE;
if(c->has_error)
if(c->has_error) {
close_fds(fds, num_fds);
return 0;
}
assert(c != 0);
assert(vector != 0);
@ -204,6 +252,7 @@ unsigned int xcb_send_request(xcb_connection_t *c, int flags, struct iovec *vect
const xcb_query_extension_reply_t *extension = xcb_get_extension_data(c, req->ext);
if(!(extension && extension->present))
{
close_fds(fds, num_fds);
_xcb_conn_shutdown(c, XCB_CONN_CLOSED_EXT_NOTSUPPORTED);
return 0;
}
@ -234,6 +283,7 @@ unsigned int xcb_send_request(xcb_connection_t *c, int flags, struct iovec *vect
}
else if(longlen > xcb_get_maximum_request_length(c))
{
close_fds(fds, num_fds);
_xcb_conn_shutdown(c, XCB_CONN_CLOSED_REQ_LEN_EXCEED);
return 0; /* server can't take this; maybe need BIGREQUESTS? */
}
@ -264,6 +314,11 @@ unsigned int xcb_send_request(xcb_connection_t *c, int flags, struct iovec *vect
/* get a sequence number and arrange for delivery. */
pthread_mutex_lock(&c->iolock);
/* send FDs before establishing a good request number, because this might
* call send_sync(), too
*/
send_fds(c, fds, num_fds);
prepare_socket_request(c);
/* send GetInputFocus (sync_req) when 64k-2 requests have been sent without
@ -272,7 +327,7 @@ unsigned int xcb_send_request(xcb_connection_t *c, int flags, struct iovec *vect
* applications see sequence 0 as that is used to indicate
* an error in sending the request
*/
while ((req->isvoid && c->out.request == c->in.request_expected + (1 << 16) - 2) ||
(unsigned int) (c->out.request + 1) == 0)
{
@ -286,22 +341,36 @@ unsigned int xcb_send_request(xcb_connection_t *c, int flags, struct iovec *vect
return request;
}
/* request number are actually uint64_t internally but keep API compat with unsigned int */
unsigned int xcb_send_request_with_fds(xcb_connection_t *c, int flags, struct iovec *vector,
const xcb_protocol_request_t *req, unsigned int num_fds, int *fds)
{
return xcb_send_request_with_fds64(c, flags, vector, req, num_fds, fds);
}
uint64_t xcb_send_request64(xcb_connection_t *c, int flags, struct iovec *vector, const xcb_protocol_request_t *req)
{
return xcb_send_request_with_fds64(c, flags, vector, req, 0, NULL);
}
/* request number are actually uint64_t internally but keep API compat with unsigned int */
unsigned int xcb_send_request(xcb_connection_t *c, int flags, struct iovec *vector, const xcb_protocol_request_t *req)
{
return xcb_send_request64(c, flags, vector, req);
}
void
xcb_send_fd(xcb_connection_t *c, int fd)
{
#if HAVE_SENDMSG
if (c->has_error)
int fds[1] = { fd };
if (c->has_error) {
close(fd);
return;
pthread_mutex_lock(&c->iolock);
while (c->out.out_fd.nfd == XCB_MAX_PASS_FD) {
_xcb_out_flush_to(c, c->out.request);
if (c->has_error)
break;
}
if (!c->has_error)
c->out.out_fd.fd[c->out.out_fd.nfd++] = fd;
pthread_mutex_lock(&c->iolock);
send_fds(c, &fds[0], 1);
pthread_mutex_unlock(&c->iolock);
#endif
}
int xcb_take_socket(xcb_connection_t *c, void (*return_socket)(void *closure), void *closure, int flags, uint64_t *sent)
@ -322,8 +391,14 @@ int xcb_take_socket(xcb_connection_t *c, void (*return_socket)(void *closure), v
{
c->out.return_socket = return_socket;
c->out.socket_closure = closure;
if(flags)
_xcb_in_expect_reply(c, c->out.request, WORKAROUND_EXTERNAL_SOCKET_OWNER, flags);
if(flags) {
/* c->out.request + 1 will be the first request sent by the external
* socket owner. If the socket is returned before this request is sent
* it will be detected in _xcb_in_replies_done and this pending_reply
* will be discarded.
*/
_xcb_in_expect_reply(c, c->out.request + 1, WORKAROUND_EXTERNAL_SOCKET_OWNER, flags);
}
assert(c->out.request == c->out.request_written);
*sent = c->out.request;
}
@ -372,6 +447,7 @@ int _xcb_out_init(_xcb_out *out)
out->request = 0;
out->request_written = 0;
out->request_expected_written = 0;
if(pthread_mutex_init(&out->reqlenlock, 0))
return 0;
@ -382,8 +458,9 @@ int _xcb_out_init(_xcb_out *out)
void _xcb_out_destroy(_xcb_out *out)
{
pthread_cond_destroy(&out->cond);
pthread_mutex_destroy(&out->reqlenlock);
pthread_cond_destroy(&out->cond);
pthread_cond_destroy(&out->socket_cond);
}
int _xcb_out_send(xcb_connection_t *c, struct iovec *vector, int count)
@ -392,6 +469,7 @@ int _xcb_out_send(xcb_connection_t *c, struct iovec *vector, int count)
while(ret && count)
ret = _xcb_conn_wait(c, &c->out.cond, &vector, &count);
c->out.request_written = c->out.request;
c->out.request_expected_written = c->in.request_expected;
pthread_cond_broadcast(&c->out.cond);
_xcb_in_wake_up_next_reader(c);
return ret;

View File

@ -36,12 +36,12 @@
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <unistd.h>
#include <string.h>
#ifdef _WIN32
#include "xcb_windefs.h"
#else
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/un.h>
@ -60,16 +60,27 @@
# include <sys/stat.h>
#endif
#ifdef HAVE_LAUNCHD
#include <sys/stat.h>
#ifndef __has_builtin
# define __has_builtin(x) 0
#endif
int xcb_popcount(uint32_t mask)
{
#if __has_builtin(__builtin_popcount)
return __builtin_popcount(mask);
#else
/*
* Count the number of bits set to 1 in a 32-bit word.
* Algorithm from MIT AI Lab Memo 239: "HAKMEM", ITEM 169.
* https://dspace.mit.edu/handle/1721.1/6086
*/
uint32_t y;
y = (mask >> 1) & 033333333333;
y = mask - y - ((y >> 1) & 033333333333);
return ((y + (y >> 3)) & 030707070707) % 077;
#endif
}
int xcb_sumof(uint8_t *list, int len)
@ -82,7 +93,6 @@ int xcb_sumof(uint8_t *list, int len)
return s;
}
#ifdef HAVE_LAUNCHD
/* Return true and parse if name matches <path to socket>[.<screen>]
* Upon success:
* host = <path to socket>
@ -94,20 +104,33 @@ static int _xcb_parse_display_path_to_socket(const char *name, char **host, char
int *displayp, int *screenp)
{
struct stat sbuf;
char path[PATH_MAX];
int _screen = 0;
/* In addition to the AF_UNIX path, there may be a screen number.
* The trailing \0 is already accounted in the size of sun_path. */
char path[sizeof(((struct sockaddr_un*)0)->sun_path) + 1 + 10];
size_t len;
int _screen = 0, res;
strlcpy(path, name, sizeof(path));
if (0 != stat(path, &sbuf)) {
char *dot = strrchr(path, '.');
if (!dot)
len = strlen(name);
if (len >= sizeof(path))
return 0;
memcpy(path, name, len + 1);
res = stat(path, &sbuf);
if (0 != res) {
unsigned long lscreen;
char *dot, *endptr;
if (res != -1 || (errno != ENOENT && errno != ENOTDIR))
return 0;
dot = strrchr(path, '.');
if (!dot || dot[1] < '1' || dot[1] > '9')
return 0;
*dot = '\0';
errno = 0;
lscreen = strtoul(dot + 1, &endptr, 10);
if (lscreen > INT_MAX || !endptr || *endptr || errno)
return 0;
if (0 != stat(path, &sbuf))
return 0;
_screen = atoi(dot + 1);
_screen = (int)lscreen;
}
if (host) {
@ -133,7 +156,6 @@ static int _xcb_parse_display_path_to_socket(const char *name, char **host, char
return 1;
}
#endif
static int _xcb_parse_display(const char *name, char **host, char **protocol,
int *displayp, int *screenp)
@ -146,11 +168,12 @@ static int _xcb_parse_display(const char *name, char **host, char **protocol,
if(!name)
return 0;
#ifdef HAVE_LAUNCHD
/* First check for <path to socket>[.<screen>] */
if (_xcb_parse_display_path_to_socket(name, host, protocol, displayp, screenp))
return 1;
#endif
if (name[0] == '/')
return _xcb_parse_display_path_to_socket(name, host, protocol, displayp, screenp);
if (strncmp(name, "unix:", 5) == 0)
return _xcb_parse_display_path_to_socket(name + 5, host, protocol, displayp, screenp);
slash = strrchr(name, '/');
@ -236,39 +259,46 @@ static int _xcb_open(const char *host, char *protocol, const int display)
char *file = NULL;
int actual_filelen;
/* If protocol or host is "unix", fall through to Unix socket code below */
if ((!protocol || (strcmp("unix",protocol) != 0)) &&
(*host != '\0') && (strcmp("unix",host) != 0))
{
/* display specifies TCP */
unsigned short port = X_TCP_PORT + display;
return _xcb_open_tcp(host, protocol, port);
}
#ifndef _WIN32
if (protocol && strcmp("unix", protocol) == 0 && host && host[0] == '/') {
/* Full path to socket provided, ignore everything else */
filelen = strlen(host) + 1;
if (filelen > INT_MAX)
return -1;
file = malloc(filelen);
if (file == NULL)
return -1;
memcpy(file, host, filelen);
actual_filelen = (int)(filelen - 1);
} else {
#endif
/* If protocol or host is "unix", fall through to Unix socket code below */
if ((!protocol || (strcmp("unix",protocol) != 0)) &&
(*host != '\0') && (strcmp("unix",host) != 0))
{
/* display specifies TCP */
unsigned short port = X_TCP_PORT + display;
return _xcb_open_tcp(host, protocol, port);
}
#ifndef _WIN32
#if defined(HAVE_TSOL_LABEL_H) && defined(HAVE_IS_SYSTEM_LABELED)
/* Check special path for Unix sockets under Solaris Trusted Extensions */
if (is_system_labeled())
{
struct stat sbuf;
const char *tsol_base = "/var/tsol/doors/.X11-unix/X";
char tsol_socket[PATH_MAX];
/* Check special path for Unix sockets under Solaris Trusted Extensions */
if (is_system_labeled())
{
const char *tsol_base = "/var/tsol/doors/.X11-unix/X";
char tsol_socket[PATH_MAX];
struct stat sbuf;
snprintf(tsol_socket, sizeof(tsol_socket), "%s%d", tsol_base, display);
snprintf(tsol_socket, sizeof(tsol_socket), "%s%d", tsol_base, display);
if (stat(tsol_socket, &sbuf) == 0)
base = tsol_base;
}
if (stat(tsol_socket, &sbuf) == 0)
base = tsol_base;
else if (errno != ENOENT)
return 0;
}
#endif
#ifdef HAVE_LAUNCHD
struct stat sbuf;
if (0 == stat(host, &sbuf)) {
file = strdup(host);
filelen = actual_filelen = strlen(file);
} else
#endif
{
filelen = strlen(base) + 1 + sizeof(display) * 3 + 1;
file = malloc(filelen);
if(file == NULL)
@ -276,24 +306,23 @@ static int _xcb_open(const char *host, char *protocol, const int display)
/* display specifies Unix socket */
actual_filelen = snprintf(file, filelen, "%s%d", base, display);
}
if(actual_filelen < 0)
{
free(file);
return -1;
}
/* snprintf may truncate the file */
filelen = MIN(actual_filelen, filelen - 1);
if(actual_filelen < 0)
{
free(file);
return -1;
}
/* snprintf may truncate the file */
filelen = MIN(actual_filelen, filelen - 1);
#ifdef HAVE_ABSTRACT_SOCKETS
fd = _xcb_open_abstract(protocol, file, filelen);
if (fd >= 0 || (errno != ENOENT && errno != ECONNREFUSED))
{
free(file);
return fd;
}
fd = _xcb_open_abstract(protocol, file, filelen);
if (fd >= 0 || (errno != ENOENT && errno != ECONNREFUSED))
{
free(file);
return fd;
}
#endif
}
fd = _xcb_open_unix(protocol, file);
free(file);
@ -387,7 +416,11 @@ static int _xcb_open_tcp(const char *host, char *protocol, const unsigned short
fd = _xcb_socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
if (_xcb_do_connect(fd, addr->ai_addr, addr->ai_addrlen) >= 0)
break;
#ifdef _WIN32
closesocket(fd);
#else
close(fd);
#endif
fd = -1;
}
freeaddrinfo(results);
@ -413,7 +446,11 @@ static int _xcb_open_tcp(const char *host, char *protocol, const unsigned short
if(_xcb_do_connect(fd, (struct sockaddr*)&_s, sizeof(_s)) >= 0)
break;
#ifdef _WIN32
closesocket(fd);
#else
close(fd);
#endif
fd = -1;
++_c;
}
@ -428,6 +465,8 @@ static int _xcb_open_unix(char *protocol, const char *file)
{
int fd;
struct sockaddr_un addr;
socklen_t len = sizeof(int);
int val;
if (protocol && strcmp("unix",protocol))
return -1;
@ -440,6 +479,11 @@ static int _xcb_open_unix(char *protocol, const char *file)
fd = _xcb_socket(AF_UNIX, SOCK_STREAM, 0);
if(fd == -1)
return -1;
if(getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &val, &len) == 0 && val < 64 * 1024)
{
val = 64 * 1024;
setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &val, sizeof(int));
}
if(connect(fd, (struct sockaddr *) &addr, sizeof(addr)) == -1) {
close(fd);
return -1;
@ -515,10 +559,8 @@ xcb_connection_t *xcb_connect_to_display_with_auth_info(const char *displayname,
if(auth) {
c = xcb_connect_to_fd(fd, auth);
goto out;
}
if(_xcb_get_auth_info(fd, &ourauth, display))
else if(_xcb_get_auth_info(fd, &ourauth, display))
{
c = xcb_connect_to_fd(fd, &ourauth);
free(ourauth.name);

View File

@ -55,7 +55,7 @@ uint32_t xcb_generate_id(xcb_connection_t *c)
/* check for extension */
const xcb_query_extension_reply_t *xc_misc_reply =
xcb_get_extension_data(c, &xcb_xc_misc_id);
if (!xc_misc_reply) {
if (!xc_misc_reply || !xc_misc_reply->present) {
pthread_mutex_unlock(&c->xid.lock);
return -1;
}

View File

@ -60,21 +60,21 @@ enum xcb_send_request_flags_t {
/**
* @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.
* @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
* array and the necessary 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.
* Please note that this function is not the preferred 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,
@ -82,28 +82,115 @@ enum xcb_send_request_flags_t {
*/
unsigned int xcb_send_request(xcb_connection_t *c, int flags, struct iovec *vector, const xcb_protocol_request_t *request);
/**
* @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.
* @param num_fds Number of additional file descriptors to send to the server
* @param fds Additional file descriptors that should be send to the server.
* @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 necessary management information are given in the @p request
* argument.
*
* If @p num_fds is non-zero, @p fds points to an array of file descriptors that
* will be sent to the X server along with this request. After this function
* returns, all file descriptors sent are owned by xcb and will be closed
* eventually.
*
* 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 preferred way for sending requests.
*
* 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_with_fds(xcb_connection_t *c, int flags, struct iovec *vector,
const xcb_protocol_request_t *request, unsigned int num_fds, int *fds);
/**
* @brief Send a request to the server, with 64-bit sequence number returned.
* @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 necessary 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 preferred 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!
*/
uint64_t xcb_send_request64(xcb_connection_t *c, int flags, struct iovec *vector, const xcb_protocol_request_t *request);
/**
* @brief Send a request to the server, with 64-bit sequence number returned.
* @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.
* @param num_fds Number of additional file descriptors to send to the server
* @param fds Additional file descriptors that should be send to the server.
* @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 necessary management information are given in the @p request
* argument.
*
* If @p num_fds is non-zero, @p fds points to an array of file descriptors that
* will be sent to the X server along with this request. After this function
* returns, all file descriptors sent are owned by xcb and will be closed
* eventually.
*
* 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 preferred 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!
*/
uint64_t xcb_send_request_with_fds64(xcb_connection_t *c, int flags, struct iovec *vector,
const xcb_protocol_request_t *request, unsigned int num_fds, int *fds);
/**
* @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.
* @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.
* @deprecated This function cannot be used in a thread-safe way. Two threads
* that run xcb_send_fd(); xcb_send_request(); could mix up their file
* descriptors. Instead, xcb_send_request_with_fds() should be used.
*/
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
* @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.
* @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.
*
@ -127,10 +214,10 @@ int xcb_take_socket(xcb_connection_t *c, void (*return_socket)(void *closure), v
/**
* @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.
* @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
@ -151,9 +238,9 @@ int xcb_writev(xcb_connection_t *c, struct iovec *vector, int count, uint64_t re
/**
* @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.
* @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
@ -161,41 +248,74 @@ int xcb_writev(xcb_connection_t *c, struct iovec *vector, int count, uint64_t re
*/
void *xcb_wait_for_reply(xcb_connection_t *c, unsigned int request, xcb_generic_error_t **e);
/**
* @brief Wait for the reply of a given request, with 64-bit sequence number
* @param c The connection to the X server.
* @param request 64-bit sequence number of the request as returned by xcb_send_request64().
* @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.
*
* Unlike its xcb_wait_for_reply() counterpart, the given sequence number is not
* automatically "widened" to 64-bit.
*/
void *xcb_wait_for_reply64(xcb_connection_t *c, uint64_t 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.
* @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 error 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 Poll for the reply of a given request, with 64-bit sequence number.
* @param c The connection to the X server.
* @param request 64-bit sequence number of the request as returned by xcb_send_request().
* @param reply Location to store the reply in, must not be NULL.
* @param error 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.
*
* Unlike its xcb_poll_for_reply() counterpart, the given sequence number is not
* automatically "widened" to 64-bit.
*/
int xcb_poll_for_reply64(xcb_connection_t *c, uint64_t 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.
* @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.
*/
XCB_CONST_FUNCTION
int *xcb_get_reply_fds(xcb_connection_t *c, void *reply, size_t replylen);
/* xcb_util.c */
/**
* @param mask: The mask to check
* @param mask The mask to check
* @return The number of set bits in the mask
*/
XCB_CONST_FUNCTION
int xcb_popcount(uint32_t mask);
/**
* @param list: The base of an array
* @param len: The length of the array
* @param list The base of an array
* @param len The length of the array
* @return The sum of all entries in the array.
*/
XCB_PURE_FUNCTION
int xcb_sumof(uint8_t *list, int len);
#ifdef __cplusplus

View File

@ -38,6 +38,16 @@
#pragma GCC visibility push(hidden)
#endif
#ifndef __has_attribute
# define __has_attribute(x) 0 /* Compatibility with older compilers. */
#endif
#if __has_attribute(fallthrough)
# define XCB_ALLOW_FALLTHRU __attribute__ ((fallthrough));
#else
# define XCB_ALLOW_FALLTHRU /* FALLTHRU */
#endif
enum workarounds {
WORKAROUND_NONE,
WORKAROUND_GLX_GET_FB_CONFIGS_BUG,
@ -73,8 +83,8 @@ typedef struct _xcb_map _xcb_map;
_xcb_map *_xcb_map_new(void);
void _xcb_map_delete(_xcb_map *q, xcb_list_free_func_t do_free);
int _xcb_map_put(_xcb_map *q, unsigned int key, void *data);
void *_xcb_map_remove(_xcb_map *q, unsigned int key);
int _xcb_map_put(_xcb_map *q, uint64_t key, void *data);
void *_xcb_map_remove(_xcb_map *q, uint64_t key);
/* xcb_out.c */
@ -103,6 +113,8 @@ typedef struct _xcb_out {
uint64_t request;
uint64_t request_written;
uint64_t request_expected_written;
uint64_t total_written;
pthread_mutex_t reqlenlock;
enum lazy_reply_tag maximum_request_length_tag;
@ -135,6 +147,7 @@ typedef struct _xcb_in {
uint64_t request_expected;
uint64_t request_read;
uint64_t request_completed;
uint64_t total_read;
struct reply_list *current_reply;
struct reply_list **current_reply_tail;
@ -142,6 +155,7 @@ typedef struct _xcb_in {
struct event_list *events;
struct event_list **events_tail;
struct reader_list *readers;
struct special_list *special_waiters;
struct pending_reply *pending_replies;
struct pending_reply **pending_replies_tail;
@ -211,6 +225,7 @@ struct xcb_connection_t {
void _xcb_conn_shutdown(xcb_connection_t *c, int err);
XCB_CONST_FUNCTION
xcb_connection_t *_xcb_conn_ret_error(int err);
int _xcb_conn_wait(xcb_connection_t *c, pthread_cond_t *cond, struct iovec **vector, int *count);

View File

@ -1,10 +1,19 @@
#include <stdlib.h>
#include "check_suites.h"
#if CHECK_MAJOR_VERSION == 0 && CHECK_MINOR_VERSION < 13
void suite_add_test(Suite *s, TFun tf, const char *name)
#else
void suite_add_test(Suite *s, const TTest *tt, const char *name)
#endif
{
TCase *tc = tcase_create(name);
#if CHECK_MAJOR_VERSION == 0 && CHECK_MINOR_VERSION < 13
tcase_add_test(tc, tf);
#else
tcase_add_test(tc, tt);
#endif
suite_add_tcase(s, tc);
}

View File

@ -1,6 +1,10 @@
#include <check.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#ifdef __unix__
#include <unistd.h>
#endif
#include "check_suites.h"
#include "xcb.h"
#include "xcbext.h"
@ -12,6 +16,10 @@ typedef enum test_type_t {
} test_type_t;
static const char *const test_string[] = { "", "via $DISPLAY " };
/* putenv(3) takes a pointer to a writable string that it adds directly
to the environment, so it must be in persistent memory, not on the stack */
static char display_env[] = "DISPLAY=";
static void parse_display_pass(const char *name, const char *host, const int display, const int screen)
{
int success;
@ -25,7 +33,7 @@ static void parse_display_pass(const char *name, const char *host, const int dis
if(test_type == TEST_ARGUMENT)
{
argument = name;
putenv("DISPLAY=");
putenv(display_env);
}
else if(test_type == TEST_ENVIRONMENT)
{
@ -37,20 +45,20 @@ static void parse_display_pass(const char *name, const char *host, const int dis
got_display = got_screen = -42;
mark_point();
success = xcb_parse_display(argument, &got_host, &got_display, &got_screen);
fail_unless(success, "unexpected parse failure %sfor '%s'", test_string[test_type], name);
fail_unless(strcmp(host, got_host) == 0, "parse %sproduced unexpected hostname '%s' for '%s': expected '%s'", test_string[test_type], got_host, name, host);
fail_unless(display == got_display, "parse %sproduced unexpected display '%d' for '%s': expected '%d'", test_string[test_type], got_display, name, display);
fail_unless(screen == got_screen, "parse %sproduced unexpected screen '%d' for '%s': expected '%d'", test_string[test_type], got_screen, name, screen);
ck_assert_msg(success, "unexpected parse failure %sfor '%s'", test_string[test_type], name);
ck_assert_msg(strcmp(host, got_host) == 0, "parse %sproduced unexpected hostname '%s' for '%s': expected '%s'", test_string[test_type], got_host, name, host);
ck_assert_msg(display == got_display, "parse %sproduced unexpected display '%d' for '%s': expected '%d'", test_string[test_type], got_display, name, display);
ck_assert_msg(screen == got_screen, "parse %sproduced unexpected screen '%d' for '%s': expected '%d'", test_string[test_type], got_screen, name, screen);
got_host = (char *) -1;
got_display = got_screen = -42;
mark_point();
success = xcb_parse_display(argument, &got_host, &got_display, 0);
fail_unless(success, "unexpected screenless parse failure %sfor '%s'", test_string[test_type], name);
fail_unless(strcmp(host, got_host) == 0, "screenless parse %sproduced unexpected hostname '%s' for '%s': expected '%s'", test_string[test_type], got_host, name, host);
fail_unless(display == got_display, "screenless parse %sproduced unexpected display '%d' for '%s': expected '%d'", test_string[test_type], got_display, name, display);
ck_assert_msg(success, "unexpected screenless parse failure %sfor '%s'", test_string[test_type], name);
ck_assert_msg(strcmp(host, got_host) == 0, "screenless parse %sproduced unexpected hostname '%s' for '%s': expected '%s'", test_string[test_type], got_host, name, host);
ck_assert_msg(display == got_display, "screenless parse %sproduced unexpected display '%d' for '%s': expected '%d'", test_string[test_type], got_display, name, display);
}
putenv("DISPLAY=");
putenv(display_env);
}
static void parse_display_fail(const char *name)
@ -66,7 +74,7 @@ static void parse_display_fail(const char *name)
if(test_type == TEST_ARGUMENT)
{
argument = name;
putenv("DISPLAY=");
putenv(display_env);
}
else if(test_type == TEST_ENVIRONMENT)
{
@ -79,24 +87,55 @@ static void parse_display_fail(const char *name)
got_display = got_screen = -42;
mark_point();
success = xcb_parse_display(argument, &got_host, &got_display, &got_screen);
fail_unless(!success, "unexpected parse success %sfor '%s'", test_string[test_type], name);
fail_unless(got_host == (char *) -1, "host changed on parse failure %sfor '%s': got %p", test_string[test_type], name, got_host);
fail_unless(got_display == -42, "display changed on parse failure %sfor '%s': got %d", test_string[test_type], name, got_display);
fail_unless(got_screen == -42, "screen changed on parse failure %sfor '%s': got %d", test_string[test_type], name, got_screen);
ck_assert_msg(!success, "unexpected parse success %sfor '%s'", test_string[test_type], name);
ck_assert_msg(got_host == (char *) -1, "host changed on parse failure %sfor '%s': got %p", test_string[test_type], name, got_host);
ck_assert_msg(got_display == -42, "display changed on parse failure %sfor '%s': got %d", test_string[test_type], name, got_display);
ck_assert_msg(got_screen == -42, "screen changed on parse failure %sfor '%s': got %d", test_string[test_type], name, got_screen);
got_host = (char *) -1;
got_display = got_screen = -42;
mark_point();
success = xcb_parse_display(argument, &got_host, &got_display, 0);
fail_unless(!success, "unexpected screenless parse success %sfor '%s'", test_string[test_type], name);
fail_unless(got_host == (char *) -1, "host changed on parse failure %sfor '%s': got %p", test_string[test_type], name, got_host);
fail_unless(got_display == -42, "display changed on parse failure %sfor '%s': got %d", test_string[test_type], name, got_display);
ck_assert_msg(!success, "unexpected screenless parse success %sfor '%s'", test_string[test_type], name);
ck_assert_msg(got_host == (char *) -1, "host changed on parse failure %sfor '%s': got %p", test_string[test_type], name, got_host);
ck_assert_msg(got_display == -42, "display changed on parse failure %sfor '%s': got %d", test_string[test_type], name, got_display);
}
putenv("DISPLAY=");
putenv(display_env);
}
START_TEST(parse_display_unix)
{
#ifdef __unix__
char buf[sizeof "/tmp/xcb-test.XXXXXXX"];
char buf2[sizeof(buf) + 7];
int r, v;
memcpy(buf, "/tmp/xcb-test.XXXXXXX", sizeof buf);
v = mkstemp(buf);
ck_assert_msg(v >= 0, "cannot create temporary file");
parse_display_pass(buf, buf, 0, 0);
r = snprintf(buf2, sizeof buf2, "unix:%s", buf);
if (r < 5 || r >= (int)sizeof buf2) {
ck_assert_msg(0, "snprintf() failed (return value %d)", r);
unlink(buf);
return;
}
parse_display_pass(buf2, buf, 0, 0);
r = snprintf(buf2, sizeof buf2, "unix:%s.1", buf);
if (r < 7 || r >= (int)sizeof buf2) {
ck_assert_msg(0, "snprintf() failed (return value %d)", r);
unlink(buf);
return;
}
parse_display_pass(buf2, buf, 0, 1);
r = snprintf(buf2, sizeof buf2, "%s.1", buf);
if (r < 2 || r >= (int)sizeof buf2) {
ck_assert_msg(0, "snprintf() failed (return value %d)", r);
unlink(buf);
return;
}
parse_display_pass(buf2, buf, 0, 1);
unlink(buf);
#endif
parse_display_pass(":0", "", 0, 0);
parse_display_pass(":1", "", 1, 0);
parse_display_pass(":0.1", "", 0, 1);
@ -183,7 +222,7 @@ END_TEST
static void popcount_eq(uint32_t bits, int count)
{
fail_unless(xcb_popcount(bits) == count, "unexpected popcount(%08x) != %d", bits, count);
ck_assert_msg(xcb_popcount(bits) == count, "unexpected popcount(%08x) != %d", bits, count);
}
START_TEST(popcount)
@ -206,7 +245,7 @@ END_TEST
Suite *public_suite(void)
{
Suite *s = suite_create("Public API");
putenv("DISPLAY=");
putenv(display_env);
suite_add_test(s, parse_display_unix, "xcb_parse_display unix");
suite_add_test(s, parse_display_ip, "xcb_parse_display ip");
suite_add_test(s, parse_display_ipv4, "xcb_parse_display ipv4");

View File

@ -1,4 +1,8 @@
#include <check.h>
#if CHECK_MAJOR_VERSION == 0 && CHECK_MINOR_VERSION < 13
void suite_add_test(Suite *s, TFun tf, const char *name);
#else
void suite_add_test(Suite *s, const TTest *tt, const char *name);
#endif
Suite *public_suite(void);

View File

@ -6,6 +6,6 @@ includedir=@includedir@
Name: XCB Composite
Description: XCB Composite Extension
Version: @PACKAGE_VERSION@
Requires: xcb xcb-xfixes
Requires.private: xcb xcb-xfixes
Libs: -L${libdir} -lxcb-composite
Cflags: -I${includedir}

View File

@ -6,6 +6,6 @@ includedir=@includedir@
Name: XCB Damage
Description: XCB Damage Extension
Version: @PACKAGE_VERSION@
Requires: xcb xcb-xfixes
Requires.private: xcb xcb-xfixes
Libs: -L${libdir} -lxcb-damage
Cflags: -I${includedir}

11
xcb-dbe.pc.in Normal file
View File

@ -0,0 +1,11 @@
prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
Name: XCB Dbe
Description: XCB Double Buffer Extension
Version: @PACKAGE_VERSION@
Requires.private: xcb
Libs: -L${libdir} -lxcb-dbe
Cflags: -I${includedir}

View File

@ -6,6 +6,6 @@ includedir=@includedir@
Name: XCB DPMS
Description: XCB DPMS Extension
Version: @PACKAGE_VERSION@
Requires: xcb
Requires.private: xcb
Libs: -L${libdir} -lxcb-dpms
Cflags: -I${includedir}

View File

@ -6,6 +6,6 @@ includedir=@includedir@
Name: XCB DRI2
Description: XCB DRI2 Extension
Version: @PACKAGE_VERSION@
Requires: xcb
Requires.private: xcb
Libs: -L${libdir} -lxcb-dri2
Cflags: -I${includedir}

View File

@ -6,6 +6,6 @@ includedir=@includedir@
Name: XCB DRI3
Description: XCB DRI3 Extension
Version: @PACKAGE_VERSION@
Requires: xcb
Requires.private: xcb
Libs: -L${libdir} -lxcb-dri3
Cflags: -I${includedir}

11
xcb-ge.pc.in Normal file
View File

@ -0,0 +1,11 @@
prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
Name: XCB GenericEvent
Description: XCB GenericEvent Extension
Version: @PACKAGE_VERSION@
Requires.private: xcb
Libs: -L${libdir} -lxcb-ge
Cflags: -I${includedir}

View File

@ -6,6 +6,6 @@ includedir=@includedir@
Name: XCB GLX
Description: XCB GLX Extension
Version: @PACKAGE_VERSION@
Requires: xcb
Requires.private: xcb
Libs: -L${libdir} -lxcb-glx
Cflags: -I${includedir}

View File

@ -6,6 +6,6 @@ includedir=@includedir@
Name: XCB Present
Description: XCB Present Extension
Version: @PACKAGE_VERSION@
Requires: xcb xcb-randr xcb-xfixes xcb-sync
Requires.private: xcb xcb-randr xcb-xfixes xcb-sync xcb-dri3
Libs: -L${libdir} -lxcb-present
Cflags: -I${includedir}

View File

@ -6,6 +6,6 @@ includedir=@includedir@
Name: XCB RandR
Description: XCB RandR Extension
Version: @PACKAGE_VERSION@
Requires: xcb xcb-render
Requires.private: xcb xcb-render
Libs: -L${libdir} -lxcb-randr
Cflags: -I${includedir}

View File

@ -6,6 +6,6 @@ includedir=@includedir@
Name: XCB Record
Description: XCB Record Extension
Version: @PACKAGE_VERSION@
Requires: xcb
Requires.private: xcb
Libs: -L${libdir} -lxcb-record
Cflags: -I${includedir}

View File

@ -6,6 +6,6 @@ includedir=@includedir@
Name: XCB Render
Description: XCB Render Extension
Version: @PACKAGE_VERSION@
Requires: xcb
Requires.private: xcb
Libs: -L${libdir} -lxcb-render
Cflags: -I${includedir}

View File

@ -6,6 +6,6 @@ includedir=@includedir@
Name: XCB Res
Description: XCB X-Resource Extension
Version: @PACKAGE_VERSION@
Requires: xcb
Requires.private: xcb
Libs: -L${libdir} -lxcb-res
Cflags: -I${includedir}

View File

@ -6,6 +6,6 @@ includedir=@includedir@
Name: XCB Screensaver
Description: XCB Screensaver Extension
Version: @PACKAGE_VERSION@
Requires: xcb
Requires.private: xcb
Libs: -L${libdir} -lxcb-screensaver
Cflags: -I${includedir}

View File

@ -6,6 +6,6 @@ includedir=@includedir@
Name: XCB Shape
Description: XCB Shape Extension
Version: @PACKAGE_VERSION@
Requires: xcb
Requires.private: xcb
Libs: -L${libdir} -lxcb-shape
Cflags: -I${includedir}

View File

@ -6,6 +6,6 @@ includedir=@includedir@
Name: XCB Shm
Description: XCB Shm Extension
Version: @PACKAGE_VERSION@
Requires: xcb
Requires.private: xcb
Libs: -L${libdir} -lxcb-shm
Cflags: -I${includedir}

View File

@ -6,6 +6,6 @@ includedir=@includedir@
Name: XCB Sync
Description: XCB Sync Extension
Version: @PACKAGE_VERSION@
Requires: xcb
Requires.private: xcb
Libs: -L${libdir} -lxcb-sync
Cflags: -I${includedir}

View File

@ -6,6 +6,6 @@ includedir=@includedir@
Name: XCB Xevie
Description: XCB Xevie Extension
Version: @PACKAGE_VERSION@
Requires: xcb
Requires.private: xcb
Libs: -L${libdir} -lxcb-xevie
Cflags: -I${includedir}

View File

@ -6,6 +6,6 @@ includedir=@includedir@
Name: XCB XFree86-DRI
Description: XCB XFree86-DRI Extension
Version: @PACKAGE_VERSION@
Requires: xcb
Requires.private: xcb
Libs: -L${libdir} -lxcb-xf86dri
Cflags: -I${includedir}

View File

@ -6,6 +6,6 @@ includedir=@includedir@
Name: XCB XFixes
Description: XCB XFixes Extension
Version: @PACKAGE_VERSION@
Requires: xcb xcb-render xcb-shape
Requires.private: xcb xcb-render xcb-shape
Libs: -L${libdir} -lxcb-xfixes
Cflags: -I${includedir}

View File

@ -6,6 +6,6 @@ includedir=@includedir@
Name: XCB Xinerama
Description: XCB Xinerama Extension
Version: @PACKAGE_VERSION@
Requires: xcb
Requires.private: xcb
Libs: -L${libdir} -lxcb-xinerama
Cflags: -I${includedir}

View File

@ -6,6 +6,6 @@ includedir=@includedir@
Name: XCB XInput
Description: XCB XInput Extension (EXPERIMENTAL)
Version: @PACKAGE_VERSION@
Requires: xcb xcb-xfixes
Requires.private: xcb xcb-xfixes
Libs: -L${libdir} -lxcb-xinput
Cflags: -I${includedir}

View File

@ -6,6 +6,6 @@ includedir=@includedir@
Name: XCB XKB
Description: XCB Keyboard Extension (EXPERIMENTAL)
Version: @PACKAGE_VERSION@
Requires: xcb
Requires.private: xcb
Libs: -L${libdir} -lxcb-xkb
Cflags: -I${includedir}

View File

@ -6,6 +6,6 @@ includedir=@includedir@
Name: XCB Xprint
Description: XCB Xprint Extension
Version: @PACKAGE_VERSION@
Requires: xcb
Requires.private: xcb
Libs: -L${libdir} -lxcb-xprint
Cflags: -I${includedir}

View File

@ -6,6 +6,6 @@ includedir=@includedir@
Name: XCB SELinux
Description: XCB SELinux Extension
Version: @PACKAGE_VERSION@
Requires: xcb
Requires.private: xcb
Libs: -L${libdir} -lxcb-xselinux
Cflags: -I${includedir}

View File

@ -6,6 +6,6 @@ includedir=@includedir@
Name: XCB XTEST
Description: XCB XTEST Extension
Version: @PACKAGE_VERSION@
Requires: xcb
Requires.private: xcb
Libs: -L${libdir} -lxcb-xtest
Cflags: -I${includedir}

View File

@ -6,6 +6,6 @@ includedir=@includedir@
Name: XCB Xv
Description: XCB Xv Extension
Version: @PACKAGE_VERSION@
Requires: xcb xcb-shm
Requires.private: xcb xcb-shm
Libs: -L${libdir} -lxcb-xv
Cflags: -I${includedir}

View File

@ -6,6 +6,6 @@ includedir=@includedir@
Name: XCB XvMC
Description: XCB XvMC Extension
Version: @PACKAGE_VERSION@
Requires: xcb xcb-xv
Requires.private: xcb xcb-xv
Libs: -L${libdir} -lxcb-xvmc
Cflags: -I${includedir}