1 /*****************************************************************************
2 * x11.c: Screen capture module.
3 *****************************************************************************
4 * Copyright (C) 2004-2008 the VideoLAN team
7 * Authors: Gildas Bazin <gbazin@videolan.org>
8 * Antoine Cellerier <dionoea at videolan dot org>
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23 *****************************************************************************/
25 /*****************************************************************************
27 *****************************************************************************/
33 #include <vlc_common.h>
36 #include <X11/Xutil.h>
40 int screen_InitCapture( demux_t *p_demux )
42 demux_sys_t *p_sys = p_demux->p_sys;
44 XWindowAttributes win_info;
47 /* Open the display */
48 p_display = XOpenDisplay( NULL );
51 msg_Err( p_demux, "cannot open display" );
54 p_sys->p_data = (void *)p_display;
56 /* Get the parameters of the root window */
57 if( !XGetWindowAttributes( p_display,
58 DefaultRootWindow( p_display ),
61 msg_Err( p_demux, "can't get root window attributes" );
62 XCloseDisplay( p_display );
66 switch( win_info.depth )
68 case 8: /* FIXME: set the palette */
69 i_chroma = VLC_FOURCC('R','G','B','2'); break;
71 i_chroma = VLC_FOURCC('R','V','1','5'); break;
73 i_chroma = VLC_FOURCC('R','V','1','6'); break;
76 i_chroma = VLC_FOURCC('R','V','3','2');
80 msg_Err( p_demux, "unknown screen depth %i", win_info.depth );
81 XCloseDisplay( p_display );
85 es_format_Init( &p_sys->fmt, VIDEO_ES, i_chroma );
86 p_sys->fmt.video.i_visible_width =
87 p_sys->fmt.video.i_width = win_info.width;
88 p_sys->fmt.video.i_visible_height =
89 p_sys->fmt.video.i_height = win_info.height;
90 p_sys->fmt.video.i_bits_per_pixel = win_info.depth;
91 p_sys->fmt.video.i_chroma = i_chroma;
94 win_info.visual->red_mask;
95 win_info.visual->green_mask;
96 win_info.visual->blue_mask;
97 win_info.visual->bits_per_rgb;
103 int screen_CloseCapture( demux_t *p_demux )
105 demux_sys_t *p_sys = p_demux->p_sys;
106 Display *p_display = (Display *)p_sys->p_data;
108 XCloseDisplay( p_display );
111 module_Unneed( p_sys->p_blend, p_sys->p_blend->p_module );
112 vlc_object_detach( p_sys->p_blend );
113 vlc_object_release( p_sys->p_blend );
118 block_t *screen_Capture( demux_t *p_demux )
120 demux_sys_t *p_sys = p_demux->p_sys;
121 Display *p_display = (Display *)p_sys->p_data;
125 int root_x = 0, root_y = 0;
127 if( p_sys->b_follow_mouse || p_sys->p_mouse )
129 Window root = DefaultRootWindow( p_display ), child;
132 if( XQueryPointer( p_display, root,
133 &root, &child, &root_x, &root_y, &win_x, &win_y,
136 if( p_sys->b_follow_mouse )
137 FollowMouse( p_sys, root_x, root_y );
140 msg_Dbg( p_demux, "XQueryPointer() failed" );
144 image = XGetImage( p_display, DefaultRootWindow( p_display ),
145 p_sys->i_left, p_sys->i_top, p_sys->fmt.video.i_width,
146 p_sys->fmt.video.i_height, AllPlanes, ZPixmap );
150 msg_Warn( p_demux, "cannot get image" );
154 i_size = image->bytes_per_line * image->height;
156 if( !( p_block = block_New( p_demux, i_size ) ) )
158 msg_Warn( p_demux, "cannot get block" );
159 XDestroyImage( image );
163 if( !p_sys->p_mouse )
164 vlc_memcpy( p_block->p_buffer, image->data, i_size );
167 if( !p_sys->dst.i_planes )
168 vout_InitPicture( p_demux, &p_sys->dst,
169 p_sys->fmt.video.i_chroma,
170 p_sys->fmt.video.i_width,
171 p_sys->fmt.video.i_height,
172 p_sys->fmt.video.i_aspect );
173 if( !p_sys->p_blend )
175 p_sys->p_blend = vlc_object_create( p_demux, sizeof(filter_t) );
176 if( !p_sys->p_blend )
177 msg_Err( p_demux, "Could not allocate memory for blending module" );
180 es_format_Init( &p_sys->p_blend->fmt_in, VIDEO_ES,
181 VLC_FOURCC('R','G','B','A') );
182 p_sys->p_blend->fmt_in.video = p_sys->p_mouse->format;
183 p_sys->p_blend->fmt_out = p_sys->fmt;
184 p_sys->p_blend->p_module =
185 module_Need( p_sys->p_blend, "video blending", 0, 0 );
186 if( !p_sys->p_blend->p_module )
188 msg_Err( p_demux, "Could not load video blending module" );
189 vlc_object_detach( p_sys->p_blend );
190 vlc_object_release( p_sys->p_blend );
191 p_sys->p_blend = NULL;
197 vlc_memcpy( p_block->p_buffer, image->data, i_size );
198 p_sys->dst.p->p_pixels = p_block->p_buffer;
199 p_sys->p_blend->pf_video_blend( p_sys->p_blend,
208 picture_Release( p_sys->p_mouse );
209 p_sys->p_mouse = NULL;
210 vlc_memcpy( p_block->p_buffer, image->data, i_size );
214 XDestroyImage( image );