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