You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
			
				
					143 lines
				
				4.2 KiB
			
		
		
			
		
	
	
					143 lines
				
				4.2 KiB
			| 
											13 years ago
										 | /*
 | ||
|  |  * Copyright © 2013 Intel Corporation
 | ||
|  |  *
 | ||
|  |  * Permission to use, copy, modify, distribute, and sell this software and
 | ||
|  |  * its documentation for any purpose is hereby granted without fee, provided
 | ||
|  |  * that the above copyright notice appear in all copies and that both that
 | ||
|  |  * copyright notice and this permission notice appear in supporting
 | ||
|  |  * documentation, and that the name of the copyright holders not be used in
 | ||
|  |  * advertising or publicity pertaining to distribution of the software
 | ||
|  |  * without specific, written prior permission.  The copyright holders make
 | ||
|  |  * no representations about the suitability of this software for any
 | ||
|  |  * purpose.  It is provided "as is" without express or implied warranty.
 | ||
|  |  *
 | ||
|  |  * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
 | ||
|  |  * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
 | ||
|  |  * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
 | ||
|  |  * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
 | ||
|  |  * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
 | ||
|  |  * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 | ||
|  |  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | ||
|  |  *
 | ||
|  |  * Author: Tiago Vignatti
 | ||
|  |  *
 | ||
|  |  * xwayland-test: the idea is to guarantee that XWayland infrastructure in
 | ||
|  |  * general works with Weston.
 | ||
|  |  */
 | ||
|  | 
 | ||
|  | #include "weston-test-runner.h"
 | ||
|  | 
 | ||
|  | #include <assert.h>
 | ||
|  | #include <unistd.h>
 | ||
|  | #include <stdlib.h>
 | ||
|  | #include <stdio.h>
 | ||
|  | #include <fcntl.h>
 | ||
|  | #include <string.h>
 | ||
|  | #include <xcb/xcb.h>
 | ||
|  | #include <xcb/dri2.h>
 | ||
|  | #include <xf86drm.h>
 | ||
|  | 
 | ||
|  | 
 | ||
|  | static int
 | ||
|  | dri2_open(xcb_connection_t *c, xcb_screen_t *screen)
 | ||
|  | {
 | ||
|  | 	xcb_dri2_connect_cookie_t cookie;
 | ||
|  | 	xcb_dri2_connect_reply_t *reply;
 | ||
|  | 	xcb_dri2_authenticate_cookie_t cookie_auth;
 | ||
|  | 	xcb_dri2_authenticate_reply_t *reply_auth;
 | ||
|  | 	char *driver, *device;
 | ||
|  | 	int fd;
 | ||
|  | 	drm_magic_t magic;
 | ||
|  | 
 | ||
|  | 	cookie = xcb_dri2_connect(c, screen->root, XCB_DRI2_DRIVER_TYPE_DRI);
 | ||
|  | 	reply = xcb_dri2_connect_reply(c, cookie, 0);
 | ||
|  | 	assert(reply);
 | ||
|  | 
 | ||
|  | 	driver = strndup(xcb_dri2_connect_driver_name (reply),
 | ||
|  | 			 xcb_dri2_connect_driver_name_length (reply));
 | ||
|  | 	device = strndup(xcb_dri2_connect_device_name (reply),
 | ||
|  | 			 xcb_dri2_connect_device_name_length (reply));
 | ||
|  | 
 | ||
|  | 	fd = open(device, O_RDWR);
 | ||
|  | 	printf ("Trying connect to %s driver on %s\n", driver, device);
 | ||
|  | 	free(driver);
 | ||
|  | 	free(device);
 | ||
|  | 
 | ||
|  | 	if (fd < 0)
 | ||
|  | 		return -1;
 | ||
|  | 
 | ||
|  | 	drmGetMagic(fd, &magic);
 | ||
|  | 
 | ||
|  | 	cookie_auth = xcb_dri2_authenticate(c, screen->root, magic);
 | ||
|  | 	reply_auth = xcb_dri2_authenticate_reply(c, cookie_auth, 0);
 | ||
|  | 	assert(reply_auth);
 | ||
|  | 
 | ||
|  | 	return fd;
 | ||
|  | }
 | ||
