2 VIDIX accelerated overlay in a X window
4 (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! ;))
18 #include "video_out.h"
19 #include "video_out_internal.h"
22 #include <X11/Xutil.h>
23 //#include <X11/keysym.h>
25 #ifdef CONFIG_XINERAMA
26 #include <X11/extensions/Xinerama.h>
29 #include "x11_common.h"
33 #include "vosub_vidix.h"
34 #include "vidix/vidix.h"
37 #include "gui/interface.h"
41 static const vo_info_t info
= {
49 #define UNUSED(x) ((void)(x)) /* Removes warning about unused arguments */
50 /* X11 related variables */
51 /* Colorkey handling */
53 static vidix_grkey_t gr_key
;
56 static char *vidix_name
;
58 /* Image parameters */
59 static uint32_t image_width
;
60 static uint32_t image_height
;
61 static uint32_t image_format
;
63 /* Window parameters */
64 static uint32_t window_x
, window_y
;
65 static uint32_t window_width
, window_height
;
67 /* used by XGetGeometry & XTranslateCoordinates for moving/resizing window */
68 static uint32_t drwX
, drwY
, drwWidth
, drwHeight
, drwBorderWidth
,
69 drwDepth
, drwcX
, drwcY
, dwidth
, dheight
;
71 void set_video_eq(int cap
);
74 static void set_window(int force_update
)
80 XGetGeometry(mDisplay
, vo_window
, &mRoot
, &drwX
, &drwY
, &drwWidth
,
81 &drwHeight
, &drwBorderWidth
, &drwDepth
);
84 XTranslateCoordinates(mDisplay
, vo_window
, mRoot
, 0, 0,
85 &drwcX
, &drwcY
, &mRoot
);
86 aspect(&dwidth
, &dheight
, A_NOZOOM
);
88 mp_msg(MSGT_VO
, MSGL_V
,
89 "[xvidix] dcx: %d dcy: %d dx: %d dy: %d dw: %d dh: %d\n",
90 drwcX
, drwcY
, drwX
, drwY
, drwWidth
, drwHeight
);
92 /* following stuff copied from vo_xmga.c */
95 aspect(&dwidth
, &dheight
, A_NOZOOM
);
99 drwHeight
= vo_dheight
;
105 aspect(&dwidth
, &dheight
, A_ZOOM
);
108 (dwidth
> vo_screenwidth
? vo_screenwidth
: dwidth
)) / 2;
112 (dheight
> vo_screenheight
? vo_screenheight
: dheight
)) / 2;
114 drwWidth
= (dwidth
> vo_screenwidth
? vo_screenwidth
: dwidth
);
116 (dheight
> vo_screenheight
? vo_screenheight
: dheight
);
117 mp_msg(MSGT_VO
, MSGL_V
,
118 "[xvidix-fs] dcx: %d dcy: %d dx: %d dy: %d dw: %d dh: %d\n",
119 drwcX
, drwcY
, drwX
, drwY
, drwWidth
, drwHeight
);
123 vo_dwidth
= drwWidth
;
124 vo_dheight
= drwHeight
;
126 update_xinerama_info();
130 if (vo_panscan
> 0.0f
&& vo_fs
)
132 drwcX
-= vo_panscan_x
>> 1;
133 drwcY
-= vo_panscan_y
>> 1;
134 drwX
-= vo_panscan_x
>> 1;
135 drwY
-= vo_panscan_y
>> 1;
136 drwWidth
+= vo_panscan_x
;
137 drwHeight
+= vo_panscan_y
;
140 /* set new values in VIDIX */
141 if (force_update
|| (window_x
!= drwcX
) || (window_y
!= drwcY
) ||
142 (window_width
!= drwWidth
) || (window_height
!= drwHeight
))
144 // do a backup of window coordinates
149 window_width
= drwWidth
;
150 window_height
= drwHeight
;
152 /* FIXME: implement runtime resize/move if possible, this way is very ugly! */
154 if (vidix_init(image_width
, image_height
, vo_dx
, vo_dy
,
155 window_width
, window_height
, image_format
,
156 vo_depthonscreen
, vo_screenwidth
,
157 vo_screenheight
) != 0)
159 mp_msg(MSGT_VO
, MSGL_FATAL
,
160 "Can't initialize VIDIX driver: %s\n", strerror(errno
));
166 mp_msg(MSGT_VO
, MSGL_V
,
167 "[xvidix] window properties: pos: %dx%d, size: %dx%d\n", vo_dx
,
168 vo_dy
, window_width
, window_height
);
172 /* fill drawable with specified color */
173 if (!(vo_colorkey
& 0xff000000))
175 XSetBackground(mDisplay
, vo_gc
, 0L);
176 XClearWindow(mDisplay
, vo_window
);
177 XSetForeground(mDisplay
, vo_gc
, colorkey
);
178 XFillRectangle(mDisplay
, vo_window
, vo_gc
, drwX
, drwY
, drwWidth
,
179 (vo_fs
? drwHeight
- 1 : drwHeight
));
181 /* flush, update drawable */
187 /* connect to server, create and map window,
188 * allocate colors and (shared) memory
190 static int config(uint32_t width
, uint32_t height
, uint32_t d_width
,
191 uint32_t d_height
, uint32_t flags
, char *title
,
197 XSetWindowAttributes xswa
;
198 unsigned long xswamask
;
199 XWindowAttributes attribs
;
200 int window_depth
, r
, g
, b
;
202 title
= "MPlayer VIDIX X11 Overlay";
204 image_height
= height
;
206 image_format
= format
;
208 window_width
= d_width
;
209 window_height
= d_height
;
211 // vo_fs = flags&0x01;
213 // { vo_old_width=d_width; vo_old_height=d_height; }
215 r
= (vo_colorkey
& 0x00ff0000) >> 16;
216 g
= (vo_colorkey
& 0x0000ff00) >> 8;
217 b
= vo_colorkey
& 0x000000ff;
218 switch (vo_depthonscreen
)
221 colorkey
= vo_colorkey
;
224 colorkey
= vo_colorkey
& 0x00ffffff;
227 colorkey
= ((r
>> 3) << 11) | ((g
>> 2) << 5) | (b
>> 3);
230 colorkey
= ((r
>> 3) << 10) | ((g
>> 3) << 5) | (b
>> 3);
233 mp_msg(MSGT_VO
, MSGL_ERR
,
234 "Sorry, this (%d) color depth is not supported\n",
237 mp_msg(MSGT_VO
, MSGL_V
, "Using colorkey: %x\n", colorkey
);
241 guiGetEvent(guiSetShVideo
, 0); // the GUI will set up / resize the window
246 #ifdef X11_FULLSCREEN
247 if ((flags
& VOFLAG_FULLSCREEN
) || (flags
& VOFLAG_SWSCALE
))
248 aspect(&d_width
, &d_height
, A_ZOOM
);
252 /* Make the window */
253 XGetWindowAttributes(mDisplay
, DefaultRootWindow(mDisplay
),
257 window_depth
= attribs
.depth
;
258 if ((window_depth
!= 15) && (window_depth
!= 16)
259 && (window_depth
!= 24) && (window_depth
!= 32))
261 XMatchVisualInfo(mDisplay
, mScreen
, window_depth
, TrueColor
,
264 xswa
.background_pixel
= BlackPixel(mDisplay
, mScreen
);
265 xswa
.border_pixel
= 0;
267 XCreateColormap(mDisplay
, RootWindow(mDisplay
, mScreen
),
268 vinfo
.visual
, AllocNone
);
269 xswamask
= CWBackPixel
| CWBorderPixel
| CWColormap
;
271 vo_x11_create_vo_window(&vinfo
, vo_dx
, vo_dy
,
272 window_width
, window_height
, flags
,
273 CopyFromParent
, "xvidix", title
);
274 XChangeWindowAttributes(mDisplay
, vo_window
, xswamask
, &xswa
);
280 if ((!WinID
) && (flags
& VOFLAG_FULLSCREEN
))
284 vo_dwidth
= vo_screenwidth
;
285 vo_dheight
= vo_screenheight
;
289 if (vidix_grkey_support())
291 vidix_grkey_get(&gr_key
);
292 gr_key
.key_op
= KEYS_PUT
;
293 if (!(vo_colorkey
& 0xff000000))
295 gr_key
.ckey
.op
= CKEY_TRUE
;
297 gr_key
.ckey
.green
= g
;
298 gr_key
.ckey
.blue
= b
;
300 gr_key
.ckey
.op
= CKEY_FALSE
;
301 vidix_grkey_set(&gr_key
);
306 XSync(mDisplay
, False
);
313 static void check_events(void)
315 const int event
= vo_x11_check_events(mDisplay
);
317 if ((event
& VO_EVENT_RESIZE
) || (event
& VO_EVENT_EXPOSE
))
323 /* draw_osd, flip_page, draw_slice, draw_frame should be
324 overwritten with vidix functions (vosub_vidix.c) */
325 static void draw_osd(void)
327 mp_msg(MSGT_VO
, MSGL_FATAL
,
328 "[xvidix] error: didn't used vidix draw_osd!\n");
332 static void flip_page(void)
334 mp_msg(MSGT_VO
, MSGL_FATAL
,
335 "[xvidix] error: didn't used vidix flip_page!\n");
339 static int draw_slice(uint8_t * src
[], int stride
[],
340 int w
, int h
, int x
, int y
)
348 mp_msg(MSGT_VO
, MSGL_FATAL
,
349 "[xvidix] error: didn't used vidix draw_slice!\n");
353 static int draw_frame(uint8_t * src
[])
356 mp_msg(MSGT_VO
, MSGL_FATAL
,
357 "[xvidix] error: didn't used vidix draw_frame!\n");
361 static int query_format(uint32_t format
)
363 return vidix_query_fourcc(format
);
366 static void uninit(void)
368 if (!vo_config_count
)
381 static int preinit(const char *arg
)
385 vidix_name
= strdup(arg
);
388 mp_msg(MSGT_VO
, MSGL_INFO
,
389 "No vidix driver name provided, probing available ones (-v option for details)!\n");
396 if (vidix_preinit(vidix_name
, &video_out_xvidix
) != 0)
402 static int control(uint32_t request
, void *data
, ...)
406 case VOCTRL_QUERY_FORMAT
:
407 return query_format(*((uint32_t *) data
));
408 case VOCTRL_GUISUPPORT
:
410 case VOCTRL_GET_PANSCAN
:
411 if (!vo_config_count
|| !vo_fs
)
417 case VOCTRL_FULLSCREEN
:
419 case VOCTRL_SET_PANSCAN
:
420 if (vo_fs
&& (vo_panscan
!= vo_panscan_amount
))
426 case VOCTRL_SET_EQUALIZER
:
432 value
= va_arg(ap
, int);
436 return vidix_control(request
, data
, value
);
438 case VOCTRL_GET_EQUALIZER
:
444 value
= va_arg(ap
, int *);
448 return vidix_control(request
, data
, value
);
450 case VOCTRL_UPDATE_SCREENINFO
:
451 aspect_save_screenres(vo_screenwidth
, vo_screenheight
);
455 return vidix_control(request
, data
);
456 // return VO_NOTIMPL;