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"
52 static const vo_info_t info
= {
60 #define UNUSED(x) ((void)(x)) /* Removes warning about unused arguments */
61 /* X11 related variables */
62 /* Colorkey handling */
64 static vidix_grkey_t gr_key
;
67 static char *vidix_name
;
69 /* Image parameters */
70 static uint32_t image_width
;
71 static uint32_t image_height
;
72 static uint32_t image_format
;
74 /* Window parameters */
75 static uint32_t window_x
, window_y
;
76 static uint32_t window_width
, window_height
;
78 /* used by XGetGeometry & XTranslateCoordinates for moving/resizing window */
79 static uint32_t drwX
, drwY
, drwWidth
, drwHeight
, drwBorderWidth
,
80 drwDepth
, drwcX
, drwcY
, dwidth
, dheight
;
82 void set_video_eq(int cap
);
85 static void set_window(int force_update
)
91 XGetGeometry(mDisplay
, vo_window
, &mRoot
, &drwX
, &drwY
, &drwWidth
,
92 &drwHeight
, &drwBorderWidth
, &drwDepth
);
95 XTranslateCoordinates(mDisplay
, vo_window
, mRoot
, 0, 0,
96 &drwcX
, &drwcY
, &mRoot
);
97 aspect(&dwidth
, &dheight
, A_NOZOOM
);
99 mp_msg(MSGT_VO
, MSGL_V
,
100 "[xvidix] dcx: %d dcy: %d dx: %d dy: %d dw: %d dh: %d\n",
101 drwcX
, drwcY
, drwX
, drwY
, drwWidth
, drwHeight
);
103 /* following stuff copied from vo_xmga.c */
106 aspect(&dwidth
, &dheight
, A_NOZOOM
);
107 drwcX
= drwX
= vo_dx
;
108 drwcY
= drwY
= vo_dy
;
109 drwWidth
= vo_dwidth
;
110 drwHeight
= vo_dheight
;
116 aspect(&dwidth
, &dheight
, A_ZOOM
);
119 (dwidth
> vo_screenwidth
? vo_screenwidth
: dwidth
)) / 2;
123 (dheight
> vo_screenheight
? vo_screenheight
: dheight
)) / 2;
125 drwWidth
= (dwidth
> vo_screenwidth
? vo_screenwidth
: dwidth
);
127 (dheight
> vo_screenheight
? vo_screenheight
: dheight
);
128 mp_msg(MSGT_VO
, MSGL_V
,
129 "[xvidix-fs] dcx: %d dcy: %d dx: %d dy: %d dw: %d dh: %d\n",
130 drwcX
, drwcY
, drwX
, drwY
, drwWidth
, drwHeight
);
134 vo_dwidth
= drwWidth
;
135 vo_dheight
= drwHeight
;
137 update_xinerama_info();
141 if (vo_panscan
> 0.0f
&& vo_fs
)
143 drwcX
-= vo_panscan_x
>> 1;
144 drwcY
-= vo_panscan_y
>> 1;
145 drwX
-= vo_panscan_x
>> 1;
146 drwY
-= vo_panscan_y
>> 1;
147 drwWidth
+= vo_panscan_x
;
148 drwHeight
+= vo_panscan_y
;
151 /* set new values in VIDIX */
152 if (force_update
|| (window_x
!= drwcX
) || (window_y
!= drwcY
) ||
153 (window_width
!= drwWidth
) || (window_height
!= drwHeight
))
155 // do a backup of window coordinates
160 window_width
= drwWidth
;
161 window_height
= drwHeight
;
163 /* FIXME: implement runtime resize/move if possible, this way is very ugly! */
165 if (vidix_init(image_width
, image_height
, vo_dx
, vo_dy
,
166 window_width
, window_height
, image_format
,
167 vo_depthonscreen
, vo_screenwidth
,
168 vo_screenheight
) != 0)
170 mp_msg(MSGT_VO
, MSGL_FATAL
,
171 "Can't initialize VIDIX driver: %s\n", strerror(errno
));
177 mp_msg(MSGT_VO
, MSGL_V
,
178 "[xvidix] window properties: pos: %dx%d, size: %dx%d\n", vo_dx
,
179 vo_dy
, window_width
, window_height
);
183 /* fill drawable with specified color */
184 if (!(vo_colorkey
& 0xff000000))
186 XSetBackground(mDisplay
, vo_gc
, 0L);
187 XClearWindow(mDisplay
, vo_window
);
188 XSetForeground(mDisplay
, vo_gc
, colorkey
);
189 XFillRectangle(mDisplay
, vo_window
, vo_gc
, drwX
, drwY
, drwWidth
,
190 (vo_fs
? drwHeight
- 1 : drwHeight
));
192 /* flush, update drawable */
198 /* connect to server, create and map window,
199 * allocate colors and (shared) memory
201 static int config(uint32_t width
, uint32_t height
, uint32_t d_width
,
202 uint32_t d_height
, uint32_t flags
, char *title
,
208 XSetWindowAttributes xswa
;
209 unsigned long xswamask
;
210 XWindowAttributes attribs
;
211 int window_depth
, r
, g
, b
;
213 title
= "MPlayer VIDIX X11 Overlay";
215 image_height
= height
;
217 image_format
= format
;
219 window_width
= d_width
;
220 window_height
= d_height
;
222 // vo_fs = flags&0x01;
224 // { vo_old_width=d_width; vo_old_height=d_height; }
226 r
= (vo_colorkey
& 0x00ff0000) >> 16;
227 g
= (vo_colorkey
& 0x0000ff00) >> 8;
228 b
= vo_colorkey
& 0x000000ff;
229 switch (vo_depthonscreen
)
232 colorkey
= vo_colorkey
;
235 colorkey
= vo_colorkey
& 0x00ffffff;
238 colorkey
= ((r
>> 3) << 11) | ((g
>> 2) << 5) | (b
>> 3);
241 colorkey
= ((r
>> 3) << 10) | ((g
>> 3) << 5) | (b
>> 3);
244 mp_msg(MSGT_VO
, MSGL_ERR
,
245 "Sorry, this (%d) color depth is not supported\n",
248 mp_msg(MSGT_VO
, MSGL_V
, "Using colorkey: %x\n", colorkey
);
250 #ifdef X11_FULLSCREEN
251 if ((flags
& VOFLAG_FULLSCREEN
) || (flags
& VOFLAG_SWSCALE
))
252 aspect(&d_width
, &d_height
, A_ZOOM
);
256 /* Make the window */
257 XGetWindowAttributes(mDisplay
, DefaultRootWindow(mDisplay
),
261 window_depth
= attribs
.depth
;
262 if ((window_depth
!= 15) && (window_depth
!= 16)
263 && (window_depth
!= 24) && (window_depth
!= 32))
265 XMatchVisualInfo(mDisplay
, mScreen
, window_depth
, TrueColor
,
268 xswa
.background_pixel
= BlackPixel(mDisplay
, mScreen
);
269 xswa
.border_pixel
= 0;
271 XCreateColormap(mDisplay
, RootWindow(mDisplay
, mScreen
),
272 vinfo
.visual
, AllocNone
);
273 xswamask
= CWBackPixel
| CWBorderPixel
| CWColormap
;
275 vo_x11_create_vo_window(&vinfo
, vo_dx
, vo_dy
,
276 window_width
, window_height
, flags
,
277 CopyFromParent
, "xvidix", title
);
278 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
.old_functions
) != 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_GET_PANSCAN
:
409 if (!vo_config_count
|| !vo_fs
)
415 case VOCTRL_FULLSCREEN
:
417 case VOCTRL_SET_PANSCAN
:
418 if (vo_fs
&& (vo_panscan
!= vo_panscan_amount
))
424 case VOCTRL_UPDATE_SCREENINFO
:
425 aspect_save_screenres(vo_screenwidth
, vo_screenheight
);
429 return vidix_control(request
, data
);
430 // return VO_NOTIMPL;