@ -338,250 +338,6 @@ device_add(struct wl_client *client,
}
}
enum weston_test_screenshot_outcome {
WESTON_TEST_SCREENSHOT_SUCCESS ,
WESTON_TEST_SCREENSHOT_NO_MEMORY ,
WESTON_TEST_SCREENSHOT_BAD_BUFFER
} ;
typedef void ( * weston_test_screenshot_done_func_t ) ( void * data ,
enum weston_test_screenshot_outcome outcome ) ;
struct test_screenshot {
struct weston_compositor * compositor ;
struct wl_global * global ;
struct wl_client * client ;
struct weston_process process ;
struct wl_listener destroy_listener ;
} ;
struct test_screenshot_frame_listener {
struct wl_listener listener ;
struct weston_buffer * buffer ;
struct weston_output * output ;
weston_test_screenshot_done_func_t done ;
void * data ;
} ;
static void
copy_bgra_yflip ( uint8_t * dst , uint8_t * src , int height , int stride )
{
uint8_t * end ;
end = dst + height * stride ;
while ( dst < end ) {
memcpy ( dst , src , stride ) ;
dst + = stride ;
src - = stride ;
}
}
static void
copy_bgra ( uint8_t * dst , uint8_t * src , int height , int stride )
{
/* TODO: optimize this out */
memcpy ( dst , src , height * stride ) ;
}
static void
copy_row_swap_RB ( void * vdst , void * vsrc , int bytes )
{
uint32_t * dst = vdst ;
uint32_t * src = vsrc ;
uint32_t * end = dst + bytes / 4 ;
while ( dst < end ) {
uint32_t v = * src + + ;
/* A R G B */
uint32_t tmp = v & 0xff00ff00 ;
tmp | = ( v > > 16 ) & 0x000000ff ;
tmp | = ( v < < 16 ) & 0x00ff0000 ;
* dst + + = tmp ;
}
}
static void
copy_rgba_yflip ( uint8_t * dst , uint8_t * src , int height , int stride )
{
uint8_t * end ;
end = dst + height * stride ;
while ( dst < end ) {
copy_row_swap_RB ( dst , src , stride ) ;
dst + = stride ;
src - = stride ;
}
}
static void
copy_rgba ( uint8_t * dst , uint8_t * src , int height , int stride )
{
uint8_t * end ;
end = dst + height * stride ;
while ( dst < end ) {
copy_row_swap_RB ( dst , src , stride ) ;
dst + = stride ;
src + = stride ;
}
}
static void
test_screenshot_frame_notify ( struct wl_listener * listener , void * data )
{
struct test_screenshot_frame_listener * l =
container_of ( listener ,
struct test_screenshot_frame_listener , listener ) ;
struct weston_output * output = l - > output ;
struct weston_compositor * compositor = output - > compositor ;
int32_t stride ;
uint8_t * pixels , * d , * s ;
weston_output_disable_planes_decr ( output ) ;
wl_list_remove ( & listener - > link ) ;
stride = l - > buffer - > width * ( PIXMAN_FORMAT_BPP ( compositor - > read_format ) / 8 ) ;
pixels = malloc ( stride * l - > buffer - > height ) ;
if ( pixels = = NULL ) {
l - > done ( l - > data , WESTON_TEST_SCREENSHOT_NO_MEMORY ) ;
free ( l ) ;
return ;
}
/* FIXME: Needs to handle output transformations */
compositor - > renderer - > read_pixels ( output ,
compositor - > read_format ,
pixels ,
0 , 0 ,
output - > current_mode - > width ,
output - > current_mode - > height ) ;
stride = wl_shm_buffer_get_stride ( l - > buffer - > shm_buffer ) ;
d = wl_shm_buffer_get_data ( l - > buffer - > shm_buffer ) ;
s = pixels + stride * ( l - > buffer - > height - 1 ) ;
wl_shm_buffer_begin_access ( l - > buffer - > shm_buffer ) ;
/* XXX: It would be nice if we used Pixman to do all this rather
* than our own implementation
*/
switch ( compositor - > read_format ) {
case PIXMAN_a8r8g8b8 :
case PIXMAN_x8r8g8b8 :
if ( compositor - > capabilities & WESTON_CAP_CAPTURE_YFLIP )
copy_bgra_yflip ( d , s , output - > current_mode - > height , stride ) ;
else
copy_bgra ( d , pixels , output - > current_mode - > height , stride ) ;
break ;
case PIXMAN_x8b8g8r8 :
case PIXMAN_a8b8g8r8 :
if ( compositor - > capabilities & WESTON_CAP_CAPTURE_YFLIP )
copy_rgba_yflip ( d , s , output - > current_mode - > height , stride ) ;
else
copy_rgba ( d , pixels , output - > current_mode - > height , stride ) ;
break ;
default :
break ;
}
wl_shm_buffer_end_access ( l - > buffer - > shm_buffer ) ;
l - > done ( l - > data , WESTON_TEST_SCREENSHOT_SUCCESS ) ;
free ( pixels ) ;
free ( l ) ;
}
static bool
weston_test_screenshot_shoot ( struct weston_output * output ,
struct weston_buffer * buffer ,
weston_test_screenshot_done_func_t done ,
void * data )
{
struct test_screenshot_frame_listener * l ;
/* Get the shm buffer resource the client created */
if ( ! wl_shm_buffer_get ( buffer - > resource ) ) {
done ( data , WESTON_TEST_SCREENSHOT_BAD_BUFFER ) ;
return false ;
}
buffer - > shm_buffer = wl_shm_buffer_get ( buffer - > resource ) ;
buffer - > width = wl_shm_buffer_get_width ( buffer - > shm_buffer ) ;
buffer - > height = wl_shm_buffer_get_height ( buffer - > shm_buffer ) ;
/* Verify buffer is big enough */
if ( buffer - > width < output - > current_mode - > width | |
buffer - > height < output - > current_mode - > height ) {
done ( data , WESTON_TEST_SCREENSHOT_BAD_BUFFER ) ;
return false ;
}
/* allocate the frame listener */
l = malloc ( sizeof * l ) ;
if ( l = = NULL ) {
done ( data , WESTON_TEST_SCREENSHOT_NO_MEMORY ) ;
return false ;
}
/* Set up the listener */
l - > buffer = buffer ;
l - > output = output ;
l - > done = done ;
l - > data = data ;
l - > listener . notify = test_screenshot_frame_notify ;
wl_signal_add ( & output - > frame_signal , & l - > listener ) ;
/* Fire off a repaint */
weston_output_disable_planes_incr ( output ) ;
weston_output_schedule_repaint ( output ) ;
return true ;
}
static void
capture_screenshot_done ( void * data , enum weston_test_screenshot_outcome outcome )
{
struct wl_resource * resource = data ;
switch ( outcome ) {
case WESTON_TEST_SCREENSHOT_SUCCESS :
weston_test_send_capture_screenshot_done ( resource ) ;
break ;
case WESTON_TEST_SCREENSHOT_NO_MEMORY :
wl_resource_post_no_memory ( resource ) ;
break ;
default :
break ;
}
}
/**
* Grabs a snapshot of the screen .
*/
static void
capture_screenshot ( struct wl_client * client ,
struct wl_resource * resource ,
struct wl_resource * output_resource ,
struct wl_resource * buffer_resource )
{
struct weston_output * output =
weston_head_from_resource ( output_resource ) - > output ;
struct weston_buffer * buffer =
weston_buffer_from_resource ( buffer_resource ) ;
if ( buffer = = NULL ) {
wl_resource_post_no_memory ( resource ) ;
return ;
}
weston_test_screenshot_shoot ( output , buffer ,
capture_screenshot_done , resource ) ;
}
static void
send_touch ( struct wl_client * client , struct wl_resource * resource ,
uint32_t tv_sec_hi , uint32_t tv_sec_lo , uint32_t tv_nsec ,
@ -608,7 +364,6 @@ static const struct weston_test_interface test_implementation = {
send_key ,
device_release ,
device_add ,
capture_screenshot ,
send_touch ,
} ;