# HG changeset patch # User alex # Date 1010878102 0 # Node ID 467a7141f5c95f6d5e569fcfc693e2fcc9103492 # Parent 3ee2a23f91c7ba66d8e6361ed40341190d60b63f added X11/VIDIX diff -r 3ee2a23f91c7 -r 467a7141f5c9 libvo/vo_xvidix.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libvo/vo_xvidix.c Sat Jan 12 23:28:22 2002 +0000 @@ -0,0 +1,336 @@ +/* + VIDIX accelerated overlay in a X window + + (C) Alex Beregszaszi + + WS window manager by Pontscho/Fresh! + + Based on vo_gl.c and vo_vesa.c +*/ + +#include +#include +#include +#include +#include + +#include "config.h" +#include "video_out.h" +#include "video_out_internal.h" + +#include +#include +//#include + +#include "x11_common.h" +#include "aspect.h" +#include "mp_msg.h" + +#include "vosub_vidix.h" + +LIBVO_EXTERN(xvidix) + +static vo_info_t vo_info = +{ + "X11 (VIDIX)", + "xvidix", + "Alex Beregszaszi", + "" +}; + +/* X11 related variables */ +static Window mywindow; +static int X_already_started = 0; + +/* VIDIX related stuff */ +static const char *vidix_name = NULL; + +/* Image parameters */ +static uint32_t image_width; +static uint32_t image_height; +static uint32_t image_format; +static uint32_t image_depth; + +/* Window parameters */ +static uint32_t window_x, window_y; +static uint32_t window_width, window_height; + +/* used by XGetGeometry & XTranslateCoordinates */ +static Window mRoot; +static uint32_t drwX, drwY, drwWidth, drwHeight, drwBorderWidth, + drwDepth, drwcX, drwcY, dwidth, dheight, mFullscreen; + +static void resize(int x, int y) +{ + XGetGeometry(mDisplay, mywindow, &mRoot, &drwX, &drwY, &drwWidth, + &drwHeight, &drwBorderWidth, &drwDepth); + drwX = drwY = 0; + XTranslateCoordinates(mDisplay, mywindow, mRoot, 0, 0, &drwcX, &drwcY, &mRoot); + + mp_msg(MSGT_VO, MSGL_DBG2, "[xvidix] dcx: %d dcy: %d dx: %d dy: %d dw: %d dh: %d\n", + drwcX, drwcY, drwX, drwY, drwWidth, drwHeight); + + if ((window_x != drwcX) || (window_y != drwcY) || + (window_width != drwWidth) || (window_height != drwHeight)) + { + /* FIXME: implement runtime resize/move if possible, this way is very ugly! */ + vidix_term(); + vidix_preinit(vidix_name, &video_out_xvidix); + if (vidix_init(image_width, image_height, window_x, window_y, + window_width, window_height, image_format, image_depth, image_width, image_height) != 0) + { + mp_msg(MSGT_VO, MSGL_FATAL, "Can't initialize VIDIX driver: %s: %s\n", + vidix_name, strerror(errno)); + vidix_term(); + uninit(); + exit(1); /* !!! */ + } + } + + window_x = drwcX; + window_y = drwcY; + window_width = drwWidth; + window_height = drwHeight; + + mp_msg(MSGT_VO, MSGL_INFO, "[xvidix] window properties: pos: %dx%d, size: %dx%d\n", + window_x, window_y, window_width, window_height); + + return; +} + +/* connect to server, create and map window, + * allocate colors and (shared) memory + */ +static uint32_t init(uint32_t width, uint32_t height, uint32_t d_width, + uint32_t d_height, uint32_t flags, char *title, uint32_t format) +{ + unsigned int fg, bg; + XVisualInfo vinfo; + XEvent xev; + XSizeHints hint; + XSetWindowAttributes xswa; + unsigned long xswamask; + XWindowAttributes attribs; + int window_depth; + + if (!vo_subdevice) + mp_msg(MSGT_VO, MSGL_INFO, "No vidix driver name provided, probing available drivers!\n"); + else + vidix_name = strdup(vo_subdevice); + + if (!title) + title = strdup("X11/VIDIX"); + + image_height = height; + image_width = width; + image_format = format; + + if (IMGFMT_IS_RGB(format)) + { + image_depth = IMGFMT_RGB_DEPTH(format); + } + else + if (IMGFMT_IS_BGR(format)) + { + image_depth = IMGFMT_BGR_DEPTH(format); + } + else + switch(format) + { + case IMGFMT_IYUV: + case IMGFMT_I420: + case IMGFMT_YV12: + image_depth = 12; + break; + case IMGFMT_YUY2: + image_depth = 16; + break; + default: + mp_msg(MSGT_VO, MSGL_FATAL, "Unknown image format: %s", + vo_format_name(format)); + return(-1); + } + + if (X_already_started) + return(-1); + if (!vo_init()) + return(-1); + + aspect_save_orig(width,height); + aspect_save_prescale(d_width,d_height); + aspect_save_screenres(vo_screenwidth,vo_screenheight); + + X_already_started++; + + aspect(&d_width, &d_height, A_NOZOOM); +#ifdef X11_FULLSCREEN + if (flags & 0x01) /* fullscreen */ + aspect(&d_width, &d_height, A_ZOOM); +#endif + + hint.x = 0; + hint.y = 0; + hint.width = d_width; + hint.height = d_height; + hint.flags = PPosition | PSize; + + /* Get some colors */ + bg = WhitePixel(mDisplay, mScreen); + fg = BlackPixel(mDisplay, mScreen); + + /* Make the window */ + XGetWindowAttributes(mDisplay, DefaultRootWindow(mDisplay), &attribs); + + /* from vo_x11 */ + window_depth = attribs.depth; + if ((window_depth != 15) && (window_depth != 16) && (window_depth != 24) + && (window_depth != 32)) + window_depth = 24; + XMatchVisualInfo(mDisplay, mScreen, window_depth, TrueColor, &vinfo); + + xswa.background_pixel = 0; + xswa.border_pixel = 1; + xswa.colormap = XCreateColormap(mDisplay, RootWindow(mDisplay, mScreen), + vinfo.visual, AllocNone); + xswamask = CWBackPixel | CWBorderPixel | CWColormap; +// xswamask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask | CWCursor | CWOverrideRedirect | CWSaveUnder | CWX | CWY | CWWidth | CWHeight; + + if (WinID >= 0) + { + mywindow = WinID ? ((Window)WinID) : RootWindow(mDisplay, mScreen); + XUnmapWindow(mDisplay, mywindow); + XChangeWindowAttributes(mDisplay, mywindow, xswamask, &xswa); + } + else + mywindow = XCreateWindow(mDisplay, RootWindow(mDisplay, mScreen), + hint.x, hint.y, hint.width, hint.height, xswa.border_pixel, + vinfo.depth, CopyFromParent, vinfo.visual, xswamask, &xswa); + + vo_x11_classhint(mDisplay, mywindow, "xvidix"); + vo_hidecursor(mDisplay, mywindow); + + if (flags & 0x01) /* fullscreen */ + vo_x11_decoration(mDisplay, mywindow, 0); + + XSelectInput(mDisplay, mywindow, StructureNotifyMask); + + /* Tell other applications about this window */ + XSetStandardProperties(mDisplay, mywindow, title, title, None, NULL, 0, &hint); + + /* Map window. */ + XMapWindow(mDisplay, mywindow); +#ifdef HAVE_XINERAMA + vo_x11_xinerama_move(mDisplay, mywindow); +#endif + + /* Wait for map. */ + do + { + XNextEvent(mDisplay, &xev); + } + while ((xev.type != MapNotify) || (xev.xmap.event != mywindow)); + + XSelectInput(mDisplay, mywindow, NoEventMask); + + XGetGeometry(mDisplay, mywindow, &mRoot, &drwX, &drwY, &drwWidth, + &drwHeight, &drwBorderWidth, &drwDepth); + drwX = drwY = 0; + XTranslateCoordinates(mDisplay, mywindow, mRoot, 0, 0, &drwcX, &drwcY, &mRoot); + + window_x = drwcX; + window_y = drwcY; + window_width = drwWidth; + window_height = drwHeight; + + mp_msg(MSGT_VO, MSGL_INFO, "[xvidix] image properties: %dx%d depth: %d\n", + image_width, image_height, image_depth); + mp_msg(MSGT_VO, MSGL_INFO, "[xvidix] window properties: pos: %dx%d, size: %dx%d\n", + window_x, window_y, window_width, window_height); + + if (vidix_init(image_width, image_height, window_x, window_y, window_width, + window_height, format, image_depth, image_width, image_height) != 0) + { + mp_msg(MSGT_VO, MSGL_FATAL, "Can't initialize VIDIX driver: %s: %s\n", + vidix_name, strerror(errno)); + vidix_term(); + return(-1); + } + + XFlush(mDisplay); + XSync(mDisplay, False); + + XSelectInput(mDisplay, mywindow, StructureNotifyMask | KeyPressMask ); + + saver_off(mDisplay); /* turning off screen saver */ + + return(0); +} + +static const vo_info_t *get_info(void) +{ + return(&vo_info); +} + +static void Terminate_Display_Process(void) +{ + getchar(); /* wait for enter to remove window */ + vidix_term(); + XDestroyWindow(mDisplay, mywindow); + XCloseDisplay(mDisplay); + X_already_started = 0; +} + +static void check_events(void) +{ + const int event = vo_x11_check_events(mDisplay); + if (event & VO_EVENT_RESIZE) + resize(vo_dwidth, vo_dheight); +} + +/* draw_osd, flip_page, draw_slice, draw_frame should be + overwritten with vidix functions (vosub_vidix.c) */ +static void draw_osd(void) +{ + mp_msg(MSGT_VO, MSGL_FATAL, "[xvidix] error: didn't used vidix draw_osd!\n"); + return; +} + +static void flip_page(void) +{ + mp_msg(MSGT_VO, MSGL_FATAL, "[xvidix] error: didn't used vidix flip_page!\n"); + return; +} + +static uint32_t draw_slice(uint8_t *src[], int stride[], + int w, int h, int x, int y) +{ + mp_msg(MSGT_VO, MSGL_FATAL, "[xvidix] error: didn't used vidix draw_slice!\n"); + return(0); +} + +static uint32_t draw_frame(uint8_t *src[]) +{ + mp_msg(MSGT_VO, MSGL_FATAL, "[xvidix] error: didn't used vidix draw_frame!\n"); + return(0); +} + +static uint32_t query_format(uint32_t format) +{ + vidix_preinit(vidix_name, &video_out_xvidix); + + return(vidix_query_fourcc(format)); +} + + +static void uninit(void) +{ +#ifdef HAVE_NEW_GUI + if (vo_window == None) +#endif + { + vidix_term(); + saver_on(mDisplay); /* screen saver back on */ + XDestroyWindow(mDisplay, mywindow); +// XCloseDisplay(mDisplay); + } +}