Initialize Tizen 2.3 tizen_2.3 2.3a_release submit/tizen_2.3/20140531.114846 submit/tizen_2.3/20150202.053011 tizen_2.3_release
authorSehong Na <sehong.na@samsung.com>
Sat, 31 May 2014 04:20:51 +0000 (13:20 +0900)
committerSehong Na <sehong.na@samsung.com>
Sat, 31 May 2014 04:20:51 +0000 (13:20 +0900)
44 files changed:
AUTHORS [new file with mode: 0644]
COPYING [new file with mode: 0644]
ChangeLog [new file with mode: 0644]
Makefile.am [new file with mode: 0644]
autogen.sh [new file with mode: 0755]
configure.ac [new file with mode: 0644]
man/Makefile.am [new file with mode: 0644]
man/emulfb.man [new file with mode: 0644]
packaging/xorg-x11-drv-emulfb.spec [new file with mode: 0644]
src/Makefile.am [new file with mode: 0644]
src/crtcconfig/fbdev_crtc.c [new file with mode: 0644]
src/crtcconfig/fbdev_crtc_priv.h [new file with mode: 0644]
src/crtcconfig/fbdev_crtcconfig.c [new file with mode: 0644]
src/crtcconfig/fbdev_crtcconfig.h [new file with mode: 0644]
src/crtcconfig/fbdev_mode.c [new file with mode: 0644]
src/crtcconfig/fbdev_mode.h [new file with mode: 0644]
src/crtcconfig/fbdev_output_priv.h [new file with mode: 0644]
src/crtcconfig/lcd_output.c [new file with mode: 0644]
src/debug/fbdev_event_trace.c [new file with mode: 0755]
src/debug/fbdev_event_trace.h [new file with mode: 0644]
src/fb/fbdev_fb.c [new file with mode: 0644]
src/fb/fbdev_fb.h [new file with mode: 0644]
src/fbdev.c [new file with mode: 0644]
src/fbdev.h [new file with mode: 0644]
src/fbdev_dpms.c [new file with mode: 0644]
src/fbdev_dpms.h [new file with mode: 0644]
src/fbdevhw/fbdev_hw.c [new file with mode: 0644]
src/fbdevhw/fbdev_hw.h [new file with mode: 0644]
src/util/fbdev_pixman.c [new file with mode: 0644]
src/util/fbdev_pixman.h [new file with mode: 0644]
src/util/fbdev_util.c [new file with mode: 0644]
src/util/fbdev_util.h [new file with mode: 0644]
src/xv/arm/fbdev_video_v4l2.c [new file with mode: 0644]
src/xv/fbdev_v4l2.c [new file with mode: 0644]
src/xv/fbdev_v4l2.h [new file with mode: 0644]
src/xv/fbdev_video.c [new file with mode: 0644]
src/xv/fbdev_video.h [new file with mode: 0644]
src/xv/fbdev_video_fourcc.h [new file with mode: 0644]
src/xv/fbdev_video_types.h [new file with mode: 0644]
src/xv/fbdev_video_v4l2.h [new file with mode: 0644]
src/xv/fbdev_video_virtual.c [new file with mode: 0644]
src/xv/fbdev_video_virtual.h [new file with mode: 0644]
src/xv/i386/fbdev_video_v4l2.c [new file with mode: 0644]
src/xv/xv_types.h [new file with mode: 0644]