|  | 
 | ||
|  | static int
 | ||
|  | create_window(void)
 | ||
|  | {
 | ||
|  | 	xcb_connection_t *c;
 | ||
|  | 	xcb_screen_t *screen;
 | ||
|  | 	xcb_window_t win;
 | ||
|  | 	int fd;
 | ||
|  | 
 | ||
|  | 	c = xcb_connect (NULL, NULL);
 | ||
|  | 	if (c == NULL) {
 | ||
|  | 		printf("failed to get X11 connection\n");
 | ||
|  | 		return -1;
 | ||
|  | 	}
 | ||
|  | 
 | ||
|  | 	screen = xcb_setup_roots_iterator(xcb_get_setup(c)).data;
 | ||
|  | 
 | ||
|  | 	win = xcb_generate_id(c);
 | ||
|  | 	xcb_create_window(c, XCB_COPY_FROM_PARENT, win, screen->root,
 | ||
|  | 			0, 0, 150, 150, 1, XCB_WINDOW_CLASS_INPUT_OUTPUT,
 | ||
|  | 			screen->root_visual, 0, NULL);
 | ||
|  | 
 | ||
|  | 	xcb_change_property (c, XCB_PROP_MODE_REPLACE, win,
 | ||
|  | 			XCB_ATOM_WM_NAME, XCB_ATOM_STRING, 8,
 | ||
|  | 			5, "title");
 | ||
|  | 	xcb_map_window(c, win);
 | ||
|  | 	xcb_flush(c);
 | ||
|  | 
 | ||
|  | 	fd = dri2_open(c, screen);
 | ||
|  | 	if (fd < 0)
 | ||
|  | 		return -1;
 | ||
|  | 
 | ||
|  | 	xcb_destroy_window(c, win);
 | ||
|  | 	xcb_disconnect(c);
 | ||
|  | 	return 0;
 | ||
|  | }
 | ||
|  | 
 | ||
|  | /*
 | ||
|  |  * Ideally, the X Window Manager (XWM) and Weston Wayland compositor shouldn't
 | ||
|  |  * be in the same process because they are using two different protocol
 | ||
|  |  * streams in which one does not interface with the other. Probably the
 | ||
|  |  * biggest problem with such architecture are the potentials dead locks that
 | ||
|  |  * it may occur. So hypothetically, an X client might issue an X11 blocking
 | ||
|  |  * request via X (DRI2Authenticate) which in turn sends a Wayland blocking
 | ||
|  |  * request for Weston process it. X is blocked. At the same time, XWM might be
 | ||
|  |  * trying to process an XChangeProperty, so it requests a blocking X11 call to
 | ||
|  |  * the X server (xcb_get_property_reply -> xcb_wait_for_reply) which therefore
 | ||
|  |  * will blocks there. It's a deadlock situation and this test is trying to
 | ||
|  |  * catch that.
 | ||
|  |  */
 | ||
|  | static void
 | ||
|  | check_dri2_authenticate(void)
 | ||
|  | {
 | ||
|  | 	int i, num_tests;
 | ||
|  | 
 | ||
|  | 	/* TODO: explain why num_tests times */
 | ||
|  | 	num_tests = 10;
 | ||
|  | 	for (i = 0; i < num_tests; i++)
 | ||
|  | 		assert(create_window() == 0);
 | ||
|  | }
 | ||
|  | 
 | ||
|  | TEST(xwayland_client_test)
 | ||
|  | {
 | ||
|  | 	check_dri2_authenticate();
 | ||
|  | 	exit(EXIT_SUCCESS);
 | ||
|  | }
 |