xcb_disp.c revision 61b2299d
1/* Copyright (C) 2003-2006 Jamey Sharp, Josh Triplett
2 * This file is licensed under the MIT license. See the file COPYING. */
3
4#include "Xlibint.h"
5#include "Xxcbint.h"
6#include <xcb/xcbext.h>
7#include <X11/Xatom.h>
8#include <X11/Xresource.h>
9#include <stdio.h>
10
11static xcb_auth_info_t xauth;
12
13static void *alloc_copy(const void *src, int *dstn, size_t n)
14{
15	void *dst;
16	if(n <= 0)
17	{
18		*dstn = 0;
19		return NULL;
20	}
21	dst = Xmalloc(n);
22	if(!dst)
23		return NULL;
24	memcpy(dst, src, n);
25	*dstn = n;
26	return dst;
27}
28
29void XSetAuthorization(char *name, int namelen, char *data, int datalen)
30{
31	_XLockMutex(_Xglobal_lock);
32	Xfree(xauth.name);
33	Xfree(xauth.data);
34
35	/* if either of these allocs fail, _XConnectXCB won't use this auth
36	 * data, so we don't need to check it here. */
37	xauth.name = alloc_copy(name, &xauth.namelen, namelen);
38	xauth.data = alloc_copy(data, &xauth.datalen, datalen);
39
40#if 0 /* but, for the paranoid among us: */
41	if((namelen > 0 && !xauth.name) || (datalen > 0 && !xauth.data))
42	{
43		Xfree(xauth.name);
44		Xfree(xauth.data);
45		xauth.name = xauth.data = 0;
46		xauth.namelen = xauth.datalen = 0;
47	}
48#endif
49
50	_XUnlockMutex(_Xglobal_lock);
51}
52
53int _XConnectXCB(Display *dpy, _Xconst char *display, char **fullnamep, int *screenp)
54{
55	char *host;
56	int n = 0;
57	int len;
58	xcb_connection_t *c;
59
60	dpy->fd = -1;
61
62	dpy->xcb = Xcalloc(1, sizeof(_X11XCBPrivate));
63	if(!dpy->xcb)
64		return 0;
65
66#ifdef HAVE_LAUNCHD
67	if(!display || !*display) display = getenv("DISPLAY");
68
69	if(display && strlen(display)>11 && !strncmp(display, "/tmp/launch", 11)) {
70		/* do nothing -- the magic happens inside of xcb_connect */
71	} else
72#endif
73	{
74		if(!xcb_parse_display(display, &host, &n, screenp))
75			return 0;
76
77		len = strlen(host) + (1 + 20 + 1 + 20 + 1);
78		*fullnamep = Xmalloc(len);
79		if (!*fullnamep) {
80			free(host);
81			return 0;
82		}
83
84		snprintf(*fullnamep, len, "%s:%d.%d", host, n, *screenp);
85		free(host);
86	}
87
88	_XLockMutex(_Xglobal_lock);
89	if(xauth.name && xauth.data)
90		c = xcb_connect_to_display_with_auth_info(display, &xauth, NULL);
91	else
92		c = xcb_connect(display, NULL);
93	_XUnlockMutex(_Xglobal_lock);
94
95	dpy->fd = xcb_get_file_descriptor(c);
96
97	dpy->xcb->connection = c;
98	dpy->xcb->pending_requests_tail = &dpy->xcb->pending_requests;
99	dpy->xcb->next_xid = xcb_generate_id(dpy->xcb->connection);
100
101	dpy->xcb->event_notify = xcondition_malloc();
102	if (!dpy->xcb->event_notify)
103		return 0;
104	xcondition_init(dpy->xcb->event_notify);
105	return !xcb_connection_has_error(c);
106}
107
108void _XFreeX11XCBStructure(Display *dpy)
109{
110	/* reply_data was allocated by system malloc, not Xmalloc */
111	free(dpy->xcb->reply_data);
112	while(dpy->xcb->pending_requests)
113	{
114		PendingRequest *tmp = dpy->xcb->pending_requests;
115		dpy->xcb->pending_requests = tmp->next;
116		free(tmp);
117	}
118	xcondition_free(dpy->xcb->event_notify);
119	Xfree(dpy->xcb);
120}
121