diff --git a/AUTHORS b/AUTHORS
new file mode 100644 (file)
index 0000000..edf3b5c
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1,3 @@
+SooChan Lim <sc1.lim@samsung.com>
+SangJin Lee <lsj119@samsung.com>
+Boram Park <boram1288.park@samsung.com>
diff --git a/COPYING b/COPYING
new file mode 100644 (file)
index 0000000..05596fe
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,24 @@
+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.
diff --git a/ChangeLog b/ChangeLog
new file mode 100644 (file)
index 0000000..181a903
--- /dev/null
+++ b/ChangeLog
@@ -0,0 +1,5 @@
+2010-08-30  SooChan Lim  <sc1.lim@samsung.com>
+
+       Initial version of xserver-xorg-video-emulfb
+
+
diff --git a/Makefile.am b/Makefile.am
new file mode 100644 (file)
index 0000000..7052905
--- /dev/null
@@ -0,0 +1,22 @@
+#  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
diff --git a/autogen.sh b/autogen.sh
new file mode 100755 (executable)
index 0000000..218197d
--- /dev/null
@@ -0,0 +1,12 @@
+#! /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 "$@"
diff --git a/configure.ac b/configure.ac
new file mode 100644 (file)
index 0000000..6b63778
--- /dev/null
@@ -0,0 +1,117 @@
+#  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
+])
diff --git a/man/Makefile.am b/man/Makefile.am
new file mode 100644 (file)
index 0000000..ecd9bb8
--- /dev/null
@@ -0,0 +1,57 @@
+# $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) < $< > $@
diff --git a/man/emulfb.man b/man/emulfb.man
new file mode 100644 (file)
index 0000000..aed60ce
--- /dev/null
@@ -0,0 +1,63 @@
+.\" $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
diff --git a/packaging/xorg-x11-drv-emulfb.spec b/packaging/xorg-x11-drv-emulfb.spec
new file mode 100644 (file)
index 0000000..0183b96
--- /dev/null
@@ -0,0 +1,71 @@
+# >> 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}
diff --git a/src/Makefile.am b/src/Makefile.am
new file mode 100644 (file)
index 0000000..7eaedb7
--- /dev/null
@@ -0,0 +1,80 @@
+#  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
+
diff --git a/src/crtcconfig/fbdev_crtc.c b/src/crtcconfig/fbdev_crtc.c
new file mode 100644 (file)
index 0000000..478836d
--- /dev/null
@@ -0,0 +1,250 @@
+/**************************************************************************
+
+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;
+
+}
+
+
diff --git a/src/crtcconfig/fbdev_crtc_priv.h b/src/crtcconfig/fbdev_crtc_priv.h
new file mode 100644 (file)
index 0000000..7919fab
--- /dev/null
@@ -0,0 +1,45 @@
+/**************************************************************************
+
+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_
diff --git a/src/crtcconfig/fbdev_crtcconfig.c b/src/crtcconfig/fbdev_crtcconfig.c
new file mode 100644 (file)
index 0000000..412162b
--- /dev/null
@@ -0,0 +1,139 @@
+/**************************************************************************
+
+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;
+
+}
diff --git a/src/crtcconfig/fbdev_crtcconfig.h b/src/crtcconfig/fbdev_crtcconfig.h
new file mode 100644 (file)
index 0000000..d84928a
--- /dev/null
@@ -0,0 +1,37 @@
+/**************************************************************************
+
+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_
diff --git a/src/crtcconfig/fbdev_mode.c b/src/crtcconfig/fbdev_mode.c
new file mode 100644 (file)
index 0000000..446417d
--- /dev/null
@@ -0,0 +1,173 @@
+/**************************************************************************
+
+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;
+}
diff --git a/src/crtcconfig/fbdev_mode.h b/src/crtcconfig/fbdev_mode.h
new file mode 100644 (file)
index 0000000..3cd7417
--- /dev/null
@@ -0,0 +1,44 @@
+/**************************************************************************
+
+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
+
+
diff --git a/src/crtcconfig/fbdev_output_priv.h b/src/crtcconfig/fbdev_output_priv.h
new file mode 100644 (file)
index 0000000..ade694b
--- /dev/null
@@ -0,0 +1,46 @@
+/**************************************************************************
+
+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_
+
+
diff --git a/src/crtcconfig/lcd_output.c b/src/crtcconfig/lcd_output.c
new file mode 100644 (file)
index 0000000..b47f333
--- /dev/null
@@ -0,0 +1,300 @@
+/**************************************************************************
+
+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;
+
+}
diff --git a/src/debug/fbdev_event_trace.c b/src/debug/fbdev_event_trace.c
new file mode 100755 (executable)
index 0000000..120633a
--- /dev/null
@@ -0,0 +1,100 @@
+/**************************************************************************
+
+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;
+}
+
diff --git a/src/debug/fbdev_event_trace.h b/src/debug/fbdev_event_trace.h
new file mode 100644 (file)
index 0000000..1b0dbbd
--- /dev/null
@@ -0,0 +1,38 @@
+/**************************************************************************
+
+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 */
+
diff --git a/src/fb/fbdev_fb.c b/src/fb/fbdev_fb.c
new file mode 100644 (file)
index 0000000..7cd4e05
--- /dev/null
@@ -0,0 +1,298 @@
+/**************************************************************************
+
+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;
+       }
+}
diff --git a/src/fb/fbdev_fb.h b/src/fb/fbdev_fb.h
new file mode 100644 (file)
index 0000000..6fa8c15
--- /dev/null
@@ -0,0 +1,54 @@
+/**************************************************************************
+
+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
diff --git a/src/fbdev.c b/src/fbdev.c
new file mode 100644 (file)
index 0000000..45c1f19
--- /dev/null
@@ -0,0 +1,771 @@
+/*
+ * 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);
+}
+
+
+
+
diff --git a/src/fbdev.h b/src/fbdev.h
new file mode 100644 (file)
index 0000000..9839e45
--- /dev/null
@@ -0,0 +1,109 @@
+/**************************************************************************
+
+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
+
diff --git a/src/fbdev_dpms.c b/src/fbdev_dpms.c
new file mode 100644 (file)
index 0000000..d9e0806
--- /dev/null
@@ -0,0 +1,140 @@
+/**************************************************************************
+
+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;
+}
+
diff --git a/src/fbdev_dpms.h b/src/fbdev_dpms.h
new file mode 100644 (file)
index 0000000..9633efc
--- /dev/null
@@ -0,0 +1,45 @@
+/**************************************************************************
+
+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 */
+
diff --git a/src/fbdevhw/fbdev_hw.c b/src/fbdevhw/fbdev_hw.c
new file mode 100644 (file)
index 0000000..fd5c0d4
--- /dev/null
@@ -0,0 +1,196 @@
+/**************************************************************************
+
+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;
+       }
+}
diff --git a/src/fbdevhw/fbdev_hw.h b/src/fbdevhw/fbdev_hw.h
new file mode 100644 (file)
index 0000000..1f83443
--- /dev/null
@@ -0,0 +1,51 @@
+/**************************************************************************
+
+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
+
diff --git a/src/util/fbdev_pixman.c b/src/util/fbdev_pixman.c
new file mode 100644 (file)
index 0000000..8455cb8
--- /dev/null
@@ -0,0 +1,170 @@
+/**************************************************************************
+
+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
diff --git a/src/util/fbdev_pixman.h b/src/util/fbdev_pixman.h
new file mode 100644 (file)
index 0000000..a746ea8
--- /dev/null
@@ -0,0 +1,64 @@
+/**************************************************************************
+
+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__ */
diff --git a/src/util/fbdev_util.c b/src/util/fbdev_util.c
new file mode 100644 (file)
index 0000000..4a12b04
--- /dev/null
@@ -0,0 +1,311 @@
+/**************************************************************************
+
+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);
+}
diff --git a/src/util/fbdev_util.h b/src/util/fbdev_util.h
new file mode 100644 (file)
index 0000000..27f4b21
--- /dev/null
@@ -0,0 +1,89 @@
+/**************************************************************************
+
+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
diff --git a/src/xv/arm/fbdev_video_v4l2.c b/src/xv/arm/fbdev_video_v4l2.c
new file mode 100644 (file)
index 0000000..49b8df5
--- /dev/null
@@ -0,0 +1,1111 @@
+/**************************************************************************
+
+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;
+}
diff --git a/src/xv/fbdev_v4l2.c b/src/xv/fbdev_v4l2.c
new file mode 100644 (file)
index 0000000..a49305e
--- /dev/null
@@ -0,0 +1,511 @@
+/**************************************************************************
+
+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;
+}
diff --git a/src/xv/fbdev_v4l2.h b/src/xv/fbdev_v4l2.h
new file mode 100644 (file)
index 0000000..931da95
--- /dev/null
@@ -0,0 +1,84 @@
+/**************************************************************************
+
+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
diff --git a/src/xv/fbdev_video.c b/src/xv/fbdev_video.c
new file mode 100644 (file)
index 0000000..763cad8
--- /dev/null
@@ -0,0 +1,1238 @@
+/*
+ * 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++;
+               }
+       }
+}
diff --git a/src/xv/fbdev_video.h b/src/xv/fbdev_video.h
new file mode 100644 (file)
index 0000000..428a8af
--- /dev/null
@@ -0,0 +1,81 @@
+/**************************************************************************
+
+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
diff --git a/src/xv/fbdev_video_fourcc.h b/src/xv/fbdev_video_fourcc.h
new file mode 100644 (file)
index 0000000..8c5f0e2
--- /dev/null
@@ -0,0 +1,196 @@
+/**************************************************************************
+
+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__
diff --git a/src/xv/fbdev_video_types.h b/src/xv/fbdev_video_types.h
new file mode 100644 (file)
index 0000000..3f9f48b
--- /dev/null
@@ -0,0 +1,107 @@
+/**************************************************************************
+
+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
diff --git a/src/xv/fbdev_video_v4l2.h b/src/xv/fbdev_video_v4l2.h
new file mode 100644 (file)
index 0000000..04c9b58
--- /dev/null
@@ -0,0 +1,73 @@
+/**************************************************************************
+
+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
diff --git a/src/xv/fbdev_video_virtual.c b/src/xv/fbdev_video_virtual.c
new file mode 100644 (file)
index 0000000..fe8ac6f
--- /dev/null
@@ -0,0 +1,683 @@
+/**************************************************************************
+
+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;
+}
diff --git a/src/xv/fbdev_video_virtual.h b/src/xv/fbdev_video_virtual.h
new file mode 100644 (file)
index 0000000..fbf363d
--- /dev/null
@@ -0,0 +1,37 @@
+/**************************************************************************
+
+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__
diff --git a/src/xv/i386/fbdev_video_v4l2.c b/src/xv/i386/fbdev_video_v4l2.c
new file mode 100644 (file)
index 0000000..20bc6a1
--- /dev/null
@@ -0,0 +1,880 @@
+/**************************************************************************
+
+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;
+}
diff --git a/src/xv/xv_types.h b/src/xv/xv_types.h
new file mode 100644 (file)
index 0000000..d8465d9
--- /dev/null
@@ -0,0 +1,80 @@
+/**************************************************************************
+
+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;
+}