--- /dev/null
+SooChan Lim <sc1.lim@samsung.com>
+SangJin Lee <lsj119@samsung.com>
+Boram Park <boram1288.park@samsung.com>
--- /dev/null
+Copyright (C) 1994-2003 The XFree86 Project, Inc. All Rights Reserved.
+Copyright (C) 2010 - 2011 Samsung Electronics co., Ltd. All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is fur-
+nished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT-
+NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CON-
+NECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the XFree86 Project shall not
+be used in advertising or otherwise to promote the sale, use or other deal-
+ings in this Software without prior written authorization from the XFree86
+Project.
--- /dev/null
+2010-08-30 SooChan Lim <sc1.lim@samsung.com>
+
+ Initial version of xserver-xorg-video-emulfb
+
+
--- /dev/null
+# Copyright 2005 Adam Jackson.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# on the rights to use, copy, modify, merge, publish, distribute, sub
+# license, and/or sell copies of the Software, and to permit persons to whom
+# the Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice (including the next
+# paragraph) shall be included in all copies or substantial portions of the
+# Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+# ADAM JACKSON BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+AUTOMAKE_OPTIONS = foreign
+SUBDIRS = src man
--- /dev/null
+#! /bin/sh
+
+srcdir=`dirname $0`
+test -z "$srcdir" && srcdir=.
+
+ORIGDIR=`pwd`
+cd $srcdir
+
+autoreconf -v --install || exit 1
+cd $ORIGDIR || exit $?
+
+#$srcdir/configure --enable-maintainer-mode "$@"
--- /dev/null
+# Copyright 2005 Adam Jackson.
+# Copyright (C) 2010 - 2011 Samsung Electronics co., Ltd. All Rights Reserved.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# on the rights to use, copy, modify, merge, publish, distribute, sub
+# license, and/or sell copies of the Software, and to permit persons to whom
+# the Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice (including the next
+# paragraph) shall be included in all copies or substantial portions of the
+# Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+# ADAM JACKSON BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+# Process this file with autoconf to produce a configure script
+
+AC_PREREQ(2.57)
+AC_INIT([xserver-xorg-video-emulfb],
+ 0.1.0,
+ [https://],
+ xserver-xorg-video-emulfb)
+
+AC_CONFIG_SRCDIR([Makefile.am])
+AM_CONFIG_HEADER([config.h])
+AC_CONFIG_AUX_DIR(.)
+
+AM_INIT_AUTOMAKE([dist-bzip2])
+
+AM_MAINTAINER_MODE
+
+# Checks for programs.
+AC_DISABLE_STATIC
+AC_PROG_LIBTOOL
+AC_PROG_CC
+AM_PROG_AS
+
+AH_TOP([#include "xorg-server.h"])
+
+AC_ARG_WITH(xorg-module-dir,
+ AC_HELP_STRING([--with-xorg-module-dir=DIR],
+ [Default xorg module directory [[default=$libdir/xorg/modules]]]),
+ [moduledir="$withval"],
+ [moduledir="$libdir/xorg/modules"])
+
+AC_ARG_ENABLE(pciaccess,
+ AS_HELP_STRING([--enable-pciaccess],
+ [Enable use of libpciaccess (default: disabled)]),
+ [PCIACCESS=$enableval], [PCIACCESS=no])
+
+AC_ARG_ENABLE(arm,
+ AS_HELP_STRING([--enable-arm],
+ [Enable arm (default: enabled)]),
+ [ARM=$enableval], [ARM=no])
+
+# Checks for extensions
+XORG_DRIVER_CHECK_EXT(RANDR, randrproto)
+XORG_DRIVER_CHECK_EXT(RENDER, renderproto)
+XORG_DRIVER_CHECK_EXT(XV, videoproto)
+
+# Checks for pkg-config packages
+PKG_CHECK_MODULES(XORG, [xorg-server >= 1.0.99.901 xproto fontsproto $REQUIRED_MODULES])
+sdkdir=$(pkg-config --variable=sdkdir xorg-server)
+
+# check the conditions
+EMULFB_CFALGS=""
+EMULFB_LIBS=""
+
+PKG_CHECK_MODULES(DLOG, dlog)
+PKG_CHECK_MODULES(DRM, libdrm)
+PKG_CHECK_MODULES(PIXMAN, pixman-1)
+PKG_CHECK_MODULES(XDBG, xdbg)
+
+EMULFB_CFLAGS="$EMULFB_CFLAGS $DLOG_CFLAGS $PIXMAN_CFLAGS $DRM_CFLAGS $XDBG_CFLAGS "
+EMULFB_LIBS="$EMULFB_LIBS $DLOG_LIBS $PIXMAN_LIBS $DRM_LIBS $XDBG_LIBS "
+
+
+AM_CONDITIONAL(ENABLE_ARM, [test "x$ARM" = xyes])
+if test "x$ARM" = xyes; then
+ AC_DEFINE(ENABLE_ARM, 1, [Enable arm])
+fi
+
+AM_CONDITIONAL(PCIACCESS, [test "x$PCIACCESS" = xyes])
+if test "x$PCIACCESS" = xyes; then
+ AC_DEFINE(PCIACCESS, 1, [Use libpciaccess])
+ PKG_CHECK_MODULES([PCIACCESS], [pciaccess >= 0.8.0])
+ XORG_CFLAGS="$XORG_CFLAGS $PCIACCESS_CFLAGS "
+fi
+
+# Checks for libraries.
+
+# Checks for header files.
+AC_HEADER_STDC
+
+AC_SUBST([EMULFB_CFLAGS])
+AC_SUBST([EMULFB_LIBS])
+
+AC_SUBST([XORG_CFLAGS])
+AC_SUBST([moduledir])
+
+DRIVER_NAME=emulfb
+AC_SUBST([DRIVER_NAME])
+
+XORG_MANPAGE_SECTIONS
+XORG_RELEASE_VERSION
+
+AC_OUTPUT([
+ Makefile
+ src/Makefile
+ man/Makefile
+])
--- /dev/null
+# $Id$
+#
+# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Copyright (C) 2010 - 2011 Samsung Electronics co., Ltd. All Rights Reserved.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice (including the next
+# paragraph) shall be included in all copies or substantial portions of the
+# Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+# DEALINGS IN THE SOFTWARE.
+#
+
+drivermandir = $(DRIVER_MAN_DIR)
+
+driverman_PRE = @DRIVER_NAME@.man
+
+driverman_DATA = $(driverman_PRE:man=@DRIVER_MAN_SUFFIX@)
+
+EXTRA_DIST = @DRIVER_NAME@.man
+
+CLEANFILES = $(driverman_DATA)
+
+SED = sed
+
+# Strings to replace in man pages
+XORGRELSTRING = @PACKAGE_STRING@
+ XORGMANNAME = X Version 11
+
+MAN_SUBSTS = \
+ -e 's|__vendorversion__|"$(XORGRELSTRING)" "$(XORGMANNAME)"|' \
+ -e 's|__xorgversion__|"$(XORGRELSTRING)" "$(XORGMANNAME)"|' \
+ -e 's|__xservername__|Xorg|g' \
+ -e 's|__xconfigfile__|xorg.conf|g' \
+ -e 's|__projectroot__|$(prefix)|g' \
+ -e 's|__appmansuffix__|$(APP_MAN_SUFFIX)|g' \
+ -e 's|__drivermansuffix__|$(DRIVER_MAN_SUFFIX)|g' \
+ -e 's|__adminmansuffix__|$(ADMIN_MAN_SUFFIX)|g' \
+ -e 's|__miscmansuffix__|$(MISC_MAN_SUFFIX)|g' \
+ -e 's|__filemansuffix__|$(FILE_MAN_SUFFIX)|g'
+
+SUFFIXES = .$(DRIVER_MAN_SUFFIX) .man
+
+.man.$(DRIVER_MAN_SUFFIX):
+ sed $(MAN_SUBSTS) < $< > $@
--- /dev/null
+.\" $XFree86: xc/programs/Xserver/hw/xfree86/drivers/fbdev/fbdev.man,v 1.2 2001/01/27 18:20:47 dawes Exp $
+.\" shorthand for double quote that works everywhere.
+.ds q \N'34'
+.TH FBDEV __drivermansuffix__ __vendorversion__
+.SH NAME
+fbdev \- video driver for framebuffer device
+.SH SYNOPSIS
+.nf
+.B "Section \*qDevice\*q"
+.BI " Identifier \*q" devname \*q
+.B " Driver \*qfbdev\*q"
+.BI " BusID \*qpci:" bus : dev : func \*q
+\ \ ...
+.B EndSection
+.fi
+.SH DESCRIPTION
+.B fbdev
+is an __xservername__ driver for framebuffer devices. This is a non-accelerated
+driver, the following framebuffer depths are supported: 8, 15, 16, 24.
+All visual types are supported for depth 8, and TrueColor visual is
+supported for the other depths. Multi-head configurations are supported.
+.SH SUPPORTED HARDWARE
+The
+.B fbdev
+driver supports all hardware where a framebuffer driver is available.
+fbdev uses the os-specific submodule fbdevhw(__drivermansuffix__) to talk
+to the kernel
+device driver. Currently a fbdevhw module is available for linux.
+.SH CONFIGURATION DETAILS
+Please refer to __xconfigfile__(__filemansuffix__) for general configuration
+details. This section only covers configuration details specific to
+this driver.
+.PP
+For this driver it is not required to specify modes in the screen
+section of the config file. The
+.B fbdev
+driver can pick up the currently used video mode from the framebuffer
+driver and will use it if there are no video modes configured.
+.PP
+For PCI boards you might have to add a BusID line to the Device
+section. See above for a sample line. You can use \*q\__xservername__
+-scanpci\*q
+to figure out the correct values.
+.PP
+The following driver
+.B Options
+are supported:
+.TP
+.BI "Option \*qfbdev\*q \*q" string \*q
+The framebuffer device to use. Default: /dev/fb0.
+.TP
+.BI "Option \*qShadowFB\*q \*q" boolean \*q
+Enable or disable use of the shadow framebuffer layer. Default: on.
+.TP
+.BI "Option \*qRotate\*q \*q" string \*q
+Enable rotation of the display. The supported values are "CW" (clockwise,
+90 degrees), "UD" (upside down, 180 degrees) and "CCW" (counter clockwise,
+270 degrees). Implies use of the shadow framebuffer layer. Default: off.
+.SH "SEE ALSO"
+__xservername__(__appmansuffix__), __xconfigfile__(__filemansuffix__), xorgconfig(__appmansuffix__), Xserver(__appmansuffix__),
+X(__miscmansuffix__), fbdevhw(__drivermansuffix__)
+.SH AUTHORS
+Authors include: Gerd Knorr, Michel D\(:anzer, Geert Uytterhoeven
--- /dev/null
+# >> macros
+# << macros
+
+Name: xorg-x11-drv-emulfb
+Summary: X.Org X server driver for sdk emulation
+Version: 0.5.9
+Release: 1
+#ExclusiveArch: %arm
+Group: System/X Hardware Support
+License: Samsung
+Source0: %{name}-%{version}.tar.gz
+
+BuildRequires: prelink
+BuildRequires: xorg-x11-xutils-dev
+BuildRequires: pkgconfig(xorg-server)
+BuildRequires: pkgconfig(randrproto)
+BuildRequires: pkgconfig(renderproto)
+BuildRequires: pkgconfig(fontsproto)
+BuildRequires: pkgconfig(xproto)
+BuildRequires: pkgconfig(videoproto)
+BuildRequires: pkgconfig(resourceproto)
+BuildRequires: pkgconfig(dlog)
+BuildRequires: pkgconfig(libdrm)
+BuildRequires: pkgconfig(pixman-1)
+BuildRequires: pkgconfig(xdbg)
+
+%description
+This package provides the driver for sdk emulation
+
+%prep
+%setup -q
+
+# >> setup
+# << setup
+
+%build
+# >> build pre
+# << build pre
+
+%ifarch %{arm}
+%define ENABLE_ARM --enable-arm
+%else
+%define ENABLE_ARM --disable-arm
+%endif
+
+%reconfigure --disable-static %{ENABLE_ARM} \
+ CFLAGS="-Wall -Werror ${CFLAGS}" LDFLAGS="${LDFLAGS} -Wl,--hash-style=both -Wl,--as-needed"
+
+make %{?jobs:-j%jobs}
+
+# >> build post
+# << build post
+%install
+rm -rf %{buildroot}
+# >> install pre
+# << install pre
+mkdir -p %{buildroot}/usr/share/license
+cp -af COPYING %{buildroot}/usr/share/license/%{name}
+%make_install
+
+# >> install post
+execstack -c %{buildroot}%{_libdir}/xorg/modules/drivers/emulfb_drv.so
+# << install post
+
+%files
+%defattr(-,root,root,-)
+# >> files emulfb
+%{_libdir}/xorg/modules/drivers/*.so
+%{_datadir}/man/man4/*
+# << files emulfb
+/usr/share/license/%{name}
--- /dev/null
+# Copyright 2005 Adam Jackson.
+# Copyright (C) 2010 - 2011 Samsung Electronics co., Ltd. All Rights Reserved.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# on the rights to use, copy, modify, merge, publish, distribute, sub
+# license, and/or sell copies of the Software, and to permit persons to whom
+# the Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice (including the next
+# paragraph) shall be included in all copies or substantial portions of the
+# Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+# ADAM JACKSON BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+# this is obnoxious:
+# -module lets us name the module exactly how we want
+# -avoid-version prevents gratuitous .0.0.0 version numbers on the end
+# _ladir passes a dummy rpath to libtool so the thing will actually link
+# TODO: -nostdlib/-Bstatic/-lgcc platform magic, not installing the .a, etc.
+
+AM_CFLAGS = -I@top_srcdir@/src @XORG_CFLAGS@ @EMULFB_CFLAGS@
+emulfb_drv_la_LTLIBRARIES = emulfb_drv.la
+#emulfb_drv_la_LDFLAGS = -module -avoid-version @EMULFB_LIBS@
+emulfb_drv_la_LDFLAGS = -module -avoid-version
+emulfb_drv_la_LIBADD = @EMULFB_LIBS@
+emulfb_drv_ladir = @moduledir@/drivers
+
+# common
+emulfb_drv_la_SOURCES = \
+ fbdev.c \
+ fb/fbdev_fb.c \
+ fbdev_dpms.c
+AM_CFLAGS += -I@top_srcdir@/src/fb
+
+if ENABLE_ARM
+ xvtarget = arm
+else
+ xvtarget = i386
+endif
+
+# xv
+emulfb_drv_la_SOURCES += \
+ xv/fbdev_video.c \
+ xv/fbdev_video_virtual.c \
+ xv/fbdev_v4l2.c \
+ xv/${xvtarget}/fbdev_video_v4l2.c
+AM_CFLAGS += -I@top_srcdir@/src/xv
+AM_CFLAGS += -I@top_srcdir@/src/xv/${xvtarget}
+
+# fbdevhw
+emulfb_drv_la_SOURCES += \
+ fbdevhw/fbdev_hw.c
+AM_CFLAGS += -I@top_srcdir@/src/fbdevhw
+
+# util
+emulfb_drv_la_SOURCES += \
+ util/fbdev_util.c \
+ util/fbdev_pixman.c
+AM_CFLAGS += -I@top_srcdir@/src/util
+
+# crtcconfig
+emulfb_drv_la_SOURCES += \
+ crtcconfig/fbdev_crtcconfig.c \
+ crtcconfig/fbdev_crtc.c \
+ crtcconfig/lcd_output.c \
+ crtcconfig/fbdev_mode.c
+AM_CFLAGS += -I@top_srcdir@/src/crtcconfig
+
+# crtcconfig
+emulfb_drv_la_SOURCES += \
+ debug/fbdev_event_trace.c
+AM_CFLAGS += -I@top_srcdir@/src/debug
+
--- /dev/null
+/**************************************************************************
+
+xserver-xorg-video-emulfb
+
+Copyright 2010 - 2011 Samsung Electronics co., Ltd. All Rights Reserved.
+
+Contact: SooChan Lim <sc1.lim@samsung.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sub license, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <unistd.h>
+#include <sys/mman.h>
+#include <errno.h>
+#include <math.h>
+
+#include "xace.h"
+#include "xacestr.h"
+#include <X11/Xatom.h>
+
+#include "fbdev.h"
+#include "fbdevhw.h"
+#include "fbdev_hw.h"
+#include "fbdev_crtc_priv.h"
+#include "fbdev_util.h"
+
+#include "xf86Crtc.h"
+#include "xf86Xinput.h"
+#include "exevents.h"
+
+/********************************************************************************************/
+/* Implementation of Crtc entry points */
+/********************************************************************************************/
+/**
+ * Turns the crtc on/off, or sets intermediate power levels if available.
+ *
+ * Unsupported intermediate modes drop to the lower power setting. If the
+ * mode is DPMSModeOff, the crtc must be disabled sufficiently for it to
+ * be safe to call mode_set.
+ */
+static void fbdev_crtc_dpms(xf86CrtcPtr crtc, int mode)
+{
+ return;
+}
+
+/**
+ * Lock CRTC prior to mode setting, mostly for DRI.
+ * Returns whether unlock is needed
+ */
+static Bool fbdev_crtc_lock(xf86CrtcPtr crtc)
+{
+
+ /* check whether unlock is needed */
+ return TRUE;
+}
+
+/**
+ * Lock CRTC prior to mode setting, mostly for DRI.
+ * Returns whether unlock is needed
+ */
+static void fbdev_crtc_unlock(xf86CrtcPtr crtc)
+{
+ return;
+}
+
+
+/**
+ * Callback to adjust the mode to be set in the CRTC.
+ *
+ * This allows a CRTC to adjust the clock or even the entire set of
+ * timings, which is used for panels with fixed timings or for
+ * buses with clock limitations.
+ */
+static Bool fbdev_crtc_mode_fixup(xf86CrtcPtr crtc, DisplayModePtr mode,
+ DisplayModePtr adjusted_mode)
+{
+ return TRUE;
+}
+
+/**
+ * Prepare CRTC for an upcoming mode set.
+ */
+static void fbdev_crtc_prepare(xf86CrtcPtr crtc)
+{
+
+}
+
+/**
+ * Callback for setting up a video mode after fixups have been made.
+ */
+static void fbdev_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
+ DisplayModePtr adjusted_mode, int x, int y)
+{
+
+}
+
+/**
+ * Commit mode changes to a CRTC
+ */
+static void fbdev_crtc_commit(xf86CrtcPtr crtc)
+{
+
+}
+
+/* Set the color ramps for the CRTC to the given values. */
+static void fbdev_crtc_gamma_set(xf86CrtcPtr crtc, CARD16 * red, CARD16 * green,
+ CARD16 * blue, int size)
+{
+
+}
+
+/**
+ * Set cursor colors
+ */
+void fbdev_crtc_set_cursor_colors(xf86CrtcPtr crtc, int bg, int fg)
+{
+ return;
+}
+
+/**
+ * Set cursor position
+ */
+void fbdev_crtc_set_cursor_position(xf86CrtcPtr crtc, int x, int y)
+{
+
+ return;
+}
+
+/**
+ * Show cursor
+ */
+void fbdev_crtc_show_cursor(xf86CrtcPtr crtc)
+{
+
+ return;
+}
+
+/**
+ * Hide cursor
+ */
+void fbdev_crtc_hide_cursor(xf86CrtcPtr crtc)
+{
+
+ return;
+}
+
+/**
+ * Load ARGB image
+ */
+void fbdev_crtc_load_cursor_argb(xf86CrtcPtr crtc, CARD32 *image)
+{
+
+ return;
+}
+
+/**
+ * Less fine-grained mode setting entry point for kernel modesetting
+ */
+Bool fbdev_crtc_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
+ Rotation rotation, int x, int y)
+{
+ return TRUE;
+}
+
+
+/**
+ * Callback for panning. Doesn't change the mode.
+ * Added in ABI version 2
+ */
+static void fbdev_crtc_set_origin(xf86CrtcPtr crtc, int x, int y)
+{
+ xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR, "set_origin: unimplemented");
+ return; /* XXX implement */
+}
+
+/* crtc funcs */
+static const xf86CrtcFuncsRec fbdev_crtc_funcs =
+{
+ .dpms = fbdev_crtc_dpms,
+ .save = NULL, /* XXX */
+ .restore = NULL, /* XXX */
+ .lock = fbdev_crtc_lock,
+ .unlock = fbdev_crtc_unlock,
+ .mode_fixup = fbdev_crtc_mode_fixup,
+
+ .prepare = fbdev_crtc_prepare,
+ .mode_set = fbdev_crtc_mode_set,
+ .commit = fbdev_crtc_commit,
+ .gamma_set = fbdev_crtc_gamma_set,
+
+ .shadow_create = NULL,
+ .shadow_allocate = NULL,
+ .shadow_destroy = NULL,
+
+ .set_cursor_colors = fbdev_crtc_set_cursor_colors,
+ .set_cursor_position = fbdev_crtc_set_cursor_position,
+ .show_cursor = fbdev_crtc_show_cursor,
+ .hide_cursor = fbdev_crtc_hide_cursor,
+ .load_cursor_argb = fbdev_crtc_load_cursor_argb,
+ .destroy = NULL, /* XXX */
+ .set_mode_major = NULL, /*???*/
+#if RANDR_13_INTERFACE
+ .set_origin = fbdev_crtc_set_origin,
+#endif
+};
+
+void FBDevCrtcInit(ScrnInfoPtr pScrn, int num)
+{
+ xf86CrtcPtr crtc;
+ FBDevCrtcPrivPtr fbdev_crtc;
+
+ crtc = xf86CrtcCreate (pScrn, &fbdev_crtc_funcs);
+ if (crtc == NULL)
+ return;
+
+ fbdev_crtc = xnfcalloc (sizeof (FBDevCrtcPriv), 1);
+ if (!fbdev_crtc)
+ {
+ xf86CrtcDestroy (crtc);
+ return;
+ }
+
+ crtc->driver_private = fbdev_crtc;
+
+}
+
+
--- /dev/null
+/**************************************************************************
+
+xserver-xorg-video-emulfb
+
+Copyright 2010 - 2011 Samsung Electronics co., Ltd. All Rights Reserved.
+
+Contact: SooChan Lim <sc1.lim@samsung.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sub license, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+#ifndef _FBDEV_CRTC_PRIV_H_
+#define _FBDEV_CRTC_PRIV_H_
+
+#include "fbdev.h"
+
+/* fbdev crtc private infomation */
+typedef struct _fbdevCrtcPriv
+{
+ int type;
+
+} FBDevCrtcPriv, *FBDevCrtcPrivPtr;
+#define FBDEVCRTCPTR(o) ((FBDevCrtcPrivPtr)((o)->driver_private))
+
+void FBDevCrtcInit(ScrnInfoPtr pScrn, int num);
+#endif // _FBDEV_CRTC_PRIV_H_
--- /dev/null
+/**************************************************************************
+
+xserver-xorg-video-emulfb
+
+Copyright 2010 - 2011 Samsung Electronics co., Ltd. All Rights Reserved.
+
+Contact: SooChan Lim <sc1.lim@samsung.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sub license, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+#include "fbdev.h"
+#include "fbdevhw.h"
+#include "fbdev_crtcconfig.h"
+#include "fbdev_crtc_priv.h"
+#include "fbdev_output_priv.h"
+
+#include "xf86Crtc.h"
+
+#define MIN_CRTC_DPY_WIDTH 320
+#define MAX_CRTC_DPY_WIDTH 1024
+#define MIN_CRTC_DPY_HEIGHT 200
+#define MAX_CRTC_DPY_HEIGHT 1024
+
+#define NUM_CRTCS 1
+
+/**
+ * Requests that the driver resize the screen.
+ *
+ * The driver is responsible for updating scrn->virtualX and scrn->virtualY.
+ * If the requested size cannot be set, the driver should leave those values
+ * alone and return FALSE.
+ *
+ * A naive driver that cannot reallocate the screen may simply change
+ * virtual[XY]. A more advanced driver will want to also change the
+ * devPrivate.ptr and devKind of the screen pixmap, update any offscreen
+ * pixmaps it may have moved, and change pScrn->displayWidth.
+ */
+static Bool fbdev_crtc_config_resize (ScrnInfoPtr scrn, int width, int height)
+{
+
+ scrn->virtualX = width;
+ scrn->virtualY = height;
+
+ return TRUE;
+}
+
+
+/* crtc_config_func */
+static const xf86CrtcConfigFuncsRec fbdev_crtc_config_funcs =
+{
+ .resize = fbdev_crtc_config_resize,
+};
+
+
+/*
+ * Initialize the CrtcConfig.
+ * And initialize the mode setting throught create the avaliable crtcs and outputs
+ * then Initialize the Configuration of Crtc
+ */
+Bool FBDevCrtcConfigInit(ScrnInfoPtr pScrn)
+{
+ int min_width, max_width, min_height, max_height;
+ xf86CrtcConfigPtr crtc_config;
+ int i, o, c;
+ FBDevPtr pFBDev = FBDEVPTR(pScrn);
+ /* TODO: check this routines later whether it is right setting */
+ {
+
+ fbdevHWUseBuildinMode(pScrn); /* sets pScrn->modes */
+ pScrn->modes = xf86DuplicateMode(pScrn->modes); /* well done, fbdevhw. */
+ pScrn->modes->name = NULL; /* fbdevhw string can't be freed */
+ pScrn->modes->type = M_T_DRIVER | M_T_PREFERRED;
+ pScrn->currentMode = pScrn->modes;
+ pFBDev->builtin = xf86DuplicateMode(pScrn->modes);
+
+ }
+
+ /* allocate an xf86CrtcConfig */
+ xf86CrtcConfigInit(pScrn, &fbdev_crtc_config_funcs);
+ crtc_config = XF86_CRTC_CONFIG_PTR (pScrn);
+
+ min_width = pScrn->modes->HDisplay;
+ max_width = pScrn->modes->HDisplay;
+ min_height = pScrn->modes->VDisplay;
+ max_height = pScrn->modes->VDisplay;
+
+ xf86CrtcSetSizeRange(pScrn, min_width, min_height, max_width, max_height);
+
+ /* set up the crtcs */
+ for( i = 0; i < NUM_CRTCS; i++)
+ FBDevCrtcInit(pScrn, i);
+
+ /* set up the outputs */
+ LcdOutputInit(pScrn);
+
+ /* [TODO]: set the crtc to the output in some manner ???? */
+ for (o = 0; o < crtc_config->num_output; o++)
+ {
+ xf86OutputPtr output = crtc_config->output[o];
+ int crtc_mask;
+
+ crtc_mask = 0;
+ for (c = 0; c < crtc_config->num_crtc; c++)
+ {
+ crtc_mask |= (1 << c);
+ }
+ output->possible_crtcs = crtc_mask;
+ output->possible_clones = FALSE;
+ }
+
+ /* initialize the configuration */
+ if(!xf86InitialConfiguration(pScrn, TRUE))
+ {
+ return FALSE;
+ }
+
+ return TRUE;
+
+}
--- /dev/null
+/**************************************************************************
+
+xserver-xorg-video-emulfb
+
+Copyright 2010 - 2011 Samsung Electronics co., Ltd. All Rights Reserved.
+
+Contact: SooChan Lim <sc1.lim@samsung.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sub license, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+#ifndef _FBDEV_CRTCCONFIG_H_
+#define _FBDEV_CRTCCONFIG_H_
+
+Bool FBDevCrtcConfigInit(ScrnInfoPtr pScrn);
+
+
+#endif // _FBDEV_CRTCCONFIG_H_
--- /dev/null
+/**************************************************************************
+
+xserver-xorg-video-emulfb
+
+Copyright 2010 - 2011 Samsung Electronics co., Ltd. All Rights Reserved.
+
+Contact: SooChan Lim <sc1.lim@samsung.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sub license, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+
+#include "fbdev.h"
+
+#include <linux/fb.h>
+#include "fbdev_hw.h"
+#include "fbdev_mode.h"
+
+typedef struct _FBDevDisplayModeRec
+{
+ char name[32]; /* identifier for the mode */
+
+ /* These are the values that the user sees/provides */
+ int Clock; /* pixel clock freq (kHz) */
+ int HDisplay; /* horizontal timing */
+ int HSyncStart;
+ int HSyncEnd;
+ int HTotal;
+ int HSkew;
+ int VDisplay; /* vertical timing */
+ int VSyncStart;
+ int VSyncEnd;
+ int VTotal;
+ int VScan;
+ int Flags;
+
+} FBDevDisplayModeRec, *FBDevDisplayModePtr;
+
+/* [soolim: 20100206][TODO] : it has to be recalculated when it comes to change the target framebuffer
+ * The display mode data has to be changed whenever the target is changed
+ * Always check it out.
+ */
+const FBDevDisplayModeRec fbdevDisplayModes[] =
+{
+ /* CGA ( 320 x 200 ) */
+ {"320x200", 38, 320, 336, 338, 354, 0, 200, 203, 205, 233, 0, 0,},
+ /* QVGA ( 320 x 240 ) */
+ {"320x240", 38, 320, 336, 338, 354, 0, 240, 243, 245, 273, 0, 0,},
+ /* XX ( 240 x 400 ) */
+ {"240x400", 38, 240, 256, 258, 274, 0, 400, 428, 430, 433, 0, 0,},
+ /* HVGA (320 x 480 ) */
+ {"320x480", 38, 320, 336, 338, 354, 0, 480, 483, 485, 513, 0, 0,},
+ /* WVGA ( 480 x 720 ) */
+ {"480x720", 38, 480, 496, 498, 514, 0, 720, 723, 725, 753, 0, 0},
+ /* WVGA ( 480 x 800 ) */
+ {"480x800", 38, 480, 496, 498, 514, 0, 800, 803, 805, 833, 0, 0},
+ /* VGA ( 640 x 480 ) */
+ {"640x480", 19, 640, 840, 880, 959, 0, 480, 491, 501, 511, 0, 0,},
+ /* NTSC ( 720 x 480 ) */
+ {"720x480", 19, 720, 920, 960, 1039, 0, 480, 491, 501, 511, 0, 0,},
+ /* PAL ( 768 x 576 ) */
+ {"768x576", 19, 768, 968, 1008, 1087, 0, 576, 587, 597, 607, 0, 0,},
+ /* WVGA ( 800 x 480 ) */
+ {"800x480", 19, 800, 1000, 1040, 1119, 0, 480, 491, 501, 511, 0, 0},
+ /* WVGA ( 854 x 480 ) */
+ {"854x480", 19, 854, 1054, 1094, 1173, 0, 480, 491, 501, 511, 0, 0,},
+ /* WSVGA ( 600 x 1024 ) */
+ {"600x1024", 19, 600, 611, 621, 631, 0, 1024, 1224, 1264, 1343, 0, 0},
+ /* WSVGA ( 1024 x 600 ) */
+ {"1024x600", 19, 1024, 1224, 1264, 1343, 0, 600, 611, 621, 631, 0, 0},
+#if 0
+ /* XGA ( 1024 x 768 ) */
+ {"1024x768", 19, 1024, 1224, 1264, 1343, 600, 611, 621, 631, 0,},
+#endif
+};
+
+
+#define NUM_DISPLAY_MODES (sizeof(fbdevDisplayModes)/sizeof(fbdevDisplayModes[0]))
+
+const int fbdevNumDisplayModes = NUM_DISPLAY_MODES;
+
+
+DisplayModePtr
+FBDevGetSupportModes(DisplayModePtr builtin_mode)
+{
+ DisplayModePtr pMode = NULL;
+ DisplayModePtr prev_pMode = NULL;
+ DisplayModePtr ret_pMode = NULL;
+ int i;
+ int clock = 0;
+ if(builtin_mode)
+ clock = builtin_mode->Clock;
+ else
+ clock = 0;
+
+ for(i=0; i< fbdevNumDisplayModes; i++)
+ {
+ pMode = calloc(1, sizeof(DisplayModeRec));
+ pMode->next = NULL;
+ pMode->prev = NULL;
+ pMode->name = calloc(1, sizeof(char)*32);
+ sprintf(pMode->name,"%s", fbdevDisplayModes[i].name);
+ pMode->status = MODE_OK;
+ pMode->type = M_T_DRIVER | M_T_PREFERRED;
+
+ pMode->Clock = clock;
+ pMode->HDisplay = fbdevDisplayModes[i].HDisplay;
+ pMode->HSyncStart = fbdevDisplayModes[i].HSyncStart;
+ pMode->HSyncEnd = fbdevDisplayModes[i].HSyncEnd;
+ pMode->HTotal = fbdevDisplayModes[i].HTotal;
+ pMode->HSkew = fbdevDisplayModes[i].HSkew;
+ pMode->VDisplay = fbdevDisplayModes[i].VDisplay;
+ pMode->VSyncStart = fbdevDisplayModes[i].VSyncStart;
+ pMode->VSyncEnd = fbdevDisplayModes[i].VSyncEnd;
+ pMode->VTotal = fbdevDisplayModes[i].VTotal;
+ pMode->VScan = fbdevDisplayModes[i].VScan;
+ pMode->Flags = fbdevDisplayModes[i].Flags;
+
+ if(prev_pMode)
+ {
+ pMode->prev = prev_pMode;
+ prev_pMode->next = pMode;
+ prev_pMode = prev_pMode->next;
+ }
+ else
+ {
+ prev_pMode = pMode;
+ ret_pMode = pMode;
+ }
+
+ pMode = NULL;
+ }
+
+ return ret_pMode;
+}
+
+#define OPTION_PREFERRED_MODE 0
+
+char *
+FBDevCheckPreferredMode(ScrnInfoPtr pScrn, xf86OutputPtr output)
+{
+ char *preferred_mode = NULL;
+
+ /* Check for a configured preference for a particular mode */
+ preferred_mode = xf86GetOptValString (output->options,
+ OPTION_PREFERRED_MODE);
+ if (preferred_mode)
+ return preferred_mode;
+
+ if (pScrn->display->modes && *pScrn->display->modes)
+ preferred_mode = *pScrn->display->modes;
+
+ return preferred_mode;
+}
--- /dev/null
+/**************************************************************************
+
+xserver-xorg-video-emulfb
+
+Copyright 2010 - 2011 Samsung Electronics co., Ltd. All Rights Reserved.
+
+Contact: SooChan Lim <sc1.lim@samsung.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sub license, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+#ifndef FBDEV_MODE_H
+#define FBDEV_MODE_H
+
+#include "xf86Crtc.h"
+
+DisplayModePtr
+FBDevGetSupportModes(DisplayModePtr builtin_mode);
+
+char *
+FBDevCheckPreferredMode(ScrnInfoPtr pScrn, xf86OutputPtr output);
+
+#endif //FBDEV_MODE_H
+
+
--- /dev/null
+/**************************************************************************
+
+xserver-xorg-video-emulfb
+
+Copyright 2010 - 2011 Samsung Electronics co., Ltd. All Rights Reserved.
+
+Contact: SooChan Lim <sc1.lim@samsung.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sub license, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+#ifndef _FBDEV_OUTPUT_PRIV_H_
+#define _FBDEV_OUTPUT_PRIV_H_
+
+/* fbdev output private infomation */
+typedef struct _fbdevOutputPriv
+{
+ int type;
+ void *devPrivate;
+} FBDevOutputPriv, *FBDevOutputPrivPtr;
+#define FBDEVOUTPUTPTR(o) ((FBDevOutputPrivPtr)((o)->driver_private))
+
+void LcdOutputInit(ScrnInfoPtr pScrn);
+
+#endif // _FBDEV_OUTPUT_PRIV_H_
+
+
--- /dev/null
+/**************************************************************************
+
+xserver-xorg-video-emulfb
+
+Copyright 2010 - 2011 Samsung Electronics co., Ltd. All Rights Reserved.
+
+Contact: SooChan Lim <sc1.lim@samsung.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sub license, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+#include "fbdev.h"
+#include "fbdev_output_priv.h"
+#include "fbdev_mode.h"
+#include "fbdev_util.h"
+#include "fbdev_video.h"
+
+#include <xf86Crtc.h>
+
+#define STR_XRR_VIDEO_OFFSET_PROPERTY "XRR_PROPERTY_VIDEO_OFFSET"
+
+static Bool g_video_offset_prop_init = FALSE;
+
+static Atom xrr_property_video_offset_atom;
+
+static Bool
+_lcd_output_prop_video_offset (xf86OutputPtr pOutput, Atom property, RRPropertyValuePtr value)
+{
+ int x, y;
+ char str[128];
+ char *p;
+
+ if (g_video_offset_prop_init == FALSE)
+ {
+ xrr_property_video_offset_atom = MakeAtom (STR_XRR_VIDEO_OFFSET_PROPERTY,
+ strlen (STR_XRR_VIDEO_OFFSET_PROPERTY), TRUE);
+ g_video_offset_prop_init = TRUE;
+ }
+
+ if (xrr_property_video_offset_atom != property)
+ return FALSE;
+
+ if (!value || !value->data || value->size == 0)
+ return TRUE;
+
+ if (value->format != 8)
+ return TRUE;
+
+ snprintf (str, sizeof(str), "%s", (char*)value->data);
+
+ p = strtok (str, ",");
+ return_val_if_fail (p != NULL, FALSE);
+ x = atoi (p);
+
+ p = strtok (NULL, ",");
+ return_val_if_fail (p != NULL, FALSE);
+ y = atoi (p);
+
+ DRVLOG ("%s : offset(%d,%d) \n", __FUNCTION__, x, y);
+
+ fbdevVideoSetOffset (pOutput->scrn, x, y);
+
+ return TRUE;
+}
+
+
+/********************************************************************************************/
+/* Implementation of Output entry points */
+/********************************************************************************************/
+static void lcd_output_create_resources(xf86OutputPtr output)
+{
+}
+
+static void lcd_output_dpms(xf86OutputPtr output, int mode)
+{
+ return;
+}
+
+static void lcd_output_save(xf86OutputPtr output)
+{
+ return;
+}
+
+static void lcd_output_restore(xf86OutputPtr output)
+{
+ return;
+}
+
+static int lcd_output_mode_valid(xf86OutputPtr output, DisplayModePtr mode)
+{
+ FBDevPtr pFBDev = FBDEVPTR(output->scrn);
+
+ if(pFBDev->builtin->HDisplay < mode->HDisplay)
+ return MODE_HSYNC;
+
+ if(pFBDev->builtin->VDisplay < mode->VDisplay)
+ return MODE_VSYNC;
+
+ output->scrn->currentMode = mode;
+
+ return MODE_OK;
+
+}
+
+static Bool lcd_output_mode_fixup(xf86OutputPtr output, DisplayModePtr mode,
+ DisplayModePtr adjusted_mode)
+{
+ return TRUE;
+}
+
+static void lcd_output_prepare(xf86OutputPtr output)
+{
+ return;
+}
+
+static void lcd_output_mode_set(xf86OutputPtr output, DisplayModePtr mode,
+ DisplayModePtr adjusted_mode)
+{
+ ScrnInfoPtr pScrn = output ->scrn;
+ FBDevPtr pFBDev = FBDEVPTR(pScrn);
+
+ /* have to set the physical size of the output */
+ output->mm_width = pFBDev->var.width;
+ output->mm_height = pFBDev->var.height;
+ output->conf_monitor->mon_width = pFBDev->var.width;
+ output ->conf_monitor->mon_height = pFBDev->var.height;
+
+ return;
+}
+
+static void lcd_output_commit(xf86OutputPtr output)
+{
+ return;
+}
+
+static xf86OutputStatus lcd_output_detect(xf86OutputPtr output)
+{
+ return XF86OutputStatusConnected;
+}
+
+
+
+/**
+ * Name : lcd_output_get_modes
+ * Input : xf86OutputPtr
+ * Return : DisplayModePtr
+ * Description : Query the device for the modes it provides.
+ This function may also update MonInfo, mm_width, and mm_height.
+ return singly-linked list of modes or NULL if no modes found.
+
+ */
+static int first_time_rotated = TRUE;
+static DisplayModePtr lcd_output_get_modes(xf86OutputPtr output)
+{
+ FBDevPtr pFBDev = FBDEVPTR(output->scrn);
+
+ /* [soolim:20100205] : if there is no mode name in xorg.conf, use the builtin mode */
+ char *preferred_mode;
+ preferred_mode = FBDevCheckPreferredMode(output->scrn, output);
+ if(!preferred_mode)
+ {
+ int HDisplay, VDisplay;
+
+ Bool rotated = (pFBDev->rotate & (RR_Rotate_90|RR_Rotate_270)) != 0;
+
+ if(rotated)
+ {
+ if(first_time_rotated)
+ {
+ memcpy(&pFBDev->builtin_saved, pFBDev->builtin, sizeof(*pFBDev->builtin));
+ VDisplay = pFBDev->builtin->VDisplay;
+ HDisplay = pFBDev->builtin->HDisplay;
+ pFBDev->builtin->HDisplay = VDisplay;
+ pFBDev->builtin->VDisplay = HDisplay;
+ pFBDev->builtin->name = "fake_mode";
+ first_time_rotated = FALSE;
+ }
+ return xf86DuplicateMode(pFBDev->builtin);
+ }
+ else
+ {
+ return xf86DuplicateMode(pFBDev->builtin);
+ }
+ }
+
+ /* [soolim:20100205] : gets the supported modes from framebuffer and makes the list */
+ DisplayModePtr support_modes = NULL;
+
+ if(!pFBDev->support_modes)
+ {
+ support_modes = FBDevGetSupportModes(pFBDev->builtin);
+ if(pFBDev->builtin != NULL)
+ {
+ if(!pFBDev->builtin->next)
+ {
+ support_modes->prev = pFBDev->builtin;
+ pFBDev->builtin->next = support_modes;
+ pFBDev->builtin->prev = NULL;
+ }
+ }
+ else
+ {
+ pFBDev->builtin = support_modes;
+ }
+ }
+
+ return support_modes;
+}
+
+static Bool lcd_output_set_property(xf86OutputPtr output, Atom property,
+ RRPropertyValuePtr value)
+{
+ if (_lcd_output_prop_video_offset (output, property, value))
+ return TRUE;
+
+ return TRUE;
+}
+
+static Bool lcd_output_get_property(xf86OutputPtr output, Atom property)
+{
+ return TRUE;
+}
+
+static xf86CrtcPtr lcd_output_crtc_get(xf86OutputPtr output)
+{
+ return 0;
+}
+
+static void lcd_output_destroy(xf86OutputPtr output)
+{
+ return;
+}
+
+
+/* output funcs */
+static const xf86OutputFuncsRec lcd_output_funcs =
+{
+ .create_resources = lcd_output_create_resources,
+ .destroy = lcd_output_destroy,
+ .dpms = lcd_output_dpms,
+ .save = lcd_output_save,
+ .restore = lcd_output_restore,
+ .mode_valid = lcd_output_mode_valid,
+
+ .mode_fixup = lcd_output_mode_fixup,
+ .prepare = lcd_output_prepare,
+ .mode_set = lcd_output_mode_set,
+ .commit = lcd_output_commit,
+ .detect = lcd_output_detect,
+ .get_modes = lcd_output_get_modes,
+#ifdef RANDR_12_INTERFACE
+ .set_property = lcd_output_set_property,
+#endif
+#ifdef RANDR_13_INTERFACE /* not a typo */
+ .get_property = lcd_output_get_property,
+#endif
+#ifdef RANDR_GET_CRTC_INTERFACE
+ .get_crtc = lcd_output_crtc_get,
+#endif
+};
+
+void LcdOutputInit(ScrnInfoPtr pScrn)
+{
+ xf86OutputPtr output;
+ FBDevOutputPrivPtr lcd_output;
+
+ output = xf86OutputCreate (pScrn, &lcd_output_funcs, "LVDS1");
+ if (!output)
+ return;
+ lcd_output = xnfcalloc (sizeof (FBDevOutputPriv), 1);
+ if (!lcd_output)
+ {
+ xf86OutputDestroy (output);
+ return;
+ }
+
+ output->driver_private = lcd_output;
+ output->interlaceAllowed = FALSE;
+ output->doubleScanAllowed = FALSE;
+
+}
--- /dev/null
+/**************************************************************************
+
+xserver-xorg-video-emulfb
+
+Copyright 2010 - 2011 Samsung Electronics co., Ltd. All Rights Reserved.
+
+Contact: SooChan Lim <sc1.lim@samsung.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sub license, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+#include "fbdev.h"
+#include "xace.h"
+#include "xacestr.h"
+
+#if 0
+#include <stdio.h>
+#include <string.h>
+#include <strings.h>
+
+#include <sys/types.h>
+#include <sys/fcntl.h>
+#include <unistd.h>
+#include <stdarg.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <X11/Xatom.h>
+#include <X11/extensions/XI2proto.h>
+
+#include "windowstr.h"
+
+#define XREGISTRY
+#include "registry.h"
+
+#define __USE_GNU
+#include <sys/socket.h>
+#include <linux/socket.h>
+
+#ifdef HAS_GETPEERUCRED
+# include <ucred.h>
+#endif
+#endif
+
+static void
+_traceReceive (CallbackListPtr *pcbl, pointer unused, pointer calldata)
+{
+ XaceReceiveAccessRec *rec = calldata;
+
+ if (rec->events->u.u.type != VisibilityNotify)
+ return;
+
+ rec->status = BadAccess;
+}
+
+Bool
+fbdevTraceInstallHooks (void)
+{
+ int ret = TRUE;
+
+ /*Disable Visibility Event*/
+ ret &= XaceRegisterCallback (XACE_RECEIVE_ACCESS, _traceReceive, NULL);
+
+ if (!ret)
+ {
+ ErrorF ("fbdevInstallHooks: Failed to register one or more callbacks\n");
+ return BadAlloc;
+ }
+
+ return Success;
+}
+
+
+Bool
+fbdevTraceUninstallHooks (void)
+{
+ XaceDeleteCallback (XACE_RECEIVE_ACCESS, _traceReceive, NULL);
+
+ return Success;
+}
+
--- /dev/null
+/**************************************************************************
+
+xserver-xorg-video-emulfb
+
+Copyright 2010 - 2011 Samsung Electronics co., Ltd. All Rights Reserved.
+
+Contact: SooChan Lim <sc1.lim@samsung.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sub license, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+#ifndef __HEADER_FBDEV_EVENT_TRACE
+#define __HEADER_FBDEV_EVENT_TRACE
+
+Bool fbdevTraceInstallHooks (void);
+Bool fbdevTraceUninstallHooks (void);
+
+#endif /* __HEADER_FBDEV_EVENT_TRACE */
+
--- /dev/null
+/**************************************************************************
+
+xserver-xorg-video-emulfb
+
+Copyright 2010 - 2011 Samsung Electronics co., Ltd. All Rights Reserved.
+
+Contact: SooChan Lim <sc1.lim@samsung.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sub license, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+#include "fbdev.h"
+#include "fbdev_util.h"
+#include "fbdev_fb.h"
+
+struct s3cfb_user_window
+{
+ int x;
+ int y;
+};
+
+#define S3CFB_WIN_ON _IOW('F', 305, uint)
+#define S3CFB_WIN_OFF _IOW('F', 306, uint)
+#define S3CFB_WIN_POSITION _IOW('F', 203, struct s3cfb_user_window)
+#define S3CFB_WIN_SET_PIXEL_ALPHA _IOW('F', 211, struct fb_var_screeninfo)
+
+Bool
+fbdevFbGetVarScreenInfo (int fd, struct fb_var_screeninfo *fbVarInfo)
+{
+ int ret;
+
+ return_val_if_fail (fd >= 0, FALSE);
+ return_val_if_fail (fbVarInfo != NULL, FALSE);
+
+ ret = ioctl (fd, FBIOGET_VSCREENINFO, (void*)fbVarInfo);
+
+ if (ret)
+ {
+ xf86DrvMsg (0, X_ERROR, "FBIOGET_VSCREENINFO failed.\n");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+Bool
+fbdevFbSetVarScreenInfo (int fd, struct fb_var_screeninfo *fbVarInfo)
+{
+ int ret;
+
+ return_val_if_fail (fd >= 0, FALSE);
+ return_val_if_fail (fbVarInfo != NULL, FALSE);
+
+ ret = ioctl (fd, FBIOPUT_VSCREENINFO, (void*)fbVarInfo);
+
+ if (ret)
+ {
+ xf86DrvMsg (0, X_ERROR, "FBIOPUT_VSCREENINFO failed.\n");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+Bool
+fbdevFbGetFixScreenInfo (int fd, struct fb_fix_screeninfo *fbFixInfo)
+{
+ int ret;
+
+ return_val_if_fail (fd >= 0, FALSE);
+ return_val_if_fail (fbFixInfo != NULL, FALSE);
+
+ ret = ioctl (fd, FBIOGET_FSCREENINFO, (void*)fbFixInfo);
+
+ if (ret)
+ {
+ xf86DrvMsg (0, X_ERROR, "FBIOGET_FSCREENINFO failed.\n");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+Bool
+fbdevFbSetWinPosition (int fd, int x, int y)
+{
+ struct s3cfb_user_window pos;
+ int ret;
+
+ return_val_if_fail (fd >= 0, FALSE);
+
+ pos.x = x;
+ pos.y = y;
+
+ ret = ioctl (fd, S3CFB_WIN_POSITION, &pos);
+ if (ret < 0)
+ {
+ xf86DrvMsg (0, X_ERROR, "S3CFB_WIN_POSITION failed. pos(%d,%d)\n", x, y);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+Bool
+fbdevFbScreenAlphaInit (int fd)
+{
+ struct fb_var_screeninfo var;
+ int ret;
+
+ ret = ioctl (fd, FBIOGET_VSCREENINFO, &var);
+ if (ret < 0)
+ {
+ xf86DrvMsg (0, X_ERROR, "failed to get fb_var\n");
+ return FALSE;
+ }
+
+ if (var.bits_per_pixel != 32)
+ {
+ xf86DrvMsg (0, X_ERROR, "per pixel overlay alpha is supported with 32 bpp mode\n");
+ return FALSE;
+ }
+ var.transp.length = 8;
+ var.activate = FB_ACTIVATE_FORCE;
+ ret = ioctl (fd, FBIOPUT_VSCREENINFO, &var);
+ if (ret < 0)
+ {
+ xf86DrvMsg (0, X_ERROR, "failed to set fb_var\n");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+Bool
+fbdevFbScreenAlphaDeinit (int fd)
+{
+ struct fb_var_screeninfo var;
+ int ret;
+
+ ret = ioctl (fd, FBIOGET_VSCREENINFO, &var);
+ if (ret < 0)
+ {
+ xf86DrvMsg (0, X_ERROR, "failed to get fb_var\n");
+ return FALSE;
+ }
+
+ var.transp.length = 0;
+ ret = ioctl (fd, FBIOPUT_VSCREENINFO, &var);
+ if (ret < 0)
+ {
+ xf86DrvMsg (0, X_ERROR, "failed to set fb_var\n");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+#include <sys/utsname.h>
+void
+fbdevFbResetLCDModule()
+{
+ char rmmod[255];
+ char insmod[255];
+ struct utsname name;
+
+ if (uname (&name))
+ {
+ ErrorF ("Fail get umane\n");
+ }
+ sprintf (rmmod, "/sbin/rmmod s3c_lcd");
+ sprintf (insmod, "/sbin/insmod /opt/driver/s3c_lcd.ko");
+
+ if (system (rmmod))
+ ErrorF ("%s failed.\n", rmmod);
+ if (system (insmod))
+ ErrorF ("%s failed.\n", insmod);
+}
+
+
+/* activate fb */
+Bool
+fbdevFbActivate (int fd)
+{
+ struct fb_var_screeninfo var;
+ int ret;
+
+ ret = ioctl (fd, FBIOGET_VSCREENINFO, &var);
+ if (ret < 0)
+ {
+ ErrorF ("failed to get fb_var\n");
+ return FALSE;
+ }
+
+ var.activate = FB_ACTIVATE_FORCE;
+
+ ret = ioctl (fd, FBIOPUT_VSCREENINFO, &var);
+ if (ret < 0)
+ {
+ ErrorF ("failed to set fb_var.activate\n");
+ return FALSE;
+ }
+
+ ret = ioctl (fd, FBIOBLANK, FB_BLANK_UNBLANK);
+ if (ret < 0)
+ {
+ ErrorF ("failed to set FBIOBLANK : FB_BLANK_UNBLANK\n");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/* deactivate fb3 */
+Bool
+fbdevFbDeActivate (int fd)
+{
+ int ret;
+
+ ret = ioctl (fd, FBIOBLANK, FB_BLANK_NORMAL);
+ if (ret < 0)
+ {
+ ErrorF ("failed to set FBIOBLANK : FB_BLANK_NORMAL\n");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+Bool
+fbdevFbSetBase (int fd)
+{
+ struct fb_var_screeninfo var;
+ int ret;
+
+ ret = ioctl (fd, FBIOGET_VSCREENINFO, &var);
+ if (ret < 0)
+ {
+ xf86DrvMsg (0, X_ERROR, "failed to get fb_var\n");
+ return FALSE;
+ }
+
+ var.yoffset = 0;
+ ret = ioctl (fd, FBIOPAN_DISPLAY,&var);
+ if (ret < 0)
+ {
+ xf86DrvMsg (0, X_ERROR, "failed to set fb_var\n");
+ return FALSE;
+ }
+ return TRUE;
+}
+
+
+void
+fbdevFbHWPanDisplay (int fd, int x, int y)
+{
+ struct fb_var_screeninfo var;
+ int ret;
+
+ ret = ioctl (fd, FBIOGET_VSCREENINFO, &var);
+ if (ret < 0)
+ {
+ xf86DrvMsg (0, X_WARNING, "!!WARNING::%s::fail to get vscreen_info\n",
+ __func__);
+ return;
+ }
+
+ var.xoffset = x;
+ var.yoffset = y;
+ ret = ioctl (fd, FBIOPAN_DISPLAY, &var);
+ if (ret < 0)
+ {
+ xf86DrvMsg (0, X_WARNING, "!!WARNING::%s::fail to pandisplay(xoff,%d)(yoff,%d)\n",
+ __func__,
+ var.xoffset,
+ var.yoffset);
+ return;
+ }
+}
--- /dev/null
+/**************************************************************************
+
+xserver-xorg-video-emulfb
+
+Copyright 2010 - 2011 Samsung Electronics co., Ltd. All Rights Reserved.
+
+Contact: SooChan Lim <sc1.lim@samsung.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sub license, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+#ifndef __FBDEV_FB_H__
+#define __FBDEV_FB_H__
+
+#include <linux/fb.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <X11/Xdefs.h>
+
+Bool fbdevFbGetVarScreenInfo (int fd, struct fb_var_screeninfo *fbVarInfo);
+Bool fbdevFbSetVarScreenInfo (int fd, struct fb_var_screeninfo *fbVarInfo);
+Bool fbdevFbGetFixScreenInfo (int fd, struct fb_fix_screeninfo *fbFixInfo);
+
+Bool fbdevFbSetWinPosition (int fd, int x, int y);
+
+Bool fbdevFbScreenAlphaInit (int fd);
+Bool fbdevFbScreenAlphaDeinit (int fd);
+void fbdevFbResetLCDModule (void);
+Bool fbdevFbActivate (int fd);
+Bool fbdevFbDeActivate (int fd);
+Bool fbdevFbSetBase (int fd);
+void fbdevFbHWPanDisplay (int fd, int x, int y);
+
+#endif //__FBDEV_FB_H__
\ No newline at end of file
--- /dev/null
+/*
+ * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk>
+ * Michel Dänzer, <michel@tungstengraphics.com>
+ */
+/**************************************************************************
+
+xserver-xorg-video-emulfb
+
+Copyright (C) 1994-2003 The XFree86 Project, Inc. All Rights Reserved.
+Copyright 2010 - 2011 Samsung Electronics co., Ltd. All Rights Reserved.
+
+Contact: SooChan Lim <sc1.lim@samsung.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sub license, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+/* all driver need this */
+#include "xf86.h"
+#include "xf86_OSproc.h"
+
+#include "fb.h"
+#include "mipointer.h"
+#include "mibstore.h"
+#include "micmap.h"
+#include "colormapst.h"
+#include "xf86cmap.h"
+#include "xf86xv.h"
+#include "xf86Crtc.h"
+
+#include "fbdev.h"
+#include "fbdevhw.h"
+#include "fbdev_hw.h"
+#include "fbdev_video.h"
+#include "fbdev_crtcconfig.h"
+#include "fbdev_dpms.h"
+#include "fbdev_event_trace.h"
+
+#include <string.h>
+#include <sys/ioctl.h>
+#include <linux/fb.h>
+
+#if USE_XDBG
+#include "xdbg.h"
+#endif
+
+/* prototypes */
+static const OptionInfoRec * FBDevAvailableOptions(int chipid, int busid);
+static void FBDevIdentify(int flags);
+static Bool FBDevProbe(DriverPtr drv, int flags);
+static Bool FBDevPreInit(ScrnInfoPtr pScrn, int flags);
+static Bool FBDevScreenInit(ScreenPtr pScreen, int argc, char **argv);
+static Bool FBDevEnterVT(ScrnInfoPtr pScrn);
+static void FBDevLeaveVT(ScrnInfoPtr pScrn);
+static Bool FBDevCloseScreen(ScreenPtr pScreen);
+static void FBDevSaveCurrent(ScrnInfoPtr pScrn);
+
+/* This DriverRec must be defined in the driver for Xserver to load this driver */
+_X_EXPORT DriverRec FBDEV =
+{
+ FBDEV_VERSION,
+ FBDEV_DRIVER_NAME,
+ FBDevIdentify,
+ FBDevProbe,
+ FBDevAvailableOptions,
+ NULL,
+ 0,
+ NULL,
+};
+
+/* Supported "chipsets" */
+static SymTabRec FBDevChipsets[] =
+{
+ {-1, NULL }
+};
+
+/* Supported options */
+typedef enum
+{
+ OPTION_SWCURSOR,
+ OPTION_FBDEV
+} FBDevOpts;
+
+static const OptionInfoRec FBDevOptions[] =
+{
+ { OPTION_SWCURSOR, "swcursor", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_FBDEV, "fbdev", OPTV_STRING, {0}, FALSE },
+ { -1, NULL, OPTV_NONE, {0}, FALSE }
+};
+
+/* -------------------------------------------------------------------- */
+
+
+#ifdef XFree86LOADER
+
+MODULESETUPPROTO(FBDevSetup);
+
+static XF86ModuleVersionInfo FBDevVersRec =
+{
+ "emulfb",
+ MODULEVENDORSTRING,
+ MODINFOSTRING1,
+ MODINFOSTRING2,
+ XORG_VERSION_CURRENT,
+ PACKAGE_VERSION_MAJOR,
+ PACKAGE_VERSION_MINOR,
+ PACKAGE_VERSION_PATCHLEVEL,
+ ABI_CLASS_VIDEODRV,
+ ABI_VIDEODRV_VERSION,
+ NULL,
+ {0,0,0,0}
+};
+
+_X_EXPORT XF86ModuleData emulfbModuleData = { &FBDevVersRec, FBDevSetup, NULL };
+
+pointer
+FBDevSetup(pointer module, pointer opts, int *errmaj, int *errmin)
+{
+ static Bool setupDone = FALSE;
+
+ if (!setupDone)
+ {
+ setupDone = TRUE;
+ xf86AddDriver(&FBDEV, module, HaveDriverFuncs);
+ return (pointer)1;
+ }
+ else
+ {
+ if (errmaj) *errmaj = LDR_ONCEONLY;
+ return NULL;
+ }
+}
+
+#endif /* XFree86LOADER */
+
+static Bool
+FBDevGetRec(ScrnInfoPtr pScrn)
+{
+ if (pScrn->driverPrivate != NULL)
+ return TRUE;
+
+ pScrn->driverPrivate = xnfcalloc(sizeof(FBDevRec), 1);
+ return TRUE;
+}
+
+static void
+FBDevFreeRec(ScrnInfoPtr pScrn)
+{
+ if (pScrn->driverPrivate == NULL)
+ return;
+ free(pScrn->driverPrivate);
+ pScrn->driverPrivate = NULL;
+}
+
+/* -------------------------------------------------------------------- */
+
+static const OptionInfoRec *
+FBDevAvailableOptions(int chipid, int busid)
+{
+ return FBDevOptions;
+}
+
+static void
+FBDevIdentify(int flags)
+{
+ xf86PrintChipsets(FBDEV_NAME, "driver for framebuffer", FBDevChipsets);
+}
+
+/*
+ * Probing the device with the device node, this probing depend on the specific hw.
+ * This function just verify whether the display hw is avaliable or not.
+ */
+static Bool
+FBDevHWProbe(struct pci_device * pPci, const char *device,char **namep)
+{
+ return fbdevHWProbe(pPci, (char *)device,namep);
+}
+
+/* The purpose of this function is to identify all instances of hardware supported
+ * by the driver. The probe must find the active device sections that match the driver
+ * by calling xf86MatchDevice().
+ */
+static Bool
+FBDevProbe(DriverPtr drv, int flags)
+{
+ int i;
+ ScrnInfoPtr pScrn;
+ GDevPtr *devSections;
+ int numDevSections;
+ const char *dev;
+ int entity;
+ Bool foundScreen = FALSE;
+ const char * drv_name = "fbdev";
+ const char * module_name = "fbdevhw";
+
+ /* For now, just bail out for PROBE_DETECT. */
+ if (flags & PROBE_DETECT)
+ return FALSE;
+
+ if ((numDevSections = xf86MatchDevice(FBDEV_DRIVER_NAME, &devSections)) <= 0)
+ return FALSE;
+
+ if (!xf86LoadDrvSubModule (drv, module_name))
+ return FALSE;
+
+ for (i = 0; i < numDevSections; i++)
+ {
+ dev = xf86FindOptionValue (devSections[i]->options, drv_name);
+ if (FBDevHWProbe(NULL,dev,NULL))
+ {
+ pScrn = NULL;
+ entity = xf86ClaimFbSlot(drv, 0, devSections[i], TRUE);
+ pScrn = xf86ConfigFbEntity(pScrn,0,entity, NULL,NULL,NULL,NULL);
+
+ if (pScrn)
+ {
+ foundScreen = TRUE;
+
+ pScrn->driverVersion = FBDEV_VERSION;
+ pScrn->driverName = FBDEV_DRIVER_NAME;
+ pScrn->name = FBDEV_NAME;
+ pScrn->Probe = FBDevProbe;
+ pScrn->PreInit = FBDevPreInit;
+ pScrn->ScreenInit = FBDevScreenInit;
+ pScrn->SwitchMode = fbdevHWSwitchModeWeak();
+ pScrn->AdjustFrame = fbdevHWAdjustFrameWeak();
+ pScrn->EnterVT = FBDevEnterVT;
+ pScrn->LeaveVT = FBDevLeaveVT;
+ pScrn->ValidMode = fbdevHWValidModeWeak();
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO
+ ,"using %s\n", dev ? dev : "default device");
+ }
+ }
+ }
+ free(devSections);
+
+ return foundScreen;
+}
+
+/*
+ * Return the default depth and bits per pixel.
+ * Determine the depth and the bpp supported by hw with the hw color format.
+ */
+static int
+FBDevGetDefaultDepth(ScrnInfoPtr pScrn, int *bitsPerPixel)
+{
+ int defaultDepth;
+
+ /* finding out the valid default_depth */
+ defaultDepth = fbdevHWGetDepth(pScrn,bitsPerPixel);
+
+ /* the default depth is not more than 24 */
+ defaultDepth = ((*bitsPerPixel)==32)?24:*bitsPerPixel;
+
+ return defaultDepth;
+}
+
+/*
+ * Initialize the device Probing the device with the device node,
+ * this probing depend on the specific hw.
+ * This function just verify whether the display hw is avaliable or not.
+ */
+static Bool
+FBDevHWInit(ScrnInfoPtr pScrn, struct pci_device *pPci, const char *device)
+{
+ /* open device : open the framebuffer device */
+ if (!fbdevHWInit(pScrn, NULL, (char *)device))
+ {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/*
+ * DeInitialize the hw
+ */
+static void
+FBDevHWDeInit(ScrnInfoPtr pScrn)
+{
+ /* close the fd of the fb device ??? */
+
+ return;
+}
+
+/*
+ * Check the driver option.
+ * Set the option flags to the driver private
+ */
+static void
+FBDevCheckDriverOptions(ScrnInfoPtr pScrn)
+{
+ FBDevPtr pFBDev = FBDEVPTR(pScrn);
+
+ /* sw cursor */
+ if (xf86ReturnOptValBool(pFBDev->Options, OPTION_SWCURSOR, FALSE))
+ pFBDev->bSWCursorEnbled = TRUE;
+}
+
+
+
+/*
+ * This is called before ScreenInit to probe the screen configuration.
+ * The main tasks to do in this funtion are probing, module loading, option handling,
+ * card mapping, and Crtcs setup.
+ */
+static Bool
+FBDevPreInit(ScrnInfoPtr pScrn, int flags)
+{
+ FBDevPtr pFBDev;
+ int default_depth, fbbpp;
+ const char *path;
+ Gamma defualt_gamma = {0.0, 0.0, 0.0};
+ rgb default_weight = { 0, 0, 0 };
+ int flag24;
+ const char * fb_name = "fbdev";
+
+ if (flags & PROBE_DETECT) return FALSE;
+
+ /* Check the number of entities, and fail if it isn't one. */
+ if (pScrn->numEntities != 1)
+ return FALSE;
+
+ pScrn->monitor = pScrn->confScreen->monitor;
+
+ /* allocate private */
+ FBDevGetRec(pScrn);
+ pFBDev = FBDEVPTR(pScrn);
+
+ pFBDev->pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
+
+ /* can set the path with fbdev option */
+ path = xf86FindOptionValue(pFBDev->pEnt->device->options, fb_name);
+
+ /* Init HW */
+ if(!FBDevHWInit(pScrn,NULL,path))
+ {
+ xf86DrvMsg(pScrn->scrnIndex, X_Error
+ , "fail to initialize hardware\n");
+ goto bail1;
+ }
+
+ /* finding out the valid default_depth */
+ default_depth = FBDevGetDefaultDepth(pScrn,&fbbpp);
+
+ /* set the depth and the bpp to pScrn */
+ flag24 = Support24bppFb | Support32bppFb;
+ if (!xf86SetDepthBpp(pScrn, default_depth, default_depth, fbbpp, flag24))
+ {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR
+ , "fail to find the depth\n");
+ goto bail1;
+ }
+ xf86PrintDepthBpp(pScrn); /* just print out the depth and the bpp */
+
+ /* color weight */
+ if (!xf86SetWeight(pScrn, default_weight, default_weight))
+ {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR
+ , "fail to set the color weight of RGB\n");
+ goto bail1;
+ }
+
+ /* visual init, make a TrueColor, -1 */
+ if (!xf86SetDefaultVisual(pScrn, -1))
+ {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR
+ , "fail to initialize the default visual\n");
+ goto bail1;
+ }
+
+ /* set gamma */
+ if (!xf86SetGamma(pScrn,defualt_gamma))
+ {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR
+ , "fail to set the gamma\n");
+ goto bail1;
+ }
+
+ pScrn->progClock = TRUE;
+ pScrn->rgbBits = 8;
+ pScrn->chipset = "fbdev";
+ pScrn->videoRam = fbdevHWGetVidmem(pScrn);
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO
+ , "hardware: %s (video memory: %dkB)\n"
+ , fbdevHWGetName(pScrn)
+ , pScrn->videoRam/1024);
+
+ /* Collect all the option flags (fill in pScrn->options) */
+ xf86CollectOptions(pScrn, NULL);
+
+ /*
+ * Process the options based on the information S5POptions.
+ * The results are written to pS5P->Options. If all the options
+ * processing is done within this fuction a local variable "options"
+ * can be used instead of pS5P->Options
+ */
+ if (!(pFBDev->Options = malloc(sizeof(FBDevOptions))))
+ goto bail1;
+ memcpy(pFBDev->Options, FBDevOptions, sizeof(FBDevOptions));
+ xf86ProcessOptions(pScrn->scrnIndex, pFBDev->pEnt->device->options, pFBDev->Options);
+
+ /* Check with the driver options */
+ FBDevCheckDriverOptions(pScrn);
+
+ /* Set the Crtc, the default Output, and the current Mode */
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO
+ , "checking modes against framebuffer device and creating crtc and ouput...\n");
+ if(!FBDevCrtcConfigInit(pScrn))
+ {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR
+ , "Fail to init the CrtcConfig\n");
+ goto bail1;
+ }
+ FBDevSaveCurrent(pScrn);
+
+ /* TODO::soolim:: re-confirm this condition */
+ if(pScrn->currentMode->HDisplay == pFBDev->var.xres_virtual
+ && pScrn->currentMode->VDisplay <= pFBDev->var.yres_virtual)
+ {
+ pScrn->virtualX = pFBDev->var.xres_virtual;
+ pScrn->virtualY = pFBDev->var.yres_virtual;
+ }
+ else
+ {
+ pScrn->virtualX = pScrn->currentMode->HDisplay;
+ pScrn->virtualY = pScrn->currentMode->VDisplay;
+ }
+ pScrn->displayWidth = pScrn->virtualX;
+ xf86PrintModes(pScrn); /* just print the current mode */
+
+ /* Set display resolution */
+ if(pFBDev->var.width && pFBDev->var.height)
+ {
+ pScrn->monitor->widthmm = pFBDev->var.width;
+ pScrn->monitor->heightmm = pFBDev->var.height;
+ }
+ xf86SetDpi(pScrn, 0, 0);
+
+ /* Load fb submodule */
+ if (!xf86LoadSubModule(pScrn, "fb"))
+ {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "fail to load fb module\n");
+ goto bail1;
+ }
+
+ return TRUE;
+
+bail1:
+ FBDevFreeRec(pScrn);
+ FBDevHWDeInit(pScrn);
+ return FALSE;
+}
+
+static void
+FBDevAdjustFrame(ScrnInfoPtr pScrn, int x, int y)
+{
+ fbdevHWAdjustFrame(pScrn, x, y);
+}
+
+
+/* Save the hw information */
+static void
+FBDevSave(ScrnInfoPtr pScrn)
+{
+ FBDevPtr pFBDev = FBDEVPTR(pScrn);
+
+ FBDevGetVarScreenInfo(fbdevHWGetFD(pScrn), &pFBDev->saved_var);
+}
+
+/* Restore the hw information */
+static void
+FBDevRestore(ScrnInfoPtr pScrn)
+{
+ FBDevPtr pFBDev = FBDEVPTR(pScrn);
+
+ FBDevSetVarScreenInfo(fbdevHWGetFD(pScrn), &pFBDev->saved_var);
+}
+
+/* Save the current hw information */
+static void
+FBDevSaveCurrent(ScrnInfoPtr pScrn)
+{
+ FBDevPtr pFBDev = FBDEVPTR(pScrn);
+
+ FBDevGetVarScreenInfo(fbdevHWGetFD(pScrn), &pFBDev->var);
+ FBDevGetFixScreenInfo(fbdevHWGetFD(pScrn), &pFBDev->fix);
+}
+
+static Bool
+FBDevModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ if (!fbdevHWModeInit(pScrn, mode))
+ return FALSE;
+
+ return TRUE;
+}
+
+/* Get the address of the framebuffer */
+static unsigned char *
+FBDevGetFbAddr(ScrnInfoPtr pScrn)
+{
+ FBDevPtr pFBDev = FBDEVPTR(pScrn);
+ return pFBDev->fbstart;
+}
+
+static Bool
+FBDevScreenInit(ScreenPtr pScreen, int argc, char **argv)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ FBDevPtr pFBDev = FBDEVPTR(pScrn);
+ VisualPtr visual;
+ int init_picture = 0;
+ unsigned char * pFbAddr;
+ pFBDev->rotate = RR_Rotate_0;
+ Bool rotated = (pFBDev->rotate & (RR_Rotate_90|RR_Rotate_270)) != 0;
+
+ xf86DrvMsg(pScrn->scrnIndex,X_INFO,
+ "Infomation of Visual is \n\tbitsPerPixel=%d, depth=%d, defaultVisual=%s\n"
+ "\tmask: %x,%x,%x, offset: %d,%d,%d\n",
+ pScrn->bitsPerPixel,
+ pScrn->depth,
+ xf86GetVisualName(pScrn->defaultVisual),
+ (unsigned int) pScrn->mask.red,
+ (unsigned int) pScrn->mask.green,
+ (unsigned int) pScrn->mask.blue,
+ (int)pScrn->offset.red,
+ (int)pScrn->offset.green,
+ (int)pScrn->offset.blue);
+
+ pFBDev->fbmem = fbdevHWMapVidmem(pScrn); /* mmap memory pointer */
+ if (!pFBDev->fbmem)
+ {
+ xf86DrvMsg(pScrn->scrnIndex,X_ERROR
+ ,"mapping of video memory failed\n");
+ return FALSE;
+ }
+ pFBDev->fboff = fbdevHWLinearOffset(pScrn);
+
+ /* save fb information */
+ FBDevSave(pScrn);
+
+ /* set mode and set fb info */
+ DisplayModePtr tmpMode;
+
+ if(rotated)
+ tmpMode = &pFBDev->builtin_saved;
+ else
+ tmpMode = pScrn->currentMode;
+
+ if (!FBDevModeInit(pScrn, tmpMode))
+ {
+ xf86DrvMsg(pScrn->scrnIndex,X_ERROR
+ ,"mode initialization failed\n");
+ return FALSE;
+ }
+
+ fbdevHWSaveScreen(pScreen, SCREEN_SAVER_ON);
+ FBDevAdjustFrame(pScrn,0,0);
+
+ FBDevSaveCurrent(pScrn);
+
+ /* mi layer */
+ miClearVisualTypes();
+ if (!miSetVisualTypes(pScrn->depth, TrueColorMask, pScrn->rgbBits, TrueColor))
+ {
+ xf86DrvMsg(pScrn->scrnIndex,X_ERROR
+ ,"visual type setup failed for %d bits per pixel [1]\n"
+ , pScrn->bitsPerPixel);
+ return FALSE;
+ }
+ if (!miSetPixmapDepths())
+ {
+ xf86DrvMsg(pScrn->scrnIndex,X_ERROR
+ ,"pixmap depth setup failed\n");
+ return FALSE;
+ }
+
+ /* set the starting point of the framebuffer */
+ pFBDev->fbstart = pFBDev->fbmem + pFBDev->fboff;
+
+ /* Get the screen address */
+ pFbAddr = FBDevGetFbAddr(pScrn);
+
+ switch (pScrn->bitsPerPixel)
+ {
+ case 16:
+ case 24:
+ case 32:
+ if(! fbScreenInit(pScreen, pFbAddr,
+ pScrn->virtualX, pScrn->virtualY,
+ pScrn->xDpi, pScrn->yDpi,
+ pScrn->virtualX, /*Pixel width for framebuffer*/
+ pScrn->bitsPerPixel))
+ return FALSE;
+
+ init_picture = 1;
+
+ break;
+ default:
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR
+ , "internal error: invalid number of bits per pixel (%d) encountered\n"
+ , pScrn->bitsPerPixel);
+ break;
+ }
+
+ if (pScrn->bitsPerPixel > 8)
+ {
+ /* Fixup RGB ordering */
+ visual = pScreen->visuals + pScreen->numVisuals;
+ while (--visual >= pScreen->visuals)
+ {
+ if ((visual->class | DynamicClass) == DirectColor)
+ {
+ visual->offsetRed = pScrn->offset.red;
+ visual->offsetGreen = pScrn->offset.green;
+ visual->offsetBlue = pScrn->offset.blue;
+ visual->redMask = pScrn->mask.red;
+ visual->greenMask = pScrn->mask.green;
+ visual->blueMask = pScrn->mask.blue;
+ }
+ }
+ }
+
+ /* must be after RGB ordering fixed */
+ if (init_picture && !fbPictureInit(pScreen, NULL, 0))
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING
+ , "Render extension initialisation failed\n");
+
+ /* XVideo Initiailization here */
+#ifdef XV
+ if (!fbdevVideoInit(pScreen))
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "XVideo extention initialization failed\n");
+#endif
+
+ xf86SetBlackWhitePixels(pScreen);
+ miInitializeBackingStore(pScreen);
+ xf86SetBackingStore(pScreen);
+
+ /* Check whether the SWCURSOR option is enbled */
+ if(pFBDev->bSWCursorEnbled)
+ {
+ /* use software cursor */
+ miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
+ }
+ else
+ {
+ /* use dummy hw_cursro instead of sw_cursor */
+ miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO
+ , "Initializing HW Cursor\n");
+
+ if(!xf86_cursors_init(pScreen, SEC_CURSOR_W, SEC_CURSOR_H, (HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
+ HARDWARE_CURSOR_BIT_ORDER_MSBFIRST |
+ HARDWARE_CURSOR_INVERT_MASK |
+ HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK |
+ HARDWARE_CURSOR_AND_SOURCE_WITH_MASK |
+ HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64 |
+ HARDWARE_CURSOR_ARGB)))
+ {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR
+ , "Hardware cursor initialization failed\n");
+ }
+ }
+
+ /* crtc init */
+ if (!xf86CrtcScreenInit(pScreen))
+ return FALSE;
+
+ /* set the desire mode : set the mode to xf86crtc here */
+ xf86SetDesiredModes(pScrn);
+
+ /* colormap */
+ if (!miCreateDefColormap(pScreen))
+ {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR
+ , "internal error: miCreateDefColormap failed \n");
+ return FALSE;
+ }
+
+ if(!xf86HandleColormaps(pScreen, 256, 8, fbdevHWLoadPaletteWeak(), NULL, CMAP_PALETTED_TRUECOLOR))
+ return FALSE;
+
+ xf86DPMSInit(pScreen, FBDevDPMSSet(), 0);
+ pScreen->SaveScreen = FBDevSaveScreen();
+ pFBDev->isLcdOff = FALSE;
+
+ /* Wrap the current CloseScreen function */
+ pFBDev->CloseScreen = pScreen->CloseScreen;
+ pScreen->CloseScreen = FBDevCloseScreen;
+
+ /* register the event hook */
+ fbdevTraceInstallHooks ();
+
+#if USE_XDBG
+ xDbgLogPListInit (pScreen);
+#endif
+
+ return TRUE;
+}
+
+
+static Bool
+FBDevEnterVT(ScrnInfoPtr pScrn)
+{
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO
+ , "EnterVT::Hardware state at EnterVT:\n");
+ return TRUE;
+}
+
+static void
+FBDevLeaveVT(ScrnInfoPtr pScrn)
+{
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO
+ , "LeaveVT::Hardware state at LeaveVT:\n");
+}
+
+static Bool
+FBDevCloseScreen(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ FBDevPtr pFBDev = FBDEVPTR(pScrn);
+
+ fbdevTraceUninstallHooks ();
+
+ FBDevRestore(pScrn);
+
+ fbdevHWUnmapVidmem(pScrn);
+ pScrn->vtSema = FALSE;
+
+ if(!pFBDev->bLockScreen)
+ FBDevRestore(pScrn);
+ else
+ ErrorF("Screen closed but LCD was locked\n");
+
+ FBDevHWDeInit(pScrn);
+
+ pScreen->CreateScreenResources = pFBDev->CreateScreenResources;
+ pScreen->CloseScreen = pFBDev->CloseScreen;
+
+ return (*pScreen->CloseScreen)(pScreen);
+}
+
+
+
+
--- /dev/null
+/**************************************************************************
+
+xserver-xorg-video-emulfb
+
+Copyright 2010 - 2011 Samsung Electronics co., Ltd. All Rights Reserved.
+
+Contact: SooChan Lim <sc1.lim@samsung.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sub license, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+#ifndef FBDEV_H
+#define FBDEV_H
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "fbdevhw.h"
+#include "xf86xv.h"
+#include <linux/fb.h>
+
+#define PAGE_SIZE 4096
+
+#define FBDEV_VERSION 1000 /* the version of the driver */
+#define FBDEV_NAME "FBDEV" /* the name used to prefix messages */
+#define FBDEV_DRIVER_NAME "emulfb" /* the driver name as used in config file.
+ * This name should match the name of the driver module binary
+ * In this driver, the name of the driver libary module is emulfb_drv.so.
+ */
+#define SWAPINT(i, j) \
+{ int _t = i; i = j; j = _t; }
+
+#define SEC_CURSOR_W 64
+#define SEC_CURSOR_H 64
+
+#define ADAPTOR_NUM 2
+
+#define USE_XDBG 1
+
+/* FBDev driver private data structure to hold the driver's screen-specific data */
+typedef struct {
+ unsigned char *fbstart; /* start memory point of framebuffer: (fbmem + fboff) */
+ unsigned char *fbmem; /* mmap memory pointer of framebuffer */
+ int fboff; /* fb offset */
+ int lineLength;
+ CloseScreenProcPtr CloseScreen;
+ CreateScreenResourcesProcPtr CreateScreenResources;
+ void (*PointerMoved)(int index, int x, int y);
+ EntityInfoPtr pEnt;
+
+ /* driver options */
+ OptionInfoPtr Options;
+ Bool bSWCursorEnbled; /* software cursor enabled */
+ int rotate;
+
+ /* saved video mode */
+ struct fb_var_screeninfo saved_var;
+
+ /* Current information of Framebuffer */
+ struct fb_var_screeninfo var;
+ struct fb_fix_screeninfo fix;
+
+ /* mode infos */
+ DisplayModePtr builtin;
+ DisplayModeRec builtin_saved; /* original mode to send the fake mode when the screen rotates */
+ DisplayModePtr support_modes;
+
+ /* xv */
+#ifdef XV
+ XF86VideoAdaptorPtr pAdaptor[ADAPTOR_NUM];
+ void **v4l2_owner;
+ int v4l2_num;
+ Bool bFbAlphaEnabled;
+#endif
+
+ Bool bLockScreen;
+
+ /* dpms - flag for the control of lcd onoff*/
+ Bool isLcdOff;
+
+ /* Cursor */
+ Bool enableCursor;
+} FBDevRec, *FBDevPtr;
+#define FBDEVPTR(p) ((FBDevPtr)((p)->driverPrivate))
+
+#endif //FBDEV_H
+
--- /dev/null
+/**************************************************************************
+
+xserver-xorg-video-emulfb
+
+Copyright 2010 - 2011 Samsung Electronics co., Ltd. All Rights Reserved.
+
+Contact: SooChan Lim <sc1.lim@samsung.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sub license, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+#include "fbdev.h"
+#include <linux/fb.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <errno.h>
+#include "fbdev.h"
+#include "fbdevhw.h"
+#include "fbdev_hw.h"
+#include <X11/extensions/dpmsconst.h>
+
+#include "misc.h"
+#include "fbdev_dpms.h"
+
+CallbackListPtr DPMSCallback;
+
+static void
+_dpmsCallCallback (ScrnInfoPtr pScrn, int mode, int flags)
+{
+ FBDevDPMSRec dpmsinfo;
+
+ if (!DPMSCallback)
+ return;
+
+ dpmsinfo.pScrn = pScrn;
+ dpmsinfo.mode = mode;
+ dpmsinfo.flags = flags;
+
+ CallCallbacks (&DPMSCallback, (pointer) &dpmsinfo);
+}
+
+static void
+fbdevDPMSSetFunc(ScrnInfoPtr pScrn, int mode, int flags)
+{
+ FBDevPtr pFBDev = FBDEVPTR(pScrn);
+ int call_before;
+
+ call_before = (DPMSPowerLevel == DPMSModeSuspend ||
+ DPMSPowerLevel == DPMSModeOff) ? 1 : 0;
+
+ if (call_before)
+ _dpmsCallCallback (pScrn, mode, flags);
+
+ switch(DPMSPowerLevel)
+ {
+ case DPMSModeSuspend:
+ break;
+ case DPMSModeOn:
+ case DPMSModeStandby:
+ if(pFBDev->isLcdOff == FALSE) break;
+
+ /* lcd on */
+ if (-1 == ioctl(fbdevHWGetFD(pScrn), FBIOBLANK, FB_BLANK_UNBLANK))
+ {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "FBIOBLANK: %s\n", strerror(errno));
+ }
+
+ pFBDev->isLcdOff = FALSE;
+ break;
+ case DPMSModeOff:
+ if(pFBDev->isLcdOff == TRUE) break;
+
+ /* lcd off */
+ if (-1 == ioctl(fbdevHWGetFD(pScrn), FBIOBLANK, FB_BLANK_POWERDOWN))
+ {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "FBIOBLANK: %s\n", strerror(errno));
+ }
+
+ pFBDev->isLcdOff = TRUE;
+ break;
+ default:
+ return;
+ }
+
+ if (!call_before)
+ _dpmsCallCallback (pScrn, mode, flags);
+}
+
+xf86DPMSSetProc*
+FBDevDPMSSet(void)
+{
+ return fbdevDPMSSetFunc;
+}
+
+static Bool first_savescreen = FALSE;
+
+static Bool
+fbdevSaveScreenFunc(ScreenPtr pScreen, int mode)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+
+ if(!first_savescreen)
+ {
+ first_savescreen = TRUE;
+ if (-1 == ioctl(fbdevHWGetFD(pScrn), FBIOBLANK, (void *)(0)))
+ {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "FBIOBLANK: %s\n", strerror(errno));
+ }
+ }
+
+ return TRUE;
+}
+
+
+SaveScreenProcPtr
+FBDevSaveScreen(void)
+{
+ return fbdevSaveScreenFunc;
+}
+
--- /dev/null
+/**************************************************************************
+
+xserver-xorg-video-emulfb
+
+Copyright 2010 - 2011 Samsung Electronics co., Ltd. All Rights Reserved.
+
+Contact: SooChan Lim <sc1.lim@samsung.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sub license, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+#ifndef FBDEV_DPMS_H
+#define FBDEV_DPMS_H
+
+typedef struct
+{
+ ScrnInfoPtr pScrn;
+ int mode;
+ int flags;
+} FBDevDPMSRec, *FBDevDPMSPtr;
+
+xf86DPMSSetProc* FBDevDPMSSet(void);
+SaveScreenProcPtr FBDevSaveScreen(void);
+
+#endif /* FBDEV_DPMS_H */
+
--- /dev/null
+/**************************************************************************
+
+xserver-xorg-video-emulfb
+
+Copyright 2010 - 2011 Samsung Electronics co., Ltd. All Rights Reserved.
+
+Contact: SooChan Lim <sc1.lim@samsung.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sub license, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+#include "fbdev.h"
+#include "fbdev_hw.h"
+
+void
+FBDevGetVarScreenInfo(int fd, struct fb_var_screeninfo *fbVarInfo)
+{
+ if (0 != ioctl(fd,FBIOGET_VSCREENINFO, (void*)fbVarInfo))
+ fprintf(stderr, "Error : fail to get FBIOGET_VSCREENINFO\n");
+}
+
+void
+FBDevSetVarScreenInfo(int fd, struct fb_var_screeninfo *fbVarInfo)
+{
+ if (0 != ioctl(fd,FBIOPUT_VSCREENINFO,(void*)fbVarInfo))
+ fprintf(stderr, "Error : fail to get FBIOPUT_VSCREENINFO\n");
+}
+
+void
+FBDevGetFixScreenInfo(int fd, struct fb_fix_screeninfo *fbFixInfo)
+{
+ if (0 != ioctl(fd,FBIOGET_FSCREENINFO,(void*)fbFixInfo))
+ fprintf(stderr, "Error : fail to get FBIOGET_FSCREENINFO\n");
+}
+
+Bool
+FBDevScreenAlphaInit(int fd)
+{
+ struct fb_var_screeninfo var;
+ int ret;
+
+ ret = ioctl(fd, FBIOGET_VSCREENINFO, &var);
+ if (ret < 0)
+ {
+ return FALSE;
+ }
+
+ if (var.bits_per_pixel != 32)
+ {
+ return FALSE;
+ }
+ var.transp.length = 8;
+ var.activate = FB_ACTIVATE_FORCE;
+ ret = ioctl(fd, FBIOPUT_VSCREENINFO, &var);
+ if (ret < 0)
+ {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+Bool
+FBDevScreenAlphaDeinit(int fd)
+{
+ struct fb_var_screeninfo var;
+ int ret;
+
+ ret = ioctl(fd, FBIOGET_VSCREENINFO, &var);
+ if (ret < 0)
+ {
+ return FALSE;
+ }
+
+ var.transp.length = 0;
+ ret = ioctl(fd, FBIOPUT_VSCREENINFO, &var);
+ if (ret < 0)
+ {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+#include <sys/utsname.h>
+
+/* activate fb */
+Bool
+FBDevActivateFB(int fd)
+{
+ struct fb_var_screeninfo var;
+ int ret;
+
+ ret = ioctl(fd, FBIOGET_VSCREENINFO, &var);
+ if (ret < 0)
+ {
+ ErrorF("failed to get fb_var\n");
+ return FALSE;
+ }
+
+ var.activate = FB_ACTIVATE_FORCE;
+
+ ret = ioctl (fd, FBIOPUT_VSCREENINFO, &var);
+ if (ret < 0)
+ {
+ ErrorF("failed to set fb_var.activate\n");
+ return FALSE;
+ }
+
+ ret = ioctl (fd, FBIOBLANK, FB_BLANK_UNBLANK);
+ if (ret < 0)
+ {
+ ErrorF("failed to set FBIOBLANK : FB_BLANK_UNBLANK\n");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/* deactivate fb3 */
+Bool
+FBDevDeActivateFB(int fd)
+{
+ int ret;
+
+ ret = ioctl (fd, FBIOBLANK, FB_BLANK_POWERDOWN);
+ if (ret < 0)
+ {
+ ErrorF("failed to set FBIOBLANK : FB_BLANK_POWERDOWN\n");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+Bool
+FBDevSetBaseFrameBuffer(int fd)
+{
+ struct fb_var_screeninfo var;
+ int ret;
+
+ ret = ioctl(fd, FBIOGET_VSCREENINFO, &var);
+ if (ret < 0)
+ {
+ return FALSE;
+ }
+
+ var.yoffset = 0;
+ ret = ioctl (fd, FBIOPAN_DISPLAY,&var);
+ if (ret < 0)
+ {
+ return FALSE;
+ }
+ return TRUE;
+}
+
+
+void
+FBDevHWPanDisplay(int fd, int x, int y)
+{
+ struct fb_var_screeninfo var;
+ int ret;
+
+ ret = ioctl(fd, FBIOGET_VSCREENINFO, &var);
+ if(ret < 0)
+ {
+ return;
+ }
+
+ var.xoffset = x;
+ var.yoffset = y;
+ ret = ioctl(fd, FBIOPAN_DISPLAY, &var);
+ if(ret < 0)
+ {
+ return;
+ }
+}
--- /dev/null
+/**************************************************************************
+
+xserver-xorg-video-emulfb
+
+Copyright 2010 - 2011 Samsung Electronics co., Ltd. All Rights Reserved.
+
+Contact: SooChan Lim <sc1.lim@samsung.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sub license, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+#ifndef FBDEV_HW_H
+#define FBDEV_HW_H
+
+#include <linux/fb.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+
+void FBDevGetVarScreenInfo(int fd, struct fb_var_screeninfo *fbVarInfo);
+void FBDevSetVarScreenInfo(int fd, struct fb_var_screeninfo *fbVarInfo);
+void FBDevGetFixScreenInfo(int fd, struct fb_fix_screeninfo *fbFixInfo);
+
+Bool FBDevScreenAlphaInit(int fd);
+Bool FBDevScreenAlphaDeinit(int fd);
+Bool FBDevActivateFB(int fd);
+Bool FBDevDeActivateFB(int fd);
+Bool FBDevSetBaseFrameBuffer(int fd);
+void FBDevHWPanDisplay(int fd, int x, int y);
+
+#endif //FBDEV_HW_H
+
--- /dev/null
+/**************************************************************************
+
+xserver-xorg-video-emulfb
+
+Copyright 2010 - 2011 Samsung Electronics co., Ltd. All Rights Reserved.
+
+Contact: Boram Park <boram1288.park@samsung.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sub license, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+#include "fbdev_util.h"
+#include "fbdev_pixman.h"
+
+int
+fbdev_pixman_convert_image (pixman_op_t op,
+ unsigned char *srcbuf,
+ unsigned char *dstbuf,
+ pixman_format_code_t src_format,
+ pixman_format_code_t dst_format,
+ xRectangle *img,
+ xRectangle *pxm,
+ xRectangle *src,
+ xRectangle *dst,
+ RegionPtr clip_region,
+ int rotate,
+ int hflip,
+ int vflip)
+{
+ pixman_image_t *src_img;
+ pixman_image_t *dst_img;
+ struct pixman_f_transform ft;
+ pixman_transform_t transform;
+ int src_stride, dst_stride;
+ int src_bpp;
+ int dst_bpp;
+ double scale_x, scale_y;
+ int rotate_step;
+ int ret = FALSE;
+
+ return_val_if_fail (srcbuf != NULL, FALSE);
+ return_val_if_fail (dstbuf != NULL, FALSE);
+ return_val_if_fail (img != NULL, FALSE);
+ return_val_if_fail (pxm != NULL, FALSE);
+ return_val_if_fail (src != NULL, FALSE);
+ return_val_if_fail (dst != NULL, FALSE);
+ return_val_if_fail (rotate <= 360 && rotate >= -360, FALSE);
+
+ DRVLOG ("[Convert] img(%d,%d %dx%d) src(%d,%d %dx%d) pxm(%d,%d %dx%d) dst(%d,%d %dx%d) sflip(%d,%d), r(%d)\n",
+ img->x, img->y, img->width, img->height,
+ src->x, src->y, src->width, src->height,
+ pxm->x, pxm->y, pxm->width, pxm->height,
+ dst->x, dst->y, dst->width, dst->height,
+ hflip, vflip, rotate);
+
+ src_bpp = PIXMAN_FORMAT_BPP (src_format) / 8;
+ return_val_if_fail (src_bpp > 0, FALSE);
+
+ dst_bpp = PIXMAN_FORMAT_BPP (dst_format) / 8;
+ return_val_if_fail (dst_bpp > 0, FALSE);
+
+ rotate_step = (rotate + 360) / 90 % 4;
+
+ src_stride = img->width * src_bpp;
+ dst_stride = pxm->width * dst_bpp;
+
+ src_img = pixman_image_create_bits (src_format, img->width, img->height, (uint32_t*)srcbuf, src_stride);
+ dst_img = pixman_image_create_bits (dst_format, pxm->width, pxm->height, (uint32_t*)dstbuf, dst_stride);
+
+ goto_if_fail (src_img != NULL, CANT_CONVERT);
+ goto_if_fail (dst_img != NULL, CANT_CONVERT);
+
+ pixman_f_transform_init_identity (&ft);
+
+ if (hflip)
+ {
+ pixman_f_transform_scale (&ft, NULL, -1, 1);
+ pixman_f_transform_translate (&ft, NULL, dst->width, 0);
+ }
+
+ if (vflip)
+ {
+ pixman_f_transform_scale (&ft, NULL, 1, -1);
+ pixman_f_transform_translate (&ft, NULL, 0, dst->height);
+ }
+
+ if (rotate_step > 0)
+ {
+ int c, s, tx = 0, ty = 0;
+ switch (rotate_step)
+ {
+ case 1:
+ /* 90 degrees */
+ c = 0;
+ s = -1;
+ tx = -dst->width;
+ break;
+ case 2:
+ /* 180 degrees */
+ c = -1;
+ s = 0;
+ tx = -dst->width;
+ ty = -dst->height;
+ break;
+ case 3:
+ /* 270 degrees */
+ c = 0;
+ s = 1;
+ ty = -dst->height;
+ break;
+ default:
+ /* 0 degrees */
+ c = 0;
+ s = 0;
+ break;
+ }
+
+ pixman_f_transform_translate (&ft, NULL, tx, ty);
+ pixman_f_transform_rotate (&ft, NULL, c, s);
+ }
+
+ if (rotate_step % 2 == 0)
+ {
+ scale_x = (double)src->width / dst->width;
+ scale_y = (double)src->height / dst->height;
+ }
+ else
+ {
+ scale_x = (double)src->width / dst->height;
+ scale_y = (double)src->height / dst->width;
+ }
+
+ pixman_f_transform_scale (&ft, NULL, scale_x, scale_y);
+ pixman_f_transform_translate (&ft, NULL, src->x, src->y);
+
+ pixman_transform_from_pixman_f_transform (&transform, &ft);
+ pixman_image_set_transform (src_img, &transform);
+
+ pixman_image_composite (op, src_img, NULL, dst_img,
+ 0, 0, 0, 0, dst->x, dst->y, dst->width, dst->height);
+
+ ret = TRUE;
+
+CANT_CONVERT:
+ if (src_img)
+ pixman_image_unref (src_img);
+ if (dst_img)
+ pixman_image_unref (dst_img);
+
+ return ret;
+}
\ No newline at end of file
--- /dev/null
+/**************************************************************************
+
+xserver-xorg-video-emulfb
+
+Copyright 2010 - 2011 Samsung Electronics co., Ltd. All Rights Reserved.
+
+Contact: Boram Park <boram1288.park@samsung.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sub license, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+#ifndef __FBDEV_PIXMAN_H__
+#define __FBDEV_PIXMAN_H__
+
+#include <sys/types.h>
+#include <X11/Xdefs.h>
+#include <fbdevhw.h>
+
+#include <pixman.h>
+
+#ifndef FALSE
+#define FALSE 0
+#define TRUE (!FALSE)
+#endif
+
+#ifndef NULL
+#define NULL (void*)0
+#endif
+
+int
+fbdev_pixman_convert_image (pixman_op_t op,
+ unsigned char *srcbuf,
+ unsigned char *dstbuf,
+ pixman_format_code_t src_format,
+ pixman_format_code_t dst_format,
+ xRectangle *img,
+ xRectangle *pxm,
+ xRectangle *src,
+ xRectangle *dst,
+ RegionPtr clip_region,
+ int rotate,
+ int hflip,
+ int vflip);
+
+#endif /* __FBDEV_PIXMAN_H__ */
--- /dev/null
+/**************************************************************************
+
+xserver-xorg-video-emulfb
+
+Copyright 2010 - 2011 Samsung Electronics co., Ltd. All Rights Reserved.
+
+Contact: YoungHoon Jung <yhoon.jung@samsung.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sub license, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/shm.h>
+#include <sys/ipc.h>
+
+#include "X11/XWDFile.h"
+#include "fbdev.h"
+#include "fbdev_util.h"
+
+int fbdev_util_dump_raw(const char * file, const void * data, int width, int height)
+{
+ unsigned int * blocks;
+
+ FILE * fp = fopen(file, "w+");
+ if (fp == NULL)
+ return 0;
+
+ blocks = (unsigned int *) data;
+ fwrite(blocks, 4, width*height, fp);
+
+ fclose(fp);
+
+ return 1;
+}
+
+#ifndef RR_Rotate_All
+#define RR_Rotate_All (RR_Rotate_0|RR_Rotate_90|RR_Rotate_180|RR_Rotate_270)
+#endif
+
+int fbdev_util_degree_to_rotate(int degree)
+{
+ int rotate;
+
+ switch(degree)
+ {
+ case 0:
+ rotate = RR_Rotate_0;
+ break;
+ case 90:
+ rotate = RR_Rotate_90;
+ break;
+ case 180:
+ rotate = RR_Rotate_180;
+ break;
+ case 270:
+ rotate = RR_Rotate_270;
+ break;
+ default:
+ rotate = 0; /* ERROR */
+ break;
+ }
+
+ return rotate;
+}
+
+int fbdev_util_rotate_to_degree(int rotate)
+{
+ int degree;
+
+ switch(rotate & RR_Rotate_All)
+ {
+ case RR_Rotate_0:
+ degree = 0;
+ break;
+ case RR_Rotate_90:
+ degree = 90;
+ break;
+ case RR_Rotate_180:
+ degree = 180;
+ break;
+ case RR_Rotate_270:
+ degree = 270;
+ break;
+ default:
+ degree = -1; /* ERROR */
+ break;
+ }
+
+ return degree;
+}
+
+static int
+_fbdev_util_rotate_to_int(int rot)
+{
+ switch(rot & RR_Rotate_All)
+ {
+ case RR_Rotate_0:
+ return 0;
+ case RR_Rotate_90:
+ return 1;
+ case RR_Rotate_180:
+ return 2;
+ case RR_Rotate_270:
+ return 3;
+ }
+
+ return 0;
+}
+
+int fbdev_util_rotate_add(int rot_a, int rot_b)
+{
+ int a = _fbdev_util_rotate_to_int(rot_a);
+ int b = _fbdev_util_rotate_to_int(rot_b);
+
+ return (int)((1 << ((a+b)%4))&RR_Rotate_All);
+}
+
+const PropertyPtr
+fbdev_util_get_window_property(WindowPtr pWin, const char* prop_name)
+{
+ int rc;
+ Mask prop_mode = DixReadAccess;
+ Atom property;
+ PropertyPtr pProp;
+
+ property = MakeAtom(prop_name, strlen(prop_name), FALSE);
+ if(property == None)
+ return NULL;
+
+ rc = dixLookupProperty(&pProp, pWin, property, serverClient, prop_mode);
+ if (rc == Success && pProp->data)
+ {
+ return pProp;
+ }
+
+ return NULL;
+}
+
+
+void
+fbdev_util_rotate_rect (int xres,
+ int yres,
+ int src_rot,
+ int dst_rot,
+ xRectangle *src)
+{
+ int diff;
+ xRectangle temp;
+
+ return_if_fail (src != NULL);
+
+ if (src_rot == dst_rot)
+ return;
+
+ diff = (dst_rot - src_rot);
+ if (diff < 0)
+ diff = 360 + diff;
+
+ if (src_rot % 180 && diff % 180)
+ SWAP (xres, yres);
+
+ switch (diff)
+ {
+ case 270:
+ temp.x = yres - (src->y + src->height);
+ temp.y = src->x;
+ temp.width = src->height;
+ temp.height = src->width;
+ break;
+ case 180:
+ temp.x = xres - (src->x + src->width);
+ temp.y = yres - (src->y + src->height);
+ temp.width = src->width;
+ temp.height = src->height;
+ break;
+ case 90:
+ temp.x = src->y;
+ temp.y = xres - (src->x + src->width);
+ temp.width = src->height;
+ temp.height = src->width;
+ break;
+ default:
+ temp.x = src->x;
+ temp.y = src->y;
+ temp.width = src->width;
+ temp.height = src->height;
+ break;
+ }
+
+ *src = temp;
+}
+
+void
+fbdev_util_align_rect (int src_w, int src_h, int dst_w, int dst_h, xRectangle *fit, Bool hw)
+{
+ int fit_width;
+ int fit_height;
+ float rw, rh, max;
+
+ if (!fit)
+ return;
+
+ return_if_fail (src_w > 0 && src_h > 0);
+ return_if_fail (dst_w > 0 && dst_h > 0);
+
+ rw = (float)src_w / dst_w;
+ rh = (float)src_h / dst_h;
+ max = MAX (rw, rh);
+
+ fit_width = src_w / max;
+ fit_height = src_h / max;
+
+ if (hw)
+ fit_width &= (~0x3);
+
+ fit->x = (dst_w - fit_width) / 2;
+ fit->y = (dst_h - fit_height) / 2;
+ fit->width = fit_width;
+ fit->height = fit_height;
+}
+
+static void *
+_copy_one_channel (int width, int height,
+ char *s, int s_size_w, int s_pitches,
+ char *d, int d_size_w, int d_pitches)
+{
+ unsigned char *src = (unsigned char*)s;
+ unsigned char *dst = (unsigned char*)d;
+
+ if (d_size_w == width && s_size_w == width)
+ memcpy (dst, src, s_pitches * height);
+ else
+ {
+ int i;
+
+ for (i = 0; i < height; i++)
+ {
+ memcpy (dst, src, s_pitches);
+ src += s_pitches;
+ dst += d_pitches;
+ }
+ }
+
+ return dst;
+}
+
+void*
+fbdev_util_copy_image (int width, int height,
+ char *s, int s_size_w, int s_size_h,
+ int *s_pitches, int *s_offsets, int *s_lengths,
+ char *d, int d_size_w, int d_size_h,
+ int *d_pitches, int *d_offsets, int *d_lengths,
+ int channel, int h_sampling, int v_sampling)
+{
+ int i;
+
+ for (i = 0; i < channel; i++)
+ {
+ int c_width = width;
+ int c_height = height;
+
+ if (i > 0)
+ {
+ c_width = c_width / h_sampling;
+ c_height = c_height / v_sampling;
+ }
+
+ _copy_one_channel (c_width, c_height,
+ s, s_size_w, s_pitches[i],
+ d, d_size_w, d_pitches[i]);
+
+ s = s + s_lengths[i];
+ d = d + d_lengths[i];
+ }
+
+ return d;
+}
+
+void
+drvlog (const char * f, ...)
+{
+ va_list args;
+ char temp[1024];
+
+ va_start (args, f);
+ vsnprintf (temp, sizeof (temp), f, args);
+ va_end (args);
+
+ fwrite (temp, strlen (temp), 1, stderr);
+}
--- /dev/null
+/**************************************************************************
+
+xserver-xorg-video-emulfb
+
+Copyright 2010 - 2011 Samsung Electronics co., Ltd. All Rights Reserved.
+
+Contact: YoungHoon Jung <yhoon.jung@samsung.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sub license, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+#ifndef __FBDEV_UTIL_H__
+#define __FBDEV_UTIL_H__
+
+#include "property.h"
+
+#ifndef CLEAR
+#define CLEAR(x) memset(&(x), 0, sizeof (x))
+#endif
+
+#ifndef MAX
+#define MAX(a,b) (((a) > (b)) ? (a) : (b))
+#endif
+#ifndef MIN
+#define MIN(a,b) (((a) < (b)) ? (a) : (b))
+#endif
+
+#ifndef SWAP
+#define SWAP(a, b) ({int t; t = a; a = b; b = t;})
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+void drvlog (const char * f, ...);
+
+//#define ENABLE_DEBUG 1
+
+#if ENABLE_DEBUG
+#define DRVLOG(fmt, arg...) drvlog(fmt, ##arg)
+#else
+#define DRVLOG(fmt, arg...) {;}
+#endif
+
+#define return_if_fail(cond) {if (!(cond)) { ErrorF ("%s : '%s' failed.\n", __FUNCTION__, #cond); return; }}
+#define return_val_if_fail(cond, val) {if (!(cond)) { ErrorF ("%s : '%s' failed.\n", __FUNCTION__, #cond); return val; }}
+#define goto_if_fail(cond, dst) {if (!(cond)) { ErrorF ("%s : '%s' failed.\n", __FUNCTION__, #cond); goto dst; }}
+
+int fbdev_util_degree_to_rotate(int degree);
+int fbdev_util_rotate_to_degree(int rotate);
+int fbdev_util_rotate_add(int rot_a, int rot_b);
+
+void fbdev_util_rotate_rect (int xres, int yres, int src_rot, int dst_rot, xRectangle *src);
+
+const PropertyPtr fbdev_util_get_window_property(WindowPtr pWin, const char* prop_name);
+void fbdev_util_align_rect (int src_w, int src_h, int dst_w, int dst_h, xRectangle *fit, Bool hw);
+
+void* fbdev_util_copy_image (int width, int height,
+ char *s, int s_size_w, int s_size_h,
+ int *s_pitches, int *s_offsets, int *s_lengths,
+ char *d, int d_size_w, int d_size_h,
+ int *d_pitches, int *d_offsets, int *d_lengths,
+ int channel, int h_sampling, int v_sampling);
+
+#endif /* __FBDEV_UTIL_H__ */
\ No newline at end of file
--- /dev/null
+/**************************************************************************
+
+xserver-xorg-video-emulfb
+
+Copyright 2010 - 2011 Samsung Electronics co., Ltd. All Rights Reserved.
+
+Contact: Boram Park <boram1288.park@samsung.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sub license, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <X11/extensions/Xv.h>
+#include <X11/extensions/Xvproto.h>
+
+#include "fbdev_util.h"
+#include "fbdev_video_v4l2.h"
+
+#include "fbdev.h"
+#include "fbdev_fb.h"
+#include "fbdev_util.h"
+#include "fbdev_video.h"
+#include "fbdev_video_fourcc.h"
+
+typedef struct _DeviceInfo
+{
+ char *video; /* video */
+ char *fb; /* output frame buffer */
+ int type;
+ int bOpened;
+} DeviceInfo;
+
+typedef struct _FormatInfo
+{
+ int id;
+ int type;
+ uint pixelformat;
+ FBDevV4l2Memory memory;
+} FormatInfo;
+
+typedef struct
+{
+ int index;
+
+ ScreenPtr pScreen;
+
+ int video_fd;
+
+ int fb_fd;
+ char *fb_base_phy;
+ char *fb_base_vir;
+ Bool fb_shown;
+
+ struct fb_fix_screeninfo fix;
+
+ struct
+ {
+ int init;
+ xRectangle img;
+ xRectangle crop;
+ xRectangle pxm;
+ xRectangle dst;
+ int id;
+ int hw_rotate;
+ int scn_rotate;
+ int hflip;
+ int vflip;
+ int requestbuffer;
+ int streamon;
+ int cur_idx;
+
+ void* last_buffer;
+ int queued_index;
+
+ void* backup;
+ Bool sync;
+ } status;
+
+ int size;
+ unsigned int pixfmt;
+ FBDevV4l2FimcBuffer fimcbuf;
+ FBDevV4l2SrcBuffer *src_buf;
+ FBDevV4l2Memory memory;
+
+ int initial_dequeued_buf;
+ int re_setting;
+} FBDevDispHandle;
+
+enum
+{
+ TYPE_RGB,
+ TYPE_YUV444,
+ TYPE_YUV422,
+ TYPE_YUV420,
+};
+
+static FormatInfo format_infos [] =
+{
+ { FOURCC_RGB565, TYPE_RGB, V4L2_PIX_FMT_RGB565, V4L2_MEMORY_MMAP },
+ { FOURCC_RGB32, TYPE_RGB, V4L2_PIX_FMT_RGB32, V4L2_MEMORY_MMAP },
+ { FOURCC_I420, TYPE_YUV420, V4L2_PIX_FMT_YUV420, V4L2_MEMORY_MMAP },
+ { FOURCC_S420, TYPE_YUV420, V4L2_PIX_FMT_YUV420, V4L2_MEMORY_USERPTR },
+ { FOURCC_ST12, TYPE_YUV420, V4L2_PIX_FMT_NV12T, V4L2_MEMORY_USERPTR },
+ { FOURCC_NV12, TYPE_YUV420, V4L2_PIX_FMT_NV12, V4L2_MEMORY_MMAP },
+ { FOURCC_SN12, TYPE_YUV420, V4L2_PIX_FMT_NV12, V4L2_MEMORY_USERPTR },
+ { FOURCC_YUY2, TYPE_YUV422, V4L2_PIX_FMT_YUYV, V4L2_MEMORY_MMAP },
+ { FOURCC_SUYV, TYPE_YUV422, V4L2_PIX_FMT_YUYV, V4L2_MEMORY_USERPTR },
+};
+
+static XF86ImageRec Images[] =
+{
+ XVIMAGE_YUY2,
+ XVIMAGE_SUYV,
+ XVIMAGE_I420,
+ XVIMAGE_S420,
+ XVIMAGE_ST12,
+ XVIMAGE_NV12,
+ XVIMAGE_SN12,
+ XVIMAGE_RGB32,
+ XVIMAGE_RGB565,
+};
+
+static DeviceInfo device_infos[] =
+{
+ { "/dev/video2", "/dev/fb1", OUTPUT_PATH_DMA, FALSE },
+ { "/dev/video3", "/dev/fb2", OUTPUT_PATH_DMA, FALSE },
+};
+
+#define NUM_IMAGES (sizeof(Images) / sizeof(XF86ImageRec))
+#define DEVICE_NUMS (sizeof (device_infos) / sizeof (DeviceInfo))
+
+static Bool
+_fbdevVideoV4l2SetSrc (int fd,
+ xRectangle *src_rect,
+ xRectangle *crop_rect,
+ uint pixelformat)
+{
+ struct v4l2_format format = {0,};
+ struct v4l2_crop crop = {0,};
+ int capabilities;
+
+ return_val_if_fail (fd >= 0, FALSE);
+
+ DRVLOG ("[SetSrc] src_r(%d,%d %dx%d) crop_r(%d,%d %dx%d) pixfmt(0x%08x) \n",
+ src_rect->x, src_rect->y, src_rect->width, src_rect->height,
+ crop_rect->x, crop_rect->y, crop_rect->width, crop_rect->height,
+ pixelformat);
+
+ /* check if capabilities is valid */
+ capabilities = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_OVERLAY;
+ if (!fbdev_v4l2_querycap (fd, capabilities))
+ return FALSE;
+
+ /* set format */
+ CLEAR (format);
+ format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
+ if (!fbdev_v4l2_g_fmt (fd, &format))
+ return FALSE;
+
+ format.fmt.pix.width = src_rect->width;
+ format.fmt.pix.height = src_rect->height;
+ format.fmt.pix.pixelformat = pixelformat;
+ format.fmt.pix.field = V4L2_FIELD_NONE;
+ if (!fbdev_v4l2_s_fmt (fd, &format))
+ return FALSE;
+
+ /* set crop_rect */
+ CLEAR (crop);
+ crop.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
+ crop.c.left = crop_rect->x;
+ crop.c.top = crop_rect->y;
+ crop.c.width = crop_rect->width;
+ crop.c.height = crop_rect->height;
+ if (!fbdev_v4l2_cropcap (fd, crop.type, &crop.c))
+ return FALSE;
+
+ if (!fbdev_v4l2_s_crop (fd, &crop))
+ return FALSE;
+
+ return TRUE;
+}
+
+static Bool
+_fbdevVideoV4l2SetDst (int fd,
+ xRectangle *dst_rect,
+ xRectangle *win_rect,
+ int rotation,
+ int hflip,
+ int vflip,
+ int path,
+ uint addr)
+{
+ struct v4l2_format format = {0,};
+ struct v4l2_control ctrl = {0,};
+ struct v4l2_framebuffer fbuf = {0,};
+
+ return_val_if_fail (fd >= 0, FALSE);
+
+ DRVLOG ("[SetDst] dst_r(%d,%d %dx%d) win_r(%d,%d %dx%d) rot(%d) flip(%d,%d) path(%d) addr(%p) \n",
+ dst_rect->x, dst_rect->y, dst_rect->width, dst_rect->height,
+ win_rect->x, win_rect->y, win_rect->width, win_rect->height,
+ rotation, hflip, vflip, path, (void*)addr);
+
+ /* set rotation */
+ CLEAR (ctrl);
+ ctrl.id = V4L2_CID_ROTATION;
+ ctrl.value = rotation;
+ if (!fbdev_v4l2_s_ctrl (fd, &ctrl))
+ return FALSE;
+
+ CLEAR (ctrl);
+ ctrl.id = V4L2_CID_HFLIP;
+ ctrl.value = hflip;
+ if (!fbdev_v4l2_s_ctrl (fd, &ctrl))
+ return FALSE;
+
+ CLEAR (ctrl);
+ ctrl.id = V4L2_CID_VFLIP;
+ ctrl.value = vflip;
+ if (!fbdev_v4l2_s_ctrl (fd, &ctrl))
+ return FALSE;
+
+ ctrl.id = V4L2_CID_OVLY_MODE;
+ ctrl.value = 0x4; //single buffer
+ if (!fbdev_v4l2_s_ctrl (fd, &ctrl))
+ return FALSE;
+
+ /* set framebuffer */
+ CLEAR (fbuf);
+ if (!fbdev_v4l2_g_fbuf (fd, &fbuf))
+ return FALSE;
+
+ if (path == OUTPUT_PATH_DMA)
+ fbuf.base = (void*)addr;
+
+ fbuf.fmt.width = dst_rect->width;
+ fbuf.fmt.height = dst_rect->height;
+ fbuf.fmt.pixelformat = V4L2_PIX_FMT_RGB32;
+ if (!fbdev_v4l2_s_fbuf (fd, &fbuf))
+ return FALSE;
+
+ /* set format */
+ CLEAR (format);
+ format.type = V4L2_BUF_TYPE_VIDEO_OVERLAY;
+ if (!fbdev_v4l2_g_fmt (fd, &format))
+ return FALSE;
+
+ format.fmt.win.w.left = win_rect->x;
+ format.fmt.win.w.top = win_rect->y;
+ format.fmt.win.w.width = win_rect->width;
+ format.fmt.win.w.height = win_rect->height;
+ if (!fbdev_v4l2_s_fmt (fd, &format))
+ return FALSE;
+
+ return TRUE;
+}
+
+static Bool
+_fbdevVideoV4l2SetBuffer (int fd,
+ FBDevV4l2BufType type,
+ FBDevV4l2Memory memory,
+ int num_buf,
+ FBDevV4l2SrcBuffer **mem_buf)
+{
+ struct v4l2_requestbuffers req = {0,};
+
+ return_val_if_fail (fd >= 0, FALSE);
+
+ DRVLOG ("[SetBuffer] num_buf(%d) mem_buf(%p) memory(%d)\n",
+ num_buf, mem_buf, memory);
+
+ CLEAR (req);
+ req.count = num_buf;
+ req.type = type;
+ req.memory = memory;
+ if (!fbdev_v4l2_reqbuf (fd, &req))
+ return FALSE;
+
+ if (memory == V4L2_MEMORY_MMAP)
+ {
+ FBDevV4l2SrcBuffer *out_buf;
+ int i;
+
+ return_val_if_fail (mem_buf != NULL, FALSE);
+
+ out_buf = calloc (req.count, sizeof (FBDevV4l2SrcBuffer));
+ return_val_if_fail (out_buf != NULL, FALSE);
+
+ for (i = 0; i < num_buf; i++)
+ {
+ struct v4l2_buffer buffer = {0,};
+
+ CLEAR (buffer);
+ buffer.index = i;
+ buffer.type = type;
+ buffer.memory = V4L2_MEMORY_MMAP;
+ if (!fbdev_v4l2_querybuf (fd, &buffer))
+ {
+ free (out_buf);
+ return FALSE;
+ }
+
+ out_buf[i].index = buffer.index;
+ out_buf[i].size = buffer.length;
+ out_buf[i].buf = mmap (NULL, buffer.length,
+ PROT_READ | PROT_WRITE , \
+ MAP_SHARED , fd, buffer.m.offset);
+ if (out_buf[i].buf == MAP_FAILED)
+ {
+ xf86DrvMsg (0, X_ERROR, "[SetBuffer] mmap failed. index(%d)\n", i);
+ free (out_buf);
+ return FALSE;
+ }
+ }
+
+ *mem_buf = out_buf;
+ }
+
+ return TRUE;
+}
+
+static Bool
+_fbdevVideoV4l2ClearBuffer (int fd,
+ FBDevV4l2BufType type,
+ FBDevV4l2Memory memory,
+ int num_buf,
+ FBDevV4l2SrcBuffer *mem_buf)
+{
+ struct v4l2_requestbuffers req = {0,};
+
+ return_val_if_fail (fd >= 0, FALSE);
+
+ DRVLOG ("[ClearBuffer] memory(%d) num_buf(%d) mem_buf(%p)\n",
+ num_buf, mem_buf, memory);
+
+ if (memory == V4L2_MEMORY_MMAP && mem_buf)
+ {
+ int i;
+
+ for (i = 0; i < num_buf; i++)
+ if (mem_buf[i].buf)
+ if (munmap (mem_buf[i].buf, mem_buf[i].size) == -1)
+ xf86DrvMsg (0, X_WARNING, "[ClearBuffer] Failed to unmap v4l2 buffer at index %d\n", i);
+
+ free (mem_buf);
+ }
+
+ CLEAR (req);
+ req.count = 0;
+ req.type = type;
+ req.memory = memory;
+ if (!fbdev_v4l2_reqbuf (fd, &req))
+ return FALSE;
+
+ return TRUE;
+}
+
+static Bool
+_fbdevVideoV4l2StreamOn (int fd, FBDevV4l2BufType type)
+{
+ return_val_if_fail (fd >= 0, FALSE);
+
+ DRVLOG ("[StreamOn] type(%d) \n", type);
+
+ if (!fbdev_v4l2_streamon (fd, type))
+ return FALSE;
+
+ return TRUE;
+}
+
+
+static Bool
+_fbdevVideoV4l2StreamOff (int fd, FBDevV4l2BufType type)
+{
+ return_val_if_fail (fd >= 0, FALSE);
+
+ DRVLOG ("[StreamOff] type(%d) \n", type);
+
+ if (!fbdev_v4l2_streamoff (fd, type))
+ return FALSE;
+
+ return TRUE;
+}
+
+static int
+_fbdevVideoV4l2Dequeue (int fd, FBDevV4l2BufType type, FBDevV4l2Memory memory)
+{
+ struct v4l2_buffer buf = {0,};
+
+ return_val_if_fail (fd >= 0, -1);
+
+ CLEAR (buf);
+ buf.type = type;
+ buf.memory = memory;
+
+ if (!fbdev_v4l2_dequeue (fd, &buf))
+ return FALSE;
+
+ DRVLOG ("[Dequeue] index(%d) type(%d) memory(%d)\n",
+ buf.index, type, memory);
+
+ return buf.index;
+}
+
+static int
+_fbdevVideoV4l2Queue (int fd, FBDevV4l2BufType type, FBDevV4l2Memory memory, int index, FBDevV4l2FimcBuffer *fimc_buf)
+{
+ struct v4l2_buffer buf = {0,};
+
+ return_val_if_fail (fd >= 0, -1);
+
+ CLEAR (buf);
+ buf.index = index;
+ buf.type = type;
+ buf.memory = memory;
+
+ if (memory == V4L2_MEMORY_USERPTR)
+ buf.m.userptr = (unsigned long) fimc_buf;
+
+ if (!fbdev_v4l2_queue (fd, &buf))
+ return FALSE;
+
+ DRVLOG ("[Queue] index(%d) type(%d) memory(%d)\n",
+ index, type, memory);
+
+ return index;
+}
+
+static int
+_open_device (char *device)
+{
+ int fd;
+
+ return_val_if_fail (device != NULL, -1);
+
+ fd = open (device, O_RDWR);
+ if (fd < 0)
+ {
+ xf86DrvMsg (0, X_ERROR, "Cannot open '%s'. fd(%d)\n", device, fd);
+ return -1;
+ }
+
+ DRVLOG ("'%s' opened. fd(%d) \n", device, fd);
+
+ return fd;
+}
+
+static void
+_close_device (int fd)
+{
+ int ret;
+
+ return_if_fail (fd >= 0);
+
+ ret = close (fd);
+ if (ret < 0)
+ {
+ xf86DrvMsg (0, X_ERROR, "Cannot close fd(%d)\n", fd);
+ return;
+ }
+
+ DRVLOG ("fd(%d) closed. \n", fd);
+}
+
+static Bool
+_move_resize_fb (FBDevDispHandle *hdisp, int x, int y, int width, int height)
+{
+ struct fb_var_screeninfo var;
+
+ return_val_if_fail (hdisp->fb_fd >= 0, FALSE);
+
+ DRVLOG ("[MoveResize] '%s' to (%d,%d %dx%d) \n",
+ device_infos[hdisp->index].fb, x, y, width, height);
+
+ if (!fbdevFbGetVarScreenInfo (hdisp->fb_fd, &var))
+ return FALSE;
+
+ var.xres = var.xres_virtual = width;
+ var.yres = var.yres_virtual = height;
+ var.transp.length = 0;
+ var.activate = FB_ACTIVATE_FORCE;
+ if (!fbdevFbSetVarScreenInfo (hdisp->fb_fd, &var))
+ return FALSE;
+
+ if (!fbdevFbGetFixScreenInfo (hdisp->fb_fd, &hdisp->fix))
+ return FALSE;
+
+ if (hdisp->fix.smem_len == 0)
+ return FALSE;
+
+ hdisp->fb_base_phy = (void*)hdisp->fix.smem_start; /* Physical address */
+ if (!hdisp->fb_base_phy)
+ return FALSE;
+
+ hdisp->fb_base_vir = mmap (NULL, hdisp->fix.smem_len,
+ PROT_READ | PROT_WRITE, MAP_SHARED, hdisp->fb_fd, 0);
+ if (!hdisp->fb_base_vir)
+ return FALSE;
+
+ if (!fbdevFbSetWinPosition (hdisp->fb_fd, x, y)) /* 1 : auto */
+ {
+ munmap ((void*)hdisp->fb_base_vir, hdisp->fix.smem_len);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static Bool
+_fbdevVideoV4l2EnsureStreamOff (FBDevDispHandle *hdisp)
+{
+ if (!hdisp->status.streamon)
+ return TRUE;
+
+ if (!_fbdevVideoV4l2StreamOff (hdisp->video_fd, V4L2_BUF_TYPE_VIDEO_OUTPUT))
+ return FALSE;
+
+ hdisp->status.streamon = FALSE;
+
+ return TRUE;
+}
+
+static Bool
+_fbdevVideoV4l2OpenDevice (FBDevDispHandle *hdisp, int index, int requestbuffer)
+{
+ if (device_infos[index].bOpened)
+ {
+ DRVLOG ("[OpenDevice, %p] Already opened : %s\n", hdisp, device_infos[index].video);
+ return FALSE;
+ }
+
+ hdisp->video_fd = _open_device (device_infos[index].video);
+ if (hdisp->video_fd < 0)
+ return FALSE;
+
+ if (device_infos[index].type == OUTPUT_PATH_DMA)
+ {
+ hdisp->fb_fd = _open_device (device_infos[index].fb);
+ if (hdisp->fb_fd < 0)
+ {
+ _close_device (hdisp->video_fd);
+ hdisp->video_fd = -1;
+ return FALSE;
+ }
+ }
+
+ device_infos[index].bOpened = TRUE;
+
+ return TRUE;
+}
+
+/* This function never failed.
+ * If failed, it means kernel has some problems.
+ * Then a device should be rebooted.
+ */
+static void
+_fbdevVideoV4l2CloseDevice (FBDevDispHandle *hdisp)
+{
+ if (!_fbdevVideoV4l2EnsureStreamOff (hdisp)) // We will consider this as a LCD Off case.
+ xf86DrvMsg (0, X_WARNING, "[CloseDevice, %p] Warning : Cannot stream off!! \n", hdisp);
+
+ if (hdisp->status.requestbuffer > 0)
+ {
+ if (hdisp->video_fd >= 0)
+ if (!_fbdevVideoV4l2ClearBuffer (hdisp->video_fd,
+ V4L2_BUF_TYPE_VIDEO_OUTPUT,
+ hdisp->memory,
+ hdisp->status.requestbuffer,
+ hdisp->src_buf))
+ xf86DrvMsg (0, X_WARNING, "[CloseDevice, %p] Warning : Cannot clear buffer!! \n", hdisp);
+
+ hdisp->status.requestbuffer = 0;
+ hdisp->src_buf = NULL;
+ }
+
+ if (hdisp->video_fd >= 0)
+ {
+ _close_device (hdisp->video_fd);
+ hdisp->video_fd = -1;
+ }
+
+ if (hdisp->fb_fd >= 0)
+ {
+ fbdevFbDeActivate (hdisp->fb_fd);
+ if (hdisp->fb_base_vir)
+ {
+ munmap ((void*)hdisp->fb_base_vir, hdisp->fix.smem_len);
+ hdisp->fb_base_vir = NULL;
+ }
+
+ _close_device (hdisp->fb_fd);
+ hdisp->fb_fd = -1;
+ hdisp->fb_base_phy = NULL;
+ hdisp->fb_shown = FALSE;
+ }
+
+ device_infos[hdisp->index].bOpened = FALSE;
+}
+
+int
+fbdevVideoV4l2GetHandleNums (void)
+{
+ return DEVICE_NUMS;
+}
+
+Bool
+fbdevVideoV4l2HandleOpened (int index)
+{
+ return_val_if_fail (index < DEVICE_NUMS, FALSE);
+
+ return device_infos[index].bOpened;
+}
+
+void *
+fbdevVideoV4l2OpenHandle (ScreenPtr pScreen, int index, int requestbuffer)
+{
+ FBDevDispHandle *handle;
+
+ return_val_if_fail (pScreen != NULL, NULL);
+ return_val_if_fail (index < DEVICE_NUMS, NULL);
+
+ handle = (FBDevDispHandle*)calloc (sizeof (FBDevDispHandle), 1);
+
+ return_val_if_fail (handle != NULL, NULL);
+
+ handle->pScreen = pScreen;
+ handle->index = index;
+ handle->status.hw_rotate = -1;
+ handle->status.id = 0;
+ handle->status.cur_idx = -1;
+ handle->status.init = 0;
+ handle->memory = V4L2_MEMORY_MMAP;
+ handle->initial_dequeued_buf = requestbuffer;
+ handle->video_fd = -1;
+ handle->fb_fd = -1;
+
+ if (!_fbdevVideoV4l2OpenDevice (handle, index, requestbuffer))
+ {
+ free (handle);
+ return NULL;
+ }
+
+ DRVLOG ("[OpenHandle, %p] Handle(%d) opened. \n", handle, index);
+
+ return handle;
+}
+
+void
+fbdevVideoV4l2CloseHandle (void *handle)
+{
+ FBDevDispHandle *hdisp = (FBDevDispHandle*)handle;
+
+ return_if_fail (handle != NULL);
+
+ _fbdevVideoV4l2CloseDevice ((FBDevDispHandle*)handle);
+
+ if (hdisp->status.backup)
+ {
+ free (hdisp->status.backup);
+ hdisp->status.backup = NULL;
+ }
+
+ DRVLOG ("[CloseHandle, %p] Handle(%d) closed. \n", hdisp, hdisp->index);
+
+ free (handle);
+}
+
+Bool
+fbdevVideoV4l2StreamOn (void *handle)
+{
+ FBDevDispHandle *hdisp = (FBDevDispHandle*)handle;
+ uint phy_addrs[3];
+
+ return_val_if_fail (hdisp != NULL, FALSE);
+
+ hdisp->re_setting = TRUE;
+
+ if (!_fbdevVideoV4l2OpenDevice (hdisp, hdisp->index, hdisp->status.requestbuffer))
+ return FALSE;
+
+ fbdevVideoV4l2SetFormat (handle,
+ &hdisp->status.img,
+ &hdisp->status.crop,
+ &hdisp->status.dst,
+ hdisp->status.id,
+ hdisp->status.scn_rotate,
+ hdisp->status.hw_rotate,
+ hdisp->status.hflip,
+ hdisp->status.vflip,
+ hdisp->status.requestbuffer,
+ hdisp->status.sync);
+
+ phy_addrs[0] = hdisp->fimcbuf.base[0];
+ phy_addrs[1] = hdisp->fimcbuf.base[1];
+ phy_addrs[2] = hdisp->fimcbuf.base[2];
+
+ fbdevVideoV4l2Draw (handle, hdisp->status.backup, phy_addrs);
+
+ if (hdisp->status.backup)
+ {
+ free (hdisp->status.backup);
+ hdisp->status.backup = NULL;
+ }
+
+ hdisp->re_setting = FALSE;
+
+ DRVLOG ("%s \n", __FUNCTION__);
+
+ return TRUE;
+}
+
+void
+fbdevVideoV4l2StreamOff (void *handle)
+{
+ FBDevDispHandle *hdisp = (FBDevDispHandle*)handle;
+ int requestbuffer;
+
+ return_if_fail (hdisp != NULL);
+
+ if (hdisp->memory == V4L2_MEMORY_MMAP)
+ {
+ int size;
+
+ if (hdisp->status.backup)
+ {
+ free (hdisp->status.backup);
+ hdisp->status.backup = NULL;
+ }
+
+ size = fbdevVideoQueryImageAttributes (NULL, hdisp->status.id,
+ (unsigned short*)&hdisp->status.img.width,
+ (unsigned short*)&hdisp->status.img.height,
+ NULL, NULL, NULL);
+
+ if (size > 0)
+ hdisp->status.backup = malloc (size);
+
+ if (hdisp->status.backup &&
+ hdisp->src_buf &&
+ hdisp->src_buf[hdisp->status.queued_index].buf)
+ memcpy (hdisp->status.backup,
+ hdisp->src_buf[hdisp->status.queued_index].buf,
+ size);
+ }
+
+ requestbuffer = hdisp->status.requestbuffer;
+
+ _fbdevVideoV4l2CloseDevice (hdisp);
+
+ hdisp->status.requestbuffer = requestbuffer;
+
+ DRVLOG ("%s \n", __FUNCTION__);
+}
+
+/* img->x, img->y : not used. */
+Bool
+fbdevVideoV4l2SetFormat (void *handle,
+ xRectangle *img, xRectangle *crop, xRectangle *dst,
+ uint id,
+ int scn_rotate,
+ int hw_rotate,
+ int hflip,
+ int vflip,
+ int requestbuffer,
+ Bool sync)
+{
+ FBDevDispHandle *hdisp = (FBDevDispHandle*)handle;
+ Bool src_changed = FALSE;
+ Bool dst_changed = FALSE;
+ Bool buf_changed = FALSE;
+
+ return_val_if_fail (handle != NULL, FALSE);
+ return_val_if_fail (img != NULL, FALSE);
+ return_val_if_fail (crop != NULL, FALSE);
+ return_val_if_fail (dst != NULL, FALSE);
+
+ DRVLOG ("[SetFormat, %p] try to set : img(%d,%d %dx%d) crop(%d,%d %dx%d) dst(%d,%d %dx%d) id(%x), rot(%d), flip(%d,%d) req(%d)\n", hdisp,
+ img->x, img->y, img->width, img->height,
+ crop->x, crop->y, crop->width, crop->height,
+ dst->x, dst->y, dst->width, dst->height,
+ id, hw_rotate, hflip, vflip, requestbuffer);
+
+ if (memcmp (&hdisp->status.img, img, sizeof (xRectangle)) ||
+ memcmp (&hdisp->status.crop, crop, sizeof (xRectangle)) ||
+ hdisp->status.id != id)
+ src_changed = TRUE;
+
+ if (memcmp (&hdisp->status.dst, dst, sizeof (xRectangle)) ||
+ hdisp->status.hw_rotate != hw_rotate ||
+ hdisp->status.hflip != hflip ||
+ hdisp->status.vflip != vflip)
+ dst_changed = TRUE;
+
+ if (hdisp->status.requestbuffer != requestbuffer)
+ buf_changed = TRUE;
+
+ if (hdisp->status.init && (src_changed || dst_changed || buf_changed))
+ {
+ _fbdevVideoV4l2CloseDevice (hdisp);
+ _fbdevVideoV4l2OpenDevice (hdisp, hdisp->index, requestbuffer);
+
+ DRVLOG ("[SetFormat, %p] changed : img(%d) dst(%d) buf(%d) \n", hdisp,
+ src_changed, dst_changed, buf_changed);
+
+ /* After close device, below all steps should be done. */
+ src_changed = dst_changed = buf_changed = TRUE;
+ hdisp->status.init = 0;
+ }
+
+ if (hdisp->re_setting)
+ src_changed = dst_changed = buf_changed = TRUE;
+
+ if (src_changed)
+ {
+ fbdevVideoV4l2GetFormatInfo (id, NULL, &hdisp->pixfmt, &hdisp->memory);
+
+ DRVLOG ("[SetFormat, %p] id(%c%c%c%c) => pixfmt(%d) memory(%d) \n", hdisp,
+ id & 0xFF, (id & 0xFF00) >> 8, (id & 0xFF0000) >> 16, (id & 0xFF000000) >> 24,
+ hdisp->pixfmt, hdisp->memory);
+
+ if (img->width % 16)
+ xf86DrvMsg (0, X_WARNING, "img->width(%d) is not multiple of 16!!!\n", img->width);
+
+ if (!_fbdevVideoV4l2SetSrc (hdisp->video_fd, img, crop, hdisp->pixfmt))
+ {
+ xf86DrvMsg (0, X_ERROR, "[SetFormat, %p] _fbdevVideoV4l2SetSrc is failed. \n", hdisp);
+ return FALSE;
+ }
+
+ hdisp->status.img = *img;
+ hdisp->status.crop = *crop;
+ hdisp->status.id = id;
+ hdisp->status.sync = sync;
+
+ hdisp->status.requestbuffer = 0;
+ hdisp->status.init = 1;
+ }
+
+ if (dst_changed)
+ {
+ hdisp->status.cur_idx = 0;
+ hdisp->status.hw_rotate = hw_rotate;
+ hdisp->status.scn_rotate = scn_rotate;
+ hdisp->status.hflip = hflip;
+ hdisp->status.vflip = vflip;
+ hdisp->status.dst = *dst;
+
+ if (hdisp->fb_fd >= 0)
+ {
+ xRectangle fb_rect = *dst;
+ if (!_move_resize_fb (hdisp, fb_rect.x, fb_rect.y, fb_rect.width, fb_rect.height))
+ {
+ xf86DrvMsg (0, X_ERROR, "[SetFormat, %p] _move_resize_fb is failed. \n", hdisp);
+ return FALSE;
+ }
+ }
+
+ fbdev_util_rotate_rect ((int)hdisp->pScreen->width,
+ (int)hdisp->pScreen->height,
+ 0, (hw_rotate + (360 - scn_rotate)) % 360, dst);
+ if (hdisp->fb_base_phy)
+ {
+ xRectangle win_rect = {0, 0, dst->width, dst->height};
+
+ if (!_fbdevVideoV4l2SetDst (hdisp->video_fd, dst, &win_rect, hw_rotate, hflip, vflip, OUTPUT_PATH_DMA, (uint)hdisp->fb_base_phy))
+ {
+ xf86DrvMsg (0, X_ERROR, "[SetFormat, %p] _fbdevVideoV4l2SetDst is failed. \n", hdisp);
+ return FALSE;
+ }
+ }
+ else
+ {
+ if (!_fbdevVideoV4l2SetDst (hdisp->video_fd, dst, dst, hw_rotate, hflip, vflip, OUTPUT_PATH_FIMD, 0))
+ {
+ xf86DrvMsg (0, X_ERROR, "[SetFormat, %p] _fbdevVideoV4l2SetDst is failed. \n", hdisp);
+ return FALSE;
+ }
+ }
+ }
+
+ if (buf_changed)
+ {
+ if (!_fbdevVideoV4l2SetBuffer (hdisp->video_fd,
+ V4L2_BUF_TYPE_VIDEO_OUTPUT,
+ hdisp->memory,
+ requestbuffer,
+ &hdisp->src_buf))
+ {
+ xf86DrvMsg (0, X_ERROR, "[SetFormat, %p] _fbdevVideoV4l2SetBuffer is failed. \n", hdisp);
+ return FALSE;
+ }
+
+ hdisp->status.cur_idx = 0;
+ hdisp->status.requestbuffer = requestbuffer;
+ hdisp->initial_dequeued_buf = requestbuffer;
+ }
+
+ if (!hdisp->status.streamon)
+ {
+ _fbdevVideoV4l2StreamOn (hdisp->video_fd, V4L2_BUF_TYPE_VIDEO_OUTPUT);
+ hdisp->status.streamon = TRUE;
+ }
+
+ return TRUE;
+}
+
+XF86ImagePtr
+fbdevVideoV4l2SupportImages (int *count)
+{
+ if (count)
+ *count = NUM_IMAGES;
+
+ return Images;
+}
+
+int
+fbdevVideoV4l2Draw (void *handle, uchar *buf, uint *phy_addrs)
+{
+ FBDevDispHandle *hdisp = (FBDevDispHandle*)handle;
+ int idx;
+
+ return_val_if_fail (handle != NULL, FALSE);
+// return_val_if_fail (phy_addrs != NULL, FALSE);
+
+ if (!hdisp->status.sync)
+ {
+ if (hdisp->initial_dequeued_buf > 0)
+ {
+ idx = hdisp->status.requestbuffer - hdisp->initial_dequeued_buf;
+ hdisp->initial_dequeued_buf--;
+ }
+ else
+ {
+ if ((idx = _fbdevVideoV4l2Dequeue (hdisp->video_fd, V4L2_BUF_TYPE_VIDEO_OUTPUT, hdisp->memory)) < 0)
+ {
+ xf86DrvMsg (0, X_ERROR, "[Draw, %p] _fbdevVideoV4l2Dequeue is failed. \n", hdisp);
+ return FALSE;
+ }
+ }
+ }
+ else
+ idx = hdisp->status.queued_index;
+
+ if (hdisp->memory == V4L2_MEMORY_MMAP)
+ {
+ uchar *destbuf = hdisp->src_buf[idx].buf;
+ int size;
+
+ return_val_if_fail (buf != NULL, FALSE);
+
+ hdisp->status.last_buffer = destbuf;
+
+ size = fbdevVideoQueryImageAttributes (NULL, hdisp->status.id,
+ (unsigned short*)&hdisp->status.img.width,
+ (unsigned short*)&hdisp->status.img.height,
+ NULL, NULL, NULL);
+ memcpy (destbuf, buf, size);
+ }
+
+ hdisp->fimcbuf.base[0] = phy_addrs[0];
+ hdisp->fimcbuf.base[1] = phy_addrs[1];
+ hdisp->fimcbuf.base[2] = phy_addrs[2];
+ hdisp->fimcbuf.length[0] = hdisp->status.img.width * hdisp->status.img.height;
+ hdisp->fimcbuf.length[1] = hdisp->fimcbuf.length[0] >> 1;
+ hdisp->fimcbuf.length[2] = hdisp->fimcbuf.base[1] + hdisp->fimcbuf.length[1];
+
+ if ((idx = _fbdevVideoV4l2Queue (hdisp->video_fd, V4L2_BUF_TYPE_VIDEO_OUTPUT,
+ hdisp->memory, idx, &hdisp->fimcbuf)) < 0)
+ {
+ xf86DrvMsg (0, X_ERROR, "[Draw, %p] _fbdevVideoV4l2Queue is failed. \n", hdisp);
+ return FALSE;
+ }
+
+ if (hdisp->status.sync)
+ {
+ if ((idx = _fbdevVideoV4l2Dequeue (hdisp->video_fd, V4L2_BUF_TYPE_VIDEO_OUTPUT, hdisp->memory)) < 0)
+ {
+ xf86DrvMsg (0, X_ERROR, "[Draw, %p] _fbdevVideoV4l2Dequeue is failed. \n", hdisp);
+ return FALSE;
+ }
+ }
+
+ if (hdisp->fb_fd >= 0 && !hdisp->fb_shown)
+ {
+ if (!fbdevFbActivate (hdisp->fb_fd))
+ {
+ xf86DrvMsg (0, X_ERROR, "[%s, %p] %d failed. \n", __FUNCTION__, hdisp, __LINE__);
+ return FALSE;
+ }
+
+ hdisp->fb_shown = TRUE;
+ }
+
+ hdisp->status.queued_index = idx + 1;
+ if (hdisp->status.queued_index > hdisp->status.requestbuffer - 1)
+ hdisp->status.queued_index = 0;
+
+ return TRUE;
+}
+
+Bool
+fbdevVideoV4l2GetFormatInfo (int id, int *type, uint *pixelformat, FBDevV4l2Memory *memory)
+{
+ int i;
+
+ for (i = 0; i < sizeof (format_infos) / sizeof (FormatInfo); i++)
+ if (format_infos[i].id == id)
+ {
+ if (type)
+ *type = format_infos[i].type;
+ if (pixelformat)
+ *pixelformat = format_infos[i].pixelformat;
+ if (memory)
+ *memory = format_infos[i].memory;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/* img : original src size
+ * src : real src size (cropped area inside img)
+ * dst : real dst size
+ * original dst size (in case that image is drawn on opened framebuffer)
+ */
+Bool
+fbdevVideoV4l2CheckSize (void *handle, uint pixelformat,
+ xRectangle *img, xRectangle *src, xRectangle *dst,
+ int type, int memory)
+{
+ /* img */
+ if (img)
+ {
+ if (img->width % 16)
+ xf86DrvMsg (0, X_WARNING, "img's width(%d) is not multiple of 16!!!\n", img->width);
+
+ if (type == TYPE_YUV420 && img->height % 2)
+ xf86DrvMsg (0, X_WARNING, "img's height(%d) is not multiple of 2!!!\n", img->height);
+
+ return_val_if_fail (img->width >= 16, FALSE);
+ return_val_if_fail (img->height >= 16, FALSE);
+ }
+
+ /* src */
+ if (src)
+ {
+ if (type == TYPE_YUV420 || type == TYPE_YUV422)
+ {
+ src->x = src->x & (~0x1);
+ src->width = src->width & (~0x1);
+ }
+
+ if (type == TYPE_YUV420)
+ src->height = src->height & (~0x1);
+
+ return_val_if_fail (src->width >= 16, FALSE);
+ return_val_if_fail (src->height >= 16, FALSE);
+ }
+
+ /* dst */
+ if (dst)
+ {
+ dst->width = dst->width & (~0x1);
+ dst->height = dst->height & (~0x1);
+
+ return_val_if_fail (dst->width >= 8, FALSE);
+ return_val_if_fail (dst->height >= 8, FALSE);
+ }
+
+ return TRUE;
+}
+
+void
+fbdevVideoGetFBInfo (void *handle, void **base, xRectangle *pos)
+{
+ FBDevDispHandle *hdisp = (FBDevDispHandle*)handle;
+
+ if (!hdisp)
+ return;
+
+ if (pos)
+ *pos = hdisp->status.dst;
+ if (base)
+ *base = hdisp->fb_base_vir;
+}
--- /dev/null
+/**************************************************************************
+
+xserver-xorg-video-emulfb
+
+Copyright 2010 - 2011 Samsung Electronics co., Ltd. All Rights Reserved.
+
+Contact: Boram Park <boram1288.park@samsung.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sub license, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+#include <stdio.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <errno.h>
+
+#include "xf86.h"
+
+#include "fbdev_v4l2.h"
+#include "fbdev_util.h"
+
+typedef struct _CapInfo
+{
+ int value;
+ char *name;
+} CapInfo;
+
+static CapInfo cap_infos [] =
+{
+ {V4L2_CAP_VIDEO_CAPTURE, "VIDEO_CAPTURE"},
+ {V4L2_CAP_VIDEO_OUTPUT, "VIDEO_OUTPUT"},
+ {V4L2_CAP_VIDEO_OVERLAY, "VIDEO_OVERLAY"},
+ {V4L2_CAP_VBI_CAPTURE, "VBI_CAPTURE"},
+ {V4L2_CAP_VBI_OUTPUT, "VBI_OUTPUT"},
+ {V4L2_CAP_SLICED_VBI_CAPTURE, "SLICED_VBI_CAPTURE"},
+ {V4L2_CAP_SLICED_VBI_OUTPUT, "SLICED_VBI_OUTPUT"},
+ {V4L2_CAP_RDS_CAPTURE, "RDS_CAPTURE"},
+ {V4L2_CAP_VIDEO_OUTPUT_OVERLAY, "VIDEO_OUTPUT_OVERLAY"},
+ {V4L2_CAP_HW_FREQ_SEEK, "HW_FREQ_SEEK"},
+ {V4L2_CAP_RDS_OUTPUT, "RDS_OUTPUT"},
+ {V4L2_CAP_TUNER, "TUNER"},
+ {V4L2_CAP_AUDIO, "AUDIO"},
+ {V4L2_CAP_RADIO, "RADIO"},
+ {V4L2_CAP_MODULATOR, "MODULATOR"},
+ {V4L2_CAP_READWRITE, "READWRITE"},
+ {V4L2_CAP_ASYNCIO, "ASYNCIO"},
+ {V4L2_CAP_STREAMING, "STREAMING"}
+};
+
+static Bool _fbdev_v4l2_ioctl (int fd, int cmd, void *data, char *debug)
+{
+ int retry = 0;
+ int ret;
+
+try_again:
+ ret = ioctl (fd, cmd, data);
+ if (ret < 0)
+ {
+ if (errno == EINTR || errno == EAGAIN)
+ {
+ if (retry < 100)
+ {
+ retry++;
+ goto try_again;
+ }
+ }
+
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+Bool fbdev_v4l2_querycap (int fd, int capabilities)
+{
+ struct v4l2_capability cap;
+ int ret;
+
+ CLEAR (cap);
+ ret = ioctl (fd, VIDIOC_QUERYCAP, &cap);
+ if (ret < 0)
+ {
+ xf86DrvMsg (0, X_ERROR, "[QUERYCAP] failed. (%s)\n", strerror(errno));
+ return FALSE;
+ }
+
+ if (~(cap.capabilities) & capabilities)
+ {
+ int unsupport = ~(cap.capabilities) & capabilities;
+ int i;
+
+ for (i = 0; i < sizeof (cap_infos) / sizeof (CapInfo); i++)
+ if (unsupport & cap_infos[i].value)
+ xf86DrvMsg (0, X_ERROR, "[QUERYCAP] %s not support.\n", cap_infos[i].name);
+
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+Bool fbdev_v4l2_cropcap (int fd, FBDevV4l2BufType type, struct v4l2_rect *crop)
+{
+ struct v4l2_cropcap cropcap;
+ int ret;
+
+ CLEAR(cropcap);
+ cropcap.type = type;
+ ret = ioctl (fd, VIDIOC_CROPCAP, &cropcap);
+ if (ret < 0)
+ {
+ xf86DrvMsg (0, X_ERROR, "[CROPCAP] failed. (%s)\n", strerror(errno));
+ return FALSE;
+ }
+
+ /* check if crop_rect si valid */
+ if ((crop->left < cropcap.bounds.left) &&
+ (crop->top < cropcap.bounds.top) &&
+ (crop->width > cropcap.bounds.width) &&
+ (crop->height > cropcap.bounds.height))
+ {
+ xf86DrvMsg (0, X_ERROR, "(%d,%d %dx%d) is out of bound(%d,%d %dx%d)\n",
+ crop->left, crop->top, crop->width, crop->height,
+ cropcap.bounds.left, cropcap.bounds.top,
+ cropcap.bounds.width, cropcap.bounds.height);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+Bool fbdev_v4l2_enum_std (int fd, struct v4l2_standard *std, v4l2_std_id std_id)
+{
+ std->index = 0;
+
+ while (0 == ioctl (fd, VIDIOC_ENUMSTD, std))
+ {
+ /* return TRUE if std_id found */
+ if (std->id & std_id)
+ {
+ xf86DrvMsg (0, X_ERROR, "[ENUMSTD] name(%s). (%s)\n", std->name, strerror(errno));
+ return TRUE;
+ }
+
+ std->index++;
+ }
+
+ return FALSE;
+}
+
+Bool fbdev_v4l2_enum_output (int fd, struct v4l2_output *output, FBDevV4l2BufType type)
+{
+ output->index = 0;
+
+ while (0 == ioctl (fd, VIDIOC_ENUMOUTPUT, output))
+ {
+ /* return TRUE if type found */
+ if (output->type & type)
+ {
+ xf86DrvMsg (0, X_ERROR, "[ENUMOUTPUT] index(%d) type(0x%08x) name(%s). (%s)\n",
+ output->index,output->type,output->name, strerror(errno));
+ return TRUE;
+ }
+
+ output->index++;
+ }
+
+ return FALSE;
+}
+
+Bool fbdev_v4l2_enum_fmt (int fd, struct v4l2_fmtdesc *desc, FBDevV4l2BufType type)
+{
+ desc->index = 0;
+
+ while (0 == ioctl (fd, VIDIOC_ENUM_FMT, desc))
+ {
+ /* return TRUE if type found */
+ if (desc->type & type)
+ {
+ xf86DrvMsg (0, X_ERROR, "[ENUM_FMT] index(%d) type(0x%08x) desc(%s) pxlfmt(0x%08x). (%s)\n",
+ desc->index, desc->type, desc->description, desc->pixelformat, strerror(errno));
+ return TRUE;
+ }
+
+ desc->index++;
+ }
+
+ return FALSE;
+}
+
+Bool fbdev_v4l2_g_std (int fd, v4l2_std_id *std_id)
+{
+ int ret;
+
+ ret = ioctl (fd, VIDIOC_G_STD, std_id);
+ if (ret < 0)
+ {
+ xf86DrvMsg (0, X_ERROR, "[G_STD] failed. (%s)\n", strerror(errno));
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+Bool fbdev_v4l2_s_std (int fd, v4l2_std_id std_id)
+{
+ int ret;
+
+ ret = ioctl (fd, VIDIOC_S_STD, &std_id);
+ if (ret < 0)
+ {
+ xf86DrvMsg (0, X_ERROR, "[S_STD] failed. (%s)\n", strerror(errno));
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+Bool fbdev_v4l2_g_output (int fd, int *index)
+{
+ int ret;
+
+ ret = ioctl (fd, VIDIOC_G_OUTPUT, index);
+ if (ret < 0)
+ {
+ xf86DrvMsg (0, X_ERROR, "[G_OUTPUT] failed. (%s)\n", strerror(errno));
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+Bool fbdev_v4l2_s_output (int fd, int index)
+{
+ int ret;
+
+ ret = ioctl (fd, VIDIOC_S_OUTPUT, &index);
+ if (ret < 0)
+ {
+ xf86DrvMsg (0, X_ERROR, "[S_OUTPUT] failed. (%s)\n", strerror(errno));
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+Bool fbdev_v4l2_try_fmt (int fd, struct v4l2_format *format)
+{
+ int ret;
+
+ ret = ioctl (fd, VIDIOC_TRY_FMT, format);
+ if (ret < 0)
+ return FALSE;
+
+ return TRUE;
+}
+
+Bool fbdev_v4l2_g_fmt (int fd, struct v4l2_format *format)
+{
+ int ret;
+
+ ret = ioctl (fd, VIDIOC_G_FMT, format);
+ if (ret < 0)
+ {
+ xf86DrvMsg (0, X_ERROR, "[G_FMT] failed. (%s)\n", strerror(errno));
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+Bool fbdev_v4l2_s_fmt (int fd, struct v4l2_format *format)
+{
+ int ret;
+
+ ret = ioctl (fd, VIDIOC_S_FMT, format);
+ if (ret < 0)
+ {
+ xf86DrvMsg (0, X_ERROR, "[S_FMT] failed. (%s)\n", strerror(errno));
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+Bool fbdev_v4l2_g_parm (int fd, struct v4l2_streamparm *parm)
+{
+ int ret;
+
+ ret = ioctl (fd, VIDIOC_G_PARM, parm);
+ if (ret < 0)
+ {
+ xf86DrvMsg (0, X_ERROR, "[G_PARM] failed. (%s)\n", strerror(errno));
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+Bool fbdev_v4l2_s_parm (int fd, struct v4l2_streamparm *parm)
+{
+ int ret;
+
+ ret = ioctl (fd, VIDIOC_S_PARM, parm);
+ if (ret < 0)
+ {
+ xf86DrvMsg (0, X_ERROR, "[S_PARM] failed. (%s)\n", strerror(errno));
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+Bool fbdev_v4l2_g_fbuf (int fd, struct v4l2_framebuffer *frame)
+{
+ int ret;
+
+ ret = ioctl (fd, VIDIOC_G_FBUF, frame);
+ if (ret < 0)
+ {
+ xf86DrvMsg (0, X_ERROR, "[G_FBUF] failed. (%s)\n", strerror(errno));
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+Bool fbdev_v4l2_s_fbuf (int fd, struct v4l2_framebuffer *frame)
+{
+ int ret;
+
+ ret = ioctl (fd, VIDIOC_S_FBUF, frame);
+ if (ret < 0)
+ {
+ xf86DrvMsg (0, X_ERROR, "[S_FBUF] failed. (%s)\n", strerror(errno));
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+Bool fbdev_v4l2_g_crop (int fd, struct v4l2_crop *crop)
+{
+ int ret;
+
+ ret = ioctl (fd, VIDIOC_G_CROP, crop);
+ if (ret < 0)
+ {
+ xf86DrvMsg (0, X_ERROR, "[G_CROP] failed. (%s)\n", strerror(errno));
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+Bool fbdev_v4l2_s_crop (int fd, struct v4l2_crop *crop)
+{
+ int ret;
+
+ ret = ioctl (fd, VIDIOC_S_CROP, crop);
+ if (ret < 0)
+ {
+ xf86DrvMsg (0, X_ERROR, "[S_CROP] failed. (%s)\n", strerror(errno));
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+Bool fbdev_v4l2_g_ctrl (int fd, struct v4l2_control *ctrl)
+{
+ int ret;
+
+ ret = ioctl (fd, VIDIOC_G_CTRL, ctrl);
+ if (ret < 0)
+ {
+ xf86DrvMsg (0, X_ERROR, "[G_CTRL] failed. (%s)\n", strerror(errno));
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+Bool fbdev_v4l2_s_ctrl (int fd, struct v4l2_control *ctrl)
+{
+ int ret;
+
+ ret = ioctl (fd, VIDIOC_S_CTRL, ctrl);
+ if (ret < 0)
+ {
+ xf86DrvMsg (0, X_ERROR, "[S_CTRL] failed. (%s)\n", strerror(errno));
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+Bool fbdev_v4l2_streamon (int fd, FBDevV4l2BufType type)
+{
+ if (!_fbdev_v4l2_ioctl (fd, VIDIOC_STREAMON, (void*)&type, "STREAMON"))
+ {
+ xf86DrvMsg (0, X_ERROR, "[STREAMON] failed. (%s)\n", strerror(errno));
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+Bool fbdev_v4l2_streamoff (int fd, FBDevV4l2BufType type)
+{
+ if (!_fbdev_v4l2_ioctl (fd, VIDIOC_STREAMOFF, (void*)&type, "STREAMOFF"))
+ {
+ xf86DrvMsg (0, X_ERROR, "[STREAMOFF] failed. (%s)\n", strerror(errno));
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+Bool fbdev_v4l2_start_overlay (int fd)
+{
+ int start = 1;
+
+ if (!_fbdev_v4l2_ioctl (fd, VIDIOC_OVERLAY, (void*)&start, "OVERLAY (start)"))
+ {
+ xf86DrvMsg (0, X_ERROR, "[OVERLAY] (start) failed. (%s)\n", strerror(errno));
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+Bool fbdev_v4l2_stop_overlay (int fd)
+{
+ int stop = 0;
+
+ if (!_fbdev_v4l2_ioctl (fd, VIDIOC_OVERLAY, (void*)&stop, "OVERLAY (stop)"))
+ {
+ xf86DrvMsg (0, X_ERROR, "[OVERLAY] (stop) failed. (%s)\n", strerror(errno));
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+Bool fbdev_v4l2_reqbuf (int fd, struct v4l2_requestbuffers *req)
+{
+ if (!_fbdev_v4l2_ioctl (fd, VIDIOC_REQBUFS, (void*)req, "REQBUFS"))
+ {
+ xf86DrvMsg (0, X_ERROR, "[REQBUFS] failed. (%s)\n", strerror(errno));
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+Bool fbdev_v4l2_querybuf (int fd, struct v4l2_buffer *set_buf)
+{
+ if (!_fbdev_v4l2_ioctl (fd, VIDIOC_QUERYBUF, (void*)set_buf, "QUERYBUF"))
+ {
+ xf86DrvMsg (0, X_ERROR, "[QUERYBUF] failed. (%s)\n", strerror(errno));
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+Bool fbdev_v4l2_queue (int fd, struct v4l2_buffer *buf)
+{
+ if (!_fbdev_v4l2_ioctl (fd, VIDIOC_QBUF, (void*)buf, "QBUF"))
+ {
+ xf86DrvMsg (0, X_ERROR, "[QBUF] failed. (%s)\n", strerror(errno));
+
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+Bool fbdev_v4l2_dequeue (int fd, struct v4l2_buffer *buf)
+{
+ if (!_fbdev_v4l2_ioctl (fd, VIDIOC_DQBUF, (void*)buf, "DQBUF"))
+ {
+ xf86DrvMsg (0, X_ERROR, "[DQBUF] failed. (%s)\n", strerror(errno));
+
+ return FALSE;
+ }
+
+ return TRUE;
+}
--- /dev/null
+/**************************************************************************
+
+xserver-xorg-video-emulfb
+
+Copyright 2010 - 2011 Samsung Electronics co., Ltd. All Rights Reserved.
+
+Contact: Boram Park <boram1288.park@samsung.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sub license, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+#ifndef __FBDEV_V4L2_H__
+#define __FBDEV_V4L2_H__
+
+#include "fbdev_video_types.h"
+
+
+#define V4L2_PIX_FMT_NV12T v4l2_fourcc('T', 'V', '1', '2') /* 12 Y/CbCr 4:2:0 64x32 macroblocks */
+#define V4L2_CID_ROTATION (V4L2_CID_PRIVATE_BASE + 0)
+#define V4L2_CID_PADDR_Y (V4L2_CID_PRIVATE_BASE + 1)
+#define V4L2_CID_PADDR_CB (V4L2_CID_PRIVATE_BASE + 2)
+#define V4L2_CID_PADDR_CR (V4L2_CID_PRIVATE_BASE + 3)
+#define V4L2_CID_PADDR_CBCR (V4L2_CID_PRIVATE_BASE + 4)
+#define V4L2_CID_OVERLAY_AUTO (V4L2_CID_PRIVATE_BASE + 5)
+#define V4L2_CID_OVERLAY_VADDR0 (V4L2_CID_PRIVATE_BASE + 6)
+#define V4L2_CID_OVERLAY_VADDR1 (V4L2_CID_PRIVATE_BASE + 7)
+#define V4L2_CID_OVERLAY_VADDR2 (V4L2_CID_PRIVATE_BASE + 8)
+#define V4L2_CID_OVLY_MODE (V4L2_CID_PRIVATE_BASE + 9)
+
+
+Bool fbdev_v4l2_querycap (int fd, int capabilities);
+Bool fbdev_v4l2_cropcap (int fd, FBDevV4l2BufType type, struct v4l2_rect *crop);
+
+Bool fbdev_v4l2_enum_std (int fd, struct v4l2_standard *std, v4l2_std_id std_id);
+Bool fbdev_v4l2_enum_output (int fd, struct v4l2_output *output, FBDevV4l2BufType type);
+Bool fbdev_v4l2_enum_fmt (int fd, struct v4l2_fmtdesc *desc, FBDevV4l2BufType type);
+
+Bool fbdev_v4l2_g_std (int fd, v4l2_std_id *std_id);
+Bool fbdev_v4l2_s_std (int fd, v4l2_std_id std_id);
+Bool fbdev_v4l2_g_output (int fd, int *index);
+Bool fbdev_v4l2_s_output (int fd, int index);
+Bool fbdev_v4l2_try_fmt (int fd, struct v4l2_format *format);
+Bool fbdev_v4l2_g_fmt (int fd, struct v4l2_format *format);
+Bool fbdev_v4l2_s_fmt (int fd, struct v4l2_format *format);
+Bool fbdev_v4l2_g_parm (int fd, struct v4l2_streamparm *parm);
+Bool fbdev_v4l2_s_parm (int fd, struct v4l2_streamparm *parm);
+Bool fbdev_v4l2_g_fbuf (int fd, struct v4l2_framebuffer *frame);
+Bool fbdev_v4l2_s_fbuf (int fd, struct v4l2_framebuffer *frame);
+Bool fbdev_v4l2_g_crop (int fd, struct v4l2_crop *crop);
+Bool fbdev_v4l2_s_crop (int fd, struct v4l2_crop *crop);
+Bool fbdev_v4l2_g_ctrl (int fd, struct v4l2_control *ctrl);
+Bool fbdev_v4l2_s_ctrl (int fd, struct v4l2_control *ctrl);
+
+Bool fbdev_v4l2_reqbuf (int fd, struct v4l2_requestbuffers *req);
+Bool fbdev_v4l2_querybuf (int fd, struct v4l2_buffer *set_buf);
+Bool fbdev_v4l2_queue (int fd, struct v4l2_buffer *buf);
+Bool fbdev_v4l2_dequeue (int fd, struct v4l2_buffer *buf);
+
+Bool fbdev_v4l2_streamon (int fd, FBDevV4l2BufType type);
+Bool fbdev_v4l2_streamoff (int fd, FBDevV4l2BufType type);
+Bool fbdev_v4l2_start_overlay (int fd);
+Bool fbdev_v4l2_stop_overlay (int fd);
+
+
+#endif
--- /dev/null
+/*
+ * xserver-xorg-video-emulfb
+ *
+ * Copyright 2004 Keith Packard
+ * Copyright 2005 Eric Anholt
+ * Copyright 2006 Nokia Corporation
+ * Copyright 2010 - 2011 Samsung Electronics co., Ltd. All Rights Reserved.
+ *
+ * Contact: Boram Park <boram1288.park@samsung.com>
+ *
+ * Permission to use, copy, modify, distribute and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the names of the authors and/or copyright holders
+ * not be used in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission. The authors and
+ * copyright holders make no representations about the suitability of this
+ * software for any purpose. It is provided "as is" without any express
+ * or implied warranty.
+ *
+ * THE AUTHORS AND COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO
+ * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+ * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/time.h>
+#include <sys/ioctl.h>
+
+#include <pixman.h>
+#include <X11/Xatom.h>
+#include <X11/extensions/Xv.h>
+#include <X11/extensions/Xvproto.h>
+#include <X11/extensions/dpmsconst.h>
+#include "fourcc.h"
+
+#include "fb.h"
+#include "fbdevhw.h"
+#include "damage.h"
+
+#include "xf86xv.h"
+
+#include "fbdev.h"
+
+#include "fbdev_dpms.h"
+#include "fbdev_video.h"
+#include "fbdev_util.h"
+#include "fbdev_util.h"
+#include "fbdev_pixman.h"
+#include "fbdev_fb.h"
+#include "fbdev_video_fourcc.h"
+#include "fbdev_video_v4l2.h"
+#include "fbdev_video_virtual.h"
+
+#include "xv_types.h"
+
+extern CallbackListPtr DPMSCallback;
+
+static XF86VideoEncodingRec DummyEncoding[] =
+{
+ { 0, "XV_IMAGE", -1, -1, { 1, 1 } },
+ { 1, "XV_IMAGE", 2560, 2560, { 1, 1 } },
+};
+
+static XF86VideoFormatRec Formats[] =
+{
+ { 16, TrueColor },
+ { 24, TrueColor },
+ { 32, TrueColor },
+};
+
+static XF86AttributeRec Attributes[] =
+{
+ { 0, -1, 270, "_USER_WM_PORT_ATTRIBUTE_ROTATION" },
+ { 0, 0, 1, "_USER_WM_PORT_ATTRIBUTE_HFLIP" },
+ { 0, 0, 1, "_USER_WM_PORT_ATTRIBUTE_VFLIP" },
+ { 0, -1, 1, "_USER_WM_PORT_ATTRIBUTE_PREEMPTION" },
+ { 0, 0, 1, "_USER_WM_PORT_ATTRIBUTE_DRAWING_MODE" },
+ { 0, 0, 1, "_USER_WM_PORT_ATTRIBUTE_STREAM_OFF" },
+};
+
+typedef enum
+{
+ PAA_MIN,
+ PAA_ROTATION,
+ PAA_HFLIP,
+ PAA_VFLIP,
+ PAA_PREEMPTION,
+ PAA_DRAWINGMODE,
+ PAA_STREAMOFF,
+ PAA_MAX
+} FBDevPortAttrAtom;
+
+enum
+{
+ ON_NONE,
+ ON_FB,
+ ON_WINDOW,
+ ON_PIXMAP
+};
+
+static struct
+{
+ FBDevPortAttrAtom paa;
+ const char *name;
+ Atom atom;
+} atom_list[] =
+{
+ { PAA_ROTATION, "_USER_WM_PORT_ATTRIBUTE_ROTATION", None },
+ { PAA_HFLIP, "_USER_WM_PORT_ATTRIBUTE_HFLIP", None },
+ { PAA_VFLIP, "_USER_WM_PORT_ATTRIBUTE_VFLIP", None },
+ { PAA_PREEMPTION, "_USER_WM_PORT_ATTRIBUTE_PREEMPTION", None },
+ { PAA_DRAWINGMODE, "_USER_WM_PORT_ATTRIBUTE_DRAWING_MODE", None },
+ { PAA_STREAMOFF, "_USER_WM_PORT_ATTRIBUTE_STREAM_OFF", None },
+};
+
+static int registered_handler;
+extern CallbackListPtr DPMSCallback;
+
+#define FBDEV_MAX_PORT 16
+#define REQ_BUF_NUM 3
+
+#define NUM_FORMATS (sizeof(Formats) / sizeof(Formats[0]))
+#define NUM_ATTRIBUTES (sizeof(Attributes) / sizeof(Attributes[0]))
+#define NUM_ATOMS (sizeof(atom_list) / sizeof(atom_list[0]))
+
+static PixmapPtr
+_fbdevVideoGetPixmap (DrawablePtr pDraw)
+{
+ if (pDraw->type == DRAWABLE_WINDOW)
+ return pDraw->pScreen->GetWindowPixmap ((WindowPtr) pDraw);
+ else
+ return (PixmapPtr) pDraw;
+}
+
+static void
+_fbdevVideoGetRotation (ScreenPtr pScreen,
+ FBDevPortPrivPtr pPortPriv,
+ DrawablePtr pDraw,
+ int *scn_rotate,
+ int *rotate,
+ int *hw_rotate)
+{
+ ScrnInfoPtr pScrnInfo = xf86Screens[pScreen->myNum];
+ FBDevPtr pFBDev = FBDEVPTR (pScrnInfo);
+
+ *scn_rotate = 0;
+ *rotate = 0;
+ *hw_rotate = 0;
+
+#ifdef RANDR
+ switch (pFBDev->rotate)
+ {
+ case RR_Rotate_90:
+ *scn_rotate = 270;
+ break;
+ case RR_Rotate_180:
+ *scn_rotate = 180;
+ break;
+ case RR_Rotate_270:
+ *scn_rotate = 90;
+ break;
+ case RR_Rotate_0:
+ break;
+ }
+#endif
+
+ if (pPortPriv->rotate >= 0)
+ *rotate = pPortPriv->rotate;
+
+ *hw_rotate = (*rotate + *scn_rotate + 360) % 360;
+}
+
+static void
+_fbdevVideoCloseV4l2Handle (ScrnInfoPtr pScrnInfo, FBDevPortPrivPtr pPortPriv)
+{
+ FBDevPtr pFBDev = (FBDevPtr) pScrnInfo->driverPrivate;
+
+ if (pPortPriv->aligned_buffer)
+ {
+ free (pPortPriv->aligned_buffer);
+ pPortPriv->aligned_buffer = NULL;
+ pPortPriv->buffer_size = 0;
+ pPortPriv->aligned_width = 0;
+ }
+
+ if (!pPortPriv->v4l2_handle)
+ return;
+
+ fbdevVideoV4l2CloseHandle (pPortPriv->v4l2_handle);
+
+ pFBDev->v4l2_owner[pPortPriv->v4l2_index] = NULL;
+
+ pPortPriv->v4l2_handle = NULL;
+ pPortPriv->v4l2_index = -1;
+}
+
+static Atom
+_fbdevVideoGetPortAtom (FBDevPortAttrAtom paa)
+{
+ int i;
+
+ return_val_if_fail (paa > PAA_MIN && paa < PAA_MAX, None);
+
+ for (i = 0; i < NUM_ATOMS; i++)
+ {
+ if (paa == atom_list[i].paa)
+ {
+ if (atom_list[i].atom == None)
+ atom_list[i].atom = MakeAtom (atom_list[i].name, strlen (atom_list[i].name), TRUE);
+
+ return atom_list[i].atom;
+ }
+ }
+
+ ErrorF ("Error: Unknown Port Attribute Name!\n");
+
+ return None;
+}
+
+static int
+_fbdevVideoInterfbdevtXRects (xRectangle *dest, xRectangle *src1, xRectangle *src2)
+{
+ int dest_x, dest_y;
+ int dest_x2, dest_y2;
+ int return_val;
+
+ return_val_if_fail (src1 != NULL, FALSE);
+ return_val_if_fail (src2 != NULL, FALSE);
+
+ return_val = FALSE;
+
+ dest_x = MAX (src1->x, src2->x);
+ dest_y = MAX (src1->y, src2->y);
+ dest_x2 = MIN (src1->x + src1->width, src2->x + src2->width);
+ dest_y2 = MIN (src1->y + src1->height, src2->y + src2->height);
+
+ if (dest_x2 > dest_x && dest_y2 > dest_y)
+ {
+ if (dest)
+ {
+ dest->x = dest_x;
+ dest->y = dest_y;
+ dest->width = dest_x2 - dest_x;
+ dest->height = dest_y2 - dest_y;
+ }
+ return_val = TRUE;
+ }
+ else if (dest)
+ {
+ dest->width = 0;
+ dest->height = 0;
+ }
+
+ return return_val;
+}
+
+static int
+_fbdevVideodrawingOn (FBDevPortPrivPtr pPortPriv, DrawablePtr pDraw)
+{
+ if (pDraw->type == DRAWABLE_PIXMAP)
+ return ON_PIXMAP;
+ else if (pDraw->type == DRAWABLE_WINDOW)
+ {
+ PropertyPtr prop = fbdev_util_get_window_property ((WindowPtr)pDraw,
+ "XV_ON_DRAWABLE");
+ if (prop && *(int*)prop->data > 0)
+ return ON_WINDOW;
+ }
+
+ return ON_FB;
+}
+
+static int
+_fbdevVideoParseFormatBuffer (uchar *buf, uint *phy_addrs)
+{
+ XV_PUTIMAGE_DATA_PTR data = (XV_PUTIMAGE_DATA_PTR) buf;
+
+ int valid = XV_PUTIMAGE_VALIDATE_DATA (data);
+ if (valid < 0)
+ return valid;
+
+ phy_addrs[0] = data->YPhyAddr;
+ phy_addrs[1] = data->CbPhyAddr;
+ phy_addrs[2] = data->CrPhyAddr;
+
+ return 0;
+}
+
+static XF86ImageRec *
+_fbdevVideoGetImageInfo (int id)
+{
+ XF86ImagePtr pImages;
+ int i, count = 0;
+
+ pImages = fbdevVideoV4l2SupportImages (&count);
+
+ for (i = 0; i < count; i++)
+ {
+ if (pImages[i].id == id)
+ return &pImages[i];
+ }
+
+ return NULL;
+};
+
+static Bool
+_fbdevVideoSetMode (ScrnInfoPtr pScrnInfo, FBDevPortPrivPtr pPortPriv, int *index)
+{
+ FBDevPtr pFBDev = (FBDevPtr) pScrnInfo->driverPrivate;
+ Bool full = TRUE;
+ int i = 0;
+
+ *index = -1;
+
+ if (pPortPriv->preemption == -1)
+ {
+ pPortPriv->mode = PORT_MODE_WAITING;
+ return TRUE;
+ }
+
+ for (i = 0; i < pFBDev->v4l2_num; i++)
+ if (!fbdevVideoV4l2HandleOpened (i))
+ {
+ full = FALSE;
+ break;
+ }
+
+ if (!full)
+ {
+ *index = i;
+ pPortPriv->mode = PORT_MODE_V4L2;
+ return TRUE;
+ }
+
+ /* All handles are occupied. So we need to steal one of them. */
+
+ if (pPortPriv->preemption == 0)
+ {
+ pPortPriv->mode = PORT_MODE_WAITING;
+ return TRUE;
+ }
+
+ for (i = 0; i < pFBDev->v4l2_num; i++)
+ {
+ FBDevPortPrivPtr pOwnerPort = (FBDevPortPrivPtr) pFBDev->v4l2_owner[i];
+
+ if (pOwnerPort && pOwnerPort->preemption == 0)
+ {
+ _fbdevVideoCloseV4l2Handle (pScrnInfo, pOwnerPort);
+
+ pOwnerPort->mode = PORT_MODE_WAITING;
+ pPortPriv->mode = PORT_MODE_V4L2;
+ *index = i;
+ return TRUE;
+ }
+ }
+
+ xf86DrvMsg (0, X_ERROR, "fbdev/put_image: Three or more preemptive ports were requested\n");
+
+ return FALSE;
+}
+
+static int
+_fbdevVideoPutImageV4l2 (ScrnInfoPtr pScrnInfo,
+ FBDevPortPrivPtr pPortPriv,
+ xRectangle *img,
+ xRectangle *src,
+ xRectangle *dst,
+ RegionPtr clip_boxes,
+ int scn_rotate,
+ int rotate,
+ int hw_rotate,
+ XF86ImageRec *image_info,
+ uchar *buf,
+ FBDevPortMode modeBefore,
+ int v4l2_index,
+ DrawablePtr pDraw)
+{
+ FBDevPtr pFBDev = (FBDevPtr) pScrnInfo->driverPrivate;
+ uint phy_addrs[4] = {0,};
+ FBDevV4l2Memory memory;
+ uint pixelformat;
+ int fmt_type = 0;
+
+ if (!fbdevVideoV4l2GetFormatInfo (image_info->id, &fmt_type, &pixelformat, &memory))
+ {
+ xf86DrvMsg (0, X_ERROR, "ID(%c%c%c%c) is not in 'format_infos'.\n",
+ image_info->id & 0xFF, (image_info->id & 0xFF00) >> 8,
+ (image_info->id & 0xFF0000) >> 16, (image_info->id & 0xFF000000) >> 24);
+ return BadRequest;
+ }
+
+ if (memory == V4L2_MEMORY_USERPTR)
+ {
+ int ret;
+ if ((ret = _fbdevVideoParseFormatBuffer (buf, phy_addrs)) < 0)
+ {
+ if (ret == XV_HEADER_ERROR)
+ xf86DrvMsg (0, X_ERROR, "XV_HEADER_ERROR\n");
+ else if (ret == XV_VERSION_MISMATCH)
+ xf86DrvMsg (0, X_ERROR, "XV_VERSION_MISMATCH\n");
+
+ return BadRequest;
+ }
+
+ /* Skip frame */
+ if (phy_addrs[0] == 0)
+ return Success;
+ }
+
+ if (!pPortPriv->v4l2_handle)
+ {
+ pPortPriv->v4l2_handle = fbdevVideoV4l2OpenHandle (pScrnInfo->pScreen, v4l2_index, REQ_BUF_NUM);
+ if (!pPortPriv->v4l2_handle)
+ {
+ int other_index = (v4l2_index == 0) ? 1 : 0;
+ if (fbdevVideoV4l2HandleOpened (other_index))
+ {
+ xf86DrvMsg (0, X_ERROR, "fbdevVideoV4l2OpenHandle failed. no empty.\n");
+ return BadRequest;
+ }
+ else
+ {
+ pPortPriv->v4l2_handle = fbdevVideoV4l2OpenHandle (pScrnInfo->pScreen, other_index, REQ_BUF_NUM);
+ if (!pPortPriv->v4l2_handle)
+ {
+ xf86DrvMsg (0, X_ERROR, "fbdevVideoV4l2OpenHandle failed. fail open.\n");
+ return BadRequest;
+ }
+ }
+
+ v4l2_index = other_index;
+ }
+
+ pFBDev->v4l2_owner[v4l2_index] = (void*)pPortPriv;
+ pPortPriv->v4l2_index = v4l2_index;
+ }
+
+ if (!fbdevVideoV4l2CheckSize (pPortPriv->v4l2_handle, pixelformat, img, src, dst, fmt_type, V4L2_MEMORY_MMAP))
+ return BadRequest;
+
+ if (fbdevVideoV4l2SetFormat (pPortPriv->v4l2_handle, img, src, dst,
+ image_info->id, scn_rotate, hw_rotate,
+ pPortPriv->hflip, pPortPriv->vflip,
+ REQ_BUF_NUM, FALSE))
+ {
+ fbdevVideoV4l2Draw (pPortPriv->v4l2_handle, buf, phy_addrs);
+
+ if (modeBefore == PORT_MODE_WAITING)
+ pScrnInfo->pScreen->WindowExposures ((WindowPtr) pDraw, clip_boxes, NULL);
+
+#if ENABLE_ARM
+ /* update cliplist */
+ if (!REGION_EQUAL (pScrnInfo->pScreen, &pPortPriv->clip, clip_boxes))
+ {
+ /* setting transparency length to 8 */
+ if (!pFBDev->bFbAlphaEnabled)
+ {
+ fbdevFbScreenAlphaInit (fbdevHWGetFD (pScrnInfo));
+ pFBDev->bFbAlphaEnabled = TRUE;
+ }
+ }
+#endif
+
+ return Success;
+ }
+
+ _fbdevVideoCloseV4l2Handle (pScrnInfo, pPortPriv);
+
+ pPortPriv->mode = PORT_MODE_WAITING;
+
+ return Success;
+}
+
+static int
+_fbdevVideoPutImageOnDrawable (ScrnInfoPtr pScrnInfo,
+ FBDevPortPrivPtr pPortPriv,
+ xRectangle *img,
+ xRectangle *src,
+ xRectangle *dst,
+ RegionPtr clip_boxes,
+ int scn_rotate,
+ int rotate,
+ XF86ImageRec *image_info,
+ uchar *buf,
+ DrawablePtr pDraw)
+{
+ pixman_format_code_t src_format, dst_format;
+ xRectangle pxm = {0,};
+
+ PixmapPtr pPixmap = _fbdevVideoGetPixmap (pDraw);
+
+ pxm.width = pPixmap->drawable.width;
+ pxm.height = pPixmap->drawable.height;
+
+ switch (image_info->id)
+ {
+ case FOURCC_I420:
+ case FOURCC_YV12:
+ src_format = PIXMAN_yv12;
+ break;
+ case FOURCC_YUY2:
+ src_format = PIXMAN_yuy2;
+ break;
+ case FOURCC_RGB565:
+ src_format = PIXMAN_r5g6b5;
+ break;
+ case FOURCC_RGB32:
+ src_format = PIXMAN_a8r8g8b8;
+ break;
+ default:
+ return FALSE;
+ }
+
+ switch (image_info->id)
+ {
+ case FOURCC_I420:
+ dst_format = PIXMAN_x8b8g8r8;
+ break;
+ default:
+ dst_format = PIXMAN_x8r8g8b8;
+ break;
+ }
+
+ if (image_info->id == FOURCC_I420 && img->width % 16)
+ {
+ int src_p[3] = {0,}, src_o[3] = {0,}, src_l[3] = {0,};
+ int dst_p[3] = {0,}, dst_o[3] = {0,}, dst_l[3] = {0,};
+ unsigned short src_w, src_h, dst_w, dst_h;
+ int size;
+
+ src_w = img->width;
+ src_h = img->height;
+ fbdevVideoQueryImageAttributes (NULL, image_info->id, &src_w, &src_h,
+ src_p, src_o, src_l);
+
+ dst_w = (img->width + 15) & ~15;
+ dst_h = img->height;
+ size = fbdevVideoQueryImageAttributes (NULL, image_info->id, &dst_w, &dst_h,
+ dst_p, dst_o, dst_l);
+
+ if (!pPortPriv->aligned_buffer || pPortPriv->buffer_size != size)
+ {
+ if (pPortPriv->aligned_buffer)
+ free (pPortPriv->aligned_buffer);
+
+ pPortPriv->aligned_buffer = malloc (size);
+ if (!pPortPriv->aligned_buffer)
+ return FALSE;
+ pPortPriv->buffer_size = size;
+ }
+
+ fbdev_util_copy_image (src_w, src_h,
+ (char*)buf, src_w, src_h,
+ src_p, src_o, src_l,
+ (char*)pPortPriv->aligned_buffer, dst_w, dst_h,
+ dst_p, dst_o, dst_l,
+ 3, 2, 2);
+
+ pPortPriv->aligned_width = dst_w;
+ img->width = dst_w;
+ buf = pPortPriv->aligned_buffer;
+ }
+
+ /* support only RGB */
+ fbdev_pixman_convert_image (PIXMAN_OP_SRC,
+ buf, pPixmap->devPrivate.ptr,
+ src_format, dst_format,
+ img, &pxm, src, dst,
+ NULL, rotate,
+ pPortPriv->hflip, pPortPriv->vflip);
+
+ DamageDamageRegion (pDraw, clip_boxes);
+
+ return Success;
+}
+
+static Bool
+_fbdevVideoSetHWPortsProperty (ScreenPtr pScreen, int nums)
+{
+ WindowPtr pWin = pScreen->root;
+ Atom atom_hw_ports;
+
+ if (!pWin || !serverClient)
+ return FALSE;
+
+ atom_hw_ports = MakeAtom ("X_HW_PORTS", strlen ("X_HW_PORTS"), TRUE);
+
+ dixChangeWindowProperty (serverClient,
+ pWin, atom_hw_ports, XA_CARDINAL, 32,
+ PropModeReplace, 1, (unsigned int*)&nums, FALSE);
+
+ return TRUE;
+}
+
+static void
+_fbdevVideoDPMSHandler(CallbackListPtr *list, pointer closure, pointer calldata)
+{
+ FBDevDPMSPtr pDPMSInfo = (FBDevDPMSPtr) calldata;
+
+ if(!pDPMSInfo || !pDPMSInfo->pScrn)
+ {
+ xf86DrvMsg (0, X_ERROR, "[%s] DPMS info or screen info is invalid !\n", __FUNCTION__);
+ return;
+ }
+
+ switch(DPMSPowerLevel)
+ {
+ case DPMSModeOn:
+ break;
+
+ case DPMSModeSuspend:
+ break;
+
+ case DPMSModeStandby://LCD on
+ {
+ ScrnInfoPtr pScrnInfo = pDPMSInfo->pScrn;
+ FBDevPtr pFBDev = FBDEVPTR (pScrnInfo);
+ XF86VideoAdaptorPtr pAdaptor = pFBDev->pAdaptor[0];
+ int i;
+
+ DRVLOG ("%s : DPMSModeStandby \n", __FUNCTION__);
+
+ for (i = 0; i < FBDEV_MAX_PORT; i++)
+ {
+ FBDevPortPrivPtr pPortPriv = (FBDevPortPrivPtr) pAdaptor->pPortPrivates[i].ptr;
+ if (!pPortPriv->v4l2_handle || !pPortPriv->need_streamon)
+ continue;
+
+ if (!fbdevVideoV4l2StreamOn (pPortPriv->v4l2_handle))
+ {
+ /* will re-open if failed */
+ _fbdevVideoCloseV4l2Handle (pScrnInfo, pPortPriv);
+ pPortPriv->v4l2_handle = NULL;
+ }
+ pPortPriv->need_streamon = FALSE;
+ }
+ break;
+ }
+ case DPMSModeOff://LCD off
+ {
+ ScrnInfoPtr pScrnInfo = pDPMSInfo->pScrn;
+ FBDevPtr pFBDev = FBDEVPTR (pScrnInfo);
+ XF86VideoAdaptorPtr pAdaptor = pFBDev->pAdaptor[0];
+ int i;
+
+ DRVLOG ("%s : DPMSModeOff \n", __FUNCTION__);
+
+ for (i = 0; i < FBDEV_MAX_PORT; i++)
+ {
+ FBDevPortPrivPtr pPortPriv = (FBDevPortPrivPtr) pAdaptor->pPortPrivates[i].ptr;
+ if (!pPortPriv->v4l2_handle || pPortPriv->need_streamon)
+ continue;
+
+ fbdevVideoV4l2StreamOff (pPortPriv->v4l2_handle);
+ pPortPriv->need_streamon = TRUE;
+ }
+
+ break;
+ }
+ default:
+ return;
+ }
+}
+
+static void
+_fbdevVideoBlockHandler (pointer data, OSTimePtr pTimeout, pointer pRead)
+{
+ ScrnInfoPtr pScrnInfo = (ScrnInfoPtr)data;
+ FBDevPtr pFBDev = FBDEVPTR (pScrnInfo);
+ ScreenPtr pScreen = pScrnInfo->pScreen;
+
+ if(registered_handler && _fbdevVideoSetHWPortsProperty (pScreen, pFBDev->v4l2_num))
+ {
+ RemoveBlockAndWakeupHandlers(_fbdevVideoBlockHandler, (WakeupHandlerProcPtr)NoopDDA, data);
+ registered_handler = FALSE;
+ }
+}
+
+static int
+FBDevVideoGetPortAttribute (ScrnInfoPtr pScrnInfo,
+ Atom attribute,
+ INT32 *value,
+ pointer data)
+{
+ DRVLOG ("[GetPortAttribute] \n");
+
+ FBDevPortPrivPtr pPortPriv = (FBDevPortPrivPtr) data;
+
+ if (attribute == _fbdevVideoGetPortAtom (PAA_ROTATION))
+ {
+ *value = pPortPriv->rotate;
+ return Success;
+ }
+ else if (attribute == _fbdevVideoGetPortAtom (PAA_HFLIP))
+ {
+ *value = pPortPriv->hflip;
+ return Success;
+ }
+ else if (attribute == _fbdevVideoGetPortAtom (PAA_VFLIP))
+ {
+ *value = pPortPriv->vflip;
+ return Success;
+ }
+ else if (attribute == _fbdevVideoGetPortAtom (PAA_PREEMPTION))
+ {
+ *value = pPortPriv->preemption;
+ return Success;
+ }
+ else if (attribute == _fbdevVideoGetPortAtom (PAA_DRAWINGMODE))
+ {
+ *value = (pPortPriv->mode == PORT_MODE_WAITING);
+ return Success;
+ }
+ return BadMatch;
+}
+
+static int
+FBDevVideoSetPortAttribute (ScrnInfoPtr pScrnInfo,
+ Atom attribute,
+ INT32 value,
+ pointer data)
+{
+ FBDevPortPrivPtr pPortPriv = (FBDevPortPrivPtr) data;
+
+ if (attribute == _fbdevVideoGetPortAtom (PAA_ROTATION))
+ {
+ pPortPriv->rotate = value;
+ DRVLOG ("[SetPortAttribute] rotate(%d) \n", value);
+ return Success;
+ }
+ else if (attribute == _fbdevVideoGetPortAtom (PAA_HFLIP))
+ {
+ pPortPriv->hflip = value;
+ DRVLOG ("[SetPortAttribute] hflip(%d) \n", value);
+ return Success;
+ }
+ else if (attribute == _fbdevVideoGetPortAtom (PAA_VFLIP))
+ {
+ pPortPriv->vflip = value;
+ DRVLOG ("[SetPortAttribute] vflip(%d) \n", value);
+ return Success;
+ }
+ else if (attribute == _fbdevVideoGetPortAtom (PAA_PREEMPTION))
+ {
+ pPortPriv->preemption = value;
+ DRVLOG ("[SetPortAttribute] preemption(%d) \n", value);
+ return Success;
+ }
+ else if (attribute == _fbdevVideoGetPortAtom (PAA_STREAMOFF))
+ {
+ DRVLOG ("[SetPortAttribute] STREAMOFF \n");
+ _fbdevVideoCloseV4l2Handle (pScrnInfo, pPortPriv);
+ return Success;
+ }
+ return BadMatch;
+}
+
+static void
+FBDevVideoQueryBestSize (ScrnInfoPtr pScrnInfo,
+ Bool motion,
+ short vid_w, short vid_h,
+ short dst_w, short dst_h,
+ uint *p_w, uint *p_h,
+ pointer data)
+{
+ DRVLOG ("%s (%s:%d)\n", __FUNCTION__, __FILE__, __LINE__);
+
+ *p_w = dst_w;
+ *p_h = dst_h;
+}
+
+static void
+FBDevVideoStop (ScrnInfoPtr pScrnInfo, pointer data, Bool exit)
+{
+ DRVLOG ("%s (%s:%d) exit(%d)\n", __FUNCTION__, __FILE__, __LINE__, exit);
+
+ FBDevPortPrivPtr pPortPriv = (FBDevPortPrivPtr) data;
+
+ if (pPortPriv->mode == PORT_MODE_V4L2)
+ {
+ _fbdevVideoCloseV4l2Handle (pScrnInfo, pPortPriv);
+
+#if ENABLE_ARM
+ FBDevPtr pFBDev = (FBDevPtr) pScrnInfo->driverPrivate;
+
+ if (pFBDev->bFbAlphaEnabled)
+ {
+ fbdevFbScreenAlphaDeinit (fbdevHWGetFD (pScrnInfo));
+ pFBDev->bFbAlphaEnabled = FALSE;
+ }
+#endif
+ }
+
+ if (pPortPriv->aligned_buffer)
+ {
+ free (pPortPriv->aligned_buffer);
+ pPortPriv->aligned_buffer = NULL;
+ pPortPriv->buffer_size = 0;
+ pPortPriv->aligned_width = 0;
+ }
+
+ pPortPriv->mode = PORT_MODE_INIT;
+ pPortPriv->preemption = 0;
+ pPortPriv->rotate = -1;
+ pPortPriv->need_streamon = FALSE;
+
+ if (exit)
+ REGION_EMPTY (pScrnInfo, &pPortPriv->clip);
+}
+
+static int
+FBDevVideoReputImage (ScrnInfoPtr pScrn, short src_x, short src_y,
+ short drw_x, short drw_y, short src_w,
+ short src_h, short drw_w, short drw_h,
+ RegionPtr clipBoxes, pointer data,
+ DrawablePtr pDraw)
+
+{
+ return Success;
+}
+
+int
+fbdevVideoQueryImageAttributes (ScrnInfoPtr pScrnInfo,
+ int id,
+ unsigned short *w,
+ unsigned short *h,
+ int *pitches,
+ int *offsets,
+ int *lengths)
+{
+ int size = 0, tmp = 0;
+
+ *w = (*w + 1) & ~1;
+ if (offsets)
+ offsets[0] = 0;
+
+ switch (id)
+ {
+ case FOURCC_RGB565:
+ size += (*w << 1);
+ if (pitches)
+ pitches[0] = size;
+ size *= *h;
+ if (lengths)
+ lengths[0] = size;
+ break;
+ case FOURCC_RGB24:
+ size += (*w << 1) + *w;
+ if (pitches)
+ pitches[0] = size;
+ size *= *h;
+ if (lengths)
+ lengths[0] = size;
+ break;
+ case FOURCC_RGB32:
+ size += (*w << 2);
+ if (pitches)
+ pitches[0] = size;
+ size *= *h;
+ if (lengths)
+ lengths[0] = size;
+ break;
+ case FOURCC_I420:
+ case FOURCC_S420:
+ case FOURCC_YV12:
+ *h = (*h + 1) & ~1;
+ size = (*w + 3) & ~3;
+ if (pitches)
+ pitches[0] = size;
+
+ size *= *h;
+ if (offsets)
+ offsets[1] = size;
+ if (lengths)
+ lengths[0] = size;
+
+ tmp = ((*w >> 1) + 3) & ~3;
+ if (pitches)
+ pitches[1] = pitches[2] = tmp;
+
+ tmp *= (*h >> 1);
+ size += tmp;
+ if (offsets)
+ offsets[2] = size;
+ if (lengths)
+ lengths[1] = tmp;
+
+ size += tmp;
+ if (lengths)
+ lengths[2] = tmp;
+
+ break;
+ case FOURCC_UYVY:
+ case FOURCC_SUYV:
+ case FOURCC_YUY2:
+ case FOURCC_ST12:
+ case FOURCC_SN12:
+ size = *w << 1;
+ if (pitches)
+ pitches[0] = size;
+
+ size *= *h;
+ break;
+ case FOURCC_NV12:
+ size = *w;
+ if (pitches)
+ pitches[0] = size;
+
+ size *= *h;
+ if (offsets)
+ offsets[1] = size;
+
+ tmp = *w;
+ if (pitches)
+ pitches[1] = tmp;
+
+ tmp *= (*h >> 1);
+ size += tmp;
+ break;
+ default:
+ return BadIDChoice;
+ }
+
+ return size;
+}
+
+static int
+FBDEVVideoQueryImageAttributes (ScrnInfoPtr pScrnInfo,
+ int id,
+ unsigned short *w,
+ unsigned short *h,
+ int *pitches,
+ int *offsets)
+{
+ return fbdevVideoQueryImageAttributes (pScrnInfo, id, w, h, pitches, offsets, NULL);
+}
+
+static int
+FBDevVideoPutImage (ScrnInfoPtr pScrnInfo,
+ short src_x, short src_y, short dst_x, short dst_y,
+ short src_w, short src_h, short dst_w, short dst_h,
+ int id,
+ uchar *buf,
+ short width, short height,
+ Bool sync,
+ RegionPtr clip_boxes,
+ pointer data,
+ DrawablePtr pDraw)
+{
+ ScreenPtr pScreen = pScrnInfo->pScreen;
+ FBDevPortPrivPtr pPortPriv = (FBDevPortPrivPtr) data;
+ XF86ImageRec *image_info;
+ FBDevPortMode modeBefore = pPortPriv->mode;
+ xRectangle img = {0, 0, width, height};
+ xRectangle src = {src_x, src_y, src_w, src_h};
+ xRectangle dst = {dst_x, dst_y, dst_w, dst_h};
+ int scn_rotate, rotate, hw_rotate;
+ int v4l2_index = 0;
+ FBDevPtr pFBDev = FBDEVPTR (pScrnInfo);
+ int drawing;
+
+ if (pFBDev->isLcdOff)
+ return Success;
+
+ pPortPriv->pDraw = pDraw;
+ drawing = _fbdevVideodrawingOn (pPortPriv, pDraw);
+
+ image_info = _fbdevVideoGetImageInfo (id);
+ if (!image_info)
+ {
+ xf86DrvMsg (0, X_ERROR, "ID(%c%c%c%c) not supported.\n",
+ id & 0xFF, (id & 0xFF00) >> 8,
+ (id & 0xFF0000) >> 16, (id & 0xFF000000) >> 24);
+ return BadRequest;
+ }
+
+ _fbdevVideoGetRotation (pScreen, pPortPriv, pDraw, &scn_rotate, &rotate, &hw_rotate);
+
+ DRVLOG ("[PutImage] buf(%p) ID(%c%c%c%c) mode(%s) preem(%d) handle(%p) rot(%d+%d=%d) res(%dx%d) drawing(%d)\n",
+ buf, id & 0xFF, (id & 0xFF00) >> 8, (id & 0xFF0000) >> 16, (id & 0xFF000000) >> 24,
+ pPortPriv->mode == PORT_MODE_WAITING ? "waiting" : "V4L2",
+ pPortPriv->preemption,
+ pPortPriv->v4l2_handle,
+ scn_rotate, rotate, hw_rotate,
+ pScreen->width, pScreen->height, drawing);
+
+ DRVLOG ("[PutImage] \t img(%d,%d %dx%d) src(%d,%d %dx%d) dst(%d,%d %dx%d) \n",
+ img.x, img.y, img.width, img.height,
+ src.x, src.y, src.width, src.height,
+ dst.x, dst.y, dst.width, dst.height);
+
+ _fbdevVideoInterfbdevtXRects (&src, &src, &img);
+
+ DRVLOG ("[PutImage] \t=> img(%d,%d %dx%d) src(%d,%d %dx%d) dst(%d,%d %dx%d) \n",
+ img.x, img.y, img.width, img.height,
+ src.x, src.y, src.width, src.height,
+ dst.x, dst.y, dst.width, dst.height);
+
+ if (drawing == ON_PIXMAP || drawing == ON_WINDOW)
+ return _fbdevVideoPutImageOnDrawable (pScrnInfo, pPortPriv, &img, &src, &dst, clip_boxes,
+ scn_rotate, hw_rotate, image_info, buf, pDraw);
+
+ if (pPortPriv->need_streamon && pPortPriv->v4l2_handle)
+ {
+ _fbdevVideoCloseV4l2Handle (pScrnInfo, pPortPriv);
+ pPortPriv->need_streamon = FALSE;
+ pPortPriv->v4l2_handle = NULL;
+ }
+
+ if (!pPortPriv->v4l2_handle)
+ if (!_fbdevVideoSetMode (pScrnInfo, pPortPriv, &v4l2_index))
+ return BadRequest;
+
+ if (pPortPriv->mode != PORT_MODE_V4L2)
+ return Success;
+
+ return _fbdevVideoPutImageV4l2 (pScrnInfo, pPortPriv, &img, &src, &dst, clip_boxes,
+ scn_rotate, rotate, hw_rotate,
+ image_info, buf, modeBefore, v4l2_index, pDraw);
+}
+
+/**
+ * Set up all our internal structures.
+ */
+static XF86VideoAdaptorPtr
+fbdevVideoSetupImageVideo (ScreenPtr pScreen)
+{
+ DRVLOG ("%s (%s:%d)\n", __FUNCTION__, __FILE__, __LINE__);
+
+ XF86VideoAdaptorPtr pAdaptor;
+ FBDevPortPrivPtr pPortPriv;
+ XF86ImagePtr pImages;
+ int i, count = 0;
+
+ pAdaptor = calloc (1, sizeof (XF86VideoAdaptorRec) +
+ (sizeof (DevUnion) + sizeof (FBDevPortPriv)) * FBDEV_MAX_PORT);
+ if (pAdaptor == NULL)
+ return NULL;
+
+ DummyEncoding[0].width = pScreen->width;
+ DummyEncoding[0].height = pScreen->height;
+
+ pAdaptor->type = XvWindowMask | XvPixmapMask | XvInputMask | XvImageMask;
+ pAdaptor->flags = (VIDEO_CLIP_TO_VIEWPORT | VIDEO_OVERLAID_IMAGES);
+ pAdaptor->name = "FBDEV supporting Software Video Conversions";
+ pAdaptor->nEncodings = sizeof (DummyEncoding) / sizeof (XF86VideoEncodingRec);
+ pAdaptor->pEncodings = DummyEncoding;
+ pAdaptor->nFormats = NUM_FORMATS;
+ pAdaptor->pFormats = Formats;
+ pAdaptor->nPorts = FBDEV_MAX_PORT;
+ pAdaptor->pPortPrivates = (DevUnion*)(&pAdaptor[1]);
+
+ pPortPriv =
+ (FBDevPortPrivPtr) (&pAdaptor->pPortPrivates[FBDEV_MAX_PORT]);
+
+ for (i=0; i<FBDEV_MAX_PORT; i++)
+ {
+ pAdaptor->pPortPrivates[i].ptr = &pPortPriv[i];
+
+ pPortPriv[i].index = i;
+ pPortPriv[i].rotate = -1;
+ pPortPriv[i].v4l2_index = -1;
+
+ REGION_INIT (pScreen, &pPortPriv[i].clipBoxes, NullBox, 0);
+ }
+
+ pImages = fbdevVideoV4l2SupportImages (&count);
+
+ pAdaptor->nAttributes = NUM_ATTRIBUTES;
+ pAdaptor->pAttributes = Attributes;
+ pAdaptor->nImages = count;
+ pAdaptor->pImages = pImages;
+
+ pAdaptor->PutImage = FBDevVideoPutImage;
+ pAdaptor->ReputImage = FBDevVideoReputImage;
+ pAdaptor->StopVideo = FBDevVideoStop;
+ pAdaptor->GetPortAttribute = FBDevVideoGetPortAttribute;
+ pAdaptor->SetPortAttribute = FBDevVideoSetPortAttribute;
+ pAdaptor->QueryBestSize = FBDevVideoQueryBestSize;
+ pAdaptor->QueryImageAttributes = FBDEVVideoQueryImageAttributes;
+
+ return pAdaptor;
+}
+
+#ifdef XV
+/**
+ * Set up everything we need for Xv.
+ */
+Bool fbdevVideoInit (ScreenPtr pScreen)
+{
+ DRVLOG ("%s (%s:%d)\n", __FUNCTION__, __FILE__, __LINE__);
+
+ ScrnInfoPtr pScrnInfo = xf86Screens[pScreen->myNum];
+ FBDevPtr pFBDev = (FBDevPtr) pScrnInfo->driverPrivate;
+
+ pFBDev->pAdaptor[0] = fbdevVideoSetupImageVideo (pScreen);
+ if (!pFBDev->pAdaptor[0])
+ return FALSE;
+
+ pFBDev->pAdaptor[1] = fbdevVideoSetupVirtualVideo (pScreen);
+ if (!pFBDev->pAdaptor[1])
+ {
+ free (pFBDev->pAdaptor[0]);
+ return FALSE;
+ }
+
+ xf86XVScreenInit (pScreen, pFBDev->pAdaptor, ADAPTOR_NUM);
+
+ pFBDev->v4l2_num = fbdevVideoV4l2GetHandleNums ();
+ pFBDev->v4l2_owner = (void**)calloc (sizeof (void*), pFBDev->v4l2_num);
+
+ if(registered_handler == FALSE)
+ {
+ RegisterBlockAndWakeupHandlers(_fbdevVideoBlockHandler, (WakeupHandlerProcPtr)NoopDDA, pScrnInfo);
+ registered_handler = TRUE;
+ }
+
+ if (AddCallback (&DPMSCallback, _fbdevVideoDPMSHandler, NULL) != TRUE)
+ {
+ xf86DrvMsg (pScrnInfo->scrnIndex, X_ERROR, "Failed to register _fbdevVideoDPMSHandler. \n");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/**
+ * Shut down Xv, used on regeneration.
+ */
+void fbdevVideoFini (ScreenPtr pScreen)
+{
+ DRVLOG ("%s (%s:%d)\n", __FUNCTION__, __FILE__, __LINE__);
+
+ ScrnInfoPtr pScrnInfo = xf86Screens[pScreen->myNum];
+ FBDevPtr pFBDev = (FBDevPtr) pScrnInfo->driverPrivate;
+
+ XF86VideoAdaptorPtr pAdaptor = pFBDev->pAdaptor[0];
+ int i;
+
+ if (!pAdaptor)
+ return;
+
+ DeleteCallback (&DPMSCallback, _fbdevVideoDPMSHandler, NULL);
+
+ for (i = 0; i < FBDEV_MAX_PORT; i++)
+ {
+ FBDevPortPrivPtr pPortPriv = (FBDevPortPrivPtr) pAdaptor->pPortPrivates[i].ptr;
+
+ REGION_UNINIT (pScreen, &pPortPriv->clipBoxes);
+
+ _fbdevVideoCloseV4l2Handle (pScrnInfo, pPortPriv);
+ }
+
+ free (pFBDev->pAdaptor[0]);
+ pFBDev->pAdaptor[0] = NULL;
+
+ free (pFBDev->pAdaptor[1]);
+ pFBDev->pAdaptor[1] = NULL;
+
+ if (pFBDev->v4l2_owner)
+ {
+ free (pFBDev->v4l2_owner);
+ pFBDev->v4l2_owner = NULL;
+ pFBDev->v4l2_num = 0;
+ }
+}
+
+#endif
+
+void
+fbdevVideoSetOffset (ScrnInfoPtr pScrnInfo, int x, int y)
+{
+ FBDevPtr pFBDev = (FBDevPtr) pScrnInfo->driverPrivate;
+ int i;
+ for (i = 0; i < pFBDev->v4l2_num; i++)
+ {
+ FBDevPortPrivPtr pPortPriv = (FBDevPortPrivPtr) pFBDev->v4l2_owner[i];
+
+ if (pPortPriv)
+ {
+ if (!pPortPriv->v4l2_handle)
+ continue;
+
+ fbdevVideoV4l2VideoOffset (pPortPriv->v4l2_handle, x , y);
+ }
+ }
+}
+
+void
+fbdevVideoGetV4l2Handles (ScrnInfoPtr pScrnInfo, void ***handles, int *cnt)
+{
+ FBDevPtr pFBDev = (FBDevPtr) pScrnInfo->driverPrivate;
+ void **ret;
+ int i, j;
+
+ *cnt = 0;
+
+ for (i = 0; i < pFBDev->v4l2_num; i++)
+ {
+ FBDevPortPrivPtr pPortPriv = (FBDevPortPrivPtr) pFBDev->v4l2_owner[i];
+ if (pPortPriv && pPortPriv->v4l2_handle)
+ (*cnt)++;
+ }
+
+ if (*cnt == 0)
+ {
+ *handles = NULL;
+ return;
+ }
+
+ ret = (void**)calloc (*cnt, sizeof (void*));
+ *handles = ret;
+
+ j = 0;
+
+ for (i = 0; i < pFBDev->v4l2_num; i++)
+ {
+ FBDevPortPrivPtr pPortPriv = (FBDevPortPrivPtr) pFBDev->v4l2_owner[i];
+ if (pPortPriv && pPortPriv->v4l2_handle)
+ {
+ ret[j] = pPortPriv->v4l2_handle;
+ j++;
+ }
+ }
+}
--- /dev/null
+/**************************************************************************
+
+xserver-xorg-video-emulfb
+
+Copyright 2010 - 2011 Samsung Electronics co., Ltd. All Rights Reserved.
+
+Contact: Boram Park <boram1288.park@samsung.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sub license, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+#ifndef FBDEV_VIDEO_H
+#define FBDEV_VIDEO_H
+
+typedef enum
+{
+ PORT_MODE_INIT,
+ PORT_MODE_V4L2,
+ PORT_MODE_WAITING
+} FBDevPortMode;
+
+/* FBDEV port information structure */
+typedef struct
+{
+ int index;
+ FBDevPortMode mode;
+ int drawing;
+ int size;
+
+ RegionRec clip;
+
+ int rotate;
+ int hflip;
+ int vflip;
+ xRectangle dst;
+ RegionRec clipBoxes;
+ int preemption; /* 1:high, 0:default, -1:low */
+ DrawablePtr pDraw;
+
+ int v4l2_index;
+ void *v4l2_handle;
+
+ void *aligned_buffer;
+ int buffer_size;
+ int aligned_width;
+
+ int need_streamon;
+} FBDevPortPriv, *FBDevPortPrivPtr;
+
+extern Bool fbdevVideoInit (ScreenPtr pScreen);
+extern void fbdevVideoFini (ScreenPtr pScreen);
+int fbdevVideoQueryImageAttributes (ScrnInfoPtr pScrnInfo,
+ int id,
+ unsigned short *w,
+ unsigned short *h,
+ int *pitches,
+ int *offsets,
+ int *lengths);
+
+void fbdevVideoSetOffset (ScrnInfoPtr pScrnInfo, int x, int y);
+void fbdevVideoGetV4l2Handles (ScrnInfoPtr pScrnInfo, void ***handles, int *cnt);
+
+#endif // FBDEV_VIDEO_H
--- /dev/null
+/**************************************************************************
+
+xserver-xorg-video-emulfb
+
+Copyright 2010 - 2011 Samsung Electronics co., Ltd. All Rights Reserved.
+
+Contact: Boram Park <boram1288.park@samsung.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sub license, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+#ifndef __FBDEV_VIDEO_FOURCC_H__
+#define __FBDEV_VIDEO_FOURCC_H__
+
+#include <fourcc.h>
+
+#define B(c,s) ((((unsigned int)(c)) & 0xff) << (s))
+#define FOURCC(a,b,c,d) (B(d,24) | B(c,16) | B(b,8) | B(a,0))
+
+/* http://www.fourcc.org/yuv.php
+ * http://en.wikipedia.org/wiki/YUV
+ */
+#define FOURCC_RGB565 FOURCC('R','G','B','P')
+#define XVIMAGE_RGB565 \
+ { \
+ FOURCC_RGB565, \
+ XvRGB, \
+ LSBFirst, \
+ {'R','G','B','P', \
+ 0x00,0x00,0x00,0x10,0x80,0x00,0x00,0xAA,0x00,0x38,0x9B,0x71}, \
+ 16, \
+ XvPacked, \
+ 1, \
+ 16, 0x0000F800, 0x000007E0, 0x0000001F, \
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, \
+ {'R','G','B',0, \
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, \
+ XvTopToBottom \
+ }
+
+#define FOURCC_RGB24 FOURCC('R','G','B','3')
+#define XVIMAGE_RGB24 \
+ { \
+ FOURCC_RGB24, \
+ XvRGB, \
+ LSBFirst, \
+ {'R','G','B',0, \
+ 0x00,0x00,0x00,0x10,0x80,0x00,0x00,0xAA,0x00,0x38,0x9B,0x71}, \
+ 24, \
+ XvPacked, \
+ 1, \
+ 24, 0x00FF0000, 0x0000FF00, 0x000000FF, \
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, \
+ {'R','G','B',0, \
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, \
+ XvTopToBottom \
+ }
+
+#define FOURCC_RGB32 FOURCC('R','G','B','4')
+#define XVIMAGE_RGB32 \
+ { \
+ FOURCC_RGB32, \
+ XvRGB, \
+ LSBFirst, \
+ {'R','G','B',0, \
+ 0x00,0x00,0x00,0x10,0x80,0x00,0x00,0xAA,0x00,0x38,0x9B,0x71}, \
+ 32, \
+ XvPacked, \
+ 1, \
+ 24, 0x00FF0000, 0x0000FF00, 0x000000FF, \
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, \
+ {'X','R','G','B', \
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, \
+ XvTopToBottom \
+ }
+
+#define FOURCC_ST12 FOURCC('S','T','1','2')
+#define XVIMAGE_ST12 \
+ { \
+ FOURCC_ST12, \
+ XvYUV, \
+ LSBFirst, \
+ {'S','T','1','2', \
+ 0x00,0x00,0x00,0x10,0x80,0x00,0x00,0xAA,0x00,0x38,0x9B,0x71}, \
+ 12, \
+ XvPlanar, \
+ 3, \
+ 0, 0, 0, 0, \
+ 8, 8, 8, \
+ 1, 2, 2, \
+ 1, 2, 2, \
+ {'Y','U','V', \
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, \
+ XvTopToBottom \
+ }
+
+#define FOURCC_SN12 FOURCC('S','N','1','2')
+#define XVIMAGE_SN12 \
+ { \
+ FOURCC_SN12, \
+ XvYUV, \
+ LSBFirst, \
+ {'S','N','1','2', \
+ 0x00,0x00,0x00,0x10,0x80,0x00,0x00,0xAA,0x00,0x38,0x9B,0x71}, \
+ 12, \
+ XvPlanar, \
+ 3, \
+ 0, 0, 0, 0, \
+ 8, 8, 8, \
+ 1, 2, 2, \
+ 1, 2, 2, \
+ {'Y','U','V', \
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, \
+ XvTopToBottom \
+ }
+
+#define FOURCC_NV12 FOURCC('N','V','1','2')
+#define XVIMAGE_NV12 \
+ { \
+ FOURCC_NV12, \
+ XvYUV, \
+ LSBFirst, \
+ {'N','V','1','2', \
+ 0x00,0x00,0x00,0x10,0x80,0x00,0x00,0xAA,0x00,0x38,0x9B,0x71}, \
+ 12, \
+ XvPacked, \
+ 1, \
+ 0, 0, 0, 0, \
+ 8, 8, 8, \
+ 1, 2, 2, \
+ 1, 2, 2, \
+ {'Y','U','V', \
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, \
+ XvTopToBottom \
+ }
+
+#define FOURCC_S420 FOURCC('S','4','2','0')
+#define XVIMAGE_S420 \
+ { \
+ FOURCC_S420, \
+ XvYUV, \
+ LSBFirst, \
+ {'S','4','2','0', \
+ 0x00,0x00,0x00,0x10,0x80,0x00,0x00,0xAA,0x00,0x38,0x9B,0x71}, \
+ 12, \
+ XvPlanar, \
+ 3, \
+ 0, 0, 0, 0, \
+ 8, 8, 8, \
+ 1, 2, 2, \
+ 1, 2, 2, \
+ {'Y','U','V', \
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, \
+ XvTopToBottom \
+ }
+#define FOURCC_SUYV FOURCC('S','U','Y','V')
+#define XVIMAGE_SUYV \
+ { \
+ FOURCC_SUYV, \
+ XvYUV, \
+ LSBFirst, \
+ {'S','U','Y','V', \
+ 0x00,0x00,0x00,0x10,0x80,0x00,0x00,0xAA,0x00,0x38,0x9B,0x71}, \
+ 16, \
+ XvPacked, \
+ 1, \
+ 0, 0, 0, 0, \
+ 8, 8, 8, \
+ 1, 2, 2, \
+ 1, 1, 1, \
+ {'Y','U','Y','V', \
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, \
+ XvTopToBottom \
+ }
+
+
+#endif // __FBDEV_VIDEO_FOURCC_H__
--- /dev/null
+/**************************************************************************
+
+xserver-xorg-video-emulfb
+
+Copyright 2010 - 2011 Samsung Electronics co., Ltd. All Rights Reserved.
+
+Contact: Boram Park <boram1288.park@samsung.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sub license, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+#ifndef __FBDEV_V4L2_TYPES_H__
+#define __FBDEV_V4L2_TYPES_H__
+
+#include <sys/types.h>
+#include <X11/Xdefs.h>
+
+#include <linux/videodev2.h>
+
+enum
+{
+ OUTPUT_PATH_DMA, /* FrameBuffer */
+ OUTPUT_PATH_FIMD, /* LCD */
+};
+
+/************************************************************
+ * TYPE DEFINITION
+ ************************************************************/
+typedef enum v4l2_buf_type FBDevV4l2BufType;
+typedef enum v4l2_memory FBDevV4l2Memory;
+
+#ifndef uint
+typedef unsigned int uint;
+#endif
+
+#ifndef uchar
+typedef unsigned char uchar;
+#endif
+
+#ifndef ushort
+typedef unsigned short ushort;
+#endif
+
+/************************************************************
+ * STRUCTURE
+ ************************************************************/
+typedef struct _FBDevV4l2Data
+{
+ __u32 path;
+ __u32 in_format;
+ __u32 out_format;
+ __u32 field;
+ char in_file_name[50];
+
+ struct v4l2_rect src;
+ struct v4l2_rect crop;
+ struct v4l2_rect dst;
+ struct v4l2_rect win;
+
+ __u32 s_size[3];
+ __u32 src_size;
+ __u32 d_size[3];
+ __u32 dst_size;
+
+ int rotation;
+} FBDevV4l2Data;
+
+typedef struct _FBDevV4l2FimcBuffer
+{
+ uint base[3];
+ size_t length[3];
+} FBDevV4l2FimcBuffer;
+
+typedef struct _FBDevV4l2SrcBuffer
+{
+ int index;
+ int size;
+ uchar *buf;
+} FBDevV4l2SrcBuffer;
+
+typedef struct _FBDevV4l2DstBuffer
+{
+ int index;
+ int size;
+ uchar *buf;
+} FBDevV4l2DstBuffer;
+
+#endif
--- /dev/null
+/**************************************************************************
+
+xserver-xorg-video-emulfb
+
+Copyright 2010 - 2011 Samsung Electronics co., Ltd. All Rights Reserved.
+
+Contact: Boram Park <boram1288.park@samsung.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sub license, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+#ifndef __FBDEV_VIDEO_V4L2_H__
+#define __FBDEV_VIDEO_V4L2_H__
+
+#include <fbdevhw.h>
+#include <xf86xv.h>
+
+#include "fbdev_v4l2.h"
+
+XF86ImagePtr fbdevVideoV4l2SupportImages (int *count);
+
+Bool fbdevVideoV4l2GetFormatInfo (int id, int *type, uint *pixelformat, FBDevV4l2Memory *memory);
+Bool fbdevVideoV4l2CheckSize (void *handle, uint pixelformat,
+ xRectangle *img, xRectangle *src, xRectangle *dst,
+ int type, int memory);
+
+int fbdevVideoV4l2GetHandleNums (void);
+Bool fbdevVideoV4l2HandleOpened (int index);
+
+void* fbdevVideoV4l2OpenHandle (ScreenPtr pScreen, int index, int requestbuffer);
+void fbdevVideoV4l2CloseHandle (void *handle);
+
+Bool fbdevVideoV4l2StreamOn (void *handle);
+void fbdevVideoV4l2StreamOff (void *handle);
+
+void fbdevVideoV4l2VideoOffset (void *handle, int x, int y);
+
+int fbdevVideoV4l2SetFormat (void *handle,
+ xRectangle *img, /* src->x, src->y : not used. */
+ xRectangle *crop,
+ xRectangle *dest,
+ uint id,
+ int scn_rotate,
+ int hw_rotate,
+ int hflip,
+ int vflip,
+ int requestbuffer,
+ Bool sync);
+
+int fbdevVideoV4l2Draw (void *handle, uchar *buf, uint *phy_addrs);
+
+void fbdevVideoGetFBInfo (void *handle, void **base, xRectangle *pos);
+
+#endif
--- /dev/null
+/**************************************************************************
+
+xserver-xorg-video-emulfb
+
+Copyright 2010 - 2011 Samsung Electronics co., Ltd. All Rights Reserved.
+
+Contact: Boram Park <boram1288.park@samsung.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sub license, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <pixman.h>
+#include <X11/Xatom.h>
+#include <X11/extensions/Xv.h>
+
+#include "fbdev.h"
+#include "fbdev_util.h"
+#include "fbdev_video.h"
+#include "fbdev_video_fourcc.h"
+#include "fbdev_video_virtual.h"
+#include "fbdev_video_v4l2.h"
+#include "fbdev_pixman.h"
+
+#include "xv_types.h"
+
+#define BUF_NUM 3
+
+enum
+{
+ COMP_SRC,
+ COMP_OVER,
+ COMP_MAX,
+};
+
+enum
+{
+ DATA_TYPE_UI,
+ DATA_TYPE_VIDEO,
+ DATA_TYPE_MAX,
+};
+
+static unsigned int support_formats[] =
+{
+ FOURCC_RGB32,
+};
+
+static XF86VideoEncodingRec dummy_encoding[] =
+{
+ { 0, "XV_IMAGE", -1, -1, { 1, 1 } },
+ { 1, "XV_IMAGE", 2560, 2560, { 1, 1 } },
+};
+
+static XF86ImageRec images[] =
+{
+ XVIMAGE_RGB32,
+ XVIMAGE_SN12,
+ XVIMAGE_ST12,
+};
+
+static XF86VideoFormatRec formats[] =
+{
+ { 16, TrueColor },
+ { 24, TrueColor },
+ { 32, TrueColor },
+};
+
+static XF86AttributeRec attributes[] =
+{
+ { 0, 0, 0x7fffffff, "_USER_WM_PORT_ATTRIBUTE_FORMAT" },
+ { 0, 0, 1, "_USER_WM_PORT_ATTRIBUTE_CAPTURE" },
+ { 0, 0, DATA_TYPE_MAX, "_USER_WM_PORT_ATTRIBUTE_DATA_TYPE" },
+ { 0, 0, 1, "_USER_WM_PORT_ATTRIBUTE_STREAM_OFF" },
+};
+
+typedef enum
+{
+ PAA_MIN,
+ PAA_FORMAT,
+ PAA_CAPTURE,
+ PAA_DATA_TYPE,
+ PAA_STREAMOFF,
+ PAA_MAX
+} FBDEVPortAttrAtom;
+
+static struct
+{
+ FBDEVPortAttrAtom paa;
+ const char *name;
+ Atom atom;
+} atoms[] =
+{
+ { PAA_FORMAT, "_USER_WM_PORT_ATTRIBUTE_FORMAT", None },
+ { PAA_CAPTURE, "_USER_WM_PORT_ATTRIBUTE_CAPTURE", None },
+ { PAA_DATA_TYPE, "_USER_WM_PORT_ATTRIBUTE_DATA_TYPE", None },
+ { PAA_STREAMOFF, "_USER_WM_PORT_ATTRIBUTE_STREAM_OFF", None },
+};
+
+/* FBDEV port information structure */
+typedef struct
+{
+ /* index */
+ int index;
+
+ /* port attribute */
+ int id;
+ Bool capture;
+
+ /* information from outside */
+ ScrnInfoPtr pScrn;
+ DrawablePtr pDraw;
+ RegionPtr clipBoxes;
+
+ void *black;
+ int black_w;
+ int black_h;
+
+ struct xorg_list link;
+} FBDEVPortPriv, *FBDEVPortPrivPtr;
+
+static RESTYPE event_drawable_type;
+
+typedef struct _FBDEVVideoResource
+{
+ XID id;
+ RESTYPE type;
+ FBDEVPortPrivPtr pPort;
+ ScrnInfoPtr pScrn;
+} FBDEVVideoResource;
+
+#define FBDEV_MAX_PORT 1
+
+#define NUM_IMAGES (sizeof(images) / sizeof(images[0]))
+#define NUM_FORMATS (sizeof(formats) / sizeof(formats[0]))
+#define NUM_ATTRIBUTES (sizeof(attributes) / sizeof(attributes[0]))
+#define NUM_ATOMS (sizeof(atoms) / sizeof(atoms[0]))
+
+static void FBDEVVirtualVideoStop (ScrnInfoPtr pScrn, pointer data, Bool exit);
+
+static PixmapPtr
+_fbdevVirtualVideoGetPixmap (DrawablePtr pDraw)
+{
+ if (pDraw->type == DRAWABLE_WINDOW)
+ return pDraw->pScreen->GetWindowPixmap ((WindowPtr) pDraw);
+ else
+ return (PixmapPtr) pDraw;
+}
+
+static Bool
+_fbdevVirtualVideoIsSupport (unsigned int id)
+{
+ int i;
+
+ for (i = 0; i < sizeof (support_formats) / sizeof (unsigned int); i++)
+ if (support_formats[i] == id)
+ return TRUE;
+
+ return FALSE;
+}
+
+static Atom
+_fbdevVideoGetPortAtom (FBDEVPortAttrAtom paa)
+{
+ int i;
+
+ return_val_if_fail (paa > PAA_MIN && paa < PAA_MAX, None);
+
+ for (i = 0; i < NUM_ATOMS; i++)
+ {
+ if (paa == atoms[i].paa)
+ {
+ if (atoms[i].atom == None)
+ atoms[i].atom = MakeAtom (atoms[i].name,
+ strlen (atoms[i].name), TRUE);
+
+ return atoms[i].atom;
+ }
+ }
+
+ ErrorF ("Error: Unknown Port Attribute Name!\n");
+
+ return None;
+}
+
+static void
+_fbdevVirtualVideoStreamOff (FBDEVPortPrivPtr pPort)
+{
+ DRVLOG ("STREAM_OFF!\n");
+
+ if (pPort->clipBoxes)
+ {
+ RegionDestroy (pPort->clipBoxes);
+ pPort->clipBoxes = NULL;
+ }
+
+ if (pPort->black)
+ {
+ free (pPort->black);
+ pPort->black = NULL;
+ }
+
+ pPort->black_w = 0;
+ pPort->black_h = 0;
+
+ pPort->pScrn = NULL;
+ pPort->pDraw = NULL;
+ pPort->capture = FALSE;
+ pPort->id = FOURCC_RGB32;
+}
+
+static int
+_fbdevVirtualVideoPreProcess (ScrnInfoPtr pScrn, FBDEVPortPrivPtr pPort,
+ RegionPtr clipBoxes, DrawablePtr pDraw)
+{
+ if (pPort->pScrn == pScrn && pPort->pDraw == pDraw &&
+ pPort->clipBoxes && clipBoxes && RegionEqual (pPort->clipBoxes, clipBoxes))
+ return Success;
+
+ pPort->pScrn = pScrn;
+ pPort->pDraw = pDraw;
+
+ if (clipBoxes)
+ {
+ if (pPort->clipBoxes)
+ {
+ RegionDestroy (pPort->clipBoxes);
+ pPort->clipBoxes = NULL;
+ }
+
+ if (!pPort->clipBoxes)
+ pPort->clipBoxes = RegionCreate (NULL, 1);
+
+ return_val_if_fail (pPort->clipBoxes != NULL, BadAlloc);
+
+ RegionCopy (pPort->clipBoxes, clipBoxes);
+ }
+
+ DRVLOG ("[%s] pDraw(0x%x, %dx%d). \n", __FUNCTION__, pDraw->id, pDraw->width, pDraw->height);
+
+ return Success;
+}
+
+static int
+_fbdevVirtualVideoAddDrawableEvent (FBDEVPortPrivPtr pPort)
+{
+ FBDEVVideoResource *resource;
+ void *ptr;
+ int ret;
+
+ return_val_if_fail (pPort->pScrn != NULL, BadImplementation);
+ return_val_if_fail (pPort->pDraw != NULL, BadImplementation);
+
+ ptr = NULL;
+ ret = dixLookupResourceByType (&ptr, pPort->pDraw->id,
+ event_drawable_type, NULL, DixWriteAccess);
+ if (ret == Success && ptr)
+ return Success;
+
+ resource = malloc (sizeof (FBDEVVideoResource));
+ if (resource == NULL)
+ return BadAlloc;
+
+ if (!AddResource (pPort->pDraw->id, event_drawable_type, resource))
+ {
+ free (resource);
+ return BadAlloc;
+ }
+
+ DRVLOG ("[%s] id(%ld). \n", __FUNCTION__, pPort->pDraw->id);
+
+ resource->id = pPort->pDraw->id;
+ resource->type = event_drawable_type;
+ resource->pPort = pPort;
+ resource->pScrn = pPort->pScrn;
+
+ return Success;
+}
+
+static int
+_fbdevVirtualVideoRegisterEventDrawableGone (void *data, XID id)
+{
+ FBDEVVideoResource *resource = (FBDEVVideoResource*)data;
+
+ DRVLOG ("[%s] id(%ld). \n", __FUNCTION__, id);
+
+ if (!resource)
+ return Success;
+
+ if (!resource->pPort || !resource->pScrn)
+ return Success;
+
+ resource->pPort->pDraw = NULL;
+
+ FBDEVVirtualVideoStop (resource->pScrn, (pointer)resource->pPort, 1);
+
+ free(resource);
+
+ return Success;
+}
+
+static void
+_fbdevVideoEnsureBlackBuffer (FBDEVPortPrivPtr pPort, int width, int height)
+{
+ int i, size, *byte;
+
+ if (pPort->black_w != width || pPort->black_w != height)
+ {
+ if (pPort->black)
+ {
+ free (pPort->black);
+ pPort->black = NULL;
+ }
+ }
+
+ if (pPort->black)
+ return;
+
+ size = width * height;
+
+ pPort->black = (void*)malloc (size * 4);
+ pPort->black_w = width;
+ pPort->black_h = height;
+
+ byte = (int*)pPort->black;
+ for (i = 0; i < size; i++)
+ byte[i] = 0xff000000;
+}
+
+static Bool
+_fbdevVirtualVideoRegisterEventResourceTypes (void)
+{
+ event_drawable_type = CreateNewResourceType (_fbdevVirtualVideoRegisterEventDrawableGone,
+ "Fbdev Virtual Video Drawable");
+
+ if (!event_drawable_type)
+ return FALSE;
+
+ return TRUE;
+}
+
+static int
+_fbdevVirtualVideoCompositeLayers (FBDEVPortPrivPtr pPort)
+{
+ ScreenPtr pScreen = pPort->pScrn->pScreen;
+ PixmapPtr screen_pixmap;
+ PixmapPtr pPixmap;
+ void **handles = NULL;
+ int handle_cnt = 0;
+ void *srcbuf = NULL, *dstbuf = NULL;
+ xRectangle src = {0,}, dst = {0,}, pxm = {0,};
+ pixman_format_code_t format;
+ pixman_op_t op;
+ Bool over = FALSE;
+ PropertyPtr rotate_prop;
+ int rotate = 0;
+
+ screen_pixmap = (*pScreen->GetScreenPixmap) (pScreen);
+ return_val_if_fail (screen_pixmap != NULL, BadRequest);
+ return_val_if_fail (screen_pixmap->devPrivate.ptr != NULL, BadRequest);
+
+ pPixmap = _fbdevVirtualVideoGetPixmap (pPort->pDraw);
+ return_val_if_fail (pPixmap != NULL, BadRequest);
+ return_val_if_fail (pPixmap->devPrivate.ptr != NULL, BadRequest);
+
+ dstbuf = calloc (1, screen_pixmap->drawable.width * screen_pixmap->drawable.height * 4);
+ pxm.width = screen_pixmap->drawable.width;
+ pxm.height = screen_pixmap->drawable.height;
+
+ format = PIXMAN_a8r8g8b8;
+
+ fbdevVideoGetV4l2Handles (pPort->pScrn, &handles, &handle_cnt);
+ if (handles)
+ {
+ int i;
+ for (i = 0; i < handle_cnt; i++)
+ {
+ srcbuf = NULL;
+ CLEAR (src);
+ CLEAR (dst);
+
+ fbdevVideoGetFBInfo (handles[i], &srcbuf, &dst);
+ if (!srcbuf || dst.width == 0 || dst.height == 0)
+ continue;
+ src = dst;
+ src.x = src.y = 0;
+
+ if (!over)
+ {
+ op = PIXMAN_OP_SRC;
+ over = TRUE;
+ }
+ else
+ op = PIXMAN_OP_OVER;
+
+ fbdev_pixman_convert_image (op,
+ srcbuf, dstbuf,
+ format, format,
+ &src, &pxm, &src, &dst,
+ NULL, 0, 0, 0);
+ }
+
+ free (handles);
+ }
+
+ srcbuf = screen_pixmap->devPrivate.ptr;
+ src = dst = pxm;
+
+ if (!over)
+ {
+ op = PIXMAN_OP_SRC;
+ over = TRUE;
+ }
+ else
+ op = PIXMAN_OP_OVER;
+
+ fbdev_pixman_convert_image (op,
+ srcbuf, dstbuf,
+ format, format,
+ &src, &pxm, &src, &dst,
+ NULL, 0, 0, 0);
+
+
+ rotate_prop = fbdev_util_get_window_property (pScreen->root,
+ "_E_ILLUME_ROTATE_ROOT_ANGLE");
+ if (rotate_prop)
+ rotate = *(int*)rotate_prop->data;
+
+ if (rotate != 0 ||
+ pxm.width != pPort->pDraw->width ||
+ pxm.height != pPort->pDraw->height)
+ {
+ xRectangle rect;
+ int width, height;
+
+ width = pxm.width;
+ height = pxm.height;
+
+ if (rotate % 180)
+ SWAP (width, height);
+
+ fbdev_util_align_rect (width, height,
+ pPort->pDraw->width, pPort->pDraw->height,
+ &rect, FALSE);
+
+ src = pxm;
+ pxm.width = pPort->pDraw->width;
+ pxm.height = pPort->pDraw->height;
+ dst = rect;
+
+ fbdev_pixman_convert_image (PIXMAN_OP_SRC,
+ dstbuf, pPixmap->devPrivate.ptr,
+ format, format,
+ &src, &pxm, &src, &dst,
+ NULL, rotate, 0, 0);
+ }
+ else
+ memcpy (pPixmap->devPrivate.ptr, dstbuf,
+ pPort->pDraw->width * pPort->pDraw->height * 4);
+
+ free (dstbuf);
+
+ DamageDamageRegion (pPort->pDraw, pPort->clipBoxes);
+
+ return Success;
+}
+
+static int
+FBDEVVirtualVideoGetPortAttribute (ScrnInfoPtr pScrn,
+ Atom attribute,
+ INT32 *value,
+ pointer data)
+{
+ FBDEVPortPrivPtr pPort = (FBDEVPortPrivPtr) data;
+
+ if (attribute == _fbdevVideoGetPortAtom (PAA_FORMAT))
+ {
+ *value = pPort->id;
+ return Success;
+ }
+ else if (attribute == _fbdevVideoGetPortAtom (PAA_CAPTURE))
+ {
+ *value = pPort->capture;
+ return Success;
+ }
+ else if (attribute == _fbdevVideoGetPortAtom (PAA_DATA_TYPE))
+ {
+ *value = DATA_TYPE_UI;
+ return Success;
+ }
+
+ return BadMatch;
+}
+
+static int
+FBDEVVirtualVideoSetPortAttribute (ScrnInfoPtr pScrn,
+ Atom attribute,
+ INT32 value,
+ pointer data)
+{
+ FBDEVPortPrivPtr pPort = (FBDEVPortPrivPtr) data;
+
+ if (attribute == _fbdevVideoGetPortAtom (PAA_FORMAT))
+ {
+ if (!_fbdevVirtualVideoIsSupport ((unsigned int)value))
+ {
+ DRVLOG ("[%s] id(%c%c%c%c) not supported.\n", __FUNCTION__,
+ value & 0xFF, (value & 0xFF00) >> 8,
+ (value & 0xFF0000) >> 16, (value & 0xFF000000) >> 24);
+ return BadRequest;
+ }
+
+ pPort->id = (unsigned int)value;
+ DRVLOG ("[%s] id(%d) \n", __FUNCTION__, value);
+ return Success;
+ }
+ else if (attribute == _fbdevVideoGetPortAtom (PAA_CAPTURE))
+ {
+ pPort->capture = (value > 0) ? TRUE : FALSE;
+ DRVLOG ("[%s] capture(%d) \n", __FUNCTION__, pPort->capture);
+ return Success;
+ }
+ else if (attribute == _fbdevVideoGetPortAtom (PAA_STREAMOFF))
+ {
+ DRVLOG ("[%s] STREAM_OFF! \n", __FUNCTION__);
+ _fbdevVirtualVideoStreamOff (pPort);
+ return Success;
+ }
+
+ return BadMatch;
+}
+
+/* vid_w, vid_h : no meaning for us. not using.
+ * dst_w, dst_h : size to hope for PutStill.
+ * p_w, p_h : real size for PutStill.
+ */
+static void
+FBDEVVirtualVideoQueryBestSize (ScrnInfoPtr pScrn,
+ Bool motion,
+ short vid_w, short vid_h,
+ short dst_w, short dst_h,
+ unsigned int *p_w, unsigned int *p_h,
+ pointer data)
+{
+ if (p_w)
+ *p_w = (unsigned int)dst_w;
+ if (p_h)
+ *p_h = (unsigned int)dst_h;
+}
+
+/* vid_x, vid_y, vid_w, vid_h : no meaning for us. not using.
+ * drw_x, drw_y, dst_w, dst_h : no meaning for us. not using.
+ * Only pDraw's size is used.
+ */
+static int
+FBDEVVirtualVideoPutStill (ScrnInfoPtr pScrn,
+ short vid_x, short vid_y, short drw_x, short drw_y,
+ short vid_w, short vid_h, short drw_w, short drw_h,
+ RegionPtr clipBoxes, pointer data, DrawablePtr pDraw )
+{
+ FBDEVPortPrivPtr pPort = (FBDEVPortPrivPtr) data;
+ int ret = BadRequest;
+ PixmapPtr pPixmap;
+
+ _fbdevVideoEnsureBlackBuffer (pPort, pDraw->width, pDraw->height);
+
+ goto_if_fail (pPort->id > 0, get_still_fail);
+
+ ret = _fbdevVirtualVideoPreProcess (pScrn, pPort, clipBoxes, pDraw);
+ goto_if_fail (ret == Success, get_still_fail);
+
+ ret = _fbdevVirtualVideoAddDrawableEvent (pPort);
+ goto_if_fail (ret == Success, get_still_fail);
+
+ if (!pPort->capture)
+ {
+ DRVLOG ("[%s] emulfb supports only capture mode. \n", __FUNCTION__);
+ goto get_still_fail;
+ }
+
+ /* check drawable */
+ return_val_if_fail (pDraw->type == DRAWABLE_PIXMAP, BadPixmap);
+
+ ret = _fbdevVirtualVideoCompositeLayers (pPort);
+ goto_if_fail (ret == Success, get_still_fail);
+
+ return Success;
+
+get_still_fail:
+ pPixmap = _fbdevVirtualVideoGetPixmap (pDraw);
+
+ if (pPixmap->devPrivate.ptr && pPort->black)
+ memcpy (pPixmap->devPrivate.ptr, pPort->black,
+ pPort->pDraw->width * pPort->pDraw->height * 4);
+
+ DamageDamageRegion (pPort->pDraw, clipBoxes);
+
+ return ret;
+}
+
+static void
+FBDEVVirtualVideoStop (ScrnInfoPtr pScrn, pointer data, Bool exit)
+{
+ FBDEVPortPrivPtr pPort = (FBDEVPortPrivPtr) data;
+
+ _fbdevVirtualVideoStreamOff (pPort);
+}
+
+XF86VideoAdaptorPtr
+fbdevVideoSetupVirtualVideo (ScreenPtr pScreen)
+{
+ XF86VideoAdaptorPtr pAdaptor;
+ FBDEVPortPrivPtr pPort;
+ int i;
+
+ pAdaptor = calloc (1, sizeof (XF86VideoAdaptorRec) +
+ (sizeof (DevUnion) + sizeof (FBDEVPortPriv)) * FBDEV_MAX_PORT);
+ if (!pAdaptor)
+ return NULL;
+
+ dummy_encoding[0].width = pScreen->width;
+ dummy_encoding[0].height = pScreen->height;
+
+ pAdaptor->type = XvWindowMask | XvPixmapMask | XvInputMask | XvStillMask;
+ pAdaptor->flags = 0;
+ pAdaptor->name = "FBDEV Virtual Video";
+ pAdaptor->nEncodings = sizeof (dummy_encoding) / sizeof (XF86VideoEncodingRec);
+ pAdaptor->pEncodings = dummy_encoding;
+ pAdaptor->nFormats = NUM_FORMATS;
+ pAdaptor->pFormats = formats;
+ pAdaptor->nPorts = FBDEV_MAX_PORT;
+ pAdaptor->pPortPrivates = (DevUnion*)(&pAdaptor[1]);
+
+ pPort = (FBDEVPortPrivPtr) (&pAdaptor->pPortPrivates[FBDEV_MAX_PORT]);
+
+ for (i = 0; i < FBDEV_MAX_PORT; i++)
+ {
+ pAdaptor->pPortPrivates[i].ptr = &pPort[i];
+ pPort[i].index = i;
+ pPort[i].id = FOURCC_RGB32;
+ }
+
+ pAdaptor->nAttributes = NUM_ATTRIBUTES;
+ pAdaptor->pAttributes = attributes;
+ pAdaptor->nImages = NUM_IMAGES;
+ pAdaptor->pImages = images;
+
+ pAdaptor->GetPortAttribute = FBDEVVirtualVideoGetPortAttribute;
+ pAdaptor->SetPortAttribute = FBDEVVirtualVideoSetPortAttribute;
+ pAdaptor->QueryBestSize = FBDEVVirtualVideoQueryBestSize;
+ pAdaptor->PutStill = FBDEVVirtualVideoPutStill;
+ pAdaptor->StopVideo = FBDEVVirtualVideoStop;
+
+ if (!_fbdevVirtualVideoRegisterEventResourceTypes ())
+ {
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ xf86DrvMsg (pScrn->scrnIndex, X_ERROR, "Failed to register EventResourceTypes. \n");
+ return NULL;
+ }
+
+ return pAdaptor;
+}
--- /dev/null
+/**************************************************************************
+
+xserver-xorg-video-emulfb
+
+Copyright 2010 - 2011 Samsung Electronics co., Ltd. All Rights Reserved.
+
+Contact: Boram Park <boram1288.park@samsung.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sub license, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+#ifndef __FBDEV_VIDEO_VIRTUAL_H__
+#define __FBDEV_VIDEO_VIRTUAL_H__
+
+/* setup virtual adaptor */
+XF86VideoAdaptorPtr fbdevVideoSetupVirtualVideo (ScreenPtr pScreen);
+
+#endif // __FBDEV_VIDEO_VIRTUAL_H__
--- /dev/null
+/**************************************************************************
+
+xserver-xorg-video-emulfb
+
+Copyright 2010 - 2011 Samsung Electronics co., Ltd. All Rights Reserved.
+
+Contact: Boram Park <boram1288.park@samsung.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sub license, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <X11/extensions/Xv.h>
+#include <X11/extensions/Xvproto.h>
+
+#include "fbdev_util.h"
+#include "fbdev_video_v4l2.h"
+
+#include "fbdev.h"
+#include "fbdev_fb.h"
+#include "fbdev_util.h"
+#include "fbdev_video.h"
+#include "fbdev_video_fourcc.h"
+#include "fbdev_pixman.h"
+
+#define BUF_NUM 1
+
+typedef struct _DeviceInfo
+{
+ char *video; /* video */
+ int bOpened;
+} DeviceInfo;
+
+typedef struct _FormatInfo
+{
+ int id;
+ int type;
+ uint pixelformat;
+ FBDevV4l2Memory memory;
+} FormatInfo;
+
+typedef struct
+{
+ int index;
+
+ ScreenPtr pScreen;
+
+ int video_fd;
+
+ struct
+ {
+ int init;
+ xRectangle img;
+ xRectangle crop;
+ xRectangle dst;
+ int id;
+ int hw_rotate;
+ int scn_rotate;
+ int hflip;
+ int vflip;
+ int streamon;
+ int cur_idx;
+
+ void* last_buffer;
+ int queued_index;
+
+ void* backup;
+ Bool sync;
+ } status;
+
+ int size;
+ unsigned int pixfmt;
+ FBDevV4l2FimcBuffer fimcbuf;
+ FBDevV4l2SrcBuffer *src_buf;
+ FBDevV4l2DstBuffer *dst_buf;
+ FBDevV4l2Memory memory;
+
+ int offset_x;
+ int offset_y;
+
+ int re_setting;
+
+ void *aligned_buffer;
+ int aligned_width;
+} FBDevDispHandle;
+
+enum
+{
+ TYPE_RGB,
+ TYPE_YUV444,
+ TYPE_YUV422,
+ TYPE_YUV420,
+};
+
+static FormatInfo format_infos [] =
+{
+ { FOURCC_RGB565, TYPE_RGB, V4L2_PIX_FMT_RGB565, V4L2_MEMORY_MMAP },
+ { FOURCC_RGB32, TYPE_RGB, V4L2_PIX_FMT_RGB32, V4L2_MEMORY_MMAP },
+ { FOURCC_I420, TYPE_YUV420, V4L2_PIX_FMT_YUV420, V4L2_MEMORY_MMAP },
+ { FOURCC_YUY2, TYPE_YUV422, V4L2_PIX_FMT_YUYV, V4L2_MEMORY_MMAP },
+ { FOURCC_YV12, TYPE_YUV420, V4L2_PIX_FMT_YVU420, V4L2_MEMORY_MMAP },
+
+};
+
+static XF86ImageRec Images[] =
+{
+ XVIMAGE_I420,
+ XVIMAGE_YV12,
+ XVIMAGE_YUY2,
+ XVIMAGE_RGB32,
+ XVIMAGE_RGB565,
+};
+
+static DeviceInfo device_infos[] =
+{
+ { "/dev/video1", FALSE },
+ { "/dev/video2", FALSE },
+};
+
+#define NUM_IMAGES (sizeof(Images) / sizeof(XF86ImageRec))
+#define DEVICE_NUMS (sizeof (device_infos) / sizeof (DeviceInfo))
+
+static Bool
+_fbdevVideoV4l2SetDst (int fd, int offset_x, int offset_y, xRectangle *rect)
+{
+ struct v4l2_format format = {0,};
+ int caps;
+
+ return_val_if_fail (fd >= 0, FALSE);
+
+ DRVLOG ("[SetDst] offset(%d,%d) win(%d,%d %dx%d) \n", offset_x, offset_y,
+ rect->x, rect->y, rect->width, rect->height);
+
+ caps = V4L2_CAP_VIDEO_OVERLAY;
+ if (!fbdev_v4l2_querycap (fd, caps))
+ return FALSE;
+
+ /* set format */
+ CLEAR (format);
+ format.type = V4L2_BUF_TYPE_VIDEO_OVERLAY;
+ if (!fbdev_v4l2_g_fmt (fd, &format))
+ return FALSE;
+
+ format.fmt.win.w.left = rect->x + offset_x;
+ format.fmt.win.w.top = rect->y + offset_y;
+ format.fmt.win.w.width = rect->width;
+ format.fmt.win.w.height = rect->height;
+ if (!fbdev_v4l2_s_fmt (fd, &format))
+ return FALSE;
+
+ return TRUE;
+}
+
+static Bool
+_fbdevVideoV4l2SetBuffer (int fd,
+ FBDevV4l2BufType type,
+ FBDevV4l2Memory memory,
+ int num_buf,
+ FBDevV4l2DstBuffer **mem_buf)
+{
+ struct v4l2_requestbuffers req = {0,};
+
+ return_val_if_fail (fd >= 0, FALSE);
+
+ DRVLOG ("[SetBuffer] num_buf(%d) mem_buf(%p) memory(%d)\n",
+ num_buf, mem_buf, memory);
+
+ CLEAR (req);
+ req.count = num_buf;
+ req.type = type;
+ req.memory = memory;
+ if (!fbdev_v4l2_reqbuf (fd, &req))
+ return FALSE;
+
+ if (memory == V4L2_MEMORY_MMAP)
+ {
+ FBDevV4l2DstBuffer *out_buf;
+ int i;
+
+ return_val_if_fail (mem_buf != NULL, FALSE);
+
+ out_buf = calloc (req.count, sizeof (FBDevV4l2DstBuffer));
+ return_val_if_fail (out_buf != NULL, FALSE);
+
+ for (i = 0; i < num_buf; i++)
+ {
+ struct v4l2_buffer buffer = {0,};
+
+ CLEAR (buffer);
+ buffer.index = i;
+ buffer.type = type;
+ buffer.memory = V4L2_MEMORY_MMAP;
+ if (!fbdev_v4l2_querybuf (fd, &buffer))
+ {
+ free (out_buf);
+ return FALSE;
+ }
+
+ out_buf[i].index = buffer.index;
+ out_buf[i].size = buffer.length;
+ out_buf[i].buf = mmap (NULL, buffer.length,
+ PROT_READ | PROT_WRITE , \
+ MAP_SHARED , fd, buffer.m.offset & ~(PAGE_SIZE - 1));
+ out_buf[i].buf += buffer.m.offset & (PAGE_SIZE - 1);
+
+ if (out_buf[i].buf == MAP_FAILED)
+ {
+ xf86DrvMsg (0, X_ERROR, "[SetBuffer] mmap failed. index(%d)\n", i);
+ free (out_buf);
+ return FALSE;
+ }
+ }
+
+ *mem_buf = out_buf;
+ }
+
+ return TRUE;
+}
+
+static Bool
+_fbdevVideoV4l2ClearBuffer (int fd,
+ FBDevV4l2BufType type,
+ FBDevV4l2Memory memory,
+ int num_buf,
+ FBDevV4l2DstBuffer *mem_buf)
+{
+ struct v4l2_requestbuffers req = {0,};
+
+ return_val_if_fail (fd >= 0, FALSE);
+
+ DRVLOG ("[ClearBuffer] memory(%d) num_buf(%d) mem_buf(%p)\n",
+ num_buf, mem_buf, memory);
+
+ if (memory == V4L2_MEMORY_MMAP && mem_buf)
+ {
+ int i;
+
+ for (i = 0; i < num_buf; i++)
+ if (mem_buf[i].buf)
+ if (munmap (mem_buf[i].buf, mem_buf[i].size) == -1)
+ xf86DrvMsg (0, X_WARNING, "[ClearBuffer] Failed to unmap v4l2 buffer at index %d\n", i);
+
+ free (mem_buf);
+ }
+
+ CLEAR (req);
+ req.count = 0;
+ req.type = type;
+ req.memory = memory;
+ if (!fbdev_v4l2_reqbuf (fd, &req))
+ return FALSE;
+
+ return TRUE;
+}
+
+static Bool
+_fbdevVideoV4l2StreamOn (int fd)
+{
+ return_val_if_fail (fd >= 0, FALSE);
+
+ DRVLOG ("[StreamOn] \n");
+
+ if (!fbdev_v4l2_start_overlay (fd))
+ return FALSE;
+
+ return TRUE;
+}
+
+
+static Bool
+_fbdevVideoV4l2StreamOff (int fd)
+{
+ return_val_if_fail (fd >= 0, FALSE);
+
+ DRVLOG ("[StreamOff] \n");
+
+ if (!fbdev_v4l2_stop_overlay (fd))
+ return FALSE;
+
+ return TRUE;
+}
+
+static int
+_open_device (char *device)
+{
+ int fd;
+
+ return_val_if_fail (device != NULL, -1);
+
+ fd = open (device, O_RDWR);
+ if (fd < 0)
+ {
+ xf86DrvMsg (0, X_ERROR, "Cannot open '%s'. fd(%d)\n", device, fd);
+ return -1;
+ }
+
+ DRVLOG ("'%s' opened. fd(%d) \n", device, fd);
+
+ return fd;
+}
+
+static void
+_close_device (int fd)
+{
+ int ret;
+
+ return_if_fail (fd >= 0);
+
+ ret = close (fd);
+ if (ret < 0)
+ {
+ xf86DrvMsg (0, X_ERROR, "Cannot close fd(%d)\n", fd);
+ return;
+ }
+
+ DRVLOG ("fd(%d) closed. \n", fd);
+}
+
+static Bool
+_fbdevVideoV4l2EnsureStreamOff (FBDevDispHandle *hdisp)
+{
+ if (!hdisp->status.streamon)
+ return TRUE;
+
+ if (!_fbdevVideoV4l2StreamOff (hdisp->video_fd))
+ return FALSE;
+
+ hdisp->status.streamon = FALSE;
+
+ return TRUE;
+}
+
+static Bool
+_fbdevVideoV4l2OpenDevice (FBDevDispHandle *hdisp, int index)
+{
+ if (device_infos[index].bOpened)
+ {
+ DRVLOG ("[OpenDevice, %p] Already opened : %s\n", hdisp, device_infos[index].video);
+ return FALSE;
+ }
+
+ hdisp->video_fd = _open_device (device_infos[index].video);
+ if (hdisp->video_fd < 0)
+ return FALSE;
+
+ device_infos[index].bOpened = TRUE;
+
+ return TRUE;
+}
+
+/* This function never failed.
+ * If failed, it means kernel has some problems.
+ * Then a device should be rebooted.
+ */
+static void
+_fbdevVideoV4l2CloseDevice (FBDevDispHandle *hdisp)
+{
+ if (!_fbdevVideoV4l2EnsureStreamOff (hdisp)) // We will consider this as a LCD Off case.
+ xf86DrvMsg (0, X_WARNING, "[CloseDevice, %p] Warning : Cannot stream off!! \n", hdisp);
+
+ if (hdisp->video_fd >= 0)
+ if (!_fbdevVideoV4l2ClearBuffer (hdisp->video_fd,
+ V4L2_BUF_TYPE_VIDEO_OVERLAY,
+ hdisp->memory,
+ BUF_NUM,
+ hdisp->dst_buf))
+ xf86DrvMsg (0, X_WARNING, "[CloseDevice, %p] Warning : Cannot clear buffer!! \n", hdisp);
+
+ hdisp->dst_buf = NULL;
+
+ if (hdisp->video_fd >= 0)
+ {
+ _close_device (hdisp->video_fd);
+ hdisp->video_fd = -1;
+ }
+
+ if (hdisp->aligned_buffer)
+ {
+ free (hdisp->aligned_buffer);
+ hdisp->aligned_buffer = NULL;
+ hdisp->aligned_width = 0;
+ }
+
+ device_infos[hdisp->index].bOpened = FALSE;
+}
+
+int
+fbdevVideoV4l2GetHandleNums (void)
+{
+ return DEVICE_NUMS;
+}
+
+Bool
+fbdevVideoV4l2HandleOpened (int index)
+{
+ return_val_if_fail (index < DEVICE_NUMS, FALSE);
+
+ return device_infos[index].bOpened;
+}
+
+void *
+fbdevVideoV4l2OpenHandle (ScreenPtr pScreen, int index, int requestbuffer)
+{
+ FBDevDispHandle *handle;
+
+ return_val_if_fail (pScreen != NULL, NULL);
+ return_val_if_fail (index < DEVICE_NUMS, NULL);
+
+ handle = (FBDevDispHandle*)calloc (sizeof (FBDevDispHandle), 1);
+
+ return_val_if_fail (handle != NULL, NULL);
+
+ handle->pScreen = pScreen;
+ handle->index = index;
+ handle->status.hw_rotate = -1;
+ handle->status.id = 0;
+ handle->status.cur_idx = -1;
+ handle->status.init = 0;
+ handle->memory = V4L2_MEMORY_MMAP;
+ handle->video_fd = -1;
+
+ if (!_fbdevVideoV4l2OpenDevice (handle, index))
+ {
+ free (handle);
+ return NULL;
+ }
+
+ DRVLOG ("[OpenHandle, %p] Handle(%d) opened. \n", handle, index);
+
+ return handle;
+}
+
+void
+fbdevVideoV4l2CloseHandle (void *handle)
+{
+ FBDevDispHandle *hdisp = (FBDevDispHandle*)handle;
+
+ return_if_fail (handle != NULL);
+
+ _fbdevVideoV4l2CloseDevice ((FBDevDispHandle*)handle);
+
+ if (hdisp->status.backup)
+ {
+ free (hdisp->status.backup);
+ hdisp->status.backup = NULL;
+ }
+
+ DRVLOG ("[CloseHandle, %p] Handle(%d) closed. \n", hdisp, hdisp->index);
+
+ free (handle);
+}
+
+Bool
+fbdevVideoV4l2StreamOn (void *handle)
+{
+ FBDevDispHandle *hdisp = (FBDevDispHandle*)handle;
+ //uint phy_addrs[3];
+
+ return_val_if_fail (hdisp != NULL, FALSE);
+
+ hdisp->re_setting = TRUE;
+
+ if (!_fbdevVideoV4l2OpenDevice (hdisp, hdisp->index))
+ return FALSE;
+
+ fbdevVideoV4l2SetFormat (handle,
+ &hdisp->status.img,
+ &hdisp->status.crop,
+ &hdisp->status.dst,
+ hdisp->status.id,
+ hdisp->status.scn_rotate,
+ hdisp->status.hw_rotate,
+ hdisp->status.hflip,
+ hdisp->status.vflip,
+ BUF_NUM,
+ hdisp->status.sync);
+
+ //phy_addrs[0] = hdisp->fimcbuf.base[0];
+ //phy_addrs[1] = hdisp->fimcbuf.base[1];
+ //phy_addrs[2] = hdisp->fimcbuf.base[2];
+
+ if (hdisp->status.backup)
+ {
+ int size;
+
+ size = fbdevVideoQueryImageAttributes (NULL, FOURCC_RGB32,
+ (unsigned short*)&hdisp->status.dst.width,
+ (unsigned short*)&hdisp->status.dst.height,
+ NULL, NULL, NULL);
+
+ memcpy (hdisp->dst_buf[0].buf, hdisp->status.backup, size);
+
+ free (hdisp->status.backup);
+ hdisp->status.backup = NULL;
+ }
+
+ hdisp->re_setting = FALSE;
+
+ DRVLOG ("%s \n", __FUNCTION__);
+
+ return TRUE;
+}
+
+void
+fbdevVideoV4l2StreamOff (void *handle)
+{
+ FBDevDispHandle *hdisp = (FBDevDispHandle*)handle;
+
+ return_if_fail (hdisp != NULL);
+
+ if (hdisp->memory == V4L2_MEMORY_MMAP)
+ {
+ int size;
+
+ if (hdisp->status.backup)
+ {
+ free (hdisp->status.backup);
+ hdisp->status.backup = NULL;
+ }
+
+ size = fbdevVideoQueryImageAttributes (NULL, FOURCC_RGB32,
+ (unsigned short*)&hdisp->status.dst.width,
+ (unsigned short*)&hdisp->status.dst.height,
+ NULL, NULL, NULL);
+
+ if (size > 0)
+ hdisp->status.backup = malloc (size);
+
+ if (hdisp->status.backup &&
+ hdisp->dst_buf &&
+ hdisp->dst_buf[hdisp->status.queued_index].buf)
+ {
+ memcpy (hdisp->status.backup,
+ hdisp->dst_buf[hdisp->status.queued_index].buf,
+ size);
+ }
+ }
+
+ _fbdevVideoV4l2CloseDevice (hdisp);
+
+ DRVLOG ("%s \n", __FUNCTION__);
+}
+
+void
+fbdevVideoV4l2VideoOffset (void *handle, int x, int y)
+{
+ FBDevDispHandle *hdisp = (FBDevDispHandle*)handle;
+
+ return_if_fail (handle != NULL);
+
+ DRVLOG ("[VideoOffset, %p] to %d,%d\n", hdisp, x, y);
+
+ if (hdisp->offset_x == x && hdisp->offset_y == y)
+ return;
+
+ if (!_fbdevVideoV4l2SetDst (hdisp->video_fd, x, y, &hdisp->status.dst))
+ {
+ xf86DrvMsg (0, X_ERROR, "[VideoOffset, %p] _fbdevVideoV4l2SetDst is failed. \n", hdisp);
+ return;
+ }
+
+ hdisp->offset_x = x;
+ hdisp->offset_y = y;
+}
+
+/* img->x, img->y : not used. */
+Bool
+fbdevVideoV4l2SetFormat (void *handle,
+ xRectangle *img, xRectangle *crop, xRectangle *dst,
+ uint id,
+ int scn_rotate,
+ int hw_rotate,
+ int hflip,
+ int vflip,
+ int requestbuffer,
+ Bool sync)
+{
+ FBDevDispHandle *hdisp = (FBDevDispHandle*)handle;
+ Bool src_changed = FALSE;
+ Bool dst_changed = FALSE;
+ Bool buf_changed = FALSE;
+
+ return_val_if_fail (handle != NULL, FALSE);
+ return_val_if_fail (img != NULL, FALSE);
+ return_val_if_fail (crop != NULL, FALSE);
+ return_val_if_fail (dst != NULL, FALSE);
+
+ DRVLOG ("[SetFormat, %p] try to set : img(%d,%d %dx%d) crop(%d,%d %dx%d) dst(%d,%d %dx%d) id(%x), rot(%d), flip(%d,%d) req(%d)\n", hdisp,
+ img->x, img->y, img->width, img->height,
+ crop->x, crop->y, crop->width, crop->height,
+ dst->x, dst->y, dst->width, dst->height,
+ id, hw_rotate, hflip, vflip, requestbuffer);
+
+ if (memcmp (&hdisp->status.img, img, sizeof (xRectangle)) ||
+ memcmp (&hdisp->status.crop, crop, sizeof (xRectangle)) ||
+ hdisp->status.id != id)
+ src_changed = TRUE;
+
+ if (memcmp (&hdisp->status.dst, dst, sizeof (xRectangle)) ||
+ hdisp->status.hw_rotate != hw_rotate ||
+ hdisp->status.hflip != hflip ||
+ hdisp->status.vflip != vflip)
+ dst_changed = TRUE;
+
+ if (hdisp->status.init && (src_changed || dst_changed || buf_changed))
+ {
+ _fbdevVideoV4l2CloseDevice (hdisp);
+ _fbdevVideoV4l2OpenDevice (hdisp, hdisp->index);
+
+ DRVLOG ("[SetFormat, %p] changed : img(%d) dst(%d) buf(%d) \n", hdisp,
+ src_changed, dst_changed, buf_changed);
+
+ /* After close device, below all steps should be done. */
+ src_changed = dst_changed = buf_changed = TRUE;
+ hdisp->status.init = 0;
+ }
+
+ if (hdisp->re_setting)
+ src_changed = dst_changed = buf_changed = TRUE;
+
+ if (src_changed || dst_changed || buf_changed)
+ {
+ fbdevVideoV4l2GetFormatInfo (id, NULL, &hdisp->pixfmt, &hdisp->memory);
+
+ DRVLOG ("[SetFormat, %p] id(%c%c%c%c) => pixfmt(%d) memory(%d) \n", hdisp,
+ id & 0xFF, (id & 0xFF00) >> 8, (id & 0xFF0000) >> 16, (id & 0xFF000000) >> 24,
+ hdisp->pixfmt, hdisp->memory);
+
+ hdisp->status.img = *img;
+ hdisp->status.crop = *crop;
+ hdisp->status.id = id;
+ hdisp->status.sync = sync;
+ hdisp->status.init = 1;
+
+ hdisp->status.cur_idx = 0;
+ hdisp->status.hw_rotate = hw_rotate;
+ hdisp->status.scn_rotate = scn_rotate;
+ hdisp->status.hflip = hflip;
+ hdisp->status.vflip = vflip;
+ hdisp->status.dst = *dst;
+
+ if (!_fbdevVideoV4l2SetDst (hdisp->video_fd, hdisp->offset_x, hdisp->offset_y, dst))
+ {
+ xf86DrvMsg (0, X_ERROR, "[SetFormat, %p] _fbdevVideoV4l2SetDst is failed. \n", hdisp);
+ return FALSE;
+ }
+
+ if (!_fbdevVideoV4l2SetBuffer (hdisp->video_fd,
+ V4L2_BUF_TYPE_VIDEO_OVERLAY,
+ hdisp->memory,
+ BUF_NUM,
+ &hdisp->dst_buf))
+ {
+ xf86DrvMsg (0, X_ERROR, "[SetFormat, %p] _fbdevVideoV4l2SetBuffer is failed. \n", hdisp);
+ return FALSE;
+ }
+
+ hdisp->status.cur_idx = 0;
+ }
+
+ if (!hdisp->status.streamon)
+ {
+ _fbdevVideoV4l2StreamOn (hdisp->video_fd);
+ hdisp->status.streamon = TRUE;
+ }
+
+ return TRUE;
+}
+
+XF86ImagePtr
+fbdevVideoV4l2SupportImages (int *count)
+{
+ if (count)
+ *count = NUM_IMAGES;
+
+ return Images;
+}
+
+int
+fbdevVideoV4l2Draw (void *handle, uchar *buf, uint *phy_addrs)
+{
+ FBDevDispHandle *hdisp = (FBDevDispHandle*)handle;
+ pixman_format_code_t src_format, dst_format;
+ xRectangle img = hdisp->status.img;
+ xRectangle src = hdisp->status.crop;
+ xRectangle pxm = hdisp->status.dst;
+ xRectangle dst = hdisp->status.dst;
+
+ pxm.x = pxm.y = dst.x = dst.y = 0;
+
+ switch (hdisp->pixfmt)
+ {
+ case V4L2_PIX_FMT_YUV420:
+ case V4L2_PIX_FMT_YVU420:
+ src_format = PIXMAN_yv12;
+ break;
+ case V4L2_PIX_FMT_YUYV:
+ src_format = PIXMAN_yuy2;
+ break;
+ case V4L2_PIX_FMT_RGB565:
+ src_format = PIXMAN_r5g6b5;
+ break;
+ case V4L2_PIX_FMT_RGB24:
+ src_format = PIXMAN_r8g8b8;
+ break;
+ case V4L2_PIX_FMT_RGB32:
+ src_format = PIXMAN_a8r8g8b8;
+ break;
+ default:
+ return FALSE;
+ }
+
+ switch (hdisp->pixfmt)
+ {
+ case V4L2_PIX_FMT_YUV420:
+ dst_format = PIXMAN_x8b8g8r8;
+ break;
+ default:
+ dst_format = PIXMAN_x8r8g8b8;
+ break;
+ }
+
+ if (src_format == PIXMAN_yv12 && img.width % 16)
+ {
+ int src_p[3] = {0,}, src_o[3] = {0,}, src_l[3] = {0,};
+ int dst_p[3] = {0,}, dst_o[3] = {0,}, dst_l[3] = {0,};
+ unsigned short src_w, src_h, dst_w, dst_h;
+ int size;
+
+ src_w = img.width;
+ src_h = img.height;
+ fbdevVideoQueryImageAttributes (NULL, FOURCC_I420, &src_w, &src_h,
+ src_p, src_o, src_l);
+
+ dst_w = (img.width + 15) & ~15;
+ dst_h = img.height;
+ size = fbdevVideoQueryImageAttributes (NULL, FOURCC_I420, &dst_w, &dst_h,
+ dst_p, dst_o, dst_l);
+
+ if (!hdisp->aligned_buffer)
+ {
+ hdisp->aligned_buffer = malloc (size);
+ if (!hdisp->aligned_buffer)
+ return FALSE;
+ }
+
+ fbdev_util_copy_image (src_w, src_h,
+ (char*)buf, src_w, src_h,
+ src_p, src_o, src_l,
+ (char*)hdisp->aligned_buffer, dst_w, dst_h,
+ dst_p, dst_o, dst_l,
+ 3, 2, 2);
+
+ hdisp->aligned_width = dst_w;
+ img.width = dst_w;
+ buf = hdisp->aligned_buffer;
+ }
+
+ /* support only RGB */
+ fbdev_pixman_convert_image (PIXMAN_OP_SRC,
+ buf, hdisp->dst_buf[0].buf,
+ src_format, dst_format,
+ &img, &pxm, &src, &dst,
+ NULL, (hdisp->status.hw_rotate + (360 - hdisp->status.scn_rotate)) % 360,
+ hdisp->status.hflip, hdisp->status.vflip);
+
+ return TRUE;
+}
+
+Bool
+fbdevVideoV4l2GetFormatInfo (int id, int *type, uint *pixelformat, FBDevV4l2Memory *memory)
+{
+ int i;
+
+ for (i = 0; i < sizeof (format_infos) / sizeof (FormatInfo); i++)
+ if (format_infos[i].id == id)
+ {
+ if (type)
+ *type = format_infos[i].type;
+ if (pixelformat)
+ *pixelformat = format_infos[i].pixelformat;
+ if (memory)
+ *memory = format_infos[i].memory;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/* img : original src size
+ * src : real src size (cropped area inside img)
+ * dst : real dst size
+ * original dst size (in case that image is drawn on opened framebuffer)
+ */
+Bool
+fbdevVideoV4l2CheckSize (void *handle, uint pixelformat,
+ xRectangle *img, xRectangle *src, xRectangle *dst,
+ int type, int memory)
+{
+ /* img */
+ if (img)
+ {
+ if (img->width % 16)
+ xf86DrvMsg (0, X_WARNING, "img's width(%d) is not multiple of 16!!!\n", img->width);
+
+ if (type == TYPE_YUV420 && img->height % 2)
+ xf86DrvMsg (0, X_WARNING, "img's height(%d) is not multiple of 2!!!\n", img->height);
+
+ return_val_if_fail (img->width >= 16, FALSE);
+ return_val_if_fail (img->height >= 16, FALSE);
+ }
+
+ /* src */
+ if (src)
+ {
+ if (type == TYPE_YUV420 || type == TYPE_YUV422)
+ {
+ src->x = src->x & (~0x1);
+ src->width = src->width & (~0x1);
+ }
+
+ if (type == TYPE_YUV420)
+ src->height = src->height & (~0x1);
+
+ return_val_if_fail (src->width >= 16, FALSE);
+ return_val_if_fail (src->height >= 16, FALSE);
+ }
+
+ /* dst */
+ if (dst)
+ {
+ dst->width = dst->width & (~0x1);
+ dst->height = dst->height & (~0x1);
+
+ return_val_if_fail (dst->width >= 8, FALSE);
+ return_val_if_fail (dst->height >= 8, FALSE);
+ }
+
+ return TRUE;
+}
+
+void
+fbdevVideoGetFBInfo (void *handle, void **base, xRectangle *pos)
+{
+ FBDevDispHandle *hdisp = (FBDevDispHandle*)handle;
+
+ if (!hdisp)
+ return;
+
+ if (pos)
+ *pos = hdisp->status.dst;
+ if (base)
+ *base = hdisp->dst_buf[0].buf;
+}
--- /dev/null
+/**************************************************************************
+
+xserver-xorg-video-emulfb
+
+Copyright 2010 - 2011 Samsung Electronics co., Ltd. All Rights Reserved.
+
+Contact: YoungHoon Jung <yhoon.jung@samsung.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sub license, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/* */
+/* File name : xv_types.h */
+/* Author : YoungHoon Jung (yhoon.jung@samsung.com) */
+/* Protocol Version : 1.0.1 (Dec 16th 2009) */
+/* This file is for describing Xv APIs' buffer encoding method. */
+/* */
+
+#define XV_PUTIMAGE_HEADER 0xDEADCD01
+#define XV_PUTIMAGE_VERSION 0x00010001
+
+/* Return Values */
+#define XV_OK 0
+#define XV_HEADER_ERROR -1
+#define XV_VERSION_MISMATCH -2
+
+/* Data structure for XvPutImage / XvShmPutImage */
+typedef struct {
+ unsigned int _header; /* for internal use only */
+ unsigned int _version; /* for internal use only */
+
+ unsigned int YPhyAddr;
+ unsigned int CbPhyAddr;
+ unsigned int CrPhyAddr;
+ unsigned int RotAngle;
+ unsigned int VideoMode;
+} XV_PUTIMAGE_DATA, * XV_PUTIMAGE_DATA_PTR;
+
+static void
+#ifdef __GNUC__
+__attribute__ ((unused))
+#endif
+XV_PUTIMAGE_INIT_DATA(XV_PUTIMAGE_DATA_PTR data)
+{
+ data->_header = XV_PUTIMAGE_HEADER;
+ data->_version = XV_PUTIMAGE_VERSION;
+}
+
+
+static int
+#ifdef __GNUC__
+__attribute__ ((unused))
+#endif
+XV_PUTIMAGE_VALIDATE_DATA(XV_PUTIMAGE_DATA_PTR data)
+{
+ if (data->_header != XV_PUTIMAGE_HEADER)
+ return XV_HEADER_ERROR;
+ if (data->_version != XV_PUTIMAGE_VERSION)
+ return XV_VERSION_MISMATCH;
+ return XV_OK;
+}