2 * VIDIX-accelerated overlay in an X window
4 * copyright (C) Alex Beregszaszi & Zoltan Ponekker & Nick Kurshev
6 * WS window manager by Pontscho/Fresh!
8 * based on vo_gl.c and vo_vesa.c and vo_xmga.c (.so mastah! ;))
10 * This file is part of MPlayer.
12 * MPlayer is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
17 * MPlayer is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License along
23 * with MPlayer; if not, write to the Free Software Foundation, Inc.,
24 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
34 #include "video_out.h"
35 #include "video_out_internal.h"
38 #include <X11/Xutil.h>
39 //#include <X11/keysym.h>
41 #ifdef CONFIG_XINERAMA
42 #include <X11/extensions/Xinerama.h>
45 #include "x11_common.h"
49 #include "vosub_vidix.h"
50 #include "vidix/vidix.h"
53 #include "gui/interface.h"
57 static const vo_info_t info
= {
65 #define UNUSED(x) ((void)(x)) /* Removes warning about unused arguments */
66 /* X11 related variables */
67 /* Colorkey handling */
69 static vidix_grkey_t gr_key
;
72 static char *vidix_name
;
74 /* Image parameters */
75 static uint32_t image_width
;
76 static uint32_t image_height
;
77 static uint32_t image_format
;
79 /* Window parameters */
80 static uint32_t window_x
, window_y
;
81 static uint32_t window_width
, window_height
;
83 /* used by XGetGeometry & XTranslateCoordinates for moving/resizing window */
84 static uint32_t drwX
, drwY
, drwWidth
, drwHeight
, drwBorderWidth
,
85 drwDepth
, drwcX
, drwcY
, dwidth
, dheight
;
87 void set_video_eq(int cap
);
90 static void set_window(int force_update
)
96 XGetGeometry(mDisplay
, vo_window
, &mRoot
, &drwX
, &drwY
, &drwWidth
,
97 &drwHeight
, &drwBorderWidth
, &drwDepth
);
100 XTranslateCoordinates(mDisplay
, vo_window
, mRoot
, 0, 0,
101 &drwcX
, &drwcY
, &mRoot
);
102 aspect(&dwidth
, &dheight
, A_NOZOOM
);
104 mp_msg(MSGT_VO
, MSGL_V
,
105 "[xvidix] dcx: %d dcy: %d dx: %d dy: %d dw: %d dh: %d\n",
106 drwcX
, drwcY
, drwX
, drwY
, drwWidth
, drwHeight
);
108 /* following stuff copied from vo_xmga.c */
111 aspect(&dwidth
, &dheight
, A_NOZOOM
);
112 drwcX
= drwX
= vo_dx
;
113 drwcY
= drwY
= vo_dy
;
114 drwWidth
= vo_dwidth
;
115 drwHeight
= vo_dheight
;
121 aspect(&dwidth
, &dheight
, A_ZOOM
);
124 (dwidth
> vo_screenwidth
? vo_screenwidth
: dwidth
)) / 2;
128 (dheight
> vo_screenheight
? vo_screenheight
: dheight
)) / 2;
130 drwWidth
= (dwidth
> vo_screenwidth
? vo_screenwidth
: dwidth
);
132 (dheight
> vo_screenheight
? vo_screenheight
: dheight
);
133 mp_msg(MSGT_VO
, MSGL_V
,
134 "[xvidix-fs] dcx: %d dcy: %d dx: %d dy: %d dw: %d dh: %d\n",
135 drwcX
, drwcY
, drwX
, drwY
, drwWidth
, drwHeight
);
139 vo_dwidth
= drwWidth
;
140 vo_dheight
= drwHeight
;
142 update_xinerama_info();
146 if (vo_panscan
> 0.0f
&& vo_fs
)
148 drwcX
-= vo_panscan_x
>> 1;
149 drwcY
-= vo_panscan_y
>> 1;
150 drwX
-= vo_panscan_x
>> 1;
151 drwY
-= vo_panscan_y
>> 1;
152 drwWidth
+= vo_panscan_x
;
153 drwHeight
+= vo_panscan_y
;
156 /* set new values in VIDIX */
157 if (force_update
|| (window_x
!= drwcX
) || (window_y
!= drwcY
) ||
158 (window_width
!= drwWidth
) || (window_height
!= drwHeight
))
160 // do a backup of window coordinates
165 window_width
= drwWidth
;
166 window_height
= drwHeight
;
168 /* FIXME: implement runtime resize/move if possible, this way is very ugly! */
170 if (vidix_init(image_width
, image_height
, vo_dx
, vo_dy
,
171 window_width
, window_height
, image_format
,
172 vo_depthonscreen
, vo_screenwidth
,
173 vo_screenheight
) != 0)
175 mp_msg(MSGT_VO
, MSGL_FATAL
,
176 "Can't initialize VIDIX driver: %s\n", strerror(errno
));
182 mp_msg(MSGT_VO
, MSGL_V
,
183 "[xvidix] window properties: pos: %dx%d, size: %dx%d\n", vo_dx
,
184 vo_dy
, window_width
, window_height
);
188 /* fill drawable with specified color */
189 if (!(vo_colorkey
& 0xff000000))
191 XSetBackground(mDisplay
, vo_gc
, 0L);
192 XClearWindow(mDisplay
, vo_window
);
193 XSetForeground(mDisplay
, vo_gc
, colorkey
);
194 XFillRectangle(mDisplay
, vo_window
, vo_gc
, drwX
, drwY
, drwWidth
,
195 (vo_fs
? drwHeight
- 1 : drwHeight
));
197 /* flush, update drawable */
203 /* connect to server, create and map window,
204 * allocate colors and (shared) memory
206 static int config(uint32_t width
, uint32_t height
, uint32_t d_width
,
207 uint32_t d_height
, uint32_t flags
, char *title
,
213 XSetWindowAttributes xswa
;
214 unsigned long xswamask
;
215 XWindowAttributes attribs
;
216 int window_depth
, r
, g
, b
;
218 title
= "MPlayer VIDIX X11 Overlay";
220 image_height
= height
;
222 image_format
= format
;
224 window_width
= d_width
;
225 window_height
= d_height
;
227 // vo_fs = flags&0x01;
229 // { vo_old_width=d_width; vo_old_height=d_height; }
231 r
= (vo_colorkey
& 0x00ff0000) >> 16;
232 g
= (vo_colorkey
& 0x0000ff00) >> 8;
233 b
= vo_colorkey
& 0x000000ff;
234 switch (vo_depthonscreen
)
237 colorkey
= vo_colorkey
;
240 colorkey
= vo_colorkey
& 0x00ffffff;
243 colorkey
= ((r
>> 3) << 11) | ((g
>> 2) << 5) | (b
>> 3);
246 colorkey
= ((r
>> 3) << 10) | ((g
>> 3) << 5) | (b
>> 3);
249 mp_msg(MSGT_VO
, MSGL_ERR
,
250 "Sorry, this (%d) color depth is not supported\n",
253 mp_msg(MSGT_VO
, MSGL_V
, "Using colorkey: %x\n", colorkey
);
257 guiGetEvent(guiSetShVideo
, 0); // the GUI will set up / resize the window
262 #ifdef X11_FULLSCREEN
263 if ((flags
& VOFLAG_FULLSCREEN
) || (flags
& VOFLAG_SWSCALE
))
264 aspect(&d_width
, &d_height
, A_ZOOM
);
268 /* Make the window */
269 XGetWindowAttributes(mDisplay
, DefaultRootWindow(mDisplay
),
273 window_depth
= attribs
.depth
;
274 if ((window_depth
!= 15) && (window_depth
!= 16)
275 && (window_depth
!= 24) && (window_depth
!= 32))
277 XMatchVisualInfo(mDisplay
, mScreen
, window_depth
, TrueColor
,
280 xswa
.background_pixel
= BlackPixel(mDisplay
, mScreen
);
281 xswa
.border_pixel
= 0;
283 XCreateColormap(mDisplay
, RootWindow(mDisplay
, mScreen
),
284 vinfo
.visual
, AllocNone
);
285 xswamask
= CWBackPixel
| CWBorderPixel
| CWColormap
;
287 vo_x11_create_vo_window(&vinfo
, vo_dx
, vo_dy
,
288 window_width
, window_height
, flags
,
289 CopyFromParent
, "xvidix", title
);
290 XChangeWindowAttributes(mDisplay
, vo_window
, xswamask
, &xswa
);
296 if ((!WinID
) && (flags
& VOFLAG_FULLSCREEN
))
300 vo_dwidth
= vo_screenwidth
;
301 vo_dheight
= vo_screenheight
;
305 if (vidix_grkey_support())
307 vidix_grkey_get(&gr_key
);
308 gr_key
.key_op
= KEYS_PUT
;
309 if (!(vo_colorkey
& 0xff000000))
311 gr_key
.ckey
.op
= CKEY_TRUE
;
313 gr_key
.ckey
.green
= g
;
314 gr_key
.ckey
.blue
= b
;
316 gr_key
.ckey
.op
= CKEY_FALSE
;
317 vidix_grkey_set(&gr_key
);
322 XSync(mDisplay
, False
);
329 static void check_events(void)
331 const int event
= vo_x11_check_events(mDisplay
);
333 if ((event
& VO_EVENT_RESIZE
) || (event
& VO_EVENT_EXPOSE
))
339 /* draw_osd, flip_page, draw_slice, draw_frame should be
340 overwritten with vidix functions (vosub_vidix.c) */
341 static void draw_osd(void)
343 mp_msg(MSGT_VO
, MSGL_FATAL
,
344 "[xvidix] error: didn't used vidix draw_osd!\n");
348 static void flip_page(void)
350 mp_msg(MSGT_VO
, MSGL_FATAL
,
351 "[xvidix] error: didn't used vidix flip_page!\n");
355 static int draw_slice(uint8_t * src
[], int stride
[],
356 int w
, int h
, int x
, int y
)
364 mp_msg(MSGT_VO
, MSGL_FATAL
,
365 "[xvidix] error: didn't used vidix draw_slice!\n");
369 static int draw_frame(uint8_t * src
[])
372 mp_msg(MSGT_VO
, MSGL_FATAL
,
373 "[xvidix] error: didn't used vidix draw_frame!\n");
377 static int query_format(uint32_t format
)
379 return vidix_query_fourcc(format
);
382 static void uninit(void)
384 if (!vo_config_count
)
397 static int preinit(const char *arg
)
401 vidix_name
= strdup(arg
);
404 mp_msg(MSGT_VO
, MSGL_INFO
,
405 "No vidix driver name provided, probing available ones (-v option for details)!\n");
412 if (vidix_preinit(vidix_name
, &video_out_xvidix
) != 0)
418 static int control(uint32_t request
, void *data
, ...)
422 case VOCTRL_QUERY_FORMAT
:
423 return query_format(*((uint32_t *) data
));
424 case VOCTRL_GUISUPPORT
:
426 case VOCTRL_GET_PANSCAN
:
427 if (!vo_config_count
|| !vo_fs
)
433 case VOCTRL_FULLSCREEN
:
435 case VOCTRL_SET_PANSCAN
:
436 if (vo_fs
&& (vo_panscan
!= vo_panscan_amount
))
442 case VOCTRL_SET_EQUALIZER
:
448 value
= va_arg(ap
, int);
452 return vidix_control(request
, data
, value
);
454 case VOCTRL_GET_EQUALIZER
:
460 value
= va_arg(ap
, int *);
464 return vidix_control(request
, data
, value
);
466 case VOCTRL_UPDATE_SCREENINFO
:
467 aspect_save_screenres(vo_screenwidth
, vo_screenheight
);
471 return vidix_control(request
, data
);
472 // return VO_NOTIMPL;