summaryrefslogtreecommitdiff
path: root/src/video_out/video_out_syncfb.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/video_out/video_out_syncfb.c')
-rw-r--r--src/video_out/video_out_syncfb.c849
1 files changed, 849 insertions, 0 deletions
diff --git a/src/video_out/video_out_syncfb.c b/src/video_out/video_out_syncfb.c
new file mode 100644
index 000000000..2d99f3216
--- /dev/null
+++ b/src/video_out/video_out_syncfb.c
@@ -0,0 +1,849 @@
+/*
+ * Copyright (C) 2000 the xine project
+ *
+ * This file is part of xine, a unix video player.
+ *
+ * xine is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * xine is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * $Id: video_out_syncfb.c,v 1.1 2001/04/24 20:53:00 f1rmb Exp $
+ *
+ * video_out_syncfb.c, Matrox G400 video extension interface for xine
+ *
+ * based on video_out_mga code from
+ * Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
+ *
+ * xine-specific code by Joachim Koenig <joachim.koenig@gmx.net>
+ * Underlaying window by Matthias Dahl <matthew2k@web.de>
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+
+#include <sys/ioctl.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#include <sys/time.h>
+
+#include <X11/Xutil.h>
+
+#include "video_out.h"
+#include "video_out_syncfb.h"
+
+#include "monitor.h"
+#include "configfile.h"
+
+#define MWM_HINTS_DECORATIONS (1L << 1)
+#define PROP_MWM_HINTS_ELEMENTS 5
+typedef struct _mwmhints {
+ uint32_t flags;
+ uint32_t functions;
+ uint32_t decorations;
+ int32_t input_mode;
+ uint32_t status;
+} MWMHints;
+
+Display *lDisplay;
+extern Display *gDisplay;
+extern Window gVideoWin;
+extern Pixmap gXineLogo;
+extern int gXineLogoWidth, gXineLogoHeight;
+
+extern uint32_t xine_debug;
+
+
+
+typedef struct _display {
+ int width;
+ int height;
+ int depth;
+ int default_screen;
+} display;
+
+typedef struct _window {
+ char title[20];
+
+ Window clasped_window;
+ int visibility;
+} window;
+
+typedef struct _mga_globals {
+ syncfb_config_t mga_vid_config;
+ syncfb_capability_t caps;
+ syncfb_buffer_info_t bufinfo;
+ syncfb_param_t param;
+ uint8_t *vid_data, *frame0, *frame1;
+ int next_frame;
+ int fd;
+ uint32_t bespitch;
+
+ int bFullscreen;
+ int bIsFullscreen;
+ int image_width;
+ int image_height;
+ int image_xoff;
+ int image_yoff;
+ int orig_width; /* image size correct. by ratio */
+ int orig_height;
+ int dest_width;
+ int dest_height;
+ int fourcc_format;
+
+ uint32_t ratio;
+ int user_ratio, user_ratio_changed;
+
+// XvImage *cur_image;
+
+ /*
+ * misc (read: fun ;))
+ */
+ int bLogoMode;
+
+ int bright_min, bright_current, bright_max;
+ int cont_min, cont_current, cont_max;
+
+ int overlay_state;
+
+} mga_globals;
+
+mga_globals _mga_priv;
+display _display;
+window _window;
+
+int nLocks;
+
+
+
+static int _mga_write_frame_g400 (uint8_t *src[])
+{
+ uint8_t *dest;
+ int h;
+ uint8_t *y = src[0];
+ uint8_t *cb = src[1];
+ uint8_t *cr = src[2];
+
+ dest = _mga_priv.vid_data;
+
+ if (_mga_priv.fourcc_format == IMGFMT_YUY2) {
+ for (h=0; h < _mga_priv.mga_vid_config.src_height; h++) {
+ memcpy(dest, y, _mga_priv.mga_vid_config.src_width*2);
+ y += _mga_priv.mga_vid_config.src_width*2;
+ dest += _mga_priv.bespitch*2;
+ }
+ return 0;
+ }
+
+
+ for (h=0; h < _mga_priv.mga_vid_config.src_height; h++) {
+ memcpy(dest, y, _mga_priv.mga_vid_config.src_width);
+ y += _mga_priv.mga_vid_config.src_width;
+ dest += _mga_priv.bespitch;
+ }
+
+
+ for (h=0; h < _mga_priv.mga_vid_config.src_height/2; h++) {
+ memcpy(dest, cb, _mga_priv.mga_vid_config.src_width/2);
+ cb += _mga_priv.mga_vid_config.src_width/2;
+ dest += _mga_priv.bespitch/2;
+ }
+
+ dest = _mga_priv.vid_data + _mga_priv.bespitch * _mga_priv.mga_vid_config.src_height * 3 / 2;
+
+ for (h=0; h < _mga_priv.mga_vid_config.src_height/2; h++) {
+ memcpy(dest, cr, _mga_priv.mga_vid_config.src_width/2);
+ cr += _mga_priv.mga_vid_config.src_width/2;
+ dest += _mga_priv.bespitch/2;
+ }
+
+ return 0;
+}
+
+
+
+
+
+
+static int get_capabilities_mga () {
+ return VO_CAP_YV12 | VO_CAP_YUY2 | VO_CAP_CONTRAST | VO_CAP_BRIGHTNESS;
+}
+
+
+static void setup_window_mga () {
+ int ww=0, wh=0;
+ float aspect;
+
+ XWindowAttributes wattr;
+
+ Atom prop;
+ MWMHints mwmhints;
+
+ XGetWindowAttributes(lDisplay, DefaultRootWindow(lDisplay), &wattr);
+
+ _display.width = wattr.width;
+ _display.height = wattr.height;
+ _display.depth = wattr.depth;
+
+ ww = _display.width ;
+ wh = _display.height;
+
+xprintf(VERBOSE|VIDEO,"setup_window_mga: unscaled size should be %d x %d \n",_mga_priv.orig_width,_mga_priv.orig_height);
+printf("setup_window_mga: unscaled size should be %d x %d \n",_mga_priv.orig_width,_mga_priv.orig_height);
+
+ if (_mga_priv.bFullscreen) {
+
+ /*
+ * zoom to fullscreen
+ */
+
+ if (_mga_priv.orig_width != ww) {
+ aspect = (float) _mga_priv.orig_width / (float) _mga_priv.orig_height ;
+
+ _mga_priv.dest_width = ww;
+ _mga_priv.dest_height = ww / aspect;
+
+ if (_mga_priv.dest_height > wh) {
+
+ _mga_priv.dest_width = wh * aspect;
+ _mga_priv.dest_height = wh;
+ }
+
+ } else {
+
+ _mga_priv.dest_width = _mga_priv.orig_width ;
+ _mga_priv.dest_height = _mga_priv.orig_height ;
+
+ }
+ _mga_priv.image_xoff = ( ww - _mga_priv.dest_width) / 2;
+ _mga_priv.image_yoff = ( wh - _mga_priv.dest_height) / 2;
+
+
+ _mga_priv.bIsFullscreen = 1;
+
+
+ } else {
+
+ /*
+ * zoom to mpeg1 to double size
+ */
+
+// if (_mga_priv.orig_width < 600) {
+// _mga_priv.dest_width = _mga_priv.orig_width *2;
+// _mga_priv.dest_height = _mga_priv.orig_height *2;
+// } else {
+
+ if (_mga_priv.orig_width > ww) {
+ aspect = (float) _mga_priv.orig_width / (float) _mga_priv.orig_height ;
+
+ _mga_priv.dest_width = ww;
+ _mga_priv.dest_height = ww / aspect;
+
+ if (_mga_priv.dest_height > wh) {
+ _mga_priv.dest_width = wh * aspect;
+ _mga_priv.dest_height = wh;
+ }
+
+ } else {
+ _mga_priv.dest_width = _mga_priv.orig_width ;
+ _mga_priv.dest_height = _mga_priv.orig_height ;
+ }
+// }
+
+ _mga_priv.bIsFullscreen = 0;
+
+ _mga_priv.image_xoff = ( ww - _mga_priv.dest_width) / 2;
+ _mga_priv.image_yoff = ( wh - _mga_priv.dest_height) / 2;
+
+ }
+ xprintf(VERBOSE|VIDEO,"Calculated size should be %d x %d xoff %d yoff %d Display Is %d x %d\n",_mga_priv.dest_width,_mga_priv.dest_height,_mga_priv.image_xoff,_mga_priv.image_yoff,ww,wh);
+ printf("Calculated size should be %d x %d xoff %d yoff %d Display Is %d x %d\n",_mga_priv.dest_width,_mga_priv.dest_height,_mga_priv.image_xoff,_mga_priv.image_yoff,ww,wh);
+
+ if (ioctl(_mga_priv.fd,SYNCFB_GET_CAPS,&_mga_priv.caps)) perror("Error in config ioctl");
+ xprintf(VERBOSE|VIDEO,"Syncfb device name is '%s'\n", _mga_priv.caps.name);
+ xprintf(VERBOSE|VIDEO,"Memory size is %ld \n", _mga_priv.caps.memory_size);
+
+ if (ioctl(_mga_priv.fd,SYNCFB_GET_CONFIG,&_mga_priv.mga_vid_config))
+ printf("Error in get_config ioctl\n");
+
+ _mga_priv.mga_vid_config.fb_screen_size = _display.width * _display.height * (_display.depth/8); // maybe wrong if depth = 15 (?)
+ _mga_priv.mga_vid_config.src_width = _mga_priv.image_width;
+ _mga_priv.mga_vid_config.src_height= _mga_priv.image_height;
+ _mga_priv.bespitch = (_mga_priv.image_width + 31) & ~31;
+
+ switch (_mga_priv.fourcc_format) {
+ case IMGFMT_YV12:
+ _mga_priv.mga_vid_config.src_palette = VIDEO_PALETTE_YUV420P3;
+ break;
+ case IMGFMT_YUY2:
+ _mga_priv.mga_vid_config.src_palette = VIDEO_PALETTE_YUYV;
+ break;
+ default:
+ _mga_priv.mga_vid_config.src_palette = VIDEO_PALETTE_YUV420P3;
+ break;
+ }
+ _mga_priv.mga_vid_config.image_width = _mga_priv.dest_width;
+ _mga_priv.mga_vid_config.image_height= _mga_priv.dest_height;
+ _mga_priv.mga_vid_config.syncfb_mode = SYNCFB_FEATURE_BLOCK_REQUEST | SYNCFB_FEATURE_SCALE_H | SYNCFB_FEATURE_SCALE_V | SYNCFB_FEATURE_CROP ; /* | SYNCFB_FEATURE_DEINTERLACE; */
+ _mga_priv.mga_vid_config.image_xorg= _mga_priv.image_xoff;
+ _mga_priv.mga_vid_config.image_yorg= _mga_priv.image_yoff;
+
+ _mga_priv.mga_vid_config.src_crop_top = 0;
+ _mga_priv.mga_vid_config.src_crop_bot = 0;
+
+#ifdef CINEMODE
+ _mga_priv.mga_vid_config.default_repeat = 3;
+#else
+ _mga_priv.mga_vid_config.default_repeat = 2;
+#endif
+
+ if (ioctl(_mga_priv.fd,SYNCFB_SET_CONFIG,&_mga_priv.mga_vid_config))
+ xprintf(VERBOSE|VIDEO,"Error in set_config ioctl\n");
+ if (_mga_priv.bLogoMode) {
+ if (ioctl(_mga_priv.fd,SYNCFB_OFF)) {
+ xprintf(VERBOSE|VIDEO,"Error in OFF ioctl\n");
+ }
+ else
+ _mga_priv.overlay_state = 0;
+ }
+
+// if (ioctl(_mga_priv.fd,SYNCFB_ON))
+// xprintf(VERBOSE|VIDEO,"Error in ON ioctl\n");
+
+ // create a simple window without anything. Just make overlay clickable. :)
+ if (!_window.clasped_window) {
+ _window.clasped_window = XCreateSimpleWindow(lDisplay, RootWindow(lDisplay, _display.default_screen), 0, 0, _mga_priv.dest_width, _mga_priv.dest_height, 0, 0, 0);
+ gVideoWin = _window.clasped_window;
+
+ // turn off all borders etc. (taken from the Xv plugin)
+ prop = XInternAtom(lDisplay, "_MOTIF_WM_HINTS", False);
+ mwmhints.flags = MWM_HINTS_DECORATIONS;
+ mwmhints.decorations = 0;
+ XChangeProperty(lDisplay, gVideoWin, prop, prop, 32,
+ PropModeReplace, (unsigned char *) &mwmhints,
+ PROP_MWM_HINTS_ELEMENTS);
+ XSetTransientForHint(lDisplay, gVideoWin, None);
+
+ XSelectInput(gDisplay, _window.clasped_window, VisibilityChangeMask | KeyPressMask | ButtonPressMask | SubstructureNotifyMask | StructureNotifyMask);
+ XMapRaised(lDisplay, _window.clasped_window);
+ XSync(lDisplay,0);
+ }
+
+ XSetStandardProperties(lDisplay, _window.clasped_window, _window.title, _window.title, None, NULL, 0, NULL);
+ XMoveResizeWindow(lDisplay, _window.clasped_window, (_mga_priv.bIsFullscreen) ? 0 : _mga_priv.image_xoff, (_mga_priv.bIsFullscreen) ? 0 : _mga_priv.image_yoff, (_mga_priv.bIsFullscreen) ? _display.width : _mga_priv.dest_width, (_mga_priv.bIsFullscreen) ? _display.height : _mga_priv.dest_height);
+ XMapRaised(lDisplay, _window.clasped_window);
+ XSync(lDisplay,0);
+}
+
+
+
+/* setup internal variables and (re-)init window if necessary */
+static int set_image_format_mga (uint32_t width, uint32_t height, uint32_t ratio, int format) {
+
+
+ double res_h, res_v, display_ratio, aspect_ratio;
+
+ if ( (_mga_priv.image_width == width)
+ && (_mga_priv.image_height == height)
+ && (_mga_priv.ratio == ratio)
+ && (_mga_priv.bFullscreen == _mga_priv.bIsFullscreen)
+ && (_mga_priv.fourcc_format == format)
+ && !_mga_priv.user_ratio_changed ) {
+
+
+ return 0;
+ }
+
+ _mga_priv.image_width = width;
+ _mga_priv.image_height = height;
+ _mga_priv.ratio = ratio;
+ _mga_priv.fourcc_format = format;
+ _mga_priv.user_ratio_changed = 0;
+
+
+ /*
+ * Mpeg-2:
+ */
+
+ res_h = 1; // _display.width;
+ res_v = 1; // _display.height;
+
+ display_ratio = res_h / res_v;
+
+ xprintf (VERBOSE | VIDEO, "display_ratio : %f\n",display_ratio);
+
+ if (_mga_priv.user_ratio == ASPECT_AUTO) {
+ switch (_mga_priv.ratio) {
+ case 0: /* forbidden */
+ fprintf (stderr, "invalid ratio\n");
+ exit (1);
+ break;
+ case 1: /* "square" => 4:3 */
+ case 2:
+ aspect_ratio = 4.0 / 3.0;
+ break;
+ case 3:
+ aspect_ratio = 16.0 / 9.0;
+ break;
+ case 42: /* some stupid stream => don't touch aspect ratio */
+ default:
+ xprintf (VIDEO, "unknown aspect ratio (%d) in stream. untouched.\n", _mga_priv.ratio);
+ aspect_ratio = (double)_mga_priv.image_width / (double)_mga_priv.image_height;
+ break;
+ }
+ } else if (_mga_priv.user_ratio == ASPECT_ANAMORPHIC) {
+ aspect_ratio = 16.0 / 9.0;
+ } else if (_mga_priv.user_ratio == ASPECT_DVB) {
+ aspect_ratio = 2.0 / 1.0;
+ } else {
+ aspect_ratio = 1.0;
+ }
+ aspect_ratio *= display_ratio;
+ if (_mga_priv.image_height * aspect_ratio >= _mga_priv.image_width) {
+ _mga_priv.orig_width = rint((double)((double)_mga_priv.image_height * aspect_ratio));
+ _mga_priv.orig_height = _mga_priv.image_height;
+ }
+ else {
+ _mga_priv.orig_width = _mga_priv.image_width;
+ _mga_priv.orig_height = rint((double)((double)_mga_priv.image_width / aspect_ratio));
+ }
+
+
+ xprintf (VERBOSE|VIDEO, "picture size : %d x %d (Ratio: %d)\n",
+ width, height, ratio);
+
+ setup_window_mga () ;
+
+ return 1;
+}
+
+static void dispose_image_buffer_mga (vo_image_buffer_t *image) {
+
+ free (image->mem[0]);
+ free (image);
+
+}
+
+static vo_image_buffer_t *alloc_image_buffer_mga () {
+
+ vo_image_buffer_t *image;
+
+ if (!(image = malloc (sizeof (vo_image_buffer_t))))
+ return NULL;
+
+ // we only know how to do 4:2:0 planar yuv right now.
+ // we prepare for YUY2 sizes
+ if (!(image->mem[0] = malloc (_mga_priv.image_width * _mga_priv.image_height * 2))) {
+ free(image);
+ return NULL;
+ }
+
+ image->mem[2] = image->mem[0] + _mga_priv.image_width * _mga_priv.image_height;
+ image->mem[1] = image->mem[0] + _mga_priv.image_width * _mga_priv.image_height * 5 / 4;
+
+ pthread_mutex_init (&image->mutex, NULL);
+
+ return image;
+}
+
+static void process_macroblock_mga (vo_image_buffer_t *img,
+ uint8_t *py, uint8_t *pu, uint8_t *pv,
+ int slice_offset,
+ int offset){
+}
+
+int is_fullscreen_mga () {
+ return _mga_priv.bFullscreen;
+}
+
+void set_fullscreen_mga (int bFullscreen) {
+ _mga_priv.bFullscreen = bFullscreen;
+
+
+ set_image_format_mga (_mga_priv.image_width, _mga_priv.image_height, _mga_priv.ratio,
+ _mga_priv.fourcc_format);
+
+}
+
+
+static void display_frame_mga(vo_image_buffer_t *vo_img) {
+
+ // only write frame if overlay is active (otherwise syncfb hangs)
+ if (_mga_priv.overlay_state == 1) {
+ ioctl(_mga_priv.fd,SYNCFB_REQUEST_BUFFER,&_mga_priv.bufinfo);
+ //printf("get buffer %d\n",_mga_priv.bufinfo.id);
+ if ( _mga_priv.bufinfo.id == -1 ) {
+ printf( "Got buffer #%d\n", _mga_priv.bufinfo.id );
+ return;
+ }
+
+ _mga_priv.vid_data = (uint_8 *)(_mga_priv.frame0 + _mga_priv.bufinfo.offset);
+
+ _mga_write_frame_g400(vo_img->mem);
+
+ ioctl(_mga_priv.fd,SYNCFB_COMMIT_BUFFER,&_mga_priv.bufinfo);
+ }
+ /* Image is copied so release buffer */
+ vo_image_drawn ( (vo_image_buffer_t *) vo_img);
+}
+
+#if 0
+void draw_logo_xv () {
+ XClearWindow (gDisplay, gXv.window);
+
+ XCopyArea (gDisplay, gXineLogo, gXv.window, gXv.gc, 0, 0,
+ gXineLogoWidth, gXineLogoHeight,
+ (gXv.dest_width - gXineLogoWidth)/2,
+ (gXv.dest_height - gXineLogoHeight)/2);
+
+ XFlush(gDisplay);
+}
+#endif
+
+void handle_event_mga (XEvent *event) {
+ switch (event->type) {
+ case VisibilityNotify:
+ if (event->xany.window == _window.clasped_window) {
+ if (event->xvisibility.state == VisibilityFullyObscured)
+ {
+ _window.visibility = 0;
+
+ if (_mga_priv.overlay_state == 1) {
+ if (ioctl(_mga_priv.fd,SYNCFB_OFF)) {
+ xprintf(VERBOSE|VIDEO,"Error in OFF ioctl\n");
+ }
+ else
+ _mga_priv.overlay_state = 0;
+ }
+ }
+ else
+ {
+ _window.visibility = 1;
+
+ if (_mga_priv.overlay_state == 0 && !_mga_priv.bLogoMode) {
+ if (ioctl(_mga_priv.fd,SYNCFB_GET_CONFIG,&_mga_priv.mga_vid_config))
+ printf("Error in get_config ioctl\n");
+ if (ioctl(_mga_priv.fd,SYNCFB_SET_CONFIG,&_mga_priv.mga_vid_config))
+ printf("Error in get_config ioctl\n");
+ if (ioctl(_mga_priv.fd,SYNCFB_ON)) {
+ xprintf(VERBOSE|VIDEO,"Error in ON ioctl\n");
+ }
+ else
+ _mga_priv.overlay_state = 1;
+ }
+ }
+ }
+ break;
+ }
+}
+
+void set_logo_mode_mga (int bLogoMode) {
+ if (_mga_priv.bLogoMode == bLogoMode)
+ return;
+
+ _mga_priv.bLogoMode = bLogoMode;
+
+ if (bLogoMode) {
+ if (ioctl(_mga_priv.fd,SYNCFB_OFF)) {
+ xprintf(VERBOSE|VIDEO,"Error in OFF ioctl\n");
+ }
+ else
+ _mga_priv.overlay_state = 0;
+ }
+ else {
+ if (_window.visibility == 1) {
+ if (ioctl(_mga_priv.fd,SYNCFB_GET_CONFIG,&_mga_priv.mga_vid_config))
+ printf("Error in get_config ioctl\n");
+ if (ioctl(_mga_priv.fd,SYNCFB_SET_CONFIG,&_mga_priv.mga_vid_config))
+ printf("Error in get_config ioctl\n");
+ if (ioctl(_mga_priv.fd,SYNCFB_ON)) {
+ xprintf(VERBOSE|VIDEO,"Error in ON ioctl\n");
+ }
+ else {
+ _mga_priv.overlay_state = 1;
+ }
+ }
+ }
+
+#if 0
+ XLOCK
+ if (bLogoMode)
+ draw_logo_xv ();
+ else { /* FIXME : Bad hack to reinstall Xv overlay */
+ XUnmapWindow(gDisplay, gXv.window);
+ XMapRaised(gDisplay, gXv.window);
+
+ /* Spark
+ * move the window back to 0,0 in case the window manager moved it
+ * do this only is the window is fullscreen or
+ * we lose the top and left windowborders
+ */
+ if (gXv.bIsFullscreen) {
+ XMoveWindow(gDisplay, gXv.window, 0, 0);
+ }
+
+ }
+ XUNLOCK
+#endif
+}
+
+void reset_mga () {
+}
+
+void display_cursor_mga () {
+}
+
+void set_aspect_mga (int ratio) {
+
+ ratio %= 4;
+
+ if (ratio != _mga_priv.user_ratio) {
+ _mga_priv.user_ratio = ratio;
+ _mga_priv.user_ratio_changed = 1;
+
+ set_image_format_mga (_mga_priv.image_width, _mga_priv.image_height, _mga_priv.ratio, _mga_priv.fourcc_format);
+ }
+}
+
+int get_aspect_mga () {
+ return _mga_priv.user_ratio;
+}
+
+void exit_mga () {
+printf("exit mga\n");
+ if (ioctl(_mga_priv.fd,SYNCFB_ON)) {
+ xprintf(VERBOSE|VIDEO,"Error in ON ioctl\n");
+ }
+ if (ioctl(_mga_priv.fd,SYNCFB_OFF)) {
+ xprintf(VERBOSE|VIDEO,"Error in OFF ioctl\n");
+ }
+ close(_mga_priv.fd);
+ _mga_priv.fd = -1;
+}
+
+static int get_noop(void) {
+ return 0;
+}
+
+static int set_noop(int v) {
+ return v;
+}
+
+/*
+ * Contrast settings
+ */
+static int get_contrast_min(void) {
+ return _mga_priv.cont_min;
+}
+static int get_current_contrast(void) {
+ return _mga_priv.cont_current;
+}
+static int set_contrast(int value) {
+
+ _mga_priv.param.contrast = value;
+ _mga_priv.param.brightness = _mga_priv.bright_current;
+
+ if (ioctl(_mga_priv.fd,SYNCFB_SET_PARAMS,&_mga_priv.param) == 0) {
+ _mga_priv.cont_current = _mga_priv.param.contrast;
+ return _mga_priv.cont_current;
+ }
+ return value;
+}
+
+static int get_contrast_max(void) {
+ return _mga_priv.cont_max;
+}
+
+/*
+ * Brightness settings
+ */
+static int get_brightness_min(void) {
+ return _mga_priv.bright_min;
+}
+static int get_current_brightness(void) {
+ return _mga_priv.bright_current;
+}
+static int set_brightness(int value) {
+
+ _mga_priv.param.brightness = value;
+ _mga_priv.param.contrast = _mga_priv.cont_current;
+
+ if (ioctl(_mga_priv.fd,SYNCFB_SET_PARAMS,&_mga_priv.param) == 0) {
+ _mga_priv.bright_current = _mga_priv.param.brightness;
+ return _mga_priv.bright_current;
+ }
+ return value;
+}
+
+static int get_brightness_max(void) {
+ return _mga_priv.bright_max;
+}
+
+static void reset_settings(void) {
+ set_contrast(config_file_lookup_int ("contrast", _mga_priv.cont_current));
+ set_brightness(config_file_lookup_int ("brightness", _mga_priv.bright_current));
+}
+
+static void save_settings(void) {
+ config_file_set_int ("brightness", _mga_priv.bright_current);
+ config_file_set_int ("contrast", _mga_priv.cont_current);
+}
+
+
+static vo_driver_t vo_mga = {
+ get_capabilities_mga,
+ set_image_format_mga,
+ alloc_image_buffer_mga,
+ dispose_image_buffer_mga,
+ process_macroblock_mga,
+ display_frame_mga,
+ set_fullscreen_mga,
+ is_fullscreen_mga,
+ handle_event_mga,
+ set_logo_mode_mga,
+ reset_mga,
+ display_cursor_mga,
+ set_aspect_mga,
+ get_aspect_mga,
+ exit_mga,
+ /* HUE min, current, set , max */
+ get_noop,
+ get_noop,
+ set_noop,
+ get_noop,
+
+ /* SATURATION min, current, set , max */
+ get_noop,
+ get_noop,
+ set_noop,
+ get_noop,
+
+ /* Brightness min, current, set , max */
+ get_brightness_min,
+ get_current_brightness,
+ set_brightness,
+ get_brightness_max,
+
+ /* Contrast min, current, set , max */
+ get_contrast_min,
+ get_current_contrast,
+ set_contrast,
+ get_contrast_max,
+
+ /* Colorkey min , current set */
+ get_noop,
+ get_noop,
+ set_noop,
+ reset_settings,
+ save_settings
+};
+
+
+/*
+ * connect to server, create and map window,
+ * allocate colors and (shared) memory
+ */
+
+vo_driver_t *init_video_out_mga () {
+
+ char name[]= "/dev/syncfb";
+
+ _mga_priv.image_width=720;
+ _mga_priv.image_height=576;
+
+
+ if ((_mga_priv.fd = open ((char *) name, O_RDWR)) < 0) {
+ xprintf(VERBOSE|VIDEO, "Can't open %s\n", (char *) name);
+ return 0;
+ }
+
+ if (ioctl(_mga_priv.fd,SYNCFB_GET_CAPS,&_mga_priv.caps)) {
+ xprintf(VERBOSE|VIDEO,"Error in config ioctl");
+ close(_mga_priv.fd);
+ return 0;
+ }
+
+ _mga_priv.vid_data = (char*)mmap(0,_mga_priv.caps.memory_size,PROT_WRITE,MAP_SHARED,_mga_priv.fd,0);
+
+ //clear the buffer
+// memset(_mga_priv.vid_data,0,1024*768*2);
+
+
+ _mga_priv.frame0 = _mga_priv.vid_data;
+
+
+
+ /*
+ * init global variables
+ */
+
+ strcpy(_window.title, "Xine syncfb overlay\0");
+ _window.visibility = 1;
+
+ lDisplay = XOpenDisplay(":0.0"); /* Xine may run on another Display but syncfb always goes to :0.0 */
+// lDisplay = gDisplay;
+ _mga_priv.bFullscreen = 0;
+ _mga_priv.bIsFullscreen = 0;
+ _mga_priv.image_width = 0;
+ _mga_priv.image_height = 0;
+ _mga_priv.ratio = 0;
+ _mga_priv.bLogoMode = 0;
+// _mga_priv.cur_image = NULL;
+ _mga_priv.user_ratio = ASPECT_AUTO;
+ _mga_priv.user_ratio_changed = 0 ;
+ _mga_priv.fourcc_format = 0;
+
+ _window.clasped_window = 0;
+ _display.default_screen = DefaultScreen(lDisplay);
+ _mga_priv.cont_min = 0;
+ _mga_priv.cont_max = 255;
+ _mga_priv.bright_max = 127;
+ _mga_priv.bright_min = -128;
+
+ _mga_priv.overlay_state = 0; // 0 = off, 1 = on
+
+ if (ioctl(_mga_priv.fd,SYNCFB_GET_PARAMS,&_mga_priv.param) == 0) {
+ _mga_priv.cont_current = _mga_priv.param.contrast;
+ _mga_priv.bright_current = _mga_priv.param.brightness;
+ }
+ else {
+ _mga_priv.cont_current = 0x80;
+ _mga_priv.bright_current = 0;
+ xprintf(VERBOSE|VIDEO,"syncfb:Brightness and Contrast control not available, please update your syncfb module");
+ printf("syncfb:Brightness and Contrast control not available, please update your syncfb module\n");
+
+ }
+
+ set_logo_mode_mga(1);
+
+ return &vo_mga;
+}
+
+/* #else *//* no MGA */
+
+/* vo_functions_t *init_video_out_xv () { */
+/* fprintf (stderr, "Xvideo support not compiled in\n"); */
+/* return NULL; */
+/* } */
+
+/* #endif */ /* HAVE_XV */