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>
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 */
52 static XGCValues mGCV
;
54 static vidix_grkey_t gr_key
;
57 static char *vidix_name
;
59 /* Image parameters */
60 static uint32_t image_width
;
61 static uint32_t image_height
;
62 static uint32_t image_format
;
64 /* Window parameters */
65 static uint32_t window_x
, window_y
;
66 static uint32_t window_width
, window_height
;
68 /* used by XGetGeometry & XTranslateCoordinates for moving/resizing window */
69 static uint32_t drwX
, drwY
, drwWidth
, drwHeight
, drwBorderWidth
,
70 drwDepth
, drwcX
, drwcY
, dwidth
, dheight
;
72 extern void set_video_eq(int cap
);
75 static void set_window(int force_update
)
81 XGetGeometry(mDisplay
, vo_window
, &mRoot
, &drwX
, &drwY
, &drwWidth
,
82 &drwHeight
, &drwBorderWidth
, &drwDepth
);
85 XTranslateCoordinates(mDisplay
, vo_window
, mRoot
, 0, 0,
86 &drwcX
, &drwcY
, &mRoot
);
87 aspect(&dwidth
, &dheight
, A_NOZOOM
);
89 mp_msg(MSGT_VO
, MSGL_V
,
90 "[xvidix] dcx: %d dcy: %d dx: %d dy: %d dw: %d dh: %d\n",
91 drwcX
, drwcY
, drwX
, drwY
, drwWidth
, drwHeight
);
93 /* following stuff copied from vo_xmga.c */
96 aspect(&dwidth
, &dheight
, A_NOZOOM
);
100 drwHeight
= vo_dheight
;
106 aspect(&dwidth
, &dheight
, A_ZOOM
);
109 (dwidth
> vo_screenwidth
? vo_screenwidth
: dwidth
)) / 2;
113 (dheight
> vo_screenheight
? vo_screenheight
: dheight
)) / 2;
115 drwWidth
= (dwidth
> vo_screenwidth
? vo_screenwidth
: dwidth
);
117 (dheight
> vo_screenheight
? vo_screenheight
: dheight
);
118 mp_msg(MSGT_VO
, MSGL_V
,
119 "[xvidix-fs] dcx: %d dcy: %d dx: %d dy: %d dw: %d dh: %d\n",
120 drwcX
, drwcY
, drwX
, drwY
, drwWidth
, drwHeight
);
124 vo_dwidth
= drwWidth
;
125 vo_dheight
= drwHeight
;
128 if (XineramaIsActive(mDisplay
))
130 XineramaScreenInfo
*screens
;
134 screens
= XineramaQueryScreens(mDisplay
, &num_screens
);
136 /* find the screen we are on */
137 while (i
< num_screens
&&
138 ((screens
[i
].x_org
< drwcX
) || (screens
[i
].y_org
< drwcY
) ||
139 (screens
[i
].x_org
+ screens
[i
].width
>= drwcX
) ||
140 (screens
[i
].y_org
+ screens
[i
].height
>= drwcY
)))
147 /* save the screen we are on */
151 /* oops.. couldnt find the screen we are on
152 * because the upper left corner left the
153 * visual range. assume we are still on the
159 /* set drwcX and drwcY to the right values */
160 drwcX
= drwcX
- screens
[i
].x_org
;
161 drwcY
= drwcY
- screens
[i
].y_org
;
166 if (vo_panscan
> 0.0f
&& vo_fs
)
168 drwcX
-= vo_panscan_x
>> 1;
169 drwcY
-= vo_panscan_y
>> 1;
170 drwX
-= vo_panscan_x
>> 1;
171 drwY
-= vo_panscan_y
>> 1;
172 drwWidth
+= vo_panscan_x
;
173 drwHeight
+= vo_panscan_y
;
176 /* set new values in VIDIX */
177 if (force_update
|| (window_x
!= drwcX
) || (window_y
!= drwcY
) ||
178 (window_width
!= drwWidth
) || (window_height
!= drwHeight
))
180 // do a backup of window coordinates
185 window_width
= drwWidth
;
186 window_height
= drwHeight
;
188 /* FIXME: implement runtime resize/move if possible, this way is very ugly! */
190 if (vidix_init(image_width
, image_height
, vo_dx
, vo_dy
,
191 window_width
, window_height
, image_format
,
192 vo_depthonscreen
, vo_screenwidth
,
193 vo_screenheight
) != 0)
195 mp_msg(MSGT_VO
, MSGL_FATAL
,
196 "Can't initialize VIDIX driver: %s\n", strerror(errno
));
202 mp_msg(MSGT_VO
, MSGL_V
,
203 "[xvidix] window properties: pos: %dx%d, size: %dx%d\n", vo_dx
,
204 vo_dy
, window_width
, window_height
);
208 /* fill drawable with specified color */
209 if (!(vo_colorkey
& 0xff000000))
211 XSetBackground(mDisplay
, vo_gc
, 0L);
212 XClearWindow(mDisplay
, vo_window
);
213 XSetForeground(mDisplay
, vo_gc
, colorkey
);
214 XFillRectangle(mDisplay
, vo_window
, vo_gc
, drwX
, drwY
, drwWidth
,
215 (vo_fs
? drwHeight
- 1 : drwHeight
));
217 /* flush, update drawable */
223 /* connect to server, create and map window,
224 * allocate colors and (shared) memory
226 static int config(uint32_t width
, uint32_t height
, uint32_t d_width
,
227 uint32_t d_height
, uint32_t flags
, char *title
,
233 XSetWindowAttributes xswa
;
234 unsigned long xswamask
;
235 XWindowAttributes attribs
;
236 int window_depth
, r
, g
, b
;
238 title
= "MPlayer VIDIX X11 Overlay";
240 image_height
= height
;
242 image_format
= format
;
243 vo_mouse_autohide
= 1;
245 window_width
= d_width
;
246 window_height
= d_height
;
248 // vo_fs = flags&0x01;
250 // { vo_old_width=d_width; vo_old_height=d_height; }
252 r
= (vo_colorkey
& 0x00ff0000) >> 16;
253 g
= (vo_colorkey
& 0x0000ff00) >> 8;
254 b
= vo_colorkey
& 0x000000ff;
255 switch (vo_depthonscreen
)
258 colorkey
= vo_colorkey
;
261 colorkey
= vo_colorkey
& 0x00ffffff;
264 colorkey
= ((r
>> 3) << 11) | ((g
>> 2) << 5) | (b
>> 3);
267 colorkey
= ((r
>> 3) << 10) | ((g
>> 3) << 5) | (b
>> 3);
270 mp_msg(MSGT_VO
, MSGL_ERR
,
271 "Sorry, this (%d) color depth is not supported\n",
274 mp_msg(MSGT_VO
, MSGL_V
, "Using colorkey: %x\n", colorkey
);
278 guiGetEvent(guiSetShVideo
, 0); // the GUI will set up / resize the window
283 #ifdef X11_FULLSCREEN
284 if ((flags
& VOFLAG_FULLSCREEN
) || (flags
& VOFLAG_SWSCALE
))
285 aspect(&d_width
, &d_height
, A_ZOOM
);
289 /* Make the window */
290 XGetWindowAttributes(mDisplay
, DefaultRootWindow(mDisplay
),
294 window_depth
= attribs
.depth
;
295 if ((window_depth
!= 15) && (window_depth
!= 16)
296 && (window_depth
!= 24) && (window_depth
!= 32))
298 XMatchVisualInfo(mDisplay
, mScreen
, window_depth
, TrueColor
,
301 xswa
.background_pixel
= BlackPixel(mDisplay
, mScreen
);
302 xswa
.border_pixel
= 0;
304 XCreateColormap(mDisplay
, RootWindow(mDisplay
, mScreen
),
305 vinfo
.visual
, AllocNone
);
307 StructureNotifyMask
| ExposureMask
| KeyPressMask
|
308 PropertyChangeMask
| ((WinID
== 0) ? 0
309 : (ButtonPressMask
| ButtonReleaseMask
|
311 xswamask
= CWBackPixel
| CWBorderPixel
| CWColormap
| CWEventMask
;
316 WinID
? ((Window
) WinID
) : RootWindow(mDisplay
, mScreen
);
319 XUnmapWindow(mDisplay
, vo_window
);
320 XChangeWindowAttributes(mDisplay
, vo_window
, xswamask
,
322 vo_x11_selectinput_witherr(mDisplay
, vo_window
,
323 StructureNotifyMask
|
330 XMapWindow(mDisplay
, vo_window
);
332 XSelectInput(mDisplay
, vo_window
, ExposureMask
);
335 vo_x11_create_vo_window(&vinfo
, vo_dx
, vo_dy
,
336 window_width
, window_height
, flags
,
337 CopyFromParent
, "xvidix", title
);
338 XChangeWindowAttributes(mDisplay
, vo_window
, xswamask
, &xswa
);
342 XFreeGC(mDisplay
, vo_gc
);
343 vo_gc
= XCreateGC(mDisplay
, vo_window
, GCForeground
, &mGCV
);
348 if ((!WinID
) && (flags
& VOFLAG_FULLSCREEN
))
352 vo_dwidth
= vo_screenwidth
;
353 vo_dheight
= vo_screenheight
;
357 if (vidix_grkey_support())
359 vidix_grkey_get(&gr_key
);
360 gr_key
.key_op
= KEYS_PUT
;
361 if (!(vo_colorkey
& 0xff000000))
363 gr_key
.ckey
.op
= CKEY_TRUE
;
365 gr_key
.ckey
.green
= g
;
366 gr_key
.ckey
.blue
= b
;
368 gr_key
.ckey
.op
= CKEY_FALSE
;
369 vidix_grkey_set(&gr_key
);
374 XSync(mDisplay
, False
);
379 vo_x11_setlayer(mDisplay
, vo_window
, vo_ontop
);
384 static void check_events(void)
386 const int event
= vo_x11_check_events(mDisplay
);
388 if ((event
& VO_EVENT_RESIZE
) || (event
& VO_EVENT_EXPOSE
))
394 /* draw_osd, flip_page, draw_slice, draw_frame should be
395 overwritten with vidix functions (vosub_vidix.c) */
396 static void draw_osd(void)
398 mp_msg(MSGT_VO
, MSGL_FATAL
,
399 "[xvidix] error: didn't used vidix draw_osd!\n");
403 static void flip_page(void)
405 mp_msg(MSGT_VO
, MSGL_FATAL
,
406 "[xvidix] error: didn't used vidix flip_page!\n");
410 static int draw_slice(uint8_t * src
[], int stride
[],
411 int w
, int h
, int x
, int y
)
419 mp_msg(MSGT_VO
, MSGL_FATAL
,
420 "[xvidix] error: didn't used vidix draw_slice!\n");
424 static int draw_frame(uint8_t * src
[])
427 mp_msg(MSGT_VO
, MSGL_FATAL
,
428 "[xvidix] error: didn't used vidix draw_frame!\n");
432 static int query_format(uint32_t format
)
434 return vidix_query_fourcc(format
);
437 static void uninit(void)
439 if (!vo_config_count
)
452 static int preinit(const char *arg
)
456 vidix_name
= strdup(arg
);
459 mp_msg(MSGT_VO
, MSGL_INFO
,
460 "No vidix driver name provided, probing available ones (-v option for details)!\n");
467 if (vidix_preinit(vidix_name
, video_out_xvidix
.old_functions
) != 0)
473 static int control(uint32_t request
, void *data
)
477 case VOCTRL_QUERY_FORMAT
:
478 return query_format(*((uint32_t *) data
));
479 case VOCTRL_GUISUPPORT
:
481 case VOCTRL_GET_PANSCAN
:
482 if (!vo_config_count
|| !vo_fs
)
488 case VOCTRL_FULLSCREEN
:
490 case VOCTRL_SET_PANSCAN
:
491 if (vo_fs
&& (vo_panscan
!= vo_panscan_amount
))
497 case VOCTRL_UPDATE_SCREENINFO
:
498 aspect_save_screenres(vo_screenwidth
, vo_screenheight
);
502 return vidix_control(request
, data
);
503 // return VO_NOTIMPL;