1/*
2 * Copyright © 2013 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 *
23 */
24
25#ifdef HAVE_CONFIG_H
26#include "config.h"
27#endif
28
29#include <X11/Xlib.h>
30#include <X11/Xatom.h>
31
32#include <X11/Xlibint.h>
33#include <X11/extensions/record.h>
34#include <X11/extensions/XShm.h>
35#if HAVE_X11_EXTENSIONS_SHMPROTO_H
36#include <X11/extensions/shmproto.h>
37#elif HAVE_X11_EXTENSIONS_SHMSTR_H
38#include <X11/extensions/shmstr.h>
39#else
40#error Failed to find the right header for X11 MIT-SHM protocol definitions
41#endif
42#include <X11/extensions/Xdamage.h>
43#if HAVE_X11_EXTENSIONS_XINERAMA_H
44#include <X11/extensions/Xinerama.h>
45#define USE_XINERAMA
46#endif
47#include <X11/extensions/Xrandr.h>
48#include <X11/extensions/Xrender.h>
49#include <X11/Xcursor/Xcursor.h>
50#include <pixman.h>
51
52#include <sys/types.h>
53#include <sys/ipc.h>
54#include <sys/shm.h>
55#include <sys/timerfd.h>
56#include <sys/poll.h>
57#include <sys/socket.h>
58#include <sys/un.h>
59
60#include <stdarg.h>
61#include <stdio.h>
62#include <stdlib.h>
63#include <stdint.h>
64#include <signal.h>
65#include <getopt.h>
66#include <limits.h>
67#include <unistd.h>
68#include <fcntl.h>
69#include <assert.h>
70
71#define FORCE_FULL_REDRAW 0
72#define FORCE_16BIT_XFER 0
73
74#define DBG(v, x) if (verbose & v) printf x
75static int verbose;
76#define X11 0x1
77#define XRR 0x1
78#define TIMER 0x4
79#define DRAW 0x8
80#define DAMAGE 0x10
81#define CURSOR 0x20
82#define POLL 0x40
83
84struct display {
85	Display *dpy;
86	struct clone *clone;
87	struct context *ctx;
88
89	int damage_event, damage_error;
90	int xfixes_event, xfixes_error;
91	int rr_event, rr_error, rr_active;
92	int xinerama_event, xinerama_error, xinerama_active;
93	int dri3_active;
94	Window root;
95	Visual *visual;
96	Damage damage;
97
98	int width;
99	int height;
100	int depth;
101
102	XRenderPictFormat *root_format;
103	XRenderPictFormat *rgb16_format;
104	XRenderPictFormat *rgb24_format;
105
106	int has_shm;
107	int has_shm_pixmap;
108	int shm_opcode;
109	int shm_event;
110
111	Cursor invisible_cursor;
112	Cursor visible_cursor;
113
114	XcursorImage cursor_image;
115	int cursor_serial;
116	int cursor_x;
117	int cursor_y;
118	int cursor_moved;
119	int cursor_visible;
120	int cursor;
121
122	int flush;
123	int send;
124	int skip_clone;
125	int skip_frame;
126};
127
128struct output {
129	struct display *display;
130	Display *dpy;
131	char *name;
132	RROutput rr_output;
133	RRCrtc rr_crtc;
134	Window window;
135	Picture win_picture;
136	Picture pix_picture;
137	Pixmap pixmap;
138	GC gc;
139
140	long serial;
141	int use_shm;
142	int use_shm_pixmap;
143	XShmSegmentInfo shm;
144
145	XRenderPictFormat *use_render;
146
147	int x, y;
148	XRRModeInfo mode;
149	Rotation rotation;
150};
151
152struct clone {
153	struct clone *next;
154	struct clone *active;
155
156	struct output src, dst;
157	long timestamp;
158
159	XShmSegmentInfo shm;
160	XImage image;
161
162	int width, height, depth;
163	struct { int x1, x2, y1, y2; } damaged;
164	int rr_update;
165
166	struct dri3_fence {
167		XID xid;
168		void *addr;
169	} dri3;
170};
171
172struct context {
173	struct display *display;
174	struct clone *clones;
175	struct clone *active;
176	struct pollfd *pfd;
177#define timer pfd[0].fd
178	Display *record;
179	int nclone;
180	int ndisplay;
181	int nfd;
182
183	int timer_active;
184
185	long timestamp;
186	long configTimestamp;
187
188	Atom singleton;
189	char command[1024];
190	int command_continuation;
191};
192
193static inline int is_power_of_2(unsigned long n)
194{
195	return n && ((n & (n - 1)) == 0);
196}
197
198static int xlib_vendor_is_xorg(Display *dpy)
199{
200	const char *const vendor = ServerVendor(dpy);
201	return strstr(vendor, "X.Org") || strstr(vendor, "Xorg");
202}
203
204static inline XRRScreenResources *_XRRGetScreenResourcesCurrent(Display *dpy, Window window)
205{
206	XRRScreenResources *res;
207
208	res = XRRGetScreenResourcesCurrent(dpy, window);
209	if (res == NULL)
210		res = XRRGetScreenResources(dpy, window);
211
212	return res;
213}
214
215#define XORG_VERSION_ENCODE(major,minor,patch,snap) \
216    (((major) * 10000000) + ((minor) * 100000) + ((patch) * 1000) + snap)
217
218static int _x_error_occurred;
219
220static int
221_check_error_handler(Display     *display,
222		     XErrorEvent *event)
223{
224	DBG(X11, ("X11 error from display %s, serial=%ld, error=%d, req=%d.%d\n",
225	     DisplayString(display),
226	     event->serial,
227	     event->error_code,
228	     event->request_code,
229	     event->minor_code));
230	_x_error_occurred = 1;
231	return False; /* ignored */
232}
233
234static int
235can_use_shm(Display *dpy,
236	    Window window,
237	    int *shm_event,
238	    int *shm_opcode,
239	    int *shm_pixmap)
240{
241	XShmSegmentInfo shm;
242	Status success;
243	XExtCodes *codes;
244	int major, minor, has_shm, has_pixmap;
245
246	if (!XShmQueryExtension(dpy))
247		return 0;
248
249	XShmQueryVersion(dpy, &major, &minor, &has_pixmap);
250
251	shm.shmid = shmget(IPC_PRIVATE, 0x1000, IPC_CREAT | 0600);
252	if (shm.shmid == -1)
253		return 0;
254
255	shm.readOnly = 0;
256	shm.shmaddr = shmat(shm.shmid, NULL, 0);
257	if (shm.shmaddr == (char *) -1) {
258		shmctl(shm.shmid, IPC_RMID, NULL);
259		return 0;
260	}
261
262	XSync(dpy, False);
263	_x_error_occurred = 0;
264
265	success = XShmAttach(dpy, &shm);
266
267	XSync(dpy, False);
268	has_shm = success && _x_error_occurred == 0;
269
270	/* As libXext sets the SEND_EVENT bit in the ShmCompletionEvent,
271	 * the Xserver may crash if it does not take care when processing
272	 * the event type. For instance versions of Xorg prior to 1.11.1
273	 * exhibited this bug, and was fixed by:
274	 *
275	 * commit 2d2dce558d24eeea0eb011ec9ebaa6c5c2273c39
276	 * Author: Sam Spilsbury <sam.spilsbury@canonical.com>
277	 * Date:   Wed Sep 14 09:58:34 2011 +0800
278	 *
279	 * Remove the SendEvent bit (0x80) before doing range checks on event type.
280	 */
281	codes = 0;
282	if (has_shm)
283		codes = XInitExtension(dpy, SHMNAME);
284	if (xlib_vendor_is_xorg(dpy) &&
285	    VendorRelease(dpy) < XORG_VERSION_ENCODE(1,11,0,1))
286		codes = 0;
287	if (codes) {
288		XShmCompletionEvent e;
289
290		memset(&e, 0, sizeof(e));
291
292		e.type = codes->first_event;
293		e.send_event = 1;
294		e.serial = 1;
295		e.drawable = window;
296		e.major_code = codes->major_opcode;
297		e.minor_code = X_ShmPutImage;
298
299		e.shmseg = shm.shmid;
300		e.offset = 0;
301
302		XSendEvent(dpy, e.drawable, False, 0, (XEvent *)&e);
303		XSync(dpy, False);
304
305		if (_x_error_occurred == 0) {
306			*shm_opcode = codes->major_opcode;
307			*shm_event = codes->first_event;
308			*shm_pixmap = has_pixmap;
309		}
310	}
311
312	XShmDetach(dpy, &shm);
313	shmctl(shm.shmid, IPC_RMID, NULL);
314	shmdt(shm.shmaddr);
315
316	return has_shm;
317}
318
319#ifdef DRI3
320#include <X11/Xlib-xcb.h>
321#include <X11/xshmfence.h>
322#include <xcb/xcb.h>
323#include <xcb/dri3.h>
324#include <xcb/sync.h>
325static Pixmap dri3_create_pixmap(Display *dpy,
326				 Drawable draw,
327				 int width, int height, int depth,
328				 int fd, int bpp, int stride, int size)
329{
330	xcb_connection_t *c = XGetXCBConnection(dpy);
331	xcb_pixmap_t pixmap = xcb_generate_id(c);
332	xcb_dri3_pixmap_from_buffer(c, pixmap, draw, size, width, height, stride, depth, bpp, fd);
333	return pixmap;
334}
335
336static int dri3_create_fd(Display *dpy,
337			  Pixmap pixmap,
338			  int *stride)
339{
340	xcb_connection_t *c = XGetXCBConnection(dpy);
341	xcb_dri3_buffer_from_pixmap_cookie_t cookie;
342	xcb_dri3_buffer_from_pixmap_reply_t *reply;
343
344	cookie = xcb_dri3_buffer_from_pixmap(c, pixmap);
345	reply = xcb_dri3_buffer_from_pixmap_reply(c, cookie, NULL);
346	if (!reply)
347		return -1;
348
349	if (reply->nfd != 1)
350		return -1;
351
352	*stride = reply->stride;
353	return xcb_dri3_buffer_from_pixmap_reply_fds(c, reply)[0];
354}
355
356static int dri3_query_version(Display *dpy, int *major, int *minor)
357{
358	xcb_connection_t *c = XGetXCBConnection(dpy);
359	xcb_dri3_query_version_reply_t *reply;
360
361	*major = *minor = -1;
362
363	reply = xcb_dri3_query_version_reply(c,
364					     xcb_dri3_query_version(c,
365								    XCB_DRI3_MAJOR_VERSION,
366								    XCB_DRI3_MINOR_VERSION),
367					     NULL);
368	if (reply == NULL)
369		return -1;
370
371	*major = reply->major_version;
372	*minor = reply->minor_version;
373	free(reply);
374
375	return 0;
376}
377
378static int dri3_exists(Display *dpy)
379{
380	int major, minor;
381
382	if (dri3_query_version(dpy, &major, &minor) < 0)
383		return 0;
384
385	return major >= 0;
386}
387
388static void dri3_create_fence(Display *dpy, Drawable d, struct dri3_fence *fence)
389{
390	xcb_connection_t *c = XGetXCBConnection(dpy);
391	struct dri3_fence f;
392	int fd;
393
394	fd = xshmfence_alloc_shm();
395	if (fd < 0)
396		return;
397
398	f.addr = xshmfence_map_shm(fd);
399	if (f.addr == NULL) {
400		close(fd);
401		return;
402	}
403
404	f.xid = xcb_generate_id(c);
405	xcb_dri3_fence_from_fd(c, d, f.xid, 0, fd);
406
407	*fence = f;
408}
409
410static void dri3_fence_flush(Display *dpy, struct dri3_fence *fence)
411{
412	xcb_sync_trigger_fence(XGetXCBConnection(dpy), fence->xid);
413}
414
415static void dri3_fence_free(Display *dpy, struct dri3_fence *fence)
416{
417	xshmfence_unmap_shm(fence->addr);
418	xcb_sync_destroy_fence(XGetXCBConnection(dpy), fence->xid);
419}
420
421#else
422
423static int dri3_exists(Display *dpy)
424{
425	return 0;
426}
427
428static void dri3_create_fence(Display *dpy, Drawable d, struct dri3_fence *fence)
429{
430}
431
432static void dri3_fence_flush(Display *dpy, struct dri3_fence *fence)
433{
434}
435
436static void dri3_fence_free(Display *dpy, struct dri3_fence *fence)
437{
438}
439
440static Pixmap dri3_create_pixmap(Display *dpy,
441				 Drawable draw,
442				 int width, int height, int depth,
443				 int fd, int bpp, int stride, int size)
444{
445	return None;
446}
447
448static int dri3_create_fd(Display *dpy,
449			  Pixmap pixmap,
450			  int *stride)
451{
452	return -1;
453}
454#endif
455
456static int timerfd(int hz)
457{
458	struct itimerspec it;
459	int fd;
460
461	fd = -1;
462#ifdef CLOCK_MONOTONIC_COARSE
463	fd = timerfd_create(CLOCK_MONOTONIC_COARSE, TFD_NONBLOCK);
464#endif
465	if (fd < 0)
466		fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK);
467	if (fd < 0)
468		return -ETIME;
469
470	it.it_interval.tv_sec = 0;
471	it.it_interval.tv_nsec = 1000000000 / hz;
472	it.it_value = it.it_interval;
473	if (timerfd_settime(fd, 0, &it, NULL) < 0) {
474		close(fd);
475		return -ETIME;
476	}
477
478	return fd;
479}
480
481static int context_init(struct context *ctx)
482{
483	struct pollfd *pfd;
484
485	memset(ctx, 0, sizeof(*ctx));
486
487	ctx->pfd = malloc(2*sizeof(struct pollfd));
488	if (ctx->pfd == NULL)
489		return -ENOMEM;
490
491	ctx->clones = malloc(sizeof(struct clone));
492	if (ctx->clones == NULL)
493		return -ENOMEM;
494
495	ctx->display = malloc(sizeof(struct display));
496	if (ctx->display == NULL)
497		return -ENOMEM;
498
499	pfd = memset(&ctx->pfd[ctx->nfd++], 0, sizeof(struct pollfd));
500	pfd->fd = timerfd(60);
501	if (pfd->fd < 0)
502		return pfd->fd;
503	pfd->events = POLLIN;
504
505	return 0;
506}
507
508static void context_enable_timer(struct context *ctx)
509{
510	uint64_t count;
511
512	DBG(TIMER, ("%s timer active? %d\n", __func__, ctx->timer_active));
513
514	if (ctx->timer_active)
515		return;
516
517	/* reset timer */
518	count = read(ctx->timer, &count, sizeof(count));
519
520	ctx->timer_active = 1;
521}
522
523static int add_fd(struct context *ctx, int fd)
524{
525	struct pollfd *pfd;
526
527	if (fd < 0)
528		return fd;
529
530	if (is_power_of_2(ctx->nfd)) {
531		ctx->pfd = realloc(ctx->pfd, 2*ctx->nfd*sizeof(struct pollfd));
532		if (ctx->pfd == NULL)
533			return -ENOMEM;
534	}
535
536	pfd = memset(&ctx->pfd[ctx->nfd++], 0, sizeof(struct pollfd));
537	pfd->fd = fd;
538	pfd->events = POLLIN;
539	return 0;
540}
541
542static void display_mark_flush(struct display *display)
543{
544	DBG(DRAW, ("%s mark flush (flush=%d)\n",
545	     DisplayString(display->dpy), display->flush));
546
547	if (display->flush)
548		return;
549
550	context_enable_timer(display->ctx);
551	display->flush = 1;
552}
553
554static int mode_equal(const XRRModeInfo *a, const XRRModeInfo *b)
555{
556	return (a->width == b->width &&
557		a->height == b->height &&
558		a->dotClock == b->dotClock &&
559		a->hSyncStart == b->hSyncStart &&
560		a->hSyncEnd == b->hSyncEnd &&
561		a->hTotal == b->hTotal &&
562		a->hSkew == b->hSkew &&
563		a->vSyncStart == b->vSyncStart &&
564		a->vSyncEnd == b->vSyncEnd &&
565		a->vTotal == b->vTotal &&
566		a->modeFlags == b->modeFlags);
567}
568
569static XRRModeInfo *lookup_mode(XRRScreenResources *res, int id)
570{
571	int i;
572
573	for (i = 0; i < res->nmode; i++) {
574		if (res->modes[i].id == id)
575			return &res->modes[i];
576	}
577
578	return NULL;
579}
580
581static void clone_update_edid(struct clone *clone)
582{
583	unsigned long nitems, after;
584	unsigned char *data;
585	int format;
586	Atom type;
587
588	if (XRRGetOutputProperty(clone->dst.dpy, clone->dst.rr_output,
589				 XInternAtom(clone->dst.dpy, "EDID", False),
590				 0, 100, False, False, AnyPropertyType,
591				 &type, &format, &nitems, &after, &data) == Success) {
592		XRRChangeOutputProperty(clone->src.dpy, clone->src.rr_output,
593					XInternAtom(clone->src.dpy, "EDID", False),
594					type, format, PropModeReplace, data, nitems);
595	}
596}
597
598static int disable_crtc(Display *dpy, XRRScreenResources *res, RRCrtc crtc)
599{
600	XRRPanning panning;
601
602	if (crtc) {
603		XRRSetPanning(dpy, res, crtc, memset(&panning, 0, sizeof(panning)));
604
605		if (XRRSetCrtcConfig(dpy, res, crtc, CurrentTime, 0, 0, None, RR_Rotate_0, NULL, 0) != Success)
606			return 0;
607
608		if (XRRSetPanning(dpy, res, crtc, memset(&panning, 0, sizeof(panning))) != Success) {
609			DBG(XRR, ("%s failed to clear panning on CRTC:%ld\n", DisplayString(dpy), (long)crtc));
610			if (verbose) {
611				XRRCrtcInfo *c;
612				XRRPanning *p;
613
614				c = XRRGetCrtcInfo(dpy, res, crtc);
615				if (c) {
616					DBG(XRR, ("%s CRTC:%ld x=%d, y=%d, rotation=%d, mode=%ld\n",
617					     DisplayString(dpy), (long)crtc,
618					     c->x, c->y, c->rotation, c->mode));
619					XRRFreeCrtcInfo(c);
620				}
621
622				p = XRRGetPanning(dpy, res, crtc);
623				if (p) {
624					DBG(XRR, ("%s CRTC:%ld panning (%d, %d)x(%d, %d), tracking (%d, %d)x(%d, %d), border (%d, %d),(%d, %d)\n",
625					     DisplayString(dpy), (long)crtc,
626					     p->left, p->top, p->width, p->height,
627					     p->track_left, p->track_top, p->track_width, p->track_height,
628					     p->border_left, p->border_top, p->border_right, p->border_bottom));
629					XRRFreePanning(p);
630				}
631			}
632		}
633	}
634
635	return 1;
636}
637
638static int clone_update_modes__randr(struct clone *clone)
639{
640	XRRScreenResources *from_res = NULL, *to_res = NULL;
641	XRROutputInfo *from_info = NULL, *to_info = NULL;
642	int i, j, ret = ENOENT;
643
644	assert(clone->src.rr_output);
645	assert(clone->dst.rr_output);
646	assert(clone->dst.display->rr_event);
647
648	from_res = _XRRGetScreenResourcesCurrent(clone->dst.dpy, clone->dst.window);
649	if (from_res == NULL)
650		goto err;
651
652	from_info = XRRGetOutputInfo(clone->dst.dpy, from_res, clone->dst.rr_output);
653	if (from_info == NULL)
654		goto err;
655
656	DBG(XRR, ("%s(%s-%s <- %s-%s): timestamp %ld (last %ld)\n", __func__,
657	     DisplayString(clone->src.dpy), clone->src.name,
658	     DisplayString(clone->dst.dpy), clone->dst.name,
659	     from_info->timestamp, clone->timestamp));
660
661	to_res = _XRRGetScreenResourcesCurrent(clone->src.dpy, clone->src.window);
662	if (to_res == NULL)
663		goto err;
664
665	to_info = XRRGetOutputInfo(clone->src.dpy, to_res, clone->src.rr_output);
666	if (to_info == NULL)
667		goto err;
668
669	DBG(XRR, ("%s: dst.rr_crtc=%ld, now %ld\n",
670	     __func__, (long)clone->dst.rr_crtc, (long)from_info->crtc));
671	if (clone->dst.rr_crtc == from_info->crtc) {
672		for (i = 0; i < to_info->nmode; i++) {
673			XRRModeInfo *mode, *old;
674
675			mode = lookup_mode(to_res, to_info->modes[i]);
676			if (mode == NULL)
677				break;
678
679			DBG(XRR, ("%s(%s-%s): lookup mode %s\n", __func__,
680			     DisplayString(clone->src.dpy), clone->src.name,
681			     mode->name));
682
683			for (j = 0; j < from_info->nmode; j++) {
684				old = lookup_mode(from_res, from_info->modes[j]);
685				if (old && mode_equal(mode, old)) {
686					mode = NULL;
687					break;
688				}
689			}
690			if (mode) {
691				DBG(XRR, ("%s(%s-%s): unknown mode %s\n", __func__,
692				     DisplayString(clone->src.dpy), clone->src.name,
693				     mode->name));
694				break;
695			}
696		}
697		if (i == from_info->nmode && i == to_info->nmode) {
698			DBG(XRR, ("%s(%s-%s): no change in output\n", __func__,
699			     DisplayString(clone->src.dpy), clone->src.name));
700			goto done;
701		}
702	}
703
704	/* Disable the remote output */
705	if (from_info->crtc != clone->dst.rr_crtc) {
706		DBG(XRR, ("%s(%s-%s): disabling active CRTC\n", __func__,
707		     DisplayString(clone->dst.dpy), clone->dst.name));
708		if (disable_crtc(clone->dst.dpy, from_res, from_info->crtc)) {
709			clone->dst.rr_crtc = 0;
710			clone->dst.mode.id = 0;
711		} else {
712			XRRCrtcInfo *c = XRRGetCrtcInfo(clone->dst.dpy, from_res, from_info->crtc);
713			if (c) {
714				clone->dst.x = c->x;
715				clone->dst.y = c->y;
716				clone->dst.rotation = c->rotation;
717				clone->dst.mode.id = c->mode;
718				XRRFreeCrtcInfo(c);
719			}
720		}
721	}
722
723	/* Create matching modes for the real output on the virtual */
724	XGrabServer(clone->src.dpy);
725
726	/* Clear all current UserModes on the output, including any active ones */
727	if (to_info->crtc) {
728		DBG(XRR, ("%s(%s-%s): disabling active CRTC\n", __func__,
729		     DisplayString(clone->src.dpy), clone->src.name));
730		disable_crtc(clone->src.dpy, to_res, to_info->crtc);
731	}
732	for (i = 0; i < to_info->nmode; i++) {
733		DBG(XRR, ("%s(%s-%s): deleting mode %ld\n", __func__,
734		     DisplayString(clone->src.dpy), clone->src.name, (long)to_info->modes[i]));
735		XRRDeleteOutputMode(clone->src.dpy, clone->src.rr_output, to_info->modes[i]);
736	}
737
738	clone->src.rr_crtc = 0;
739
740	for (i = 0; i < from_info->nmode; i++) {
741		XRRModeInfo *mode, *old;
742		RRMode id;
743
744		mode = lookup_mode(from_res, from_info->modes[i]);
745		if (mode == NULL)
746			continue;
747		for (j = 0; j < i; j++) {
748			old = lookup_mode(from_res, from_info->modes[j]);
749			if (old && mode_equal(mode, old)) {
750				mode = NULL;
751				break;
752			}
753		}
754		if (mode == NULL)
755			continue;
756
757		id = 0;
758		for (j = 0; j < to_res->nmode; j++) {
759			old = &to_res->modes[j];
760			if (mode_equal(mode, old)) {
761				id = old->id;
762				DBG(XRR, ("%s(%s-%s): reusing mode %ld: %s\n", __func__,
763				     DisplayString(clone->src.dpy), clone->src.name, id, mode->name));
764				break;
765			}
766		}
767		if (id == 0) {
768			XRRModeInfo m;
769			char buf[256];
770
771			/* XXX User names must be unique! */
772			m = *mode;
773			m.nameLength = snprintf(buf, sizeof(buf),
774						"%s.%ld-%s", clone->src.name, (long)from_info->modes[i], mode->name);
775			m.name = buf;
776
777			id = XRRCreateMode(clone->src.dpy, clone->src.window, &m);
778			DBG(XRR, ("%s(%s-%s): adding mode %ld: %s\n", __func__,
779			     DisplayString(clone->src.dpy), clone->src.name, id, mode->name));
780		}
781
782		XRRAddOutputMode(clone->src.dpy, clone->src.rr_output, id);
783	}
784	clone_update_edid(clone);
785	XUngrabServer(clone->src.dpy);
786done:
787	ret = 0;
788	clone->timestamp = from_info->timestamp;
789
790err:
791	if (to_info)
792		XRRFreeOutputInfo(to_info);
793	if (to_res)
794		XRRFreeScreenResources(to_res);
795	if (from_info)
796		XRRFreeOutputInfo(from_info);
797	if (from_res)
798		XRRFreeScreenResources(from_res);
799
800	return ret;
801}
802
803static int clone_update_modes__fixed(struct clone *clone)
804{
805	char mode_name[80];
806	XRRScreenResources *res = NULL;
807	XRROutputInfo *info = NULL;
808	XRRModeInfo mode;
809	RRMode id;
810	int i, j, ret = ENOENT;
811
812	assert(clone->src.rr_output);
813
814	res = _XRRGetScreenResourcesCurrent(clone->src.dpy, clone->src.window);
815	if (res == NULL)
816		goto err;
817
818	info = XRRGetOutputInfo(clone->src.dpy, res, clone->src.rr_output);
819	if (info == NULL)
820		goto err;
821
822	XGrabServer(clone->src.dpy);
823
824	/* Clear all current UserModes on the output, including any active ones */
825	if (info->crtc) {
826		DBG(XRR, ("%s(%s-%s): disabling active CRTC\n", __func__,
827		     DisplayString(clone->src.dpy), clone->src.name));
828		disable_crtc(clone->src.dpy, res, info->crtc);
829	}
830	for (i = 0; i < info->nmode; i++) {
831		DBG(XRR, ("%s(%s-%s): deleting mode %ld\n", __func__,
832		     DisplayString(clone->src.dpy), clone->src.name, (long)info->modes[i]));
833		XRRDeleteOutputMode(clone->src.dpy, clone->src.rr_output, info->modes[i]);
834	}
835
836	clone->src.rr_crtc = 0;
837
838	/* Create matching mode for the real output on the virtual */
839	memset(&mode, 0, sizeof(mode));
840	mode.width = clone->width;
841	mode.height = clone->height;
842	mode.nameLength = sprintf(mode_name, "FAKE-%dx%d", mode.width, mode.height);
843	mode.name = mode_name;
844
845	id = 0;
846	for (j = 0; j < res->nmode; j++) {
847		if (mode_equal(&mode, &res->modes[j])) {
848			id = res->modes[j].id;
849			break;
850		}
851	}
852	if (id == 0)
853		id = XRRCreateMode(clone->src.dpy, clone->src.window, &mode);
854
855	XRRAddOutputMode(clone->src.dpy, clone->src.rr_output, id);
856
857	XUngrabServer(clone->src.dpy);
858	ret = 0;
859err:
860	if (info)
861		XRRFreeOutputInfo(info);
862	if (res)
863		XRRFreeScreenResources(res);
864
865	return ret;
866}
867
868static RROutput claim_virtual(struct display *display, char *output_name, int nclone)
869{
870	char mode_name[] = "ClaimVirtualHead";
871	Display *dpy = display->dpy;
872	XRRScreenResources *res;
873	XRROutputInfo *output;
874	XRRModeInfo mode;
875	RRMode id;
876	RROutput rr_output = 0;
877	int i;
878
879	DBG(X11, ("%s(%d)\n", __func__, nclone));
880	XGrabServer(dpy);
881
882	res = _XRRGetScreenResourcesCurrent(dpy, display->root);
883	if (res == NULL)
884		goto out;
885
886	sprintf(output_name, "VIRTUAL%d", nclone);
887
888	for (i = rr_output = 0; rr_output == 0 && i < res->noutput; i++) {
889		output = XRRGetOutputInfo(dpy, res, res->outputs[i]);
890		if (output == NULL)
891			continue;
892
893		if (strcmp(output->name, output_name) == 0)
894			rr_output = res->outputs[i];
895
896		XRRFreeOutputInfo(output);
897	}
898	for (i = id = 0; id == 0 && i < res->nmode; i++) {
899		if (strcmp(res->modes[i].name, mode_name) == 0)
900			id = res->modes[i].id;
901	}
902	XRRFreeScreenResources(res);
903
904	DBG(XRR, ("%s(%s): rr_output=%ld\n", __func__, output_name, (long)rr_output));
905	if (rr_output == 0)
906		goto out;
907
908	/* Set any mode on the VirtualHead to make the Xserver allocate another */
909	memset(&mode, 0, sizeof(mode));
910	mode.width = 1024;
911	mode.height = 768;
912	mode.name = mode_name;
913	mode.nameLength = sizeof(mode_name) - 1;
914
915	if (id == 0)
916		id = XRRCreateMode(dpy, display->root, &mode);
917	XRRAddOutputMode(dpy, rr_output, id);
918
919	/* Force a redetection for the ddx to spot the new outputs */
920	res = XRRGetScreenResources(dpy, display->root);
921	if (res == NULL)
922		goto out;
923
924	/* Some else may have interrupted us and installed that new mode! */
925	output = XRRGetOutputInfo(dpy, res, rr_output);
926	if (output) {
927		disable_crtc(dpy, res, output->crtc);
928		XRRFreeOutputInfo(output);
929	}
930	XRRFreeScreenResources(res);
931
932	XRRDeleteOutputMode(dpy, rr_output, id);
933	XRRDestroyMode(dpy, id);
934
935	/* And hide it again */
936	res = XRRGetScreenResources(dpy, display->root);
937	if (res != NULL)
938		XRRFreeScreenResources(res);
939out:
940	XUngrabServer(dpy);
941
942	return rr_output;
943}
944
945static int stride_for_depth(int width, int depth)
946{
947	if (depth == 24)
948		depth = 32;
949	return ((width * depth + 7) / 8 + 3) & ~3;
950}
951
952static void init_image(struct clone *clone)
953{
954	XImage *image = &clone->image;
955	int ret;
956
957	image->width = clone->width;
958	image->height = clone->height;
959	image->format = ZPixmap;
960	image->xoffset = 0;
961	image->byte_order = LSBFirst;
962	image->bitmap_unit = 32;
963	image->bitmap_bit_order = LSBFirst;
964	image->bitmap_pad = 32;
965	image->data = clone->shm.shmaddr;
966	image->bytes_per_line = stride_for_depth(clone->width, clone->depth);
967	switch (clone->depth) {
968	case 24:
969		image->red_mask = 0xff << 16;
970		image->green_mask = 0xff << 8;
971		image->blue_mask = 0xff << 0;;
972		image->depth = 24;
973		image->bits_per_pixel = 32;
974		break;
975	case 16:
976		image->red_mask = 0x1f << 11;
977		image->green_mask = 0x3f << 5;
978		image->blue_mask = 0x1f << 0;;
979		image->depth = 16;
980		image->bits_per_pixel = 16;
981		break;
982	}
983
984	ret = XInitImage(image);
985	assert(ret);
986	(void)ret;
987}
988
989static int mode_height(const XRRModeInfo *mode, Rotation rotation)
990{
991	switch (rotation & 0xf) {
992	case RR_Rotate_0:
993	case RR_Rotate_180:
994		return mode->height;
995	case RR_Rotate_90:
996	case RR_Rotate_270:
997		return mode->width;
998	default:
999		return 0;
1000	}
1001}
1002
1003static int mode_width(const XRRModeInfo *mode, Rotation rotation)
1004{
1005	switch (rotation & 0xf) {
1006	case RR_Rotate_0:
1007	case RR_Rotate_180:
1008		return mode->width;
1009	case RR_Rotate_90:
1010	case RR_Rotate_270:
1011		return mode->height;
1012	default:
1013		return 0;
1014	}
1015}
1016
1017static void output_init_xfer(struct clone *clone, struct output *output)
1018{
1019	if (output->pixmap == None && output->use_shm_pixmap) {
1020		DBG(DRAW, ("%s-%s: creating shm pixmap\n", DisplayString(output->dpy), output->name));
1021		XSync(output->dpy, False);
1022		_x_error_occurred = 0;
1023
1024		output->pixmap = XShmCreatePixmap(output->dpy, output->window,
1025						  clone->shm.shmaddr, &output->shm,
1026						  clone->width, clone->height, clone->depth);
1027		if (output->pix_picture) {
1028			XRenderFreePicture(output->dpy, output->pix_picture);
1029			output->pix_picture = None;
1030		}
1031
1032		XSync(output->dpy, False);
1033		if (_x_error_occurred) {
1034			XFreePixmap(output->dpy, output->pixmap);
1035			output->pixmap = None;
1036			output->use_shm_pixmap = 0;
1037		}
1038	}
1039	if (output->use_render) {
1040		DBG(DRAW, ("%s-%s: creating picture\n", DisplayString(output->dpy), output->name));
1041		if (output->win_picture == None)
1042			output->win_picture = XRenderCreatePicture(output->dpy, output->window,
1043								   output->display->root_format, 0, NULL);
1044		if (output->pixmap == None)
1045			output->pixmap = XCreatePixmap(output->dpy, output->window,
1046						       clone->width, clone->height, clone->depth);
1047		if (output->pix_picture == None)
1048			output->pix_picture = XRenderCreatePicture(output->dpy, output->pixmap,
1049								   output->use_render, 0, NULL);
1050	}
1051
1052	if (output->gc == None) {
1053		XGCValues gcv;
1054
1055		DBG(DRAW, ("%s-%s: creating gc\n", DisplayString(output->dpy), output->name));
1056
1057		gcv.graphics_exposures = False;
1058		gcv.subwindow_mode = IncludeInferiors;
1059
1060		output->gc = XCreateGC(output->dpy, output->pixmap ?: output->window, GCGraphicsExposures | GCSubwindowMode, &gcv);
1061	}
1062}
1063
1064static int bpp_for_depth(int depth)
1065{
1066	switch (depth) {
1067	case 1: return 1;
1068	case 8: return 8;
1069	case 15: return 16;
1070	case 16: return 16;
1071	case 24: return 24;
1072	case 32: return 32;
1073	default: return 0;
1074	}
1075}
1076
1077static int clone_init_xfer(struct clone *clone)
1078{
1079	int width, height;
1080
1081	if (clone->dst.mode.id == 0) {
1082		width = 0;
1083		height = 0;
1084	} else if (clone->dri3.xid) {
1085		width = clone->dst.display->width;
1086		height = clone->dst.display->height;
1087	} else {
1088		width = mode_width(&clone->src.mode, clone->src.rotation);
1089		height = mode_height(&clone->src.mode, clone->src.rotation);
1090	}
1091
1092	if (width == clone->width && height == clone->height)
1093		return 0;
1094
1095	DBG(DRAW, ("%s-%s create xfer, %dx%d\n",
1096	     DisplayString(clone->dst.dpy), clone->dst.name,
1097	     width, height));
1098
1099	if (clone->shm.shmaddr) {
1100		if (clone->src.use_shm)
1101			XShmDetach(clone->src.dpy, &clone->src.shm);
1102		if (clone->dst.use_shm)
1103			XShmDetach(clone->dst.dpy, &clone->dst.shm);
1104
1105		shmdt(clone->shm.shmaddr);
1106		clone->shm.shmaddr = NULL;
1107	}
1108
1109	if (clone->src.pixmap) {
1110		XFreePixmap(clone->src.dpy, clone->src.pixmap);
1111		clone->src.pixmap = 0;
1112	}
1113
1114	if (clone->dst.pixmap) {
1115		XFreePixmap(clone->dst.dpy, clone->dst.pixmap);
1116		clone->dst.pixmap = 0;
1117	}
1118
1119	if ((width | height) == 0) {
1120		clone->damaged.x2 = clone->damaged.y2 = INT_MIN;
1121		clone->damaged.x1 = clone->damaged.y1 = INT_MAX;
1122		return 0;
1123	}
1124
1125	if (clone->dri3.xid) {
1126		int fd, stride;
1127		Pixmap src;
1128
1129		_x_error_occurred = 0;
1130
1131		DBG(DRAW, ("%s-%s create xfer, trying DRI3\n",
1132		     DisplayString(clone->dst.dpy), clone->dst.name));
1133
1134		fd = dri3_create_fd(clone->dst.dpy, clone->dst.window, &stride);
1135		if (fd < 0)
1136			goto disable_dri3;
1137
1138		DBG(DRAW, ("%s-%s create xfer, DRI3 fd=%d, stride=%d\n",
1139		     DisplayString(clone->dst.dpy), clone->dst.name,
1140		     fd, stride));
1141
1142		src = dri3_create_pixmap(clone->src.dpy, clone->src.window,
1143					 width, height, clone->depth,
1144					 fd, bpp_for_depth(clone->depth),
1145					 stride, lseek(fd, 0, SEEK_END));
1146
1147		XSync(clone->src.dpy, False);
1148		if (!_x_error_occurred) {
1149			clone->src.pixmap = src;
1150			clone->width = width;
1151			clone->height = height;
1152		} else {
1153			XFreePixmap(clone->src.dpy, src);
1154			close(fd);
1155disable_dri3:
1156			dri3_fence_free(clone->src.dpy, &clone->dri3);
1157			clone->dri3.xid = 0;
1158
1159			DBG(DRAW, ("%s-%s create xfer, DRI3 failed\n",
1160			     DisplayString(clone->dst.dpy), clone->dst.name));
1161		}
1162	}
1163
1164	width = mode_width(&clone->src.mode, clone->src.rotation);
1165	height = mode_height(&clone->src.mode, clone->src.rotation);
1166
1167	if (!clone->dri3.xid) {
1168		DBG(DRAW, ("%s-%s create xfer, trying SHM\n",
1169		     DisplayString(clone->dst.dpy), clone->dst.name));
1170
1171		clone->shm.shmid = shmget(IPC_PRIVATE,
1172					  height * stride_for_depth(width, clone->depth),
1173					  IPC_CREAT | 0666);
1174		if (clone->shm.shmid == -1)
1175			return errno;
1176
1177		clone->shm.shmaddr = shmat(clone->shm.shmid, 0, 0);
1178		if (clone->shm.shmaddr == (char *) -1) {
1179			shmctl(clone->shm.shmid, IPC_RMID, NULL);
1180			return ENOMEM;
1181		}
1182
1183		if (clone->src.use_shm) {
1184			clone->src.shm = clone->shm;
1185			clone->src.shm.readOnly = False;
1186			XShmAttach(clone->src.dpy, &clone->src.shm);
1187			XSync(clone->src.dpy, False);
1188		}
1189		if (clone->dst.use_shm) {
1190			clone->dst.shm = clone->shm;
1191			clone->dst.shm.readOnly = !clone->dst.use_shm_pixmap;
1192			XShmAttach(clone->dst.dpy, &clone->dst.shm);
1193			XSync(clone->dst.dpy, False);
1194		}
1195
1196		shmctl(clone->shm.shmid, IPC_RMID, NULL);
1197
1198		clone->width = width;
1199		clone->height = height;
1200
1201		init_image(clone);
1202	}
1203
1204	output_init_xfer(clone, &clone->src);
1205	output_init_xfer(clone, &clone->dst);
1206
1207	clone->damaged.x1 = clone->src.x;
1208	clone->damaged.x2 = clone->src.x + width;
1209	clone->damaged.y1 = clone->src.y;
1210	clone->damaged.y2 = clone->src.y + height;
1211
1212	display_mark_flush(clone->dst.display);
1213	return 0;
1214}
1215
1216static void clone_update(struct clone *clone)
1217{
1218	if (!clone->rr_update)
1219		return;
1220
1221	DBG(X11, ("%s-%s cloning modes\n",
1222	     DisplayString(clone->dst.dpy), clone->dst.name));
1223
1224	clone_update_modes__randr(clone);
1225	clone->rr_update = 0;
1226}
1227
1228static int context_update(struct context *ctx)
1229{
1230	Display *dpy = ctx->display->dpy;
1231	XRRScreenResources *res;
1232	int context_changed = 0;
1233	int i, n;
1234
1235	DBG(X11, ("%s\n", __func__));
1236
1237	res = _XRRGetScreenResourcesCurrent(dpy, ctx->display->root);
1238	if (res == NULL)
1239		return 0;
1240
1241	DBG(XRR, ("%s timestamp %ld (last %ld), config %ld (last %ld)\n",
1242	     DisplayString(dpy),
1243	     res->timestamp, ctx->timestamp,
1244	     res->configTimestamp, ctx->configTimestamp));
1245	if (res->timestamp == ctx->timestamp &&
1246	    res->configTimestamp == ctx->configTimestamp &&
1247	    res->timestamp != res->configTimestamp) { /* mutter be damned */
1248		XRRFreeScreenResources(res);
1249		return 0;
1250	}
1251
1252	ctx->timestamp = res->timestamp;
1253	ctx->configTimestamp = res->configTimestamp;
1254
1255	for (n = 0; n < ctx->nclone; n++) {
1256		struct output *output = &ctx->clones[n].src;
1257		XRROutputInfo *o;
1258		XRRCrtcInfo *c;
1259		RRMode mode = 0;
1260		int changed = 0;
1261
1262		o = XRRGetOutputInfo(dpy, res, output->rr_output);
1263		if (o == NULL)
1264			continue;
1265
1266		c = NULL;
1267		if (o->crtc)
1268			c = XRRGetCrtcInfo(dpy, res, o->crtc);
1269		if (c) {
1270			DBG(XRR, ("%s-%s: (x=%d, y=%d, rotation=%d, mode=%ld) -> (x=%d, y=%d, rotation=%d, mode=%ld)\n",
1271			     DisplayString(dpy), output->name,
1272			     output->x, output->y, output->rotation, output->mode.id,
1273			     c->x, c->y, c->rotation, c->mode));
1274
1275			changed |= output->rotation != c->rotation;
1276			output->rotation = c->rotation;
1277
1278			changed |= output->x != c->x;
1279			output->x = c->x;
1280
1281			changed |= output->y != c->y;
1282			output->y = c->y;
1283
1284			changed |= output->mode.id != c->mode;
1285			mode = c->mode;
1286			XRRFreeCrtcInfo(c);
1287		} else {
1288			DBG(XRR, ("%s-%s: (x=%d, y=%d, rotation=%d, mode=%ld) -> off\n",
1289			     DisplayString(dpy), output->name,
1290			     output->x, output->y, output->rotation, output->mode.id));
1291		}
1292		output->rr_crtc = o->crtc;
1293		XRRFreeOutputInfo(o);
1294
1295		DBG(XRR, ("%s-%s crtc changed? %d\n",
1296		     DisplayString(ctx->clones[n].dst.display->dpy), ctx->clones[n].dst.name, changed));
1297
1298		if (mode) {
1299			if (output->mode.id != mode) {
1300				for (i = 0; i < res->nmode; i++) {
1301					if (res->modes[i].id == mode) {
1302						output->mode = res->modes[i];
1303						break;
1304					}
1305				}
1306			}
1307		} else {
1308			changed = output->mode.id != 0;
1309			output->mode.id = 0;
1310		}
1311
1312		DBG(XRR, ("%s-%s output changed? %d\n",
1313		     DisplayString(ctx->clones[n].dst.display->dpy), ctx->clones[n].dst.name, changed));
1314
1315		context_changed |= changed;
1316	}
1317	XRRFreeScreenResources(res);
1318
1319	DBG(XRR, ("%s changed? %d\n", DisplayString(dpy), context_changed));
1320	if (!context_changed)
1321		return 0;
1322
1323	for (n = 1; n < ctx->ndisplay; n++) {
1324		struct display *display = &ctx->display[n];
1325		struct clone *clone;
1326		int x1, x2, y1, y2;
1327
1328		if (display->rr_active == 0)
1329			continue;
1330
1331		x1 = y1 = INT_MAX;
1332		x2 = y2 = INT_MIN;
1333
1334		for (clone = display->clone; clone; clone = clone->next) {
1335			struct output *output = &clone->src;
1336			int v;
1337
1338			assert(clone->dst.display == display);
1339
1340			if (output->mode.id == 0)
1341				continue;
1342
1343			DBG(XRR, ("%s: source %s enabled (%d, %d)x(%d, %d)\n",
1344			     DisplayString(clone->dst.dpy), output->name,
1345			     output->x, output->y,
1346			     mode_width(&output->mode, output->rotation),
1347			     mode_height(&output->mode, output->rotation)));
1348
1349			if (output->x < x1)
1350				x1 = output->x;
1351			if (output->y < y1)
1352				y1 = output->y;
1353
1354			v = (int)output->x + mode_width(&output->mode, output->rotation);
1355			if (v > x2)
1356				x2 = v;
1357			v = (int)output->y + mode_height(&output->mode, output->rotation);
1358			if (v > y2)
1359				y2 = v;
1360		}
1361
1362		DBG(XRR, ("%s fb bounds (%d, %d)x(%d, %d)\n", DisplayString(display->dpy),
1363		     x1, y1, x2, y2));
1364
1365		XGrabServer(display->dpy);
1366		res = _XRRGetScreenResourcesCurrent(display->dpy, display->root);
1367		if (res == NULL)
1368			goto ungrab;
1369
1370		if (x2 <= x1 || y2 <= y1) {
1371			/* Nothing enabled, preserve the current fb, and turn everything off */
1372			for (clone = display->clone; clone; clone = clone->next) {
1373				struct output *dst = &clone->dst;
1374
1375				if (!dst->rr_crtc)
1376					continue;
1377
1378				DBG(XRR, ("%s: disabling output '%s'\n",
1379				     DisplayString(display->dpy), dst->name));
1380				assert(clone->dst.display == display);
1381				if (disable_crtc(display->dpy, res, dst->rr_crtc)) {
1382					dst->rr_crtc = 0;
1383					dst->mode.id = 0;
1384				}
1385			}
1386			goto free_res;
1387		}
1388
1389		x2 -= x1;
1390		y2 -= y1;
1391		DBG(XRR, ("%s: current size %dx%d, need %dx%d\n",
1392		     DisplayString(display->dpy),
1393		     display->width, display->height,
1394		     x2, y2));
1395
1396		if (display->width != x2 || display->height != y2) {
1397			/* When shrinking we have to manually resize the fb */
1398			for (clone = display->clone; clone; clone = clone->next) {
1399				struct output *dst = &clone->dst;
1400
1401				if (!dst->rr_crtc)
1402					continue;
1403
1404				DBG(XRR, ("%s: disabling output '%s'\n",
1405				     DisplayString(display->dpy), dst->name));
1406				assert(clone->dst.display == display);
1407				if (disable_crtc(display->dpy, res, dst->rr_crtc)) {
1408					dst->rr_crtc = 0;
1409					dst->mode.id = 0;
1410				}
1411			}
1412
1413			DBG(XRR, ("%s: XRRSetScreenSize %dx%d\n", DisplayString(display->dpy), x2, y2));
1414			XRRSetScreenSize(display->dpy, display->root, x2, y2, x2 * 96 / 25.4, y2 * 96 / 25.4);
1415			display->width = x2;
1416			display->height = y2;
1417		}
1418
1419		for (clone = display->clone; clone; clone = clone->next) {
1420			struct output *src = &clone->src;
1421			struct output *dst = &clone->dst;
1422			XRROutputInfo *o;
1423			XRRPanning panning;
1424			struct clone *set;
1425			RRCrtc rr_crtc;
1426			Status ret;
1427
1428			DBG(XRR, ("%s: copying configuration from %s (mode=%ld: %dx%d) to %s\n",
1429			     DisplayString(display->dpy),
1430			     src->name, (long)src->mode.id, src->mode.width, src->mode.height,
1431			     dst->name));
1432
1433			if (src->mode.id == 0) {
1434err:
1435				if (dst->rr_crtc) {
1436					DBG(XRR, ("%s: disabling unused output '%s'\n",
1437					     DisplayString(display->dpy), dst->name));
1438					assert(clone->dst.display == display);
1439					if (disable_crtc(display->dpy, res, dst->rr_crtc)) {
1440						dst->rr_crtc = 0;
1441						dst->mode.id = 0;
1442					}
1443				}
1444				continue;
1445			}
1446
1447			dst->x = src->x - x1;
1448			dst->y = src->y - y1;
1449			dst->rotation = src->rotation;
1450			dst->mode = src->mode;
1451
1452			dst->mode.id = 0;
1453			for (i = 0; i < res->nmode; i++) {
1454				if (mode_equal(&src->mode, &res->modes[i])) {
1455					dst->mode.id = res->modes[i].id;
1456					break;
1457				}
1458			}
1459			if (dst->mode.id == 0) {
1460				XRRModeInfo m;
1461				char buf[256];
1462				RRMode id;
1463
1464				/* XXX User names must be unique! */
1465				m = src->mode;
1466				m.nameLength = snprintf(buf, sizeof(buf),
1467							"%s.%ld-%dx%d", src->name,
1468							(long)src->mode.id,
1469							src->mode.width,
1470							src->mode.height);
1471				m.name = buf;
1472
1473				id = XRRCreateMode(dst->dpy, dst->window, &m);
1474				if (id) {
1475					DBG(XRR, ("%s: adding mode %ld: %dx%d to %s, new mode %ld\n",
1476					     DisplayString(dst->dpy),
1477					     (long)src->mode.id,
1478					     src->mode.width,
1479					     src->mode.height,
1480					     dst->name, (long)id));
1481					XRRAddOutputMode(dst->dpy, dst->rr_output, id);
1482					dst->mode.id = id;
1483				} else {
1484					DBG(XRR, ("%s: failed to find suitable mode for %s\n",
1485					     DisplayString(dst->dpy), dst->name));
1486					goto err;
1487				}
1488			}
1489
1490			rr_crtc = dst->rr_crtc;
1491			if (rr_crtc) {
1492				for (set = display->clone; set != clone; set = set->next) {
1493					if (set->dst.rr_crtc == rr_crtc) {
1494						DBG(XRR, ("%s: CRTC reassigned from %s\n",
1495						     DisplayString(dst->dpy), dst->name));
1496						rr_crtc = 0;
1497						break;
1498					}
1499				}
1500			}
1501			if (rr_crtc == 0) {
1502				o = XRRGetOutputInfo(dst->dpy, res, dst->rr_output);
1503				for (i = 0; i < o->ncrtc; i++) {
1504					DBG(XRR, ("%s: checking whether CRTC:%ld is available\n",
1505					     DisplayString(dst->dpy), (long)o->crtcs[i]));
1506					for (set = display->clone; set != clone; set = set->next) {
1507						if (set->dst.rr_crtc == o->crtcs[i]) {
1508							DBG(XRR, ("%s: CRTC:%ld already assigned to %s\n",
1509							     DisplayString(dst->dpy), (long)o->crtcs[i], set->dst.name));
1510							break;
1511						}
1512					}
1513					if (set == clone) {
1514						rr_crtc = o->crtcs[i];
1515						break;
1516					}
1517				}
1518				XRRFreeOutputInfo(o);
1519			}
1520			if (rr_crtc == 0) {
1521				DBG(XRR, ("%s: failed to find available CRTC for %s\n",
1522				     DisplayString(dst->dpy), dst->name));
1523				goto err;
1524			}
1525
1526			DBG(XRR, ("%s: enabling output '%s' (%d,%d)x(%d,%d), rotation %d, on CRTC:%ld, using mode %ld\n",
1527			     DisplayString(dst->dpy), dst->name,
1528			     dst->x, dst->y, dst->mode.width, dst->mode.height,
1529			     dst->rotation, (long)rr_crtc, dst->mode.id));
1530
1531			ret = XRRSetPanning(dst->dpy, res, rr_crtc, memset(&panning, 0, sizeof(panning)));
1532			DBG(XRR, ("%s-%s: XRRSetPanning %s\n", DisplayString(dst->dpy), dst->name, ret ? "failed" : "success"));
1533			(void)ret;
1534
1535			ret = XRRSetCrtcConfig(dst->dpy, res, rr_crtc, CurrentTime,
1536					       dst->x, dst->y, dst->mode.id, dst->rotation,
1537					       &dst->rr_output, 1);
1538			DBG(XRR, ("%s-%s: XRRSetCrtcConfig %s\n", DisplayString(dst->dpy), dst->name, ret ? "failed" : "success"));
1539			if (ret)
1540				goto err;
1541
1542			if (verbose & XRR) {
1543				XRRCrtcInfo *c;
1544				XRRPanning *p;
1545
1546				c = XRRGetCrtcInfo(dst->dpy, res, rr_crtc);
1547				if (c) {
1548					DBG(XRR, ("%s-%s: x=%d, y=%d, rotation=%d, mode=%ld\n",
1549					     DisplayString(dst->dpy), dst->name,
1550					     c->x, c->y, c->rotation, c->mode));
1551					XRRFreeCrtcInfo(c);
1552				}
1553
1554				p = XRRGetPanning(dst->dpy, res, rr_crtc);
1555				if (p) {
1556					DBG(XRR, ("%s-%s: panning (%d, %d)x(%d, %d), tracking (%d, %d)x(%d, %d), border (%d, %d),(%d, %d)\n",
1557					     DisplayString(dst->dpy), dst->name,
1558					     p->left, p->top, p->width, p->height,
1559					     p->track_left, p->track_top, p->track_width, p->track_height,
1560					     p->border_left, p->border_top, p->border_right, p->border_bottom));
1561					XRRFreePanning(p);
1562				}
1563			}
1564
1565			dst->rr_crtc = rr_crtc;
1566		}
1567free_res:
1568		XRRFreeScreenResources(res);
1569ungrab:
1570		XUngrabServer(display->dpy);
1571	}
1572
1573	ctx->active = NULL;
1574	for (n = 0; n < ctx->nclone; n++) {
1575		struct clone *clone = &ctx->clones[n];
1576
1577		clone_init_xfer(clone);
1578
1579		if (clone->dst.rr_crtc == 0)
1580			continue;
1581
1582		DBG(XRR, ("%s-%s: added to active list\n",
1583		     DisplayString(clone->dst.display->dpy), clone->dst.name));
1584
1585		clone->active = ctx->active;
1586		ctx->active = clone;
1587	}
1588
1589	return 1;
1590}
1591
1592static Cursor display_load_invisible_cursor(struct display *display)
1593{
1594	char zero[8] = {};
1595	XColor black = {};
1596	Pixmap bitmap = XCreateBitmapFromData(display->dpy, display->root, zero, 8, 8);
1597	return XCreatePixmapCursor(display->dpy, bitmap, bitmap, &black, &black, 0, 0);
1598}
1599
1600static Cursor display_get_visible_cursor(struct display *display)
1601{
1602	if (display->cursor_serial != display->cursor_image.size) {
1603		DBG(CURSOR, ("%s updating cursor\n", DisplayString(display->dpy)));
1604
1605		if (display->visible_cursor)
1606			XFreeCursor(display->dpy, display->visible_cursor);
1607
1608		display->visible_cursor = XcursorImageLoadCursor(display->dpy, &display->cursor_image);
1609		display->cursor_serial = display->cursor_image.size;
1610	}
1611
1612	return display->visible_cursor;
1613}
1614
1615static void display_load_visible_cursor(struct display *display, XFixesCursorImage *cur)
1616{
1617	unsigned long *src; /* XXX deep sigh */
1618	XcursorPixel *dst;
1619	unsigned n;
1620
1621	if (cur->width != display->cursor_image.width ||
1622	    cur->height != display->cursor_image.height)
1623		display->cursor_image.pixels = realloc(display->cursor_image.pixels,
1624						       4 * cur->width * cur->height);
1625	if (display->cursor_image.pixels == NULL)
1626		return;
1627
1628	display->cursor_image.width  = cur->width;
1629	display->cursor_image.height = cur->height;
1630	display->cursor_image.xhot = cur->xhot;
1631	display->cursor_image.yhot = cur->yhot;
1632	display->cursor_image.size++;
1633
1634	n = cur->width*cur->height;
1635	src = cur->pixels;
1636	dst = display->cursor_image.pixels;
1637	while (n--)
1638		*dst++ = *src++;
1639
1640	DBG(CURSOR, ("%s marking cursor changed\n", DisplayString(display->dpy)));
1641	display->cursor_moved++;
1642	if (display->cursor != display->invisible_cursor) {
1643		display->cursor_visible++;
1644		context_enable_timer(display->ctx);
1645	}
1646}
1647
1648static void display_cursor_move(struct display *display, int x, int y, int visible)
1649{
1650	DBG(CURSOR, ("%s cursor moved (visible=%d, (%d, %d))\n",
1651	     DisplayString(display->dpy), visible, x, y));
1652	display->cursor_moved++;
1653	display->cursor_visible += visible;
1654	if (visible) {
1655		display->cursor_x = x;
1656		display->cursor_y = y;
1657	}
1658
1659	context_enable_timer(display->ctx);
1660}
1661
1662static void display_flush_cursor(struct display *display)
1663{
1664	Cursor cursor;
1665	int x, y;
1666
1667	if (!display->cursor_moved)
1668		return;
1669
1670	if (display->cursor_visible) {
1671		x = display->cursor_x;
1672		y = display->cursor_y;
1673	} else {
1674		x = display->cursor_x++ & 31;
1675		y = display->cursor_y++ & 31;
1676	}
1677
1678	DBG(CURSOR, ("%s setting cursor position (%d, %d), visible? %d\n",
1679	     DisplayString(display->dpy), x, y, display->cursor_visible));
1680	XWarpPointer(display->dpy, None, display->root, 0, 0, 0, 0, x, y);
1681
1682	cursor = None;
1683	if (display->cursor_visible)
1684		cursor = display_get_visible_cursor(display);
1685	if (cursor == None)
1686		cursor = display->invisible_cursor;
1687	if (cursor != display->cursor) {
1688		XDefineCursor(display->dpy, display->root, cursor);
1689		display->cursor = cursor;
1690	}
1691
1692	display_mark_flush(display);
1693
1694	display->cursor_moved = 0;
1695	display->cursor_visible = 0;
1696}
1697
1698static void clone_move_cursor(struct clone *c, int x, int y)
1699{
1700	int visible;
1701
1702	DBG(CURSOR, ("%s-%s moving cursor (%d, %d) [(%d, %d), (%d, %d)]\n",
1703	     DisplayString(c->dst.dpy), c->dst.name,
1704	     x, y,
1705	     c->src.x, c->src.y,
1706	     c->src.x + c->width, c->src.y + c->height));
1707
1708	visible = (x >= c->src.x && x < c->src.x + c->width &&
1709		   y >= c->src.y && y < c->src.y + c->height);
1710
1711	x += c->dst.x - c->src.x;
1712	y += c->dst.y - c->src.y;
1713
1714	display_cursor_move(c->dst.display, x, y, visible);
1715}
1716
1717static int clone_output_init(struct clone *clone, struct output *output,
1718			     struct display *display, const char *name,
1719			     RROutput rr_output)
1720{
1721	Display *dpy = display->dpy;
1722	int depth;
1723
1724	DBG(X11, ("%s(%s, %s)\n", __func__, DisplayString(dpy), name));
1725
1726	output->name = strdup(name);
1727	if (output->name == NULL)
1728		return -ENOMEM;
1729
1730	output->display = display;
1731	output->dpy = dpy;
1732
1733	output->rr_output = rr_output;
1734	output->rotation = RR_Rotate_0;
1735
1736	output->window = display->root;
1737	output->use_shm = display->has_shm;
1738	output->use_shm_pixmap = display->has_shm_pixmap;
1739
1740	DBG(X11, ("%s-%s use shm? %d (use shm pixmap? %d)\n",
1741	     DisplayString(dpy), name, display->has_shm, display->has_shm_pixmap));
1742
1743	depth = output->use_shm && !FORCE_16BIT_XFER ? display->depth : 16;
1744	if (depth < clone->depth)
1745		clone->depth = depth;
1746
1747	return 0;
1748}
1749
1750static void ximage_prepare(XImage *image, int width, int height)
1751{
1752	image->width = width;
1753	image->height = height;
1754	image->bytes_per_line = stride_for_depth(width, image->depth);
1755}
1756
1757static void get_src(struct clone *c, const XRectangle *clip)
1758{
1759	DBG(DRAW,("%s-%s get_src(%d,%d)x(%d,%d)\n", DisplayString(c->dst.dpy), c->dst.name,
1760	     clip->x, clip->y, clip->width, clip->height));
1761
1762	c->image.obdata = (char *)&c->src.shm;
1763
1764	if (c->src.use_render) {
1765		XRenderComposite(c->src.dpy, PictOpSrc,
1766				 c->src.win_picture, 0, c->src.pix_picture,
1767				 clip->x, clip->y,
1768				 0, 0,
1769				 0, 0,
1770				 clip->width, clip->height);
1771		if (c->src.use_shm_pixmap) {
1772			XSync(c->src.dpy, False);
1773		} else if (c->src.use_shm) {
1774			ximage_prepare(&c->image, clip->width, clip->height);
1775			XShmGetImage(c->src.dpy, c->src.pixmap, &c->image,
1776				     clip->x, clip->y, AllPlanes);
1777		} else {
1778			ximage_prepare(&c->image, c->width, c->height);
1779			XGetSubImage(c->src.dpy, c->src.pixmap,
1780				     clip->x, clip->y, clip->width, clip->height,
1781				     AllPlanes, ZPixmap,
1782				     &c->image, 0, 0);
1783		}
1784	} else if (c->src.pixmap) {
1785		XCopyArea(c->src.dpy, c->src.window, c->src.pixmap, c->src.gc,
1786			  clip->x, clip->y,
1787			  clip->width, clip->height,
1788			  0, 0);
1789		XSync(c->src.dpy, False);
1790	} else if (c->src.use_shm) {
1791		ximage_prepare(&c->image, clip->width, clip->height);
1792		XShmGetImage(c->src.dpy, c->src.window, &c->image,
1793			     clip->x, clip->y, AllPlanes);
1794	} else {
1795		ximage_prepare(&c->image, c->width, c->height);
1796		XGetSubImage(c->src.dpy, c->src.window,
1797			     clip->x, clip->y, clip->width, clip->height,
1798			     AllPlanes, ZPixmap,
1799			     &c->image, 0, 0);
1800	}
1801	c->src.display->flush = 0;
1802}
1803
1804static void put_dst(struct clone *c, const XRectangle *clip)
1805{
1806	DBG(DRAW, ("%s-%s put_dst(%d,%d)x(%d,%d)\n", DisplayString(c->dst.dpy), c->dst.name,
1807	     clip->x, clip->y, clip->width, clip->height));
1808
1809	c->image.obdata = (char *)&c->dst.shm;
1810
1811	if (c->dst.use_render) {
1812		if (c->dst.use_shm_pixmap) {
1813			DBG(DRAW, ("%s-%s using SHM pixmap composite\n",
1814			     DisplayString(c->dst.dpy), c->dst.name));
1815		} else if (c->dst.use_shm) {
1816			DBG(DRAW, ("%s-%s using SHM image composite\n",
1817			     DisplayString(c->dst.dpy), c->dst.name));
1818			XShmPutImage(c->dst.dpy, c->dst.pixmap, c->dst.gc, &c->image,
1819				     0, 0,
1820				     0, 0,
1821				     clip->width, clip->height,
1822				     False);
1823		} else {
1824			DBG(DRAW, ("%s-%s using composite\n",
1825			     DisplayString(c->dst.dpy), c->dst.name));
1826			XPutImage(c->dst.dpy, c->dst.pixmap, c->dst.gc, &c->image,
1827				  0, 0,
1828				  0, 0,
1829				  clip->width, clip->height);
1830		}
1831		if (c->dst.use_shm)
1832			c->dst.serial = NextRequest(c->dst.dpy);
1833		XRenderComposite(c->dst.dpy, PictOpSrc,
1834				 c->dst.pix_picture, 0, c->dst.win_picture,
1835				 0, 0,
1836				 0, 0,
1837				 clip->x, clip->y,
1838				 clip->width, clip->height);
1839		c->dst.display->send |= c->dst.use_shm;
1840	} else if (c->dst.pixmap) {
1841		DBG(DRAW, ("%s-%s using SHM pixmap\n",
1842		     DisplayString(c->dst.dpy), c->dst.name));
1843		c->dst.serial = NextRequest(c->dst.dpy);
1844		XCopyArea(c->dst.dpy, c->dst.pixmap, c->dst.window, c->dst.gc,
1845			  0, 0,
1846			  clip->width, clip->height,
1847			  clip->x, clip->y);
1848		c->dst.display->send = 1;
1849	} else if (c->dst.use_shm) {
1850		DBG(DRAW, ("%s-%s using SHM image\n",
1851		     DisplayString(c->dst.dpy), c->dst.name));
1852		c->dst.serial = NextRequest(c->dst.dpy);
1853		XShmPutImage(c->dst.dpy, c->dst.window, c->dst.gc, &c->image,
1854			     0, 0,
1855			     clip->x, clip->y,
1856			     clip->width, clip->height,
1857			     True);
1858	} else {
1859		DBG(DRAW, ("%s-%s using image\n",
1860		     DisplayString(c->dst.dpy), c->dst.name));
1861		XPutImage(c->dst.dpy, c->dst.window, c->dst.gc, &c->image,
1862			  0, 0,
1863			  clip->x, clip->y,
1864			  clip->width, clip->height);
1865		c->dst.serial = 0;
1866	}
1867}
1868
1869static int clone_paint(struct clone *c)
1870{
1871	XRectangle clip;
1872
1873	DBG(DRAW, ("%s-%s paint clone, damaged (%d, %d), (%d, %d) [(%d, %d), (%d,  %d)]\n",
1874	     DisplayString(c->dst.dpy), c->dst.name,
1875	     c->damaged.x1, c->damaged.y1,
1876	     c->damaged.x2, c->damaged.y2,
1877	     c->src.x, c->src.y,
1878	     c->src.x + c->width, c->src.y + c->height));
1879
1880	if (c->damaged.x1 < c->src.x)
1881		c->damaged.x1 = c->src.x;
1882	if (c->damaged.x2 > c->src.x + c->width)
1883		c->damaged.x2 = c->src.x + c->width;
1884	if (c->damaged.x2 <= c->damaged.x1)
1885		goto done;
1886
1887	if (c->damaged.y1 < c->src.y)
1888		c->damaged.y1 = c->src.y;
1889	if (c->damaged.y2 > c->src.y + c->height)
1890		c->damaged.y2 = c->src.y + c->height;
1891	if (c->damaged.y2 <= c->damaged.y1)
1892		goto done;
1893
1894	DBG(DRAW, ("%s-%s is damaged, last SHM serial: %ld, now %ld\n",
1895	     DisplayString(c->dst.dpy), c->dst.name,
1896	     (long)c->dst.serial, (long)LastKnownRequestProcessed(c->dst.dpy)));
1897	if (c->dst.serial > LastKnownRequestProcessed(c->dst.dpy)) {
1898		struct pollfd pfd;
1899
1900		pfd.fd = ConnectionNumber(c->dst.dpy);
1901		pfd.events = POLLIN;
1902		XEventsQueued(c->dst.dpy,
1903			      poll(&pfd, 1, 0) ? QueuedAfterReading : QueuedAfterFlush);
1904
1905		if (c->dst.serial > LastKnownRequestProcessed(c->dst.dpy)) {
1906			c->dst.display->skip_clone++;
1907			return EAGAIN;
1908		}
1909	}
1910
1911	c->dst.display->skip_clone = 0;
1912	c->dst.display->skip_frame = 0;
1913
1914	if (FORCE_FULL_REDRAW) {
1915		c->damaged.x1 = c->src.x;
1916		c->damaged.y1 = c->src.y;
1917		c->damaged.x2 = c->src.x + c->width;
1918		c->damaged.y2 = c->src.y + c->height;
1919	}
1920
1921	if (c->dri3.xid) {
1922		if (c->src.use_render) {
1923			XRenderComposite(c->src.dpy, PictOpSrc,
1924					 c->src.win_picture, 0, c->src.pix_picture,
1925					 c->damaged.x1, c->damaged.y1,
1926					 0, 0,
1927					 c->damaged.x1 + c->dst.x - c->src.x,
1928					 c->damaged.y1 + c->dst.y - c->src.y,
1929					 c->damaged.x2 - c->damaged.x1,
1930					 c->damaged.y2 - c->damaged.y1);
1931		} else {
1932			XCopyArea(c->src.dpy, c->src.window, c->src.pixmap, c->src.gc,
1933				  c->damaged.x1, c->damaged.y1,
1934				  c->damaged.x2 - c->damaged.x1,
1935				  c->damaged.y2 - c->damaged.y1,
1936				  c->damaged.x1 + c->dst.x - c->src.x,
1937				  c->damaged.y1 + c->dst.y - c->src.y);
1938		}
1939		dri3_fence_flush(c->src.dpy, &c->dri3);
1940	} else {
1941		clip.x = c->damaged.x1;
1942		clip.y = c->damaged.y1;
1943		clip.width  = c->damaged.x2 - c->damaged.x1;
1944		clip.height = c->damaged.y2 - c->damaged.y1;
1945		get_src(c, &clip);
1946
1947		clip.x += c->dst.x - c->src.x;
1948		clip.y += c->dst.y - c->src.y;
1949		put_dst(c, &clip);
1950	}
1951	display_mark_flush(c->dst.display);
1952
1953done:
1954	c->damaged.x2 = c->damaged.y2 = INT_MIN;
1955	c->damaged.x1 = c->damaged.y1 = INT_MAX;
1956	return 0;
1957}
1958
1959static void clone_damage(struct clone *c, const XRectangle *rec)
1960{
1961	int v;
1962
1963	if ((v = rec->x) < c->damaged.x1)
1964		c->damaged.x1 = v;
1965	if ((v = (int)rec->x + rec->width) > c->damaged.x2)
1966		c->damaged.x2 = v;
1967	if ((v = rec->y) < c->damaged.y1)
1968		c->damaged.y1 = v;
1969	if ((v = (int)rec->y + rec->height) > c->damaged.y2)
1970		c->damaged.y2 = v;
1971
1972	DBG(DAMAGE, ("%s-%s damaged: (%d, %d), (%d, %d)\n",
1973	     DisplayString(c->dst.display->dpy), c->dst.name,
1974	     c->damaged.x1, c->damaged.y1,
1975	     c->damaged.x2, c->damaged.y2));
1976}
1977
1978static void usage(const char *arg0)
1979{
1980	printf("Usage: %s [OPTION]... [TARGET_DISPLAY]...\n", arg0);
1981	printf("  -d <source display>  source display\n");
1982	printf("  -f                   keep in foreground (do not detach from console and daemonize)\n");
1983	printf("  -b                   start bumblebee\n");
1984	printf("  -a                   connect to all local displays (e.g. :1, :2, etc)\n");
1985	printf("  -S                   disable use of a singleton and launch a fresh intel-virtual-output process\n");
1986	printf("  -v                   all verbose output, implies -f\n");
1987	printf("  -V <category>        specific verbose output, implies -f\n");
1988	printf("  -h                   this help\n");
1989	printf("If no target displays are parsed on the commandline, \n");
1990	printf("intel-virtual-output will attempt to connect to any local display\n");
1991	printf("and then start bumblebee.\n");
1992}
1993
1994static void record_callback(XPointer closure, XRecordInterceptData *data)
1995{
1996	struct context *ctx = (struct context *)closure;
1997
1998	DBG(X11, ("%s\n", __func__));
1999
2000	if (data->category == XRecordFromServer) {
2001		const xEvent *e = (const xEvent *)data->data;
2002
2003		DBG(X11, ("%s -- from server, event type %d, root %ld (ours? %d)\n",
2004		     __func__, e->u.u.type, (long)e->u.keyButtonPointer.root,
2005		     ctx->display->root == e->u.keyButtonPointer.root));
2006
2007		if (e->u.u.type == MotionNotify &&
2008		    e->u.keyButtonPointer.root == ctx->display->root) {
2009			struct clone *clone;
2010
2011			for (clone = ctx->active; clone; clone = clone->active)
2012				clone_move_cursor(clone,
2013						  e->u.keyButtonPointer.rootX,
2014						  e->u.keyButtonPointer.rootY);
2015		}
2016	}
2017
2018	XRecordFreeData(data);
2019}
2020
2021static int record_mouse(struct context *ctx)
2022{
2023	Display *dpy;
2024	XRecordRange *rr;
2025	XRecordClientSpec rcs;
2026	XRecordContext rc;
2027
2028	DBG(X11, ("%s(%s)\n", __func__, DisplayString(ctx->display->dpy)));
2029
2030	dpy = XOpenDisplay(DisplayString(ctx->display->dpy));
2031	if (dpy == NULL)
2032		return -ECONNREFUSED;
2033
2034	rr = XRecordAllocRange();
2035	if (rr == NULL)
2036		return -ENOMEM;
2037
2038	rr->device_events.first = rr->device_events.last = MotionNotify;
2039
2040	rcs = XRecordAllClients;
2041	rc = XRecordCreateContext(dpy, 0, &rcs, 1, &rr, 1);
2042
2043	XSync(dpy, False);
2044
2045	if (!XRecordEnableContextAsync(dpy, rc, record_callback, (XPointer)ctx))
2046		return -EINVAL;
2047
2048	ctx->record = dpy;
2049	return ConnectionNumber(dpy);
2050}
2051
2052static int bad_visual(Visual *visual, int depth)
2053{
2054	DBG(X11, ("%s? depth=%d, visual: class=%d, bits_per_rgb=%d, red_mask=%08lx, green_mask=%08lx, blue_mask=%08lx\n",
2055	     __func__, depth,
2056	     visual->class,
2057	     visual->bits_per_rgb,
2058	     visual->red_mask,
2059	     visual->green_mask,
2060	     visual->blue_mask));
2061
2062	if (!(visual->class == TrueColor || visual->class == DirectColor))
2063		return 1;
2064
2065	switch (depth) {
2066	case 16: return (/* visual->bits_per_rgb != 6          || */
2067			 visual->red_mask     != 0x1f << 11 ||
2068			 visual->green_mask   != 0x3f << 5  ||
2069			 visual->blue_mask    != 0x1f << 0);
2070
2071	case 24: return (/* visual->bits_per_rgb != 8          || */
2072			 visual->red_mask     != 0xff << 16 ||
2073			 visual->green_mask   != 0xff << 8  ||
2074			 visual->blue_mask    != 0xff << 0);
2075
2076	default: return 1;
2077	}
2078}
2079
2080static XRenderPictFormat *
2081find_xrender_format(Display *dpy, pixman_format_code_t format)
2082{
2083    XRenderPictFormat tmpl;
2084    int mask;
2085
2086#define MASK(x) ((1<<(x))-1)
2087
2088    memset(&tmpl, 0, sizeof(tmpl));
2089
2090    tmpl.depth = PIXMAN_FORMAT_DEPTH(format);
2091    mask = PictFormatType | PictFormatDepth;
2092
2093    DBG(X11, ("%s(0x%08lx)\n", __func__, (long)format));
2094
2095    switch (PIXMAN_FORMAT_TYPE(format)) {
2096    case PIXMAN_TYPE_ARGB:
2097	tmpl.type = PictTypeDirect;
2098
2099	if (PIXMAN_FORMAT_A(format)) {
2100		tmpl.direct.alphaMask = MASK(PIXMAN_FORMAT_A(format));
2101		tmpl.direct.alpha = (PIXMAN_FORMAT_R(format) +
2102				     PIXMAN_FORMAT_G(format) +
2103				     PIXMAN_FORMAT_B(format));
2104	}
2105
2106	tmpl.direct.redMask = MASK(PIXMAN_FORMAT_R(format));
2107	tmpl.direct.red = (PIXMAN_FORMAT_G(format) +
2108			   PIXMAN_FORMAT_B(format));
2109
2110	tmpl.direct.greenMask = MASK(PIXMAN_FORMAT_G(format));
2111	tmpl.direct.green = PIXMAN_FORMAT_B(format);
2112
2113	tmpl.direct.blueMask = MASK(PIXMAN_FORMAT_B(format));
2114	tmpl.direct.blue = 0;
2115
2116	mask |= PictFormatRed | PictFormatRedMask;
2117	mask |= PictFormatGreen | PictFormatGreenMask;
2118	mask |= PictFormatBlue | PictFormatBlueMask;
2119	mask |= PictFormatAlpha | PictFormatAlphaMask;
2120	break;
2121
2122    case PIXMAN_TYPE_ABGR:
2123	tmpl.type = PictTypeDirect;
2124
2125	if (tmpl.direct.alphaMask) {
2126		tmpl.direct.alphaMask = MASK(PIXMAN_FORMAT_A(format));
2127		tmpl.direct.alpha = (PIXMAN_FORMAT_B(format) +
2128				     PIXMAN_FORMAT_G(format) +
2129				     PIXMAN_FORMAT_R(format));
2130	}
2131
2132	tmpl.direct.blueMask = MASK(PIXMAN_FORMAT_B(format));
2133	tmpl.direct.blue = (PIXMAN_FORMAT_G(format) +
2134			    PIXMAN_FORMAT_R(format));
2135
2136	tmpl.direct.greenMask = MASK(PIXMAN_FORMAT_G(format));
2137	tmpl.direct.green = PIXMAN_FORMAT_R(format);
2138
2139	tmpl.direct.redMask = MASK(PIXMAN_FORMAT_R(format));
2140	tmpl.direct.red = 0;
2141
2142	mask |= PictFormatRed | PictFormatRedMask;
2143	mask |= PictFormatGreen | PictFormatGreenMask;
2144	mask |= PictFormatBlue | PictFormatBlueMask;
2145	mask |= PictFormatAlpha | PictFormatAlphaMask;
2146	break;
2147
2148    case PIXMAN_TYPE_BGRA:
2149	tmpl.type = PictTypeDirect;
2150
2151	tmpl.direct.blueMask = MASK(PIXMAN_FORMAT_B(format));
2152	tmpl.direct.blue = (PIXMAN_FORMAT_BPP(format) - PIXMAN_FORMAT_B(format));
2153
2154	tmpl.direct.greenMask = MASK(PIXMAN_FORMAT_G(format));
2155	tmpl.direct.green = (PIXMAN_FORMAT_BPP(format) - PIXMAN_FORMAT_B(format) -
2156			     PIXMAN_FORMAT_G(format));
2157
2158	tmpl.direct.redMask = MASK(PIXMAN_FORMAT_R(format));
2159	tmpl.direct.red = (PIXMAN_FORMAT_BPP(format) - PIXMAN_FORMAT_B(format) -
2160			   PIXMAN_FORMAT_G(format) - PIXMAN_FORMAT_R(format));
2161
2162	if (tmpl.direct.alphaMask) {
2163		tmpl.direct.alphaMask = MASK(PIXMAN_FORMAT_A(format));
2164		tmpl.direct.alpha = 0;
2165	}
2166
2167	mask |= PictFormatRed | PictFormatRedMask;
2168	mask |= PictFormatGreen | PictFormatGreenMask;
2169	mask |= PictFormatBlue | PictFormatBlueMask;
2170	mask |= PictFormatAlpha | PictFormatAlphaMask;
2171	break;
2172
2173    case PIXMAN_TYPE_A:
2174	tmpl.type = PictTypeDirect;
2175
2176	tmpl.direct.alpha = 0;
2177	tmpl.direct.alphaMask = MASK(PIXMAN_FORMAT_A(format));
2178
2179	mask |= PictFormatAlpha | PictFormatAlphaMask;
2180	break;
2181
2182    case PIXMAN_TYPE_COLOR:
2183    case PIXMAN_TYPE_GRAY:
2184	/* XXX Find matching visual/colormap */
2185	tmpl.type = PictTypeIndexed;
2186	//tmpl.colormap = screen->visuals[PIXMAN_FORMAT_VIS(format)].vid;
2187	//mask |= PictFormatColormap;
2188	return NULL;
2189    }
2190#undef MASK
2191
2192    return XRenderFindFormat(dpy, mask, &tmpl, 0);
2193}
2194
2195static int display_init_render(struct display *display, int depth, XRenderPictFormat **use_render)
2196{
2197	Display *dpy = display->dpy;
2198	int major, minor;
2199
2200	DBG(X11, ("%s is depth %d, want %d\n", DisplayString(dpy), display->depth, depth));
2201
2202	*use_render = 0;
2203	if (depth == display->depth && !bad_visual(display->visual, depth))
2204		return 0;
2205
2206	if (display->root_format == 0) {
2207		if (!XRenderQueryVersion(dpy, &major, &minor)) {
2208			fprintf(stderr, "Render extension not supported by %s\n", DisplayString(dpy));
2209			return -EINVAL;
2210		}
2211
2212		display->root_format = XRenderFindVisualFormat(dpy, display->visual);
2213		display->rgb16_format = find_xrender_format(dpy, PIXMAN_r5g6b5);
2214		display->rgb24_format = XRenderFindStandardFormat(dpy, PictStandardRGB24);
2215
2216		DBG(X11, ("%s: root format=%lx, rgb16 format=%lx, rgb24 format=%lx\n",
2217		     DisplayString(dpy),
2218		     (long)display->root_format,
2219		     (long)display->rgb16_format,
2220		     (long)display->rgb24_format));
2221	}
2222
2223	switch (depth) {
2224	case 16: *use_render = display->rgb16_format; break;
2225	case 24: *use_render = display->rgb24_format; break;
2226	}
2227	if (*use_render == 0)
2228		return -ENOENT;
2229
2230	return 0;
2231}
2232
2233static int clone_init_depth(struct clone *clone)
2234{
2235	int ret, depth;
2236
2237	DBG(X11,("%s-%s wants depth %d\n",
2238	     DisplayString(clone->dst.dpy), clone->dst.name, clone->depth));
2239
2240	ret = -1;
2241	for (depth = clone->depth; depth <= 24; depth += 8) {
2242		ret = display_init_render(clone->src.display, depth, &clone->src.use_render);
2243		if (ret)
2244			continue;
2245
2246		ret = display_init_render(clone->dst.display, depth, &clone->dst.use_render);
2247		if (ret)
2248			continue;
2249
2250		break;
2251	}
2252	if (ret)
2253		return ret;
2254
2255	DBG(X11, ("%s-%s using depth %d, requires xrender for src? %d, for dst? %d\n",
2256	     DisplayString(clone->dst.dpy), clone->dst.name,
2257	     clone->depth,
2258	     clone->src.use_render != NULL,
2259	     clone->dst.use_render != NULL));
2260
2261	if (!clone->dst.use_render &&
2262	    clone->src.display->dri3_active &&
2263	    clone->dst.display->dri3_active)
2264		dri3_create_fence(clone->src.dpy, clone->src.window, &clone->dri3);
2265
2266	return 0;
2267}
2268
2269#if defined(USE_XINERAMA)
2270static int xinerama_active(struct display *display)
2271{
2272	int active = 0;
2273	if (XineramaQueryExtension(display->dpy, &display->xinerama_event, &display->xinerama_error))
2274		active = XineramaIsActive(display->dpy);
2275	return active;
2276}
2277#else
2278#define xinerama_active(d) 0
2279#endif
2280
2281static int add_display(struct context *ctx, Display *dpy)
2282{
2283	struct display *display;
2284	int first_display = ctx->ndisplay == 0;
2285
2286	if (is_power_of_2(ctx->ndisplay)) {
2287		struct display *new_display;
2288
2289		new_display = realloc(ctx->display, 2*ctx->ndisplay*sizeof(struct display));
2290		if (new_display == NULL)
2291			return -ENOMEM;
2292
2293		if (new_display != ctx->display) {
2294			int n;
2295
2296			for (n = 0; n < ctx->nclone; n++) {
2297				struct clone *clone = &ctx->clones[n];
2298				clone->src.display = new_display + (clone->src.display - ctx->display);
2299				clone->dst.display = new_display + (clone->dst.display - ctx->display);
2300			}
2301		}
2302
2303		ctx->display = new_display;
2304	}
2305
2306	display = memset(&ctx->display[ctx->ndisplay++], 0, sizeof(struct display));
2307
2308	display->dpy = dpy;
2309	display->ctx = ctx;
2310
2311	display->root = DefaultRootWindow(dpy);
2312	display->depth = DefaultDepth(dpy, DefaultScreen(dpy));
2313	display->visual = DefaultVisual(dpy, DefaultScreen(dpy));
2314
2315	display->has_shm = can_use_shm(dpy, display->root,
2316				       &display->shm_event,
2317				       &display->shm_opcode,
2318				       &display->has_shm_pixmap);
2319	DBG(X11, ("%s: has_shm?=%d, event=%d, opcode=%d, has_pixmap?=%d\n",
2320	     DisplayString(dpy),
2321	     display->has_shm,
2322	     display->shm_event,
2323	     display->shm_opcode,
2324	     display->has_shm_pixmap));
2325
2326	display->rr_active = XRRQueryExtension(dpy, &display->rr_event, &display->rr_error);
2327	DBG(X11, ("%s: randr_active?=%d, event=%d, error=%d\n",
2328	     DisplayString(dpy),
2329	     display->rr_active,
2330	     display->rr_event,
2331	     display->rr_error));
2332
2333	display->xinerama_active = xinerama_active(display);
2334	DBG(X11, ("%s: xinerama_active?=%d, event=%d, error=%d\n",
2335	     DisplayString(dpy),
2336	     display->xinerama_active,
2337	     display->xinerama_event,
2338	     display->xinerama_error));
2339
2340	display->dri3_active = dri3_exists(dpy);
2341	DBG(X11, ("%s: dri3_active?=%d\n",
2342	     DisplayString(dpy),
2343	     display->dri3_active));
2344
2345	/* first display (source) is slightly special */
2346	if (!first_display) {
2347		display->invisible_cursor = display_load_invisible_cursor(display);
2348		display_cursor_move(display, 0, 0, 0);
2349	}
2350
2351	return ConnectionNumber(dpy);
2352}
2353
2354static int display_open(struct context *ctx, const char *name)
2355{
2356	Display *dpy;
2357	int n;
2358
2359	DBG(X11, ("%s(%s)\n", __func__, name));
2360
2361	dpy = XOpenDisplay(name);
2362	if (dpy == NULL)
2363		return -ECONNREFUSED;
2364
2365	/* Prevent cloning the same display twice */
2366	for (n = 0; n < ctx->ndisplay; n++) {
2367		if (strcmp(DisplayString(dpy), DisplayString(ctx->display[n].dpy)) == 0) {
2368			DBG(X11, ("%s %s is already connected\n", __func__, name));
2369			XCloseDisplay(dpy);
2370			return -EBUSY;
2371		}
2372	}
2373
2374	return add_display(ctx, dpy);
2375}
2376
2377static int bumblebee_open(struct context *ctx)
2378{
2379	char buf[256];
2380	struct sockaddr_un addr;
2381	int fd, len;
2382
2383	fd = socket(PF_UNIX, SOCK_STREAM, 0);
2384	if (fd < 0) {
2385		DBG(X11, ("%s unable to create a socket: %d\n", __func__, errno));
2386		return -ECONNREFUSED;
2387	}
2388
2389	addr.sun_family = AF_UNIX;
2390	snprintf(addr.sun_path, sizeof(addr.sun_path), "%s",
2391		 optarg && *optarg ? optarg : "/var/run/bumblebee.socket");
2392	if (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
2393		DBG(X11, ("%s unable to create a socket: %d\n", __func__, errno));
2394		goto err;
2395	}
2396
2397	/* Ask bumblebee to start the second server */
2398	buf[0] = 'C';
2399	if (send(fd, &buf, 1, 0) != 1 || (len = recv(fd, &buf, 255, 0)) <= 0) {
2400		DBG(X11, ("%s startup send/recv failed: %d\n", __func__, errno));
2401		goto err;
2402	}
2403	buf[len] = '\0';
2404
2405	/* Query the display name */
2406	strcpy(buf, "Q VirtualDisplay");
2407	if (send(fd, buf, 17, 0) != 17 || (len = recv(fd, buf, 255, 0)) <= 0) {
2408		DBG(X11, ("%s query send/recv failed: %d\n", __func__, errno));
2409		goto err;
2410	}
2411	buf[len] = '\0';
2412
2413	DBG(X11, ("%s query result '%s'\n", __func__, buf));
2414
2415	if (strncmp(buf, "Value: ", 7))
2416		goto err;
2417
2418	len = 7;
2419	while (buf[len] != '\n' && buf[len] != '\0')
2420		len++;
2421	buf[len] = '\0';
2422
2423	/* XXX We must keep the control socket open whilst we want to keep
2424	 * the display around.
2425	 *
2426	 * So what we need to do is listen for new bumblee Xservers and
2427	 * bind only for their duration.
2428	 */
2429
2430	return display_open(ctx, buf+7);
2431
2432err:
2433	close(fd);
2434	return -ECONNREFUSED;
2435}
2436
2437static int display_init_damage(struct display *display)
2438{
2439	DBG(X11, ("%s(%s)\n", __func__, DisplayString(display->dpy)));
2440
2441	if (!XDamageQueryExtension(display->dpy, &display->damage_event, &display->damage_error) ||
2442	    !XFixesQueryExtension(display->dpy, &display->xfixes_event, &display->xfixes_error)) {
2443		fprintf(stderr, "Damage/Fixes extension not supported by %s\n", DisplayString(display->dpy));
2444		return EINVAL;
2445	}
2446
2447	display->damage = XDamageCreate(display->dpy, display->root, XDamageReportBoundingBox);
2448	if (display->damage == 0)
2449		return EACCES;
2450
2451	return 0;
2452}
2453
2454static void display_reset_damage(struct display *display)
2455{
2456	Damage damage;
2457
2458	damage = XDamageCreate(display->dpy, display->root, XDamageReportBoundingBox);
2459	if (damage) {
2460		XDamageDestroy(display->dpy, display->damage);
2461		display->damage = damage;
2462		XFlush(display->dpy);
2463		display->flush = 0;
2464	}
2465}
2466
2467static void display_init_randr_hpd(struct display *display)
2468{
2469	int major, minor;
2470
2471	DBG(X11,("%s(%s)\n", __func__, DisplayString(display->dpy)));
2472
2473	if (!XRRQueryVersion(display->dpy, &major, &minor))
2474		return;
2475
2476	DBG(X11, ("%s - randr version %d.%d\n", DisplayString(display->dpy), major, minor));
2477	if (major > 1 || (major == 1 && minor >= 2))
2478		XRRSelectInput(display->dpy, display->root, RROutputChangeNotifyMask);
2479}
2480
2481static void rebuild_clones(struct context *ctx, struct clone *new_clones)
2482{
2483	int n, m;
2484
2485	for (n = 1; n < ctx->ndisplay; n++) {
2486		struct display *d = &ctx->display[n];
2487
2488		d->clone = NULL;
2489		for (m = 0; m < ctx->nclone; m++) {
2490			struct clone *c = &new_clones[m];
2491
2492			if (c->dst.display != d)
2493				continue;
2494
2495			c->next = d->clone;
2496			d->clone = c;
2497		}
2498	}
2499
2500	ctx->clones = new_clones;
2501}
2502
2503static struct clone *add_clone(struct context *ctx)
2504{
2505	if (is_power_of_2(ctx->nclone)) {
2506		struct clone *new_clones;
2507
2508		new_clones = realloc(ctx->clones, 2*ctx->nclone*sizeof(struct clone));
2509		if (new_clones == NULL)
2510			return NULL;
2511
2512		if (new_clones != ctx->clones)
2513			rebuild_clones(ctx, new_clones);
2514	}
2515
2516	return memset(&ctx->clones[ctx->nclone++], 0, sizeof(struct clone));
2517}
2518
2519static struct display *last_display(struct context *ctx)
2520{
2521	return &ctx->display[ctx->ndisplay-1];
2522}
2523
2524static void reverse_clone_list(struct display *display)
2525{
2526	struct clone *list = NULL;
2527
2528	while (display->clone) {
2529		struct clone *clone = display->clone;
2530		display->clone = clone->next;
2531		clone->next = list;
2532		list = clone;
2533	}
2534
2535	display->clone = list;
2536}
2537
2538static int last_display_add_clones__randr(struct context *ctx)
2539{
2540	struct display *display = last_display(ctx);
2541	XRRScreenResources *res;
2542	char buf[80];
2543	int i, ret;
2544
2545	DBG(X11, ("%s(%s)\n", __func__, DisplayString(display->dpy)));
2546
2547	display_init_randr_hpd(display);
2548
2549	/* Force a probe of outputs on initial connection */
2550	res = XRRGetScreenResources(display->dpy, display->root);
2551	if (res == NULL)
2552		return -ENOMEM;
2553
2554	DBG(X11, ("%s - noutputs=%d\n", DisplayString(display->dpy), res->noutput));
2555	for (i = 0; i < res->noutput; i++) {
2556		XRROutputInfo *o = XRRGetOutputInfo(display->dpy, res, res->outputs[i]);
2557		struct clone *clone = add_clone(ctx);
2558		RROutput id;
2559
2560		if (clone == NULL)
2561			return -ENOMEM;
2562
2563		clone->depth = 24;
2564		clone->next = display->clone;
2565		display->clone = clone;
2566
2567		id = claim_virtual(ctx->display, buf, ctx->nclone);
2568		if (id == 0) {
2569			fprintf(stderr, "Failed to find available VirtualHead \"%s\" for \"%s\" on display \"%s\"\n",
2570				buf, o->name, DisplayString(display->dpy));
2571			return -ENOSPC;
2572		}
2573
2574		ret = clone_output_init(clone, &clone->src, ctx->display, buf, id);
2575		if (ret) {
2576			fprintf(stderr, "Failed to add output \"%s\" on display \"%s\"\n",
2577				buf, DisplayString(ctx->display->dpy));
2578			return ret;
2579		}
2580
2581		ret = clone_output_init(clone, &clone->dst, display, o->name, res->outputs[i]);
2582		if (ret) {
2583			fprintf(stderr, "Failed to add output \"%s\" on display \"%s\"\n",
2584				o->name, DisplayString(display->dpy));
2585			return ret;
2586		}
2587
2588		ret = clone_init_depth(clone);
2589		if (ret) {
2590			fprintf(stderr, "Failed to negotiate image format for display \"%s\"\n",
2591				DisplayString(display->dpy));
2592			return ret;
2593		}
2594
2595		ret = clone_update_modes__randr(clone);
2596		if (ret) {
2597			fprintf(stderr, "Failed to clone output \"%s\" from display \"%s\"\n",
2598				o->name, DisplayString(display->dpy));
2599			return ret;
2600		}
2601
2602
2603		if (o->crtc) {
2604			DBG(X11, ("%s - disabling active output\n", DisplayString(display->dpy)));
2605			disable_crtc(display->dpy, res, o->crtc);
2606		}
2607
2608		XRRFreeOutputInfo(o);
2609	}
2610	XRRFreeScreenResources(res);
2611
2612	reverse_clone_list(display);
2613	return 0;
2614}
2615
2616#if defined(USE_XINERAMA)
2617static int last_display_add_clones__xinerama(struct context *ctx)
2618{
2619	struct display *display = last_display(ctx);
2620	Display *dpy = display->dpy;
2621	XineramaScreenInfo *xi;
2622	char buf[80];
2623	int n, count, ret;
2624
2625	DBG(X11, ("%s(%s)\n", __func__, DisplayString(display->dpy)));
2626
2627	count = 0;
2628	xi = XineramaQueryScreens(dpy, &count);
2629	for (n = 0; n < count; n++) {
2630		struct clone *clone = add_clone(ctx);
2631		RROutput id;
2632
2633		if (clone == NULL)
2634			return -ENOMEM;
2635
2636		if (xi[n].width == 0 || xi[n].height == 0)
2637			continue;
2638
2639		clone->depth = 24;
2640		clone->next = display->clone;
2641		display->clone = clone;
2642
2643		id = claim_virtual(ctx->display, buf, ctx->nclone);
2644		if (id == 0) {
2645			fprintf(stderr, "Failed to find available VirtualHead \"%s\" for Xinerama screen %d on display \"%s\"\n",
2646				buf, n, DisplayString(dpy));
2647		}
2648		ret = clone_output_init(clone, &clone->src, ctx->display, buf, id);
2649		if (ret) {
2650			fprintf(stderr, "Failed to add Xinerama screen %d on display \"%s\"\n",
2651				n, DisplayString(ctx->display->dpy));
2652			return ret;
2653		}
2654
2655		sprintf(buf, "XINERAMA%d", n);
2656		ret = clone_output_init(clone, &clone->dst, display, buf, 0);
2657		if (ret) {
2658			fprintf(stderr, "Failed to add Xinerama screen %d on display \"%s\"\n",
2659				n, DisplayString(dpy));
2660			return ret;
2661		}
2662
2663		ret = clone_init_depth(clone);
2664		if (ret) {
2665			fprintf(stderr, "Failed to negotiate image format for display \"%s\"\n",
2666				DisplayString(display->dpy));
2667			return ret;
2668		}
2669
2670		/* Replace the modes on the local VIRTUAL output with the remote Screen */
2671		clone->width = xi[n].width;
2672		clone->height = xi[n].height;
2673		clone->dst.x = xi[n].x_org;
2674		clone->dst.y = xi[n].y_org;
2675		clone->dst.rr_crtc = -1;
2676		ret = clone_update_modes__fixed(clone);
2677		if (ret) {
2678			fprintf(stderr, "Failed to clone Xinerama screen %d from display \"%s\"\n",
2679				n, DisplayString(display->dpy));
2680			return ret;
2681		}
2682
2683		clone->active = ctx->active;
2684		ctx->active = clone;
2685	}
2686	XFree(xi);
2687
2688	reverse_clone_list(display);
2689	return 0;
2690}
2691#else
2692#define last_display_add_clones__xinerama(ctx) -1
2693#endif
2694
2695static int last_display_add_clones__display(struct context *ctx)
2696{
2697	struct display *display = last_display(ctx);
2698	Display *dpy = display->dpy;
2699	struct clone *clone;
2700	Screen *scr;
2701	char buf[80];
2702	int ret;
2703	RROutput id;
2704
2705
2706	DBG(X11, ("%s(%s)\n", __func__, DisplayString(dpy)));
2707	clone = add_clone(ctx);
2708	if (clone == NULL)
2709		return -ENOMEM;
2710
2711	clone->depth = 24;
2712	clone->next = display->clone;
2713	display->clone = clone;
2714
2715	id = claim_virtual(ctx->display, buf, ctx->nclone);
2716	if (id == 0) {
2717		fprintf(stderr, "Failed to find available VirtualHead \"%s\" for on display \"%s\"\n",
2718			buf, DisplayString(dpy));
2719	}
2720	ret = clone_output_init(clone, &clone->src, ctx->display, buf, id);
2721	if (ret) {
2722		fprintf(stderr, "Failed to add display \"%s\"\n",
2723			DisplayString(ctx->display->dpy));
2724		return ret;
2725	}
2726
2727	sprintf(buf, "WHOLE");
2728	ret = clone_output_init(clone, &clone->dst, display, buf, 0);
2729	if (ret) {
2730		fprintf(stderr, "Failed to add display \"%s\"\n",
2731			DisplayString(dpy));
2732		return ret;
2733	}
2734
2735	ret = clone_init_depth(clone);
2736	if (ret) {
2737		fprintf(stderr, "Failed to negotiate image format for display \"%s\"\n",
2738			DisplayString(dpy));
2739		return ret;
2740	}
2741
2742	/* Replace the modes on the local VIRTUAL output with the remote Screen */
2743	scr = ScreenOfDisplay(dpy, DefaultScreen(dpy));
2744	clone->width = scr->width;
2745	clone->height = scr->height;
2746	clone->dst.x = 0;
2747	clone->dst.y = 0;
2748	clone->dst.rr_crtc = -1;
2749	ret = clone_update_modes__fixed(clone);
2750	if (ret) {
2751		fprintf(stderr, "Failed to clone display \"%s\"\n",
2752			DisplayString(dpy));
2753		return ret;
2754	}
2755
2756	clone->active = ctx->active;
2757	ctx->active = clone;
2758
2759	return 0;
2760}
2761
2762static int last_display_add_clones(struct context *ctx)
2763{
2764	struct display *display = last_display(ctx);
2765
2766	display->width = DisplayWidth(display->dpy, DefaultScreen(display->dpy));
2767	display->height = DisplayHeight(display->dpy, DefaultScreen(display->dpy));
2768	DBG(X11, ("%s - initial size %dx%d\n", DisplayString(display->dpy), display->width, display->height));
2769
2770	if (display->rr_active)
2771		return last_display_add_clones__randr(ctx);
2772
2773	if (display->xinerama_active)
2774		return last_display_add_clones__xinerama(ctx);
2775
2776	return last_display_add_clones__display(ctx);
2777}
2778
2779static int last_display_clone(struct context *ctx, int fd)
2780{
2781	fd = add_fd(ctx, fd);
2782	if (fd < 0)
2783		return fd;
2784
2785	fd = last_display_add_clones(ctx);
2786	if (fd)
2787		return fd;
2788
2789	return 0;
2790}
2791
2792static int first_display_has_singleton(struct context *ctx)
2793{
2794	struct display *display = ctx->display;
2795	unsigned long nitems, bytes;
2796	unsigned char *prop;
2797	int format;
2798	Atom type;
2799
2800	ctx->singleton = XInternAtom(display->dpy, "intel-virtual-output-singleton", False);
2801
2802	XGetWindowProperty(display->dpy, display->root, ctx->singleton,
2803			   0, 0, 0, AnyPropertyType, &type, &format, &nitems, &bytes, &prop);
2804	DBG(X11, ("%s: singleton registered? %d\n", DisplayString(display->dpy), type != None));
2805	return type != None;
2806}
2807
2808static int first_display_wait_for_ack(struct context *ctx, int timeout, int id)
2809{
2810	struct display *display = ctx->display;
2811	struct pollfd pfd;
2812	char expect[6]; /* "1234R\0" */
2813
2814	sprintf(expect, "%04xR", id);
2815	DBG(X11, ("%s: wait for act '%c%c%c%c%c'\n",
2816	     DisplayString(display->dpy),
2817	     expect[0], expect[1], expect[2], expect[3], expect[4]));
2818
2819	XFlush(display->dpy);
2820
2821	pfd.fd = ConnectionNumber(display->dpy);
2822	pfd.events = POLLIN;
2823	do {
2824		if (poll(&pfd, 1, timeout) <= 0)
2825			return -ETIME;
2826
2827		while (XPending(display->dpy)) {
2828			XEvent e;
2829			XClientMessageEvent *cme;
2830
2831			XNextEvent(display->dpy, &e);
2832			DBG(X11, ("%s: reading event type %d\n", DisplayString(display->dpy), e.type));
2833
2834			if (e.type != ClientMessage)
2835				continue;
2836
2837			cme = (XClientMessageEvent *)&e;
2838			if (cme->message_type != ctx->singleton)
2839				continue;
2840			if (cme->format != 8)
2841				continue;
2842
2843			DBG(X11, ("%s: client message '%c%c%c%c%c'\n",
2844			     DisplayString(display->dpy),
2845			     cme->data.b[0],
2846			     cme->data.b[1],
2847			     cme->data.b[2],
2848			     cme->data.b[3],
2849			     cme->data.b[4]));
2850			if (memcmp(cme->data.b, expect, 5))
2851				continue;
2852
2853			return -atoi(cme->data.b + 5);
2854		}
2855	} while (1);
2856}
2857
2858#if defined(__GNUC__) && (__GNUC__ > 3)
2859__attribute__((format(gnu_printf, 3, 4)))
2860#endif
2861static int first_display_send_command(struct context *ctx, int timeout,
2862				      const char *format,
2863				      ...)
2864{
2865	struct display *display = ctx->display;
2866	char buf[1024], *b;
2867	int len, id;
2868	va_list va;
2869
2870	id = rand() & 0xffff;
2871	sprintf(buf, "%04x", id);
2872	va_start(va, format);
2873	len = vsnprintf(buf+4, sizeof(buf)-4, format, va)+5;
2874	va_end(va);
2875	assert(len < sizeof(buf));
2876
2877	DBG(X11, ("%s: send command '%s'\n", DisplayString(display->dpy), buf));
2878
2879	b = buf;
2880	while (len) {
2881		XClientMessageEvent msg;
2882		int n = len;
2883		if (n > sizeof(msg.data.b))
2884			n = sizeof(msg.data.b);
2885		len -= n;
2886
2887		msg.type = ClientMessage;
2888		msg.serial = 0;
2889		msg.message_type = ctx->singleton;
2890		msg.format = 8;
2891		memcpy(msg.data.b, b, n);
2892		b += n;
2893
2894		XSendEvent(display->dpy, display->root, False, PropertyChangeMask, (XEvent *)&msg);
2895	}
2896
2897	return first_display_wait_for_ack(ctx, timeout, id);
2898}
2899
2900static void first_display_reply(struct context *ctx, int result)
2901{
2902	struct display *display = ctx->display;
2903	XClientMessageEvent msg;
2904
2905	sprintf(msg.data.b, "%c%c%c%cR%d",
2906	     ctx->command[0],
2907	     ctx->command[1],
2908	     ctx->command[2],
2909	     ctx->command[3],
2910	     -result);
2911
2912	DBG(X11, ("%s: send reply '%s'\n", DisplayString(display->dpy), msg.data.b));
2913
2914	msg.type = ClientMessage;
2915	msg.serial = 0;
2916	msg.message_type = ctx->singleton;
2917	msg.format = 8;
2918
2919	XSendEvent(display->dpy, display->root, False, PropertyChangeMask, (XEvent *)&msg);
2920	XFlush(display->dpy);
2921}
2922
2923static void first_display_handle_command(struct context *ctx,
2924					 const char *msg)
2925{
2926	int len;
2927
2928	DBG(X11, ("client message!\n"));
2929
2930	for (len = 0; len < 20 && msg[len]; len++)
2931		;
2932
2933	if (ctx->command_continuation + len > sizeof(ctx->command)) {
2934		ctx->command_continuation = 0;
2935		return;
2936	}
2937
2938	memcpy(ctx->command + ctx->command_continuation, msg, len);
2939	ctx->command_continuation += len;
2940
2941	if (len < 20) {
2942		ctx->command[ctx->command_continuation] = 0;
2943		DBG(X11, ("client command complete! '%s'\n", ctx->command));
2944		switch (ctx->command[4]) {
2945		case 'B':
2946			first_display_reply(ctx, last_display_clone(ctx, bumblebee_open(ctx)));
2947			break;
2948		case 'C':
2949			first_display_reply(ctx, last_display_clone(ctx, display_open(ctx, ctx->command + 5)));
2950			break;
2951		case 'P':
2952			first_display_reply(ctx, 0);
2953			break;
2954		case 'R':
2955			break;
2956		}
2957		ctx->command_continuation = 0;
2958		return;
2959	}
2960}
2961
2962static int first_display_register_as_singleton(struct context *ctx)
2963{
2964	struct display *display = ctx->display;
2965	struct pollfd pfd;
2966
2967	XChangeProperty(display->dpy, display->root, ctx->singleton,
2968			XA_STRING, 8, PropModeReplace, (unsigned char *)".", 1);
2969	XFlush(display->dpy);
2970
2971	/* And eat the notify (presuming that it is ours!) */
2972
2973	pfd.fd = ConnectionNumber(display->dpy);
2974	pfd.events = POLLIN;
2975	do {
2976		if (poll(&pfd, 1, 1000) <= 0) {
2977			fprintf(stderr, "Failed to register as singleton\n");
2978			return EBUSY;
2979		}
2980
2981		while (XPending(display->dpy)) {
2982			XEvent e;
2983
2984			XNextEvent(display->dpy, &e);
2985			DBG(X11, ("%s: reading event type %d\n", DisplayString(display->dpy), e.type));
2986
2987			if (e.type == PropertyNotify &&
2988			    ((XPropertyEvent *)&e)->atom == ctx->singleton)
2989				return 0;
2990		}
2991	} while (1);
2992}
2993
2994static void display_flush_send(struct display *display)
2995{
2996	XShmCompletionEvent e;
2997
2998	if (!display->send)
2999		return;
3000
3001	DBG(X11, ("%s flushing send (serial now %ld) (has shm send? %d)\n",
3002	     DisplayString(display->dpy),
3003	     (long)NextRequest(display->dpy),
3004	     display->shm_event));
3005
3006	display->send = 0;
3007
3008	if (display->shm_event == 0) {
3009		XSync(display->dpy, False);
3010		display->flush = 0;
3011		return;
3012	}
3013
3014	memset(&e, 0, sizeof(e));
3015	e.type = display->shm_event;
3016	e.send_event = 1;
3017	e.drawable = display->root;
3018	e.major_code = display->shm_opcode;
3019	e.minor_code = X_ShmPutImage;
3020
3021	XSendEvent(display->dpy, display->root, False, 0, (XEvent *)&e);
3022	display_mark_flush(display);
3023}
3024
3025static void display_sync(struct display *display)
3026{
3027	if (display->skip_clone == 0)
3028		return;
3029
3030	if (display->skip_frame++ < 2)
3031		return;
3032
3033	DBG(X11, ("%s forcing sync\n", DisplayString(display->dpy)));
3034	XSync(display->dpy, False);
3035
3036	display->flush = 0;
3037	display->send = 0;
3038
3039	/* Event tracking proven unreliable, disable */
3040	display->shm_event = 0;
3041}
3042
3043static void display_flush(struct display *display)
3044{
3045	display_flush_cursor(display);
3046	display_flush_send(display);
3047
3048	display_sync(display);
3049
3050	if (!display->flush)
3051		return;
3052
3053	DBG(X11, ("%s(%s)\n", __func__, DisplayString(display->dpy)));
3054
3055	XFlush(display->dpy);
3056	display->flush = 0;
3057}
3058
3059static int first_display_first_sibling(struct context *ctx)
3060{
3061	const char *str, *colon;
3062	int dpy, scr, len;
3063
3064	str = DisplayString(ctx->display->dpy);
3065	colon = strrchr(str, ':');
3066	if (colon == NULL)
3067		return -1;
3068
3069	if (sscanf(colon + 1, "%d.%d", &dpy, &scr) == 1)
3070		scr = 0;
3071
3072	len = (colon - str) + 1;
3073	memcpy(ctx->command, str, len);
3074	len += sprintf(ctx->command + len, "%d.", dpy);
3075	ctx->command_continuation = len;
3076
3077	return scr + 1;
3078}
3079
3080static int first_display_sibling(struct context *ctx, int i)
3081{
3082	if (i < 0)
3083		return 0;
3084
3085	sprintf(ctx->command + ctx->command_continuation, "%d", i);
3086	return 1;
3087}
3088
3089#define first_display_for_each_sibling(CTX, i) \
3090	for (i = first_display_first_sibling(CTX); first_display_sibling(CTX, i); i++)
3091
3092static void display_cleanup(struct display *display)
3093{
3094	Display *dpy = display->dpy;
3095	XRRScreenResources *res;
3096	int n;
3097
3098	XGrabServer(dpy);
3099
3100	res = _XRRGetScreenResourcesCurrent(dpy, display->root);
3101	if (res != NULL) {
3102		for (n = 0; n < res->ncrtc; n++)
3103			disable_crtc(display->dpy, res, res->crtcs[n]);
3104
3105		XRRFreeScreenResources(res);
3106	}
3107
3108	XUngrabServer(dpy);
3109}
3110
3111static void context_cleanup(struct context *ctx)
3112{
3113	Display *dpy = ctx->display->dpy;
3114	XRRScreenResources *res;
3115	int i, j;
3116
3117	for (i = 1; i < ctx->ndisplay; i++)
3118		display_cleanup(&ctx->display[i]);
3119
3120	if (dpy == NULL)
3121		return;
3122
3123	res = _XRRGetScreenResourcesCurrent(dpy, ctx->display->root);
3124	if (res == NULL)
3125		return;
3126
3127	XGrabServer(dpy);
3128
3129	for (i = 0; i < ctx->nclone; i++) {
3130		struct clone *clone = &ctx->clones[i];
3131		XRROutputInfo *output;
3132
3133		assert(clone->src.display == ctx->display);
3134
3135		output = XRRGetOutputInfo(dpy, res, clone->src.rr_output);
3136		if (output == NULL)
3137			continue;
3138
3139		disable_crtc(dpy, res, output->crtc);
3140		for (j = 0; j < output->nmode; j++)
3141			XRRDeleteOutputMode(dpy, clone->src.rr_output, output->modes[j]);
3142
3143		XRRFreeOutputInfo(output);
3144	}
3145
3146	for (i = 0; i < res->nmode; i++) {
3147		if (strncmp(res->modes[i].name, "VIRTUAL", 7) == 0) {
3148			XRRDestroyMode(dpy, res->modes[i].id);
3149			continue;
3150		}
3151
3152		if (strcmp(res->modes[i].name, "ClaimVirtualHead") == 0) {
3153			XRRDestroyMode(dpy, res->modes[i].id);
3154			continue;
3155		}
3156	}
3157	XRRFreeScreenResources(res);
3158
3159	/* And hide them again */
3160	res = XRRGetScreenResources(dpy, ctx->display->root);
3161	if (res != NULL)
3162		XRRFreeScreenResources(res);
3163
3164	XUngrabServer(dpy);
3165
3166	if (ctx->singleton)
3167		XDeleteProperty(dpy, ctx->display->root, ctx->singleton);
3168	XCloseDisplay(dpy);
3169}
3170
3171static int done;
3172
3173static void signal_handler(int sig)
3174{
3175	done = sig;
3176}
3177
3178int main(int argc, char **argv)
3179{
3180	struct context ctx;
3181	const char *src_name = NULL;
3182	uint64_t count;
3183	int daemonize = 1, bumblebee = 0, siblings = 0, singleton = 1;
3184	int i, ret, open, fail;
3185
3186	signal(SIGPIPE, SIG_IGN);
3187
3188	while ((i = getopt(argc, argv, "abd:fhSvV:")) != -1) {
3189		switch (i) {
3190		case 'd':
3191			src_name = optarg;
3192			break;
3193		case 'f':
3194			daemonize = 0;
3195			break;
3196		case 'b':
3197			bumblebee = 1;
3198			break;
3199		case 's':
3200			siblings = 1;
3201			break;
3202		case 'S':
3203			singleton = 0;
3204			break;
3205		case 'v':
3206			verbose = ~0;
3207			daemonize = 0;
3208			break;
3209		case 'V':
3210			verbose = strtol(optarg, NULL, 0);
3211			daemonize = 0;
3212			break;
3213		case 'h':
3214		default:
3215			usage(argv[0]);
3216			exit(0);
3217		}
3218	}
3219
3220	if (verbose)
3221		printf("intel-virtual-output: version %d.%d.%d\n",
3222		       PACKAGE_VERSION_MAJOR,
3223		       PACKAGE_VERSION_MINOR,
3224		       PACKAGE_VERSION_PATCHLEVEL);
3225
3226	ret = context_init(&ctx);
3227	if (ret)
3228		return -ret;
3229
3230	XSetErrorHandler(_check_error_handler);
3231
3232	ret = add_fd(&ctx, display_open(&ctx, src_name));
3233	if (ret) {
3234		fprintf(stderr, "Unable to connect to \"%s\".\n", src_name ?: getenv("DISPLAY") ?:
3235			"<unspecified>, set either the DISPLAY environment variable or pass -d <display name> on the commandline");
3236		ret = -ret;
3237		goto out;
3238	}
3239
3240	if (singleton) {
3241		XSelectInput(ctx.display->dpy, ctx.display->root, PropertyChangeMask);
3242		if (first_display_has_singleton(&ctx)) {
3243			DBG(X11, ("%s: pinging singleton\n", DisplayString(ctx.display->dpy)));
3244			ret = first_display_send_command(&ctx, 2000, "P");
3245			if (ret) {
3246				if (ret != -ETIME) {
3247					ret = -ret;
3248					goto out;
3249				}
3250				DBG(X11, ("No reply from singleton; assuming control\n"));
3251			} else {
3252				DBG(X11, ("%s: singleton active, sending open commands\n", DisplayString(ctx.display->dpy)));
3253
3254				open = fail = 0;
3255				for (i = optind; i < argc; i++) {
3256					ret = first_display_send_command(&ctx, 5000, "C%s", argv[i]);
3257					if (ret && ret != -EBUSY) {
3258						fprintf(stderr, "Unable to connect to \"%s\".\n", argv[i]);
3259						fail++;
3260					} else
3261						open++;
3262				}
3263				if (siblings || (optind == argc && !bumblebee)) {
3264					first_display_for_each_sibling(&ctx, i) {
3265						ret = first_display_send_command(&ctx, 5000, "C%s", ctx.command);
3266						if (ret && ret != -EBUSY)
3267							break;
3268						else
3269							open++;
3270					}
3271				}
3272				if (bumblebee || (optind == argc && !siblings)) {
3273					ret = first_display_send_command(&ctx, 5000, "B");
3274					if (ret && ret != -EBUSY) {
3275						if (bumblebee)
3276							fprintf(stderr, "Unable to connect to bumblebee.\n");
3277						fail++;
3278					} else
3279						open++;
3280				}
3281				ret = open || !fail ? 0 : ECONNREFUSED;
3282				goto out;
3283			}
3284		}
3285		ret = first_display_register_as_singleton(&ctx);
3286		if (ret)
3287			goto out;
3288	}
3289
3290	ret = display_init_damage(ctx.display);
3291	if (ret)
3292		goto out;
3293
3294	if ((ctx.display->rr_event | ctx.display->rr_error) == 0) {
3295		fprintf(stderr, "RandR extension not supported by %s\n", DisplayString(ctx.display->dpy));
3296		ret = EINVAL;
3297		goto out;
3298	}
3299	XRRSelectInput(ctx.display->dpy, ctx.display->root, RRScreenChangeNotifyMask);
3300	XFixesSelectCursorInput(ctx.display->dpy, ctx.display->root, XFixesDisplayCursorNotifyMask);
3301
3302	ret = add_fd(&ctx, record_mouse(&ctx));
3303	if (ret) {
3304		fprintf(stderr, "XTEST extension not supported by display \"%s\"\n", DisplayString(ctx.display->dpy));
3305		ret = -ret;
3306		goto out;
3307	}
3308
3309	open = fail = 0;
3310	for (i = optind; i < argc; i++) {
3311		ret = last_display_clone(&ctx, display_open(&ctx, argv[i]));
3312		if (ret && ret != -EBUSY) {
3313			fprintf(stderr, "Unable to connect to \"%s\".\n", argv[i]);
3314			fail++;
3315		} else
3316			open++;
3317	}
3318	if (siblings || (optind == argc && !bumblebee)) {
3319		first_display_for_each_sibling(&ctx, i) {
3320			ret = last_display_clone(&ctx, display_open(&ctx, ctx.command));
3321			if (ret && ret != -EBUSY)
3322				break;
3323			else
3324				open++;
3325		}
3326	}
3327	if (bumblebee || (optind == argc && !siblings)) {
3328		ret = last_display_clone(&ctx, bumblebee_open(&ctx));
3329		if (ret && ret != -EBUSY) {
3330			if (bumblebee)
3331				fprintf(stderr, "Unable to connect to bumblebee.\n");
3332			fail++;
3333		} else
3334			open++;
3335	}
3336	if (open == 0) {
3337		ret = fail ? ECONNREFUSED : 0;
3338		goto out;
3339	}
3340
3341	if (daemonize && daemon(0, 0)) {
3342		ret = EINVAL;
3343		goto out;
3344	}
3345
3346	signal(SIGHUP, signal_handler);
3347	signal(SIGINT, signal_handler);
3348	signal(SIGTERM, signal_handler);
3349
3350	ctx.command_continuation = 0;
3351	while (!done) {
3352		XEvent e;
3353		int reconfigure = 0;
3354		int rr_update = 0;
3355
3356		DBG(POLL, ("polling - enable timer? %d, nfd=%d, ndisplay=%d\n", ctx.timer_active, ctx.nfd, ctx.ndisplay));
3357		ret = poll(ctx.pfd + !ctx.timer_active, ctx.nfd - !ctx.timer_active, -1);
3358		if (ret <= 0)
3359			break;
3360
3361		/* pfd[0] is the timer, pfd[1] is the local display, pfd[2] is the mouse, pfd[3+] are the remotes */
3362
3363		DBG(POLL, ("poll reports %d fd awake\n", ret));
3364		if (ctx.pfd[1].revents || XPending(ctx.display[0].dpy)) {
3365			DBG(POLL,("%s woken up\n", DisplayString(ctx.display[0].dpy)));
3366			do {
3367				XNextEvent(ctx.display->dpy, &e);
3368
3369				if (e.type == ctx.display->damage_event + XDamageNotify ) {
3370					const XDamageNotifyEvent *de = (const XDamageNotifyEvent *)&e;
3371					struct clone *clone;
3372
3373					DBG(DAMAGE, ("%s damaged: (%d, %d)x(%d, %d)\n",
3374					     DisplayString(ctx.display->dpy),
3375					     de->area.x, de->area.y, de->area.width, de->area.height));
3376
3377					for (clone = ctx.active; clone; clone = clone->active)
3378						clone_damage(clone, &de->area);
3379
3380					if (ctx.active)
3381						context_enable_timer(&ctx);
3382				} else if (e.type == ctx.display->xfixes_event + XFixesCursorNotify) {
3383					XFixesCursorImage *cur;
3384
3385					DBG(CURSOR, ("%s cursor changed\n",
3386					     DisplayString(ctx.display->dpy)));
3387
3388					cur = XFixesGetCursorImage(ctx.display->dpy);
3389					if (cur == NULL)
3390						continue;
3391
3392					for (i = 1; i < ctx.ndisplay; i++)
3393						display_load_visible_cursor(&ctx.display[i], cur);
3394
3395					XFree(cur);
3396				} else if (e.type == ctx.display->rr_event + RRScreenChangeNotify) {
3397					DBG(XRR, ("%s screen changed (reconfigure pending? %d)\n",
3398					     DisplayString(ctx.display->dpy), reconfigure));
3399					reconfigure = 1;
3400				} else if (e.type == PropertyNotify) {
3401					XPropertyEvent *pe = (XPropertyEvent *)&e;
3402					if (pe->atom == ctx.singleton) {
3403						DBG(X11, ("lost control of singleton\n"));
3404						return 0;
3405					}
3406				} else if (e.type == ClientMessage) {
3407					XClientMessageEvent *cme;
3408
3409					DBG(X11, ("%s client message\n",
3410					     DisplayString(ctx.display->dpy)));
3411
3412					cme = (XClientMessageEvent *)&e;
3413					if (cme->message_type != ctx.singleton)
3414						continue;
3415					if (cme->format != 8)
3416						continue;
3417
3418					first_display_handle_command(&ctx, cme->data.b);
3419				} else {
3420					DBG(X11, ("unknown event %d\n", e.type));
3421				}
3422			} while (XEventsQueued(ctx.display->dpy, QueuedAfterReading));
3423		}
3424
3425		for (i = 1; i < ctx.ndisplay; i++) {
3426			if (ctx.pfd[i+2].revents == 0 && !XPending(ctx.display[i].dpy))
3427				continue;
3428
3429			DBG(POLL, ("%s woken up\n", DisplayString(ctx.display[i].dpy)));
3430			do {
3431				XNextEvent(ctx.display[i].dpy, &e);
3432
3433				DBG(POLL, ("%s received event %d\n", DisplayString(ctx.display[i].dpy), e.type));
3434				if (ctx.display[i].rr_active && e.type == ctx.display[i].rr_event + RRNotify) {
3435					XRRNotifyEvent *re = (XRRNotifyEvent *)&e;
3436
3437					DBG(XRR, ("%s received RRNotify, type %d\n", DisplayString(ctx.display[i].dpy), re->subtype));
3438					if (re->subtype == RRNotify_OutputChange) {
3439						XRROutputPropertyNotifyEvent *ro = (XRROutputPropertyNotifyEvent *)re;
3440						struct clone *clone;
3441
3442						DBG(XRR, ("%s RRNotify_OutputChange, timestamp %ld\n", DisplayString(ctx.display[i].dpy), ro->timestamp));
3443						for (clone = ctx.display[i].clone; clone; clone = clone->next) {
3444							if (clone->dst.rr_output == ro->output)
3445								rr_update = clone->rr_update = 1;
3446						}
3447					}
3448				}
3449			} while (XEventsQueued(ctx.display[i].dpy, QueuedAfterReading));
3450		}
3451
3452		if (rr_update) {
3453			for (i = 0; i < ctx.nclone; i++)
3454				clone_update(&ctx.clones[i]);
3455		}
3456
3457		if (reconfigure && context_update(&ctx))
3458			display_reset_damage(ctx.display);
3459
3460		while (XPending(ctx.record)) /* discard all implicit events */
3461			XNextEvent(ctx.record, &e);
3462
3463		if (ctx.timer_active && read(ctx.timer, &count, sizeof(count)) > 0) {
3464			struct clone *clone;
3465
3466			DBG(TIMER, ("%s timer expired (count=%ld)\n", DisplayString(ctx.display->dpy), (long)count));
3467			ret = 0;
3468
3469			if (ctx.active) {
3470				DBG(DAMAGE, ("%s clearing damage\n", DisplayString(ctx.display->dpy)));
3471				XDamageSubtract(ctx.display->dpy, ctx.display->damage, None, None);
3472				ctx.display->flush = 1;
3473			}
3474
3475			for (clone = ctx.active; clone; clone = clone->active)
3476				ret |= clone_paint(clone);
3477
3478			for (i = 0; i < ctx.ndisplay; i++)
3479				display_flush(&ctx.display[i]);
3480
3481			DBG(TIMER, ("%s timer still active? %d\n", DisplayString(ctx.display->dpy), ret != 0));
3482			ctx.timer_active = ret != 0;
3483		}
3484	}
3485
3486	ret = 0;
3487out:
3488	context_cleanup(&ctx);
3489	return ret;
3490}
3491