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