@ -1,5 +1,5 @@
/*
* Copyright © 2013 Intel Corporation
* Copyright © 2015 Samsung
*
* Permission to use , copy , modify , distribute , and sell this software and
* its documentation for any purpose is hereby granted without fee , provided
@ -19,125 +19,83 @@
* 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 : Confirm that we can map a window and we ' re running
* under Xwayland , not just X .
*
* xwayland - test : the idea is to guarantee that XWayland infrastructure in
* general works with Weston .
* This is done in steps :
* 1 ) Confirm that the WL_SURFACE_ID atom exists
* 2 ) Confirm that the window manager ' s name is " Weston WM "
* 3 ) Make sure we can map a window
*/
# include "config.h"
# include <unistd.h>
# include <assert.h>
# include <stdlib.h>
# include <stdio.h>
# include <fcntl.h>
# include <X11/Xlib.h>
# include <X11/Xatom.h>
# include <string.h>
# include <xcb/xcb.h>
# include <xcb/dri2.h>
# include <xf86drm.h>
# include "weston-test-runner.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 )
TEST ( xwayland_client_test )
{
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 ;
Display * display ;
Window window , root , * support ;
XEvent event ;
int screen , status , actual_format ;
unsigned long nitems , bytes ;
Atom atom , type_atom , actual_type ;
char * wm_name ;
display = XOpenDisplay ( NULL ) ;
if ( ! display )
exit ( EXIT_FAILURE ) ;
atom = XInternAtom ( display , " WL_SURFACE_ID " , True ) ;
assert ( atom ! = None ) ;
atom = XInternAtom ( display , " _NET_SUPPORTING_WM_CHECK " , True ) ;
assert ( atom ! = None ) ;
screen = DefaultScreen ( display ) ;
root = RootWindow ( display , screen ) ;
status = XGetWindowProperty ( display , root , atom , 0L , ~ 0L ,
False , XA_WINDOW , & actual_type ,
& actual_format , & nitems , & bytes ,
( void * ) & support ) ;
assert ( status = = Success ) ;
atom = XInternAtom ( display , " _NET_WM_NAME " , True ) ;
assert ( atom ! = None ) ;
type_atom = XInternAtom ( display , " UTF8_STRING " , True ) ;
assert ( atom ! = None ) ;
status = XGetWindowProperty ( display , * support , atom , 0L , BUFSIZ ,
False , type_atom , & actual_type ,
& actual_format , & nitems , & bytes ,
( void * ) & wm_name ) ;
assert ( status = = Success ) ;
assert ( nitems ) ;
assert ( strcmp ( " Weston WM " , wm_name ) = = 0 ) ;
free ( support ) ;
free ( wm_name ) ;
window = XCreateSimpleWindow ( display , root , 100 , 100 , 300 , 300 , 1 ,
BlackPixel ( display , screen ) ,
WhitePixel ( display , screen ) ) ;
XSelectInput ( display , window , ExposureMask ) ;
XMapWindow ( display , window ) ;
alarm ( 4 ) ;
while ( 1 ) {
XNextEvent ( display , & event ) ;
if ( event . type = = Expose )
break ;
}
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 ( ) ;
XCloseDisplay ( display ) ;
exit ( EXIT_SUCCESS ) ;
}