xf86-video-intel: 2 commits - src/sna/sna_display.c test/dri2-speed.c test/.gitignore test/Makefile.am test/present-speed.c

Chris Wilson ickle at kemper.freedesktop.org
Fri Mar 20 07:40:35 PDT 2015


 src/sna/sna_display.c |    2 
 test/.gitignore       |    2 
 test/Makefile.am      |    2 
 test/dri2-speed.c     |  296 ++++++++++++++++++++++++++++++++++++++++++
 test/present-speed.c  |  351 ++++++++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 651 insertions(+), 2 deletions(-)

New commits:
commit 44452825fb862c81957f53e04f739e2d96864f91
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri Mar 20 13:13:43 2015 +0000

    sna: Remove bogus assert(output->randr_output)
    
    During shutdown, we may get backlight uevents after removing the
    randr_output.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index 663853f..3ea3436 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -530,8 +530,6 @@ sna_backlight_uevent(int fd, void *closure)
 		if (sna_output->dpms_mode != DPMSModeOn)
 			continue;
 
-		assert(output->randr_output);
-
 		val = backlight_get(&sna_output->backlight);
 		if (val < 0)
 			continue;
commit 9e39bea9d3cfb1a05b3908e51fab649c1b9f6301
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri Mar 20 11:50:38 2015 +0000

    tests: Add basic present benchmark
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/test/.gitignore b/test/.gitignore
index 3b18297..da174be 100644
--- a/test/.gitignore
+++ b/test/.gitignore
@@ -22,8 +22,10 @@ mixed-stress
 lowlevel-blt-bench
 vsync.avi
 dri2-race
+dri2-speed
 dri2-swap
 dri2-test
 dri3-test
+present-speed
 present-test
 shm-test
diff --git a/test/Makefile.am b/test/Makefile.am
index 66ed8eb..9b37222 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -28,6 +28,7 @@ stress_TESTS = \
 if DRI2
 stress_TESTS += \
 	dri2-race \
+	dri2-speed \
 	dri2-swap \
 	dri2-test \
 	$(NULL)
@@ -37,6 +38,7 @@ if X11_DRI3
 stress_TESTS += \
 	dri3-test \
 	present-test \
+	present-speed \
 	$(NULL)
 endif
 check_PROGRAMS = $(stress_TESTS)
