vo_corevideo: Avoid some code duplication.
[mplayer/glamo.git] / libvo / vo_xvidix.c
blobc7481ae6138421b37340f57334bdbe77365ba056
1 /*
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.
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <math.h>
31 #include <errno.h>
33 #include "config.h"
34 #include "video_out.h"
35 #include "video_out_internal.h"
37 #include <X11/Xlib.h>
38 #include <X11/Xutil.h>
39 //#include <X11/keysym.h>
41 #ifdef CONFIG_XINERAMA
42 #include <X11/extensions/Xinerama.h>
43 #endif
45 #include "x11_common.h"
46 #include "aspect.h"
47 #include "mp_msg.h"
49 #include "vosub_vidix.h"
50 #include "vidix/vidix.h"
52 static const vo_info_t info = {
53 "X11 (VIDIX)",
54 "xvidix",
55 "Alex Beregszaszi",
59 LIBVO_EXTERN(xvidix)
60 #define UNUSED(x) ((void)(x)) /* Removes warning about unused arguments */
61 /* X11 related variables */
62 /* Colorkey handling */
63 static int colorkey;
64 static vidix_grkey_t gr_key;
66 /* VIDIX related */
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)
87 Window mRoot;
89 if (WinID)
91 XGetGeometry(mDisplay, vo_window, &mRoot, &drwX, &drwY, &drwWidth,
92 &drwHeight, &drwBorderWidth, &drwDepth);
93 drwX = drwY = 0;
95 XTranslateCoordinates(mDisplay, vo_window, mRoot, 0, 0,
96 &drwcX, &drwcY, &mRoot);
97 aspect(&dwidth, &dheight, A_NOZOOM);
98 if (!vo_fs)
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 */
104 } else
106 aspect(&dwidth, &dheight, A_NOZOOM);
107 drwcX = drwX = vo_dx;
108 drwcY = drwY = vo_dy;
109 drwWidth = vo_dwidth;
110 drwHeight = vo_dheight;
113 #if X11_FULLSCREEN
114 if (vo_fs)
116 aspect(&dwidth, &dheight, A_ZOOM);
117 drwX =
118 (vo_screenwidth -
119 (dwidth > vo_screenwidth ? vo_screenwidth : dwidth)) / 2;
120 drwcX = drwX;
121 drwY =
122 (vo_screenheight -
123 (dheight > vo_screenheight ? vo_screenheight : dheight)) / 2;
124 drwcY = drwY;
125 drwWidth = (dwidth > vo_screenwidth ? vo_screenwidth : dwidth);
126 drwHeight =
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);
132 #endif
134 vo_dwidth = drwWidth;
135 vo_dheight = drwHeight;
137 update_xinerama_info();
138 drwcX -= xinerama_x;
139 drwcY -= xinerama_y;
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
156 window_x = drwcX;
157 window_y = drwcY;
158 vo_dx = drwcX;
159 vo_dy = drwcY;
160 window_width = drwWidth;
161 window_height = drwHeight;
163 /* FIXME: implement runtime resize/move if possible, this way is very ugly! */
164 vidix_stop();
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));
172 abort();
174 vidix_start();
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);
181 /* mDrawColorKey: */
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 */
193 XFlush(mDisplay);
195 return;
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,
203 uint32_t format)
205 XVisualInfo vinfo;
207 // XSizeHints hint;
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;
216 image_width = width;
217 image_format = format;
219 window_width = d_width;
220 window_height = d_height;
222 // vo_fs = flags&0x01;
223 // if (vo_fs)
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)
231 case 32:
232 colorkey = vo_colorkey;
233 break;
234 case 24:
235 colorkey = vo_colorkey & 0x00ffffff;
236 break;
237 case 16:
238 colorkey = ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3);
239 break;
240 case 15:
241 colorkey = ((r >> 3) << 10) | ((g >> 3) << 5) | (b >> 3);
242 break;
243 default:
244 mp_msg(MSGT_VO, MSGL_ERR,
245 "Sorry, this (%d) color depth is not supported\n",
246 vo_depthonscreen);
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);
253 #endif
254 dwidth = d_width;
255 dheight = d_height;
256 /* Make the window */
257 XGetWindowAttributes(mDisplay, DefaultRootWindow(mDisplay),
258 &attribs);
260 /* from vo_x11 */
261 window_depth = attribs.depth;
262 if ((window_depth != 15) && (window_depth != 16)
263 && (window_depth != 24) && (window_depth != 32))
264 window_depth = 24;
265 XMatchVisualInfo(mDisplay, mScreen, window_depth, TrueColor,
266 &vinfo);
268 xswa.background_pixel = BlackPixel(mDisplay, mScreen);
269 xswa.border_pixel = 0;
270 xswa.colormap =
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))
282 vo_dx = 0;
283 vo_dy = 0;
284 vo_dwidth = vo_screenwidth;
285 vo_dheight = vo_screenheight;
286 vo_fs = 1;
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;
296 gr_key.ckey.red = r;
297 gr_key.ckey.green = g;
298 gr_key.ckey.blue = b;
299 } else
300 gr_key.ckey.op = CKEY_FALSE;
301 vidix_grkey_set(&gr_key);
304 set_window(1);
306 XSync(mDisplay, False);
308 panscan_calc();
310 return 0;
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))
318 set_window(0);
320 return;
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");
329 return;
332 static void flip_page(void)
334 mp_msg(MSGT_VO, MSGL_FATAL,
335 "[xvidix] error: didn't used vidix flip_page!\n");
336 return;
339 static int draw_slice(uint8_t * src[], int stride[],
340 int w, int h, int x, int y)
342 UNUSED(src);
343 UNUSED(stride);
344 UNUSED(w);
345 UNUSED(h);
346 UNUSED(x);
347 UNUSED(y);
348 mp_msg(MSGT_VO, MSGL_FATAL,
349 "[xvidix] error: didn't used vidix draw_slice!\n");
350 return -1;
353 static int draw_frame(uint8_t * src[])
355 UNUSED(src);
356 mp_msg(MSGT_VO, MSGL_FATAL,
357 "[xvidix] error: didn't used vidix draw_frame!\n");
358 return -1;
361 static int query_format(uint32_t format)
363 return vidix_query_fourcc(format);
366 static void uninit(void)
368 if (!vo_config_count)
369 return;
370 vidix_term();
372 if (vidix_name)
374 free(vidix_name);
375 vidix_name = NULL;
378 vo_x11_uninit();
381 static int preinit(const char *arg)
384 if (arg)
385 vidix_name = strdup(arg);
386 else
388 mp_msg(MSGT_VO, MSGL_INFO,
389 "No vidix driver name provided, probing available ones (-v option for details)!\n");
390 vidix_name = NULL;
393 if (!vo_init())
394 return -1;
396 if (vidix_preinit(vidix_name, video_out_xvidix.old_functions) != 0)
397 return 1;
399 return 0;
402 static int control(uint32_t request, void *data)
404 switch (request)
406 case VOCTRL_QUERY_FORMAT:
407 return query_format(*((uint32_t *) data));
408 case VOCTRL_GET_PANSCAN:
409 if (!vo_config_count || !vo_fs)
410 return VO_FALSE;
411 return VO_TRUE;
412 case VOCTRL_ONTOP:
413 vo_x11_ontop();
414 return VO_TRUE;
415 case VOCTRL_FULLSCREEN:
416 vo_x11_fullscreen();
417 case VOCTRL_SET_PANSCAN:
418 if (vo_fs && (vo_panscan != vo_panscan_amount))
420 panscan_calc();
421 set_window(0);
423 return VO_TRUE;
424 case VOCTRL_UPDATE_SCREENINFO:
425 aspect_save_screenres(vo_screenwidth, vo_screenheight);
426 return VO_TRUE;
429 return vidix_control(request, data);
430 // return VO_NOTIMPL;