diff --git a/test/dri2-speed.c b/test/dri2-speed.c
new file mode 100644
index 0000000..bd7b6e1
--- /dev/null
+++ b/test/dri2-speed.c
@@ -0,0 +1,296 @@
+/*
+ * Copyright (c) 2015 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <X11/Xlib.h>
+#include <X11/Xatom.h>
+#include <X11/Xlib-xcb.h>
+#include <X11/Xutil.h>
+#include <X11/Xlibint.h>
+#include <X11/extensions/dpms.h>
+#include <X11/extensions/randr.h>
+#include <X11/extensions/Xrandr.h>
+#include <xcb/xcb.h>
+#include <xcb/dri2.h>
+#include <xf86drm.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <assert.h>
+#include <errno.h>
+#include <setjmp.h>
+#include <signal.h>
+
+#include "dri2.h"
+
+static int _x_error_occurred;
+
+static int
+_check_error_handler(Display     *display,
+		     XErrorEvent *event)
+{
+	printf("X11 error from display %s, serial=%ld, error=%d, req=%d.%d\n",
+	       DisplayString(display),
+	       event->serial,
+	       event->error_code,
+	       event->request_code,
+	       event->minor_code);
+	_x_error_occurred++;
+	return False; /* ignored */
+}
+
+static double elapsed(const struct timespec *start,
+		      const struct timespec *end)
+{
+	return 1e6*(end->tv_sec - start->tv_sec) + (end->tv_nsec - start->tv_nsec)/1000;
+}
+
+static void run(Display *dpy, Window win, const char *name)
+{
+	xcb_connection_t *c = XGetXCBConnection(dpy);
+	struct timespec start, end;
+	int n, completed = 0;
+
+	_x_error_occurred = 0;
+
+	clock_gettime(CLOCK_MONOTONIC, &start);
+	do {
+		for (n = 0; n < 1000; n++) {
+			unsigned int attachments[] = { DRI2BufferBackLeft };
+			unsigned int seq[2];
+
+			seq[0] = xcb_dri2_swap_buffers_unchecked(c, win,
+								 0, 0, 0, 0, 0, 0).sequence;
+
+
+			seq[1] = xcb_dri2_get_buffers_unchecked(c, win,
+								1, 1, attachments).sequence;
+
+			xcb_flush(c);
+			xcb_discard_reply(c, seq[0]);
+			xcb_discard_reply(c, seq[1]);
+			completed++;
+		}
+		clock_gettime(CLOCK_MONOTONIC, &end);
+	} while (end.tv_sec < start.tv_sec + 10);
+
+	XSync(dpy, True);
+	if (_x_error_occurred)
+		abort();
+
+	printf("%s: Completed %d swaps in %.1fs, %.3fus each (%.1f FPS)\n",
+	       name, completed, elapsed(&start, &end) / 1000000,
+	       elapsed(&start, &end) / completed,
+	       completed / (elapsed(&start, &end) / 1000000));
+}
+
+static inline XRRScreenResources *_XRRGetScreenResourcesCurrent(Display *dpy, Window window)
+{
+	XRRScreenResources *res;
+
+	res = XRRGetScreenResourcesCurrent(dpy, window);
+	if (res == NULL)
+		res = XRRGetScreenResources(dpy, window);
+
+	return res;
+}
+
+static XRRModeInfo *lookup_mode(XRRScreenResources *res, int id)
+{
+	int i;
+
+	for (i = 0; i < res->nmode; i++) {
+		if (res->modes[i].id == id)
+			return &res->modes[i];
+	}
+
+	return NULL;
+}
+
+static int dri2_open(Display *dpy)
+{
+	drm_auth_t auth;
+	char *driver, *device;
+	int fd;
+
+	if (!DRI2Connect(dpy, DefaultRootWindow(dpy), &driver, &device))
+		return -1;
+
+	printf ("Connecting to %s driver on %s\n", driver, device);
+
+	fd = open(device, O_RDWR);
+	if (fd < 0)
+		return -1;
+
+	if (drmIoctl(fd, DRM_IOCTL_GET_MAGIC, &auth))
+		return -1;
+
+	if (!DRI2Authenticate(dpy, DefaultRootWindow(dpy), auth.magic))
+		return -1;
+
+	return fd;
+}
+
+static void fullscreen(Display *dpy, Window win)
+{
+	Atom atom = XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN", False);
+	XChangeProperty(dpy, win,
+			XInternAtom(dpy, "_NET_WM_STATE", False),
+			XA_ATOM, 32, PropModeReplace,
+			(unsigned char *)&atom, 1);
+}
+
+int main(void)
+{
+	Display *dpy;
+	Window root, win;
+	XRRScreenResources *res;
+	XRRCrtcInfo **original_crtc;
+	XSetWindowAttributes attr;
+	int i, j, fd;
+
+	attr.override_redirect = 1;
+
+	dpy = XOpenDisplay(NULL);
+	if (dpy == NULL)
+		return 77;
+
+	fd = dri2_open(dpy);
+	if (fd < 0)
+		return 77;
+
+	if (DPMSQueryExtension(dpy, &i, &i))
+		DPMSDisable(dpy);
+
+	root = DefaultRootWindow(dpy);
+
+	signal(SIGALRM, SIG_IGN);
+	XSetErrorHandler(_check_error_handler);
+
+	res = NULL;
+	if (XRRQueryVersion(dpy, &i, &i))
+		res = _XRRGetScreenResourcesCurrent(dpy, root);
+	if (res == NULL)
+		return 77;
+
+	original_crtc = malloc(sizeof(XRRCrtcInfo *)*res->ncrtc);
+	for (i = 0; i < res->ncrtc; i++)
+		original_crtc[i] = XRRGetCrtcInfo(dpy, res, res->crtcs[i]);
+
+	printf("noutput=%d, ncrtc=%d\n", res->noutput, res->ncrtc);
+	for (i = 0; i < res->ncrtc; i++)
+		XRRSetCrtcConfig(dpy, res, res->crtcs[i], CurrentTime,
+				 0, 0, None, RR_Rotate_0, NULL, 0);
+
+	DRI2CreateDrawable(dpy, root);
+	DRI2SwapInterval(dpy, root, 0);
+	run(dpy, root, "off");
+
+	for (i = 0; i < res->noutput; i++) {
+		XRROutputInfo *output;
+		XRRModeInfo *mode;
+
+		output = XRRGetOutputInfo(dpy, res, res->outputs[i]);
+		if (output == NULL)
+			continue;
+
+		mode = NULL;
+		if (res->nmode)
+			mode = lookup_mode(res, output->modes[0]);
+
+		for (j = 0; mode && j < 2*output->ncrtc; j++) {
+			int c = j;
+			if (c >= output->ncrtc)
+				c = 2*output->ncrtc - j - 1;
+
+			printf("[%d, %d] -- OUTPUT:%ld, CRTC:%ld: %dx%d\n",
+			       i, c, (long)res->outputs[i], (long)output->crtcs[c],
+			       mode->width, mode->height);
+			XRRSetCrtcConfig(dpy, res, output->crtcs[c], CurrentTime,
+					 0, 0, output->modes[0], RR_Rotate_0, &res->outputs[i], 1);
+
+			run(dpy, root, "root");
+
+			win = XCreateWindow(dpy, root,
+					    0, 0, mode->width, mode->height, 0,
+					    DefaultDepth(dpy, DefaultScreen(dpy)),
+					    InputOutput,
+					    DefaultVisual(dpy, DefaultScreen(dpy)),
+					    CWOverrideRedirect, &attr);
+			DRI2CreateDrawable(dpy, win);
+			DRI2SwapInterval(dpy, win, 0);
+			fullscreen(dpy, win);
+			XMapWindow(dpy, win);
+			run(dpy, win, "fullscreen");
+			XDestroyWindow(dpy, win);
+
+			win = XCreateWindow(dpy, root,
+					    0, 0, mode->width, mode->height, 0,
+					    DefaultDepth(dpy, DefaultScreen(dpy)),
+					    InputOutput,
+					    DefaultVisual(dpy, DefaultScreen(dpy)),
+					    CWOverrideRedirect, &attr);
+			DRI2CreateDrawable(dpy, win);
+			DRI2SwapInterval(dpy, win, 0);
+			XMapWindow(dpy, win);
+			run(dpy, win, "windowed");
+			XDestroyWindow(dpy, win);
+
+			win = XCreateWindow(dpy, root,
+					    0, 0, mode->width/2, mode->height/2, 0,
+					    DefaultDepth(dpy, DefaultScreen(dpy)),
+					    InputOutput,
+					    DefaultVisual(dpy, DefaultScreen(dpy)),
+					    CWOverrideRedirect, &attr);
+			DRI2CreateDrawable(dpy, win);
+			DRI2SwapInterval(dpy, win, 0);
+			XMapWindow(dpy, win);
+			run(dpy, win, "half");
+			XDestroyWindow(dpy, win);
+
+			XRRSetCrtcConfig(dpy, res, output->crtcs[c], CurrentTime,
+					 0, 0, None, RR_Rotate_0, NULL, 0);
+		}
+
+		XRRFreeOutputInfo(output);
+	}
+
+	for (i = 0; i < res->ncrtc; i++)
+		XRRSetCrtcConfig(dpy, res, res->crtcs[i], CurrentTime,
+				 original_crtc[i]->x,
+				 original_crtc[i]->y,
+				 original_crtc[i]->mode,
+				 original_crtc[i]->rotation,
+				 original_crtc[i]->outputs,
+				 original_crtc[i]->noutput);
+
+	if (DPMSQueryExtension(dpy, &i, &i))
+		DPMSEnable(dpy);
+	return 0;
+}
diff --git a/test/present-speed.c b/test/present-speed.c
new file mode 100644
index 0000000..1d3411b
--- /dev/null
+++ b/test/present-speed.c
@@ -0,0 +1,351 @@
+/*
+ * Copyright (c) 2015 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <X11/Xlib.h>
+#include <X11/Xatom.h>
+#include <X11/Xlib-xcb.h>
+#include <X11/xshmfence.h>
+#include <X11/Xutil.h>
+#include <X11/Xlibint.h>
+#include <X11/extensions/dpms.h>
+#include <X11/extensions/randr.h>
+#include <X11/extensions/Xrandr.h>
+#include <xcb/xcb.h>
+#include <xcb/present.h>
+#include <xf86drm.h>
+#include <i915_drm.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <assert.h>
+#include <errno.h>
+#include <setjmp.h>
+#include <signal.h>
+
+static int _x_error_occurred;
+static uint32_t stamp;
+
+static int
+_check_error_handler(Display     *display,
+		     XErrorEvent *event)
+{
+	printf("X11 error from display %s, serial=%ld, error=%d, req=%d.%d\n",
+	       DisplayString(display),
+	       event->serial,
+	       event->error_code,
+	       event->request_code,
+	       event->minor_code);
+	_x_error_occurred++;
+	return False; /* ignored */
+}
+
+static void *setup_msc(Display *dpy, Window win)
+{
+	xcb_connection_t *c = XGetXCBConnection(dpy);
+	uint32_t id = xcb_generate_id(c);
+
+	xcb_present_select_input(c, id, win, XCB_PRESENT_EVENT_MASK_COMPLETE_NOTIFY);
+	return xcb_register_for_special_xge(c, &xcb_present_id, id, &stamp);
+}
+
+static void teardown_msc(Display *dpy, void *q)
+{
+	xcb_unregister_for_special_event(XGetXCBConnection(dpy), q);
+}
+
+static double elapsed(const struct timespec *start,
+		      const struct timespec *end)
+{
+	return 1e6*(end->tv_sec - start->tv_sec) + (end->tv_nsec - start->tv_nsec)/1000;
+}
+
+static void run(Display *dpy, Window win, const char *name)
+{
+	xcb_connection_t *c = XGetXCBConnection(dpy);
+	struct timespec start, end;
+	Pixmap pixmap[4];
+	int busy[4];
+	Window root;
+	unsigned int width, height;
+	unsigned border, depth;
+	int i, j, n, back = 0;
+	int completed = 0;
+	void *Q;
+
+	XGetGeometry(dpy, win,
+		     &root, &i, &j, &width, &height, &border, &depth);
+
+	_x_error_occurred = 0;
+
+	for (n = 0; n < 4; n++) {
+		pixmap[n] = XCreatePixmap(dpy, win, width, height, depth);
+		busy[n] = 0;
+	}
+
+	Q = setup_msc(dpy, win);
+	clock_gettime(CLOCK_MONOTONIC, &start);
+	do {
+		for (n = 0; n < 1000; n++) {
+			Pixmap p = 0;
+			for (i = 0; i < 4; i++) {
+				j = (back + i) % 4;
+				if (!busy[j]) {
+					p = pixmap[j];
+					break;
+				}
+			}
+			if (p == 0) {
+				xcb_present_complete_notify_event_t *ce;
+				xcb_generic_event_t *ev;
+
+				ev = xcb_wait_for_special_event(c, Q);
+				if (ev == NULL)
+					abort();
+
+				do {
+					ce = (xcb_present_complete_notify_event_t *)ev;
+					if (ce->kind == XCB_PRESENT_COMPLETE_KIND_PIXMAP) {
+						completed++;
+						busy[ce->serial] = 0;
+						if (p == 0)
+							p = pixmap[j = ce->serial];
+					}
+					free(ev);
+				} while ((ev = xcb_poll_for_special_event(c, Q)));
+			}
+
+			back = j;
+			busy[back] = 1;
+
+			xcb_present_pixmap(c, win, p, back++,
+					   0, /* valid */
+					   0, /* update */
+					   0, /* x_off */
+					   0, /* y_off */
+					   None,
+					   None, /* wait fence */
+					   None,
+					   XCB_PRESENT_OPTION_ASYNC,
+					   0, /* target msc */
+					   0, /* divisor */
+					   0, /* remainder */
+					   0, NULL);
+			xcb_flush(c);
+		}
+		clock_gettime(CLOCK_MONOTONIC, &end);
+	} while (end.tv_sec < start.tv_sec + 10);
+
+	for (n = 0; n < 4; n++)
+		XFreePixmap(dpy, pixmap[n]);
+
+	XSync(dpy, True);
+	teardown_msc(dpy, Q);
+	if (_x_error_occurred)
+		abort();
+
+	printf("%s: Completed %d presents in %.1fs, %.3fus each (%.1f FPS)\n",
+	       name, completed, elapsed(&start, &end) / 1000000,
+	       elapsed(&start, &end) / completed,
+	       completed / (elapsed(&start, &end) / 1000000));
+}
+
+static int has_present(Display *dpy)
+{
+	xcb_connection_t *c = XGetXCBConnection(dpy);
+	xcb_generic_error_t *error = NULL;
+	void *reply;
+
+	reply = xcb_present_query_version_reply(c,
+						xcb_present_query_version(c,
+									  XCB_PRESENT_MAJOR_VERSION,
+									  XCB_PRESENT_MINOR_VERSION),
+						&error);
+
+	free(reply);
+	free(error);
+	if (reply == NULL) {
+		fprintf(stderr, "Present not supported on %s\n", DisplayString(dpy));
+		return 0;
+	}
+
+	return 1;
+}
+
+static inline XRRScreenResources *_XRRGetScreenResourcesCurrent(Display *dpy, Window window)
+{
+	XRRScreenResources *res;
+
+	res = XRRGetScreenResourcesCurrent(dpy, window);
+	if (res == NULL)
+		res = XRRGetScreenResources(dpy, window);
+
+	return res;
+}
+
+static XRRModeInfo *lookup_mode(XRRScreenResources *res, int id)
+{
+	int i;
+
+	for (i = 0; i < res->nmode; i++) {
+		if (res->modes[i].id == id)
+			return &res->modes[i];
+	}
+
+	return NULL;
+}
+
+static void fullscreen(Display *dpy, Window win)
+{
+	Atom atom = XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN", False);
+	XChangeProperty(dpy, win,
+			XInternAtom(dpy, "_NET_WM_STATE", False),
+			XA_ATOM, 32, PropModeReplace,
+			(unsigned char *)&atom, 1);
+}
+
+int main(void)
+{
+	Display *dpy;
+	Window root, win;
+	XRRScreenResources *res;
+	XRRCrtcInfo **original_crtc;
+	XSetWindowAttributes attr;
+	int i, j;
+
+	attr.override_redirect = 1;
+
+	dpy = XOpenDisplay(NULL);
+	if (dpy == NULL)
+		return 77;
+
+	if (!has_present(dpy))
+		return 77;
+
+	if (DPMSQueryExtension(dpy, &i, &i))
+		DPMSDisable(dpy);
+
+	root = DefaultRootWindow(dpy);
+
+	signal(SIGALRM, SIG_IGN);
+	XSetErrorHandler(_check_error_handler);
+
+	res = NULL;
+	if (XRRQueryVersion(dpy, &i, &i))
+		res = _XRRGetScreenResourcesCurrent(dpy, root);
+	if (res == NULL)
+		return 77;
+
+	original_crtc = malloc(sizeof(XRRCrtcInfo *)*res->ncrtc);
+	for (i = 0; i < res->ncrtc; i++)
+		original_crtc[i] = XRRGetCrtcInfo(dpy, res, res->crtcs[i]);
+
+	printf("noutput=%d, ncrtc=%d\n", res->noutput, res->ncrtc);
+	for (i = 0; i < res->ncrtc; i++)
+		XRRSetCrtcConfig(dpy, res, res->crtcs[i], CurrentTime,
+				 0, 0, None, RR_Rotate_0, NULL, 0);
+
+	run(dpy, root, "off");
+
+	for (i = 0; i < res->noutput; i++) {
+		XRROutputInfo *output;
+		XRRModeInfo *mode;
+
+		output = XRRGetOutputInfo(dpy, res, res->outputs[i]);
+		if (output == NULL)
+			continue;
+
+		mode = NULL;
+		if (res->nmode)
+			mode = lookup_mode(res, output->modes[0]);
+
+		for (j = 0; mode && j < 2*output->ncrtc; j++) {
+			int c = j;
+			if (c >= output->ncrtc)
+				c = 2*output->ncrtc - j - 1;
+
+			printf("[%d, %d] -- OUTPUT:%ld, CRTC:%ld: %dx%d\n",
+			       i, c, (long)res->outputs[i], (long)output->crtcs[c],
+			       mode->width, mode->height);
+			XRRSetCrtcConfig(dpy, res, output->crtcs[c], CurrentTime,
+					 0, 0, output->modes[0], RR_Rotate_0, &res->outputs[i], 1);
+
+			run(dpy, root, "root");
+
+			win = XCreateWindow(dpy, root,
+					    0, 0, mode->width, mode->height, 0,
+					    DefaultDepth(dpy, DefaultScreen(dpy)),
+					    InputOutput,
+					    DefaultVisual(dpy, DefaultScreen(dpy)),
+					    CWOverrideRedirect, &attr);
+			fullscreen(dpy, win);
+			XMapWindow(dpy, win);
+			run(dpy, win, "fullscreen");
+			XDestroyWindow(dpy, win);
+
+			win = XCreateWindow(dpy, root,
+					    0, 0, mode->width, mode->height, 0,
+					    DefaultDepth(dpy, DefaultScreen(dpy)),
+					    InputOutput,
+					    DefaultVisual(dpy, DefaultScreen(dpy)),
+					    CWOverrideRedirect, &attr);
+			XMapWindow(dpy, win);
+			run(dpy, win, "windowed");
+			XDestroyWindow(dpy, win);
+
+			win = XCreateWindow(dpy, root,
+					    0, 0, mode->width/2, mode->height/2, 0,
+					    DefaultDepth(dpy, DefaultScreen(dpy)),
+					    InputOutput,
+					    DefaultVisual(dpy, DefaultScreen(dpy)),
+					    CWOverrideRedirect, &attr);
+			XMapWindow(dpy, win);
+			run(dpy, win, "half");
+			XDestroyWindow(dpy, win);
+
+			XRRSetCrtcConfig(dpy, res, output->crtcs[c], CurrentTime,
+					 0, 0, None, RR_Rotate_0, NULL, 0);
+		}
+
+		XRRFreeOutputInfo(output);
+	}
+
+	for (i = 0; i < res->ncrtc; i++)
+		XRRSetCrtcConfig(dpy, res, res->crtcs[i], CurrentTime,
+				 original_crtc[i]->x,
+				 original_crtc[i]->y,
+				 original_crtc[i]->mode,
+				 original_crtc[i]->rotation,
+				 original_crtc[i]->outputs,
+				 original_crtc[i]->noutput);
+
+	if (DPMSQueryExtension(dpy, &i, &i))
+		DPMSEnable(dpy);
+	return 0;
+}


More information about the xorg-commit mailing list