From 7fe60435bce6595a9c58a9bfd8244d74b5320e96 Mon Sep 17 00:00:00 2001 From: Benjamin Franzke Date: Tue, 15 Jan 2013 08:46:13 +0100 Subject: Import DirectFB141_2k11R3_beta5 --- Source/DirectFB/src/display/Makefile.am | 30 + Source/DirectFB/src/display/Makefile.in | 570 ++++ .../DirectFB/src/display/idirectfbdisplaylayer.c | 1076 ++++++++ .../DirectFB/src/display/idirectfbdisplaylayer.h | 43 + Source/DirectFB/src/display/idirectfbpalette.c | 365 +++ Source/DirectFB/src/display/idirectfbpalette.h | 51 + Source/DirectFB/src/display/idirectfbscreen.c | 722 +++++ Source/DirectFB/src/display/idirectfbscreen.h | 42 + Source/DirectFB/src/display/idirectfbsurface.c | 2841 ++++++++++++++++++++ Source/DirectFB/src/display/idirectfbsurface.h | 123 + .../DirectFB/src/display/idirectfbsurface_layer.c | 244 ++ .../DirectFB/src/display/idirectfbsurface_layer.h | 57 + .../DirectFB/src/display/idirectfbsurface_window.c | 353 +++ .../DirectFB/src/display/idirectfbsurface_window.h | 48 + 14 files changed, 6565 insertions(+) create mode 100755 Source/DirectFB/src/display/Makefile.am create mode 100755 Source/DirectFB/src/display/Makefile.in create mode 100755 Source/DirectFB/src/display/idirectfbdisplaylayer.c create mode 100755 Source/DirectFB/src/display/idirectfbdisplaylayer.h create mode 100755 Source/DirectFB/src/display/idirectfbpalette.c create mode 100755 Source/DirectFB/src/display/idirectfbpalette.h create mode 100755 Source/DirectFB/src/display/idirectfbscreen.c create mode 100755 Source/DirectFB/src/display/idirectfbscreen.h create mode 100755 Source/DirectFB/src/display/idirectfbsurface.c create mode 100755 Source/DirectFB/src/display/idirectfbsurface.h create mode 100755 Source/DirectFB/src/display/idirectfbsurface_layer.c create mode 100755 Source/DirectFB/src/display/idirectfbsurface_layer.h create mode 100755 Source/DirectFB/src/display/idirectfbsurface_window.c create mode 100755 Source/DirectFB/src/display/idirectfbsurface_window.h (limited to 'Source/DirectFB/src/display') diff --git a/Source/DirectFB/src/display/Makefile.am b/Source/DirectFB/src/display/Makefile.am new file mode 100755 index 0000000..ddb1456 --- /dev/null +++ b/Source/DirectFB/src/display/Makefile.am @@ -0,0 +1,30 @@ +## Makefile.am for DirectFB/src/display + +INCLUDES = \ + -I$(top_builddir)/lib \ + -I$(top_builddir)/include \ + -I$(top_srcdir)/include \ + -I$(top_srcdir)/lib \ + -I$(top_srcdir)/src + + +internalincludedir = $(INTERNALINCLUDEDIR)/display + +internalinclude_HEADERS = \ + idirectfbpalette.h \ + idirectfbsurface.h \ + idirectfbsurface_layer.h \ + idirectfbsurface_window.h \ + idirectfbdisplaylayer.h \ + idirectfbscreen.h + + +noinst_LTLIBRARIES = libdirectfb_display.la + +libdirectfb_display_la_SOURCES = \ + idirectfbpalette.c \ + idirectfbsurface.c \ + idirectfbsurface_layer.c \ + idirectfbsurface_window.c \ + idirectfbdisplaylayer.c \ + idirectfbscreen.c diff --git a/Source/DirectFB/src/display/Makefile.in b/Source/DirectFB/src/display/Makefile.in new file mode 100755 index 0000000..312b297 --- /dev/null +++ b/Source/DirectFB/src/display/Makefile.in @@ -0,0 +1,570 @@ +# Makefile.in generated by automake 1.10.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +subdir = src/display +DIST_COMMON = $(internalinclude_HEADERS) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/as-ac-expand.m4 \ + $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +LTLIBRARIES = $(noinst_LTLIBRARIES) +libdirectfb_display_la_LIBADD = +am_libdirectfb_display_la_OBJECTS = idirectfbpalette.lo \ + idirectfbsurface.lo idirectfbsurface_layer.lo \ + idirectfbsurface_window.lo idirectfbdisplaylayer.lo \ + idirectfbscreen.lo +libdirectfb_display_la_OBJECTS = $(am_libdirectfb_display_la_OBJECTS) +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(libdirectfb_display_la_SOURCES) +DIST_SOURCES = $(libdirectfb_display_la_SOURCES) +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = `echo $$p | sed -e 's|^.*/||'`; +am__installdirs = "$(DESTDIR)$(internalincludedir)" +internalincludeHEADERS_INSTALL = $(INSTALL_HEADER) +HEADERS = $(internalinclude_HEADERS) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +AS = @AS@ +ASFLAGS = @ASFLAGS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCAS = @CCAS@ +CCASDEPMODE = @CCASDEPMODE@ +CCASFLAGS = @CCASFLAGS@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DATADIR = @DATADIR@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DFB_CFLAGS_OMIT_FRAME_POINTER = @DFB_CFLAGS_OMIT_FRAME_POINTER@ +DFB_INTERNAL_CFLAGS = @DFB_INTERNAL_CFLAGS@ +DFB_LDFLAGS = @DFB_LDFLAGS@ +DFB_SMOOTH_SCALING = @DFB_SMOOTH_SCALING@ +DIRECTFB_BINARY_AGE = @DIRECTFB_BINARY_AGE@ +DIRECTFB_CSOURCE = @DIRECTFB_CSOURCE@ +DIRECTFB_INTERFACE_AGE = @DIRECTFB_INTERFACE_AGE@ +DIRECTFB_MAJOR_VERSION = @DIRECTFB_MAJOR_VERSION@ +DIRECTFB_MICRO_VERSION = @DIRECTFB_MICRO_VERSION@ +DIRECTFB_MINOR_VERSION = @DIRECTFB_MINOR_VERSION@ +DIRECTFB_VERSION = @DIRECTFB_VERSION@ +DIRECT_BUILD_DEBUG = @DIRECT_BUILD_DEBUG@ +DIRECT_BUILD_DEBUGS = @DIRECT_BUILD_DEBUGS@ +DIRECT_BUILD_GETTID = @DIRECT_BUILD_GETTID@ +DIRECT_BUILD_NETWORK = @DIRECT_BUILD_NETWORK@ +DIRECT_BUILD_STDBOOL = @DIRECT_BUILD_STDBOOL@ +DIRECT_BUILD_TEXT = @DIRECT_BUILD_TEXT@ +DIRECT_BUILD_TRACE = @DIRECT_BUILD_TRACE@ +DSYMUTIL = @DSYMUTIL@ +DYNLIB = @DYNLIB@ +ECHO = @ECHO@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +F77 = @F77@ +FFLAGS = @FFLAGS@ +FREETYPE_CFLAGS = @FREETYPE_CFLAGS@ +FREETYPE_LIBS = @FREETYPE_LIBS@ +FREETYPE_PROVIDER = @FREETYPE_PROVIDER@ +FUSION_BUILD_KERNEL = @FUSION_BUILD_KERNEL@ +FUSION_BUILD_MULTI = @FUSION_BUILD_MULTI@ +FUSION_MESSAGE_SIZE = @FUSION_MESSAGE_SIZE@ +GIF_PROVIDER = @GIF_PROVIDER@ +GREP = @GREP@ +HAVE_LINUX = @HAVE_LINUX@ +INCLUDEDIR = @INCLUDEDIR@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INTERNALINCLUDEDIR = @INTERNALINCLUDEDIR@ +JPEG_PROVIDER = @JPEG_PROVIDER@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBJPEG = @LIBJPEG@ +LIBOBJS = @LIBOBJS@ +LIBPNG = @LIBPNG@ +LIBPNG_CONFIG = @LIBPNG_CONFIG@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_AGE = @LT_AGE@ +LT_BINARY = @LT_BINARY@ +LT_CURRENT = @LT_CURRENT@ +LT_RELEASE = @LT_RELEASE@ +LT_REVISION = @LT_REVISION@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MAN2HTML = @MAN2HTML@ +MKDIR_P = @MKDIR_P@ +MODULEDIR = @MODULEDIR@ +MODULEDIRNAME = @MODULEDIRNAME@ +NMEDIT = @NMEDIT@ +OBJEXT = @OBJEXT@ +OSX_LIBS = @OSX_LIBS@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ +PKG_CONFIG = @PKG_CONFIG@ +PNG_PROVIDER = @PNG_PROVIDER@ +RANLIB = @RANLIB@ +RUNTIME_SYSROOT = @RUNTIME_SYSROOT@ +SDL_CFLAGS = @SDL_CFLAGS@ +SDL_LIBS = @SDL_LIBS@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SOPATH = @SOPATH@ +STRIP = @STRIP@ +SYSCONFDIR = @SYSCONFDIR@ +SYSFS_LIBS = @SYSFS_LIBS@ +THREADFLAGS = @THREADFLAGS@ +THREADLIB = @THREADLIB@ +TSLIB_CFLAGS = @TSLIB_CFLAGS@ +TSLIB_LIBS = @TSLIB_LIBS@ +VERSION = @VERSION@ +VNC_CFLAGS = @VNC_CFLAGS@ +VNC_CONFIG = @VNC_CONFIG@ +VNC_LIBS = @VNC_LIBS@ +X11_CFLAGS = @X11_CFLAGS@ +X11_LIBS = @X11_LIBS@ +ZLIB_LIBS = @ZLIB_LIBS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_F77 = @ac_ct_F77@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +INCLUDES = \ + -I$(top_builddir)/lib \ + -I$(top_builddir)/include \ + -I$(top_srcdir)/include \ + -I$(top_srcdir)/lib \ + -I$(top_srcdir)/src + +internalincludedir = $(INTERNALINCLUDEDIR)/display +internalinclude_HEADERS = \ + idirectfbpalette.h \ + idirectfbsurface.h \ + idirectfbsurface_layer.h \ + idirectfbsurface_window.h \ + idirectfbdisplaylayer.h \ + idirectfbscreen.h + +noinst_LTLIBRARIES = libdirectfb_display.la +libdirectfb_display_la_SOURCES = \ + idirectfbpalette.c \ + idirectfbsurface.c \ + idirectfbsurface_layer.c \ + idirectfbsurface_window.c \ + idirectfbdisplaylayer.c \ + idirectfbscreen.c + +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/display/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/display/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +libdirectfb_display.la: $(libdirectfb_display_la_OBJECTS) $(libdirectfb_display_la_DEPENDENCIES) + $(LINK) $(libdirectfb_display_la_OBJECTS) $(libdirectfb_display_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/idirectfbdisplaylayer.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/idirectfbpalette.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/idirectfbscreen.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/idirectfbsurface.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/idirectfbsurface_layer.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/idirectfbsurface_window.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +install-internalincludeHEADERS: $(internalinclude_HEADERS) + @$(NORMAL_INSTALL) + test -z "$(internalincludedir)" || $(MKDIR_P) "$(DESTDIR)$(internalincludedir)" + @list='$(internalinclude_HEADERS)'; for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + f=$(am__strip_dir) \ + echo " $(internalincludeHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(internalincludedir)/$$f'"; \ + $(internalincludeHEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(internalincludedir)/$$f"; \ + done + +uninstall-internalincludeHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(internalinclude_HEADERS)'; for p in $$list; do \ + f=$(am__strip_dir) \ + echo " rm -f '$(DESTDIR)$(internalincludedir)/$$f'"; \ + rm -f "$(DESTDIR)$(internalincludedir)/$$f"; \ + done + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) $(HEADERS) +installdirs: + for dir in "$(DESTDIR)$(internalincludedir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: install-internalincludeHEADERS + +install-dvi: install-dvi-am + +install-exec-am: + +install-html: install-html-am + +install-info: install-info-am + +install-man: + +install-pdf: install-pdf-am + +install-ps: install-ps-am + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-internalincludeHEADERS + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-noinstLTLIBRARIES ctags distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am \ + install-internalincludeHEADERS install-man install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags uninstall uninstall-am uninstall-internalincludeHEADERS + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/Source/DirectFB/src/display/idirectfbdisplaylayer.c b/Source/DirectFB/src/display/idirectfbdisplaylayer.c new file mode 100755 index 0000000..014848a --- /dev/null +++ b/Source/DirectFB/src/display/idirectfbdisplaylayer.c @@ -0,0 +1,1076 @@ +/* + (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org) + (c) Copyright 2000-2004 Convergence (integrated media) GmbH + + All rights reserved. + + Written by Denis Oliver Kropp , + Andreas Hundt , + Sven Neumann , + Ville Syrjälä and + Claudio Ciccani . + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include + +#include +#include +#include + +#include + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + + +D_DEBUG_DOMAIN( Layer, "IDirectFBDisplayLayer", "Display Layer Interface" ); + +/* + * private data struct of IDirectFB + */ +typedef struct { + int ref; /* reference counter */ + DFBDisplayLayerDescription desc; /* description of the layer's caps */ + DFBDisplayLayerCooperativeLevel level; /* current cooperative level */ + CoreScreen *screen; /* layer's screen */ + CoreLayer *layer; /* core layer data */ + CoreLayerContext *context; /* shared or exclusive context */ + CoreLayerRegion *region; /* primary region of the context */ + CoreWindowStack *stack; /* stack of shared context */ + DFBBoolean switch_exclusive; /* switch to exclusive context after creation? */ + CoreDFB *core; +} IDirectFBDisplayLayer_data; + + + +static void +IDirectFBDisplayLayer_Destruct( IDirectFBDisplayLayer *thiz ) +{ + IDirectFBDisplayLayer_data *data = (IDirectFBDisplayLayer_data*)thiz->priv; + + D_DEBUG_AT( Layer, "IDirectFBDisplayLayer_Destruct()\n" ); + + D_DEBUG_AT( Layer, " -> unref region...\n" ); + + dfb_layer_region_unref( data->region ); + + D_DEBUG_AT( Layer, " -> unref context...\n" ); + + dfb_layer_context_unref( data->context ); + + DIRECT_DEALLOCATE_INTERFACE( thiz ); + + D_DEBUG_AT( Layer, " -> done.\n" ); +} + +static DirectResult +IDirectFBDisplayLayer_AddRef( IDirectFBDisplayLayer *thiz ) +{ + DIRECT_INTERFACE_GET_DATA(IDirectFBDisplayLayer) + + data->ref++; + + return DFB_OK; +} + +static DirectResult +IDirectFBDisplayLayer_Release( IDirectFBDisplayLayer *thiz ) +{ + DIRECT_INTERFACE_GET_DATA(IDirectFBDisplayLayer) + + if (--data->ref == 0) + IDirectFBDisplayLayer_Destruct( thiz ); + + return DFB_OK; +} + +static DFBResult +IDirectFBDisplayLayer_GetID( IDirectFBDisplayLayer *thiz, + DFBDisplayLayerID *id ) +{ + DIRECT_INTERFACE_GET_DATA(IDirectFBDisplayLayer) + + if (!id) + return DFB_INVARG; + + *id = dfb_layer_id_translated( data->layer ); + + return DFB_OK; +} + +static DFBResult +IDirectFBDisplayLayer_GetDescription( IDirectFBDisplayLayer *thiz, + DFBDisplayLayerDescription *desc ) +{ + + DIRECT_INTERFACE_GET_DATA(IDirectFBDisplayLayer) + + if (!desc) + return DFB_INVARG; + + *desc = data->desc; + + return DFB_OK; +} + +static DFBResult +IDirectFBDisplayLayer_GetSurface( IDirectFBDisplayLayer *thiz, + IDirectFBSurface **interface ) +{ + DFBResult ret; + CoreLayerRegion *region; + IDirectFBSurface *surface; + + DIRECT_INTERFACE_GET_DATA(IDirectFBDisplayLayer) + + if (!interface) + return DFB_INVARG; + + if (data->level == DLSCL_SHARED) { + D_WARN( "letting unprivileged IDirectFBDisplayLayer::GetSurface() " + "call pass until cooperative level handling is finished" ); + } + + ret = dfb_layer_context_get_primary_region( data->context, true, ®ion ); + if (ret) + return ret; + + DIRECT_ALLOCATE_INTERFACE( surface, IDirectFBSurface ); + + ret = IDirectFBSurface_Layer_Construct( surface, NULL, NULL, NULL, + region, DSCAPS_NONE, data->core ); + + if (region->config.buffermode == DLBM_FRONTONLY && data->level == DLSCL_EXCLUSIVE) { + surface->Clear( surface, 0, 0, 0, 0 ); + dfb_layer_region_flip_update( region, NULL, DSFLIP_NONE ); + } + + *interface = ret ? NULL : surface; + + dfb_layer_region_unref( region ); + + return ret; +} + +static DFBResult +IDirectFBDisplayLayer_GetScreen( IDirectFBDisplayLayer *thiz, + IDirectFBScreen **interface ) +{ + DFBResult ret; + IDirectFBScreen *screen; + + DIRECT_INTERFACE_GET_DATA(IDirectFBDisplayLayer) + + if (!interface) + return DFB_INVARG; + + DIRECT_ALLOCATE_INTERFACE( screen, IDirectFBScreen ); + + ret = IDirectFBScreen_Construct( screen, data->screen ); + + *interface = ret ? NULL : screen; + + return ret; +} + +static DFBResult +IDirectFBDisplayLayer_SetCooperativeLevel( IDirectFBDisplayLayer *thiz, + DFBDisplayLayerCooperativeLevel level ) +{ + DFBResult ret; + CoreLayerContext *context; + CoreLayerRegion *region; + + DIRECT_INTERFACE_GET_DATA(IDirectFBDisplayLayer) + + if (data->level == level) + return DFB_OK; + + switch (level) { + case DLSCL_SHARED: + case DLSCL_ADMINISTRATIVE: + if (data->level == DLSCL_EXCLUSIVE) { + ret = dfb_layer_get_primary_context( data->layer, false, &context ); + if (ret) + return ret; + + ret = dfb_layer_context_get_primary_region( context, true, ®ion ); + if (ret) { + dfb_layer_context_unref( context ); + return ret; + } + + dfb_layer_region_unref( data->region ); + dfb_layer_context_unref( data->context ); + + data->context = context; + data->region = region; + data->stack = dfb_layer_context_windowstack( data->context ); + } + + break; + + case DLSCL_EXCLUSIVE: + ret = dfb_layer_create_context( data->layer, &context ); + if (ret) + return ret; + + if (data->switch_exclusive) { + ret = dfb_layer_activate_context( data->layer, context ); + if (ret) { + dfb_layer_context_unref( context ); + return ret; + } + } + + ret = dfb_layer_context_get_primary_region( context, true, ®ion ); + if (ret) { + dfb_layer_context_unref( context ); + return ret; + } + + dfb_layer_region_unref( data->region ); + dfb_layer_context_unref( data->context ); + + data->context = context; + data->region = region; + data->stack = dfb_layer_context_windowstack( data->context ); + + break; + + default: + return DFB_INVARG; + } + + data->level = level; + + return DFB_OK; +} + +static DFBResult +IDirectFBDisplayLayer_SetOpacity( IDirectFBDisplayLayer *thiz, + u8 opacity ) +{ + DIRECT_INTERFACE_GET_DATA(IDirectFBDisplayLayer) + + if (data->level == DLSCL_SHARED) + return DFB_ACCESSDENIED; + + return dfb_layer_context_set_opacity( data->context, opacity ); +} + +static DFBResult +IDirectFBDisplayLayer_GetCurrentOutputField( IDirectFBDisplayLayer *thiz, int *field ) +{ + DIRECT_INTERFACE_GET_DATA(IDirectFBDisplayLayer) + + return dfb_layer_get_current_output_field( data->layer, field ); +} + +static DFBResult +IDirectFBDisplayLayer_SetFieldParity( IDirectFBDisplayLayer *thiz, int field ) +{ + DIRECT_INTERFACE_GET_DATA(IDirectFBDisplayLayer) + + if (data->level != DLSCL_EXCLUSIVE) + return DFB_ACCESSDENIED; + + return dfb_layer_context_set_field_parity( data->context, field ); +} + +static DFBResult +IDirectFBDisplayLayer_SetClipRegions( IDirectFBDisplayLayer *thiz, + const DFBRegion *regions, + int num_regions, + DFBBoolean positive ) +{ + DIRECT_INTERFACE_GET_DATA(IDirectFBDisplayLayer) + + if (!regions || num_regions < 1) + return DFB_INVARG; + + if (num_regions > data->desc.clip_regions) + return DFB_UNSUPPORTED; + + if (data->level != DLSCL_EXCLUSIVE) + return DFB_ACCESSDENIED; + + return dfb_layer_context_set_clip_regions( data->context, regions, num_regions, positive ); +} + +static DFBResult +IDirectFBDisplayLayer_SetSourceRectangle( IDirectFBDisplayLayer *thiz, + int x, + int y, + int width, + int height ) +{ + DFBRectangle source = { x, y, width, height }; + + DIRECT_INTERFACE_GET_DATA(IDirectFBDisplayLayer) + + if (x < 0 || y < 0 || width <= 0 || height <= 0) + return DFB_INVARG; + + if (data->level == DLSCL_SHARED) + return DFB_ACCESSDENIED; + + return dfb_layer_context_set_sourcerectangle( data->context, &source ); +} + +static DFBResult +IDirectFBDisplayLayer_SetScreenLocation( IDirectFBDisplayLayer *thiz, + float x, + float y, + float width, + float height ) +{ + DFBLocation location = { x, y, width, height }; + + DIRECT_INTERFACE_GET_DATA(IDirectFBDisplayLayer) + + if (! D_FLAGS_IS_SET( data->desc.caps, DLCAPS_SCREEN_LOCATION )) + return DFB_UNSUPPORTED; + + if (width <= 0 || height <= 0) + return DFB_INVARG; + + if (data->level == DLSCL_SHARED) + return DFB_ACCESSDENIED; + + return dfb_layer_context_set_screenlocation( data->context, &location ); +} + +static DFBResult +IDirectFBDisplayLayer_SetScreenPosition( IDirectFBDisplayLayer *thiz, + int x, + int y ) +{ + DIRECT_INTERFACE_GET_DATA(IDirectFBDisplayLayer) + + if (! D_FLAGS_IS_SET( data->desc.caps, DLCAPS_SCREEN_POSITION )) + return DFB_UNSUPPORTED; + + if (data->level == DLSCL_SHARED) + return DFB_ACCESSDENIED; + + return dfb_layer_context_set_screenposition( data->context, x, y ); +} + +static DFBResult +IDirectFBDisplayLayer_SetScreenRectangle( IDirectFBDisplayLayer *thiz, + int x, + int y, + int width, + int height ) +{ + DFBRectangle rect = { x, y, width, height }; + + DIRECT_INTERFACE_GET_DATA(IDirectFBDisplayLayer) + + if (! D_FLAGS_IS_SET( data->desc.caps, DLCAPS_SCREEN_LOCATION )) + return DFB_UNSUPPORTED; + + if (width <= 0 || height <= 0) + return DFB_INVARG; + + if (data->level == DLSCL_SHARED) + return DFB_ACCESSDENIED; + + return dfb_layer_context_set_screenrectangle( data->context, &rect ); +} + +static DFBResult +IDirectFBDisplayLayer_SetSrcColorKey( IDirectFBDisplayLayer *thiz, + u8 r, + u8 g, + u8 b ) +{ + DIRECT_INTERFACE_GET_DATA(IDirectFBDisplayLayer) + + if (data->level == DLSCL_SHARED) + return DFB_ACCESSDENIED; + + return dfb_layer_context_set_src_colorkey( data->context, r, g, b, -1 ); +} + +static DFBResult +IDirectFBDisplayLayer_SetDstColorKey( IDirectFBDisplayLayer *thiz, + u8 r, + u8 g, + u8 b ) +{ + DIRECT_INTERFACE_GET_DATA(IDirectFBDisplayLayer) + + if (data->level == DLSCL_SHARED) + return DFB_ACCESSDENIED; + + return dfb_layer_context_set_dst_colorkey( data->context, r, g, b, -1 ); +} + +static DFBResult +IDirectFBDisplayLayer_GetLevel( IDirectFBDisplayLayer *thiz, + int *level ) +{ + DFBResult ret; + int lvl; + + DIRECT_INTERFACE_GET_DATA(IDirectFBDisplayLayer) + + if (!level) + return DFB_INVARG; + + ret = dfb_layer_get_level( data->layer, &lvl ); + if (ret) + return ret; + + *level = lvl; + + return DFB_OK; +} + +static DFBResult +IDirectFBDisplayLayer_SetLevel( IDirectFBDisplayLayer *thiz, + int level ) +{ + DIRECT_INTERFACE_GET_DATA(IDirectFBDisplayLayer) + + if (! D_FLAGS_IS_SET( data->desc.caps, DLCAPS_LEVELS )) + return DFB_UNSUPPORTED; + + if (data->level == DLSCL_SHARED) + return DFB_ACCESSDENIED; + + return dfb_layer_set_level( data->layer, level ); +} + +static DFBResult +IDirectFBDisplayLayer_GetConfiguration( IDirectFBDisplayLayer *thiz, + DFBDisplayLayerConfig *config ) +{ + DIRECT_INTERFACE_GET_DATA(IDirectFBDisplayLayer) + + if (!config) + return DFB_INVARG; + + return dfb_layer_context_get_configuration( data->context, config ); +} + +static DFBResult +IDirectFBDisplayLayer_TestConfiguration( IDirectFBDisplayLayer *thiz, + const DFBDisplayLayerConfig *config, + DFBDisplayLayerConfigFlags *failed ) +{ + DIRECT_INTERFACE_GET_DATA(IDirectFBDisplayLayer) + + if (!config) + return DFB_INVARG; + + if (((config->flags & DLCONF_WIDTH) && (config->width < 0)) || + ((config->flags & DLCONF_HEIGHT) && (config->height < 0))) + return DFB_INVARG; + + return dfb_layer_context_test_configuration( data->context, config, failed ); +} + +static DFBResult +IDirectFBDisplayLayer_SetConfiguration( IDirectFBDisplayLayer *thiz, + const DFBDisplayLayerConfig *config ) +{ + DIRECT_INTERFACE_GET_DATA(IDirectFBDisplayLayer) + + if (!config) + return DFB_INVARG; + + if (((config->flags & DLCONF_WIDTH) && (config->width < 0)) || + ((config->flags & DLCONF_HEIGHT) && (config->height < 0))) + return DFB_INVARG; + + switch (data->level) { + case DLSCL_EXCLUSIVE: + case DLSCL_ADMINISTRATIVE: + return dfb_layer_context_set_configuration( data->context, config ); + + default: + break; + } + + return DFB_ACCESSDENIED; +} + +static DFBResult +IDirectFBDisplayLayer_SetBackgroundMode( IDirectFBDisplayLayer *thiz, + DFBDisplayLayerBackgroundMode background_mode ) +{ + DIRECT_INTERFACE_GET_DATA(IDirectFBDisplayLayer) + + if (data->level == DLSCL_SHARED) + return DFB_ACCESSDENIED; + + switch (background_mode) { + case DLBM_DONTCARE: + case DLBM_COLOR: + case DLBM_IMAGE: + case DLBM_TILE: + break; + + default: + return DFB_INVARG; + } + + return dfb_windowstack_set_background_mode( data->stack, background_mode ); +} + +static DFBResult +IDirectFBDisplayLayer_SetBackgroundImage( IDirectFBDisplayLayer *thiz, + IDirectFBSurface *surface ) +{ + IDirectFBSurface_data *surface_data; + + DIRECT_INTERFACE_GET_DATA(IDirectFBDisplayLayer) + + + if (!surface) + return DFB_INVARG; + + if (data->level == DLSCL_SHARED) + return DFB_ACCESSDENIED; + + surface_data = (IDirectFBSurface_data*)surface->priv; + if (!surface_data) + return DFB_DEAD; + + if (!surface_data->surface) + return DFB_DESTROYED; + + return dfb_windowstack_set_background_image( data->stack, + surface_data->surface ); +} + +static DFBResult +IDirectFBDisplayLayer_SetBackgroundColor( IDirectFBDisplayLayer *thiz, + u8 r, u8 g, u8 b, u8 a ) +{ + DFBColor color = { a: a, r: r, g: g, b: b }; + + DIRECT_INTERFACE_GET_DATA(IDirectFBDisplayLayer) + + if (data->level == DLSCL_SHARED) + return DFB_ACCESSDENIED; + + return dfb_windowstack_set_background_color( data->stack, &color ); +} + +static DFBResult +IDirectFBDisplayLayer_CreateWindow( IDirectFBDisplayLayer *thiz, + const DFBWindowDescription *desc, + IDirectFBWindow **window ) +{ + CoreWindow *w; + DFBResult ret; + DFBWindowDescription wd; + + DIRECT_INTERFACE_GET_DATA(IDirectFBDisplayLayer) + + memset( &wd, 0, sizeof(wd) ); + + wd.flags = DWDESC_WIDTH | DWDESC_HEIGHT | DWDESC_POSX | DWDESC_POSY | + DWDESC_PIXELFORMAT | DWDESC_SURFACE_CAPS | DWDESC_CAPS; + + wd.width = (desc->flags & DWDESC_WIDTH) ? desc->width : 480; + wd.height = (desc->flags & DWDESC_HEIGHT) ? desc->height : 300; + wd.posx = (desc->flags & DWDESC_POSX) ? desc->posx : 100; + wd.posy = (desc->flags & DWDESC_POSY) ? desc->posy : 100; + + D_DEBUG_AT( Layer, "CreateWindow() <- %d,%d - %dx%d )\n", wd.posx, wd.posy, wd.width, wd.height ); + + if (desc->flags & DWDESC_CAPS) + wd.caps = desc->caps; + + wd.caps |= DWCAPS_NOFOCUS; //no focus patch PR brg36mgr#118432 + + if (desc->flags & DWDESC_PIXELFORMAT) + wd.pixelformat = desc->pixelformat; + + if (desc->flags & DWDESC_SURFACE_CAPS) + wd.surface_caps = desc->surface_caps; + + if (desc->flags & DWDESC_PARENT) { + wd.flags |= DWDESC_PARENT; + wd.parent_id = desc->parent_id; + } + + if (desc->flags & DWDESC_OPTIONS) { + wd.flags |= DWDESC_OPTIONS; + wd.options = desc->options; + } + + if (desc->flags & DWDESC_STACKING) { + wd.flags |= DWDESC_STACKING; + wd.stacking = desc->stacking; + } + + if (desc->flags & DWDESC_RESOURCE_ID) { + wd.flags |= DWDESC_RESOURCE_ID; + wd.resource_id = desc->resource_id; + } + + if (desc->flags & DWDESC_TOPLEVEL_ID) { + wd.flags |= DWDESC_TOPLEVEL_ID; + wd.toplevel_id = desc->toplevel_id; + } + + + if ((wd.caps & ~DWCAPS_ALL) || !window) + return DFB_INVARG; + + if (wd.width < 1 || wd.width > 4096 || wd.height < 1 || wd.height > 4096) + return DFB_INVARG; + + ret = dfb_layer_context_create_window( data->core, data->context, &wd, &w ); + if (ret) + return ret; + + DIRECT_ALLOCATE_INTERFACE( *window, IDirectFBWindow ); + + return IDirectFBWindow_Construct( *window, w, data->layer, data->core ); +} + +static DFBResult +IDirectFBDisplayLayer_GetWindow( IDirectFBDisplayLayer *thiz, + DFBWindowID id, + IDirectFBWindow **window ) +{ + CoreWindow *w; + + DIRECT_INTERFACE_GET_DATA(IDirectFBDisplayLayer) + + if (!window) + return DFB_INVARG; + + //remove for now + //if (data->level == DLSCL_SHARED) + // return DFB_ACCESSDENIED; + + w = dfb_layer_context_find_window( data->context, id ); + if (!w) + return DFB_IDNOTFOUND; + + DIRECT_ALLOCATE_INTERFACE( *window, IDirectFBWindow ); + + return IDirectFBWindow_Construct( *window, w, data->layer, data->core ); +} + +static DFBResult +IDirectFBDisplayLayer_EnableCursor( IDirectFBDisplayLayer *thiz, int enable ) +{ + DIRECT_INTERFACE_GET_DATA(IDirectFBDisplayLayer) + + if (data->level == DLSCL_SHARED) + return DFB_ACCESSDENIED; + + return dfb_windowstack_cursor_enable( data->core, data->stack, enable ); +} + +static DFBResult +IDirectFBDisplayLayer_GetCursorPosition( IDirectFBDisplayLayer *thiz, + int *x, int *y ) +{ + DIRECT_INTERFACE_GET_DATA(IDirectFBDisplayLayer) + + if (!x && !y) + return DFB_INVARG; + + return dfb_windowstack_get_cursor_position( data->stack, x, y ); +} + +static DFBResult +IDirectFBDisplayLayer_WarpCursor( IDirectFBDisplayLayer *thiz, int x, int y ) +{ + DIRECT_INTERFACE_GET_DATA(IDirectFBDisplayLayer) + + if (data->level == DLSCL_SHARED) + return DFB_ACCESSDENIED; + + return dfb_windowstack_cursor_warp( data->stack, x, y ); +} + +static DFBResult +IDirectFBDisplayLayer_SetCursorAcceleration( IDirectFBDisplayLayer *thiz, + int numerator, + int denominator, + int threshold ) +{ + DIRECT_INTERFACE_GET_DATA(IDirectFBDisplayLayer) + + if (numerator < 0 || denominator < 1 || threshold < 0) + return DFB_INVARG; + + if (data->level == DLSCL_SHARED) + return DFB_ACCESSDENIED; + + return dfb_windowstack_cursor_set_acceleration( data->stack, numerator, + denominator, threshold ); +} + +static DFBResult +IDirectFBDisplayLayer_SetCursorShape( IDirectFBDisplayLayer *thiz, + IDirectFBSurface *shape, + int hot_x, + int hot_y ) +{ + IDirectFBSurface_data *shape_data; + + DIRECT_INTERFACE_GET_DATA(IDirectFBDisplayLayer) + + if (!shape) + return DFB_INVARG; + + if (data->level == DLSCL_SHARED) + return DFB_ACCESSDENIED; + + shape_data = (IDirectFBSurface_data*)shape->priv; + + if (hot_x < 0 || + hot_y < 0 || + hot_x >= shape_data->surface->config.size.w || + hot_y >= shape_data->surface->config.size.h) + return DFB_INVARG; + + return dfb_windowstack_cursor_set_shape( data->stack, + shape_data->surface, + hot_x, hot_y ); +} + +static DFBResult +IDirectFBDisplayLayer_SetCursorOpacity( IDirectFBDisplayLayer *thiz, + u8 opacity ) +{ + DIRECT_INTERFACE_GET_DATA(IDirectFBDisplayLayer) + + if (data->level == DLSCL_SHARED) + return DFB_ACCESSDENIED; + + return dfb_windowstack_cursor_set_opacity( data->stack, opacity ); +} + +static DFBResult +IDirectFBDisplayLayer_GetColorAdjustment( IDirectFBDisplayLayer *thiz, + DFBColorAdjustment *adj ) +{ + DIRECT_INTERFACE_GET_DATA(IDirectFBDisplayLayer) + + if (!adj) + return DFB_INVARG; + + return dfb_layer_context_get_coloradjustment( data->context, adj ); +} + +static DFBResult +IDirectFBDisplayLayer_SetColorAdjustment( IDirectFBDisplayLayer *thiz, + const DFBColorAdjustment *adj ) +{ + DIRECT_INTERFACE_GET_DATA(IDirectFBDisplayLayer) + + if (!adj || (adj->flags & ~DCAF_ALL)) + return DFB_INVARG; + + if (data->level == DLSCL_SHARED) + return DFB_ACCESSDENIED; + + if (!adj->flags) + return DFB_OK; + + return dfb_layer_context_set_coloradjustment( data->context, adj ); +} + +static DFBResult +IDirectFBDisplayLayer_WaitForSync( IDirectFBDisplayLayer *thiz ) +{ + DIRECT_INTERFACE_GET_DATA(IDirectFBDisplayLayer) + + return dfb_layer_wait_vsync( data->layer ); +} + +static DFBResult +IDirectFBDisplayLayer_GetSourceDescriptions( IDirectFBDisplayLayer *thiz, + DFBDisplayLayerSourceDescription *ret_descriptions ) +{ + int i; + + DIRECT_INTERFACE_GET_DATA(IDirectFBDisplayLayer) + + if (!ret_descriptions) + return DFB_INVARG; + + if (! D_FLAGS_IS_SET( data->desc.caps, DLCAPS_SOURCES )) + return DFB_UNSUPPORTED; + + for (i=0; idesc.sources; i++) + dfb_layer_get_source_info( data->layer, i, &ret_descriptions[i] ); + + return DFB_OK; +} + +static DFBResult +IDirectFBDisplayLayer_SwitchContext( IDirectFBDisplayLayer *thiz, + DFBBoolean exclusive ) +{ + DIRECT_INTERFACE_GET_DATA(IDirectFBDisplayLayer) + + if (!exclusive && data->level == DLSCL_EXCLUSIVE) { + DFBResult ret; + CoreLayerContext *context; + + ret = dfb_layer_get_primary_context( data->layer, false, &context ); + if (ret) + return ret; + + dfb_layer_activate_context( data->layer, context ); + + dfb_layer_context_unref( context ); + } + else + dfb_layer_activate_context( data->layer, data->context ); + + data->switch_exclusive = exclusive; + + return DFB_OK; +} + +static DFBResult +IDirectFBDisplayLayer_SetRotation( IDirectFBDisplayLayer *thiz, + int rotation ) +{ + DIRECT_INTERFACE_GET_DATA(IDirectFBDisplayLayer) + + if (data->level == DLSCL_SHARED) + return DFB_ACCESSDENIED; + + return dfb_layer_context_set_rotation( data->context, rotation ); +} + +static DFBResult +IDirectFBDisplayLayer_GetRotation( IDirectFBDisplayLayer *thiz, + int *ret_rotation ) +{ + CoreLayerContext *context; + + DIRECT_INTERFACE_GET_DATA(IDirectFBDisplayLayer) + + if (!ret_rotation) + return DFB_INVARG; + + context = data->context; + D_MAGIC_ASSERT( context, CoreLayerContext ); + + /* Lock the context. */ + if (dfb_layer_context_lock( context )) + return DFB_FUSION; + + *ret_rotation = context->rotation; + + /* Unlock the context. */ + dfb_layer_context_unlock( context ); + + return DFB_OK; +} + +typedef struct { + unsigned long resource_id; + CoreWindow *window; +} IDirectFBDisplayLayer_GetWindowByResourceID_Context; + +static DFBEnumerationResult +IDirectFBDisplayLayer_GetWindowByResourceID_WindowCallback( CoreWindow *window, + void *_ctx ) +{ + IDirectFBDisplayLayer_GetWindowByResourceID_Context *ctx = _ctx; + + if (window->surface) { + if (window->surface->resource_id == ctx->resource_id) { + ctx->window = window; + + return DFENUM_CANCEL; + } + } + + return DFENUM_OK; +} + +static DFBResult +IDirectFBDisplayLayer_GetWindowByResourceID( IDirectFBDisplayLayer *thiz, + unsigned long resource_id, + IDirectFBWindow **ret_window ) +{ + DFBResult ret; + CoreLayerContext *context; + CoreWindowStack *stack; + IDirectFBDisplayLayer_GetWindowByResourceID_Context ctx; + + DIRECT_INTERFACE_GET_DATA(IDirectFBDisplayLayer) + + if (!ret_window) + return DFB_INVARG; + + context = data->context; + D_MAGIC_ASSERT( context, CoreLayerContext ); + + stack = context->stack; + D_ASSERT( stack != NULL ); + + ctx.resource_id = resource_id; + ctx.window = NULL; + + ret = dfb_layer_context_lock( context ); + if (ret) + return ret; + + ret = dfb_wm_enum_windows( stack, IDirectFBDisplayLayer_GetWindowByResourceID_WindowCallback, &ctx ); + if (ret == DFB_OK) { + if (ctx.window) { + IDirectFBWindow *window; + + ret = dfb_window_ref( ctx.window ); + if (ret == DFB_OK) { + DIRECT_ALLOCATE_INTERFACE( window, IDirectFBWindow ); + + ret = IDirectFBWindow_Construct( window, ctx.window, data->layer, data->core ); + if (ret == DFB_OK) + *ret_window = window; + } + } + else + ret = DFB_IDNOTFOUND; + } + + dfb_layer_context_unlock( context ); + + return ret; +} + +DFBResult +IDirectFBDisplayLayer_Construct( IDirectFBDisplayLayer *thiz, + CoreLayer *layer, + CoreDFB *core ) +{ + DFBResult ret; + CoreLayerContext *context; + CoreLayerRegion *region; + + DIRECT_ALLOCATE_INTERFACE_DATA(thiz, IDirectFBDisplayLayer) + + ret = dfb_layer_get_primary_context( layer, true, &context ); + if (ret) { + DIRECT_DEALLOCATE_INTERFACE( thiz ) + return ret; + } + + ret = dfb_layer_context_get_primary_region( context, true, ®ion ); + if (ret) { + dfb_layer_context_unref( context ); + DIRECT_DEALLOCATE_INTERFACE( thiz ) + return ret; + } + + data->ref = 1; + data->core = core; + data->screen = dfb_layer_screen( layer ); + data->layer = layer; + data->context = context; + data->region = region; + data->stack = dfb_layer_context_windowstack( context ); + data->switch_exclusive = DFB_TRUE; + + dfb_layer_get_description( data->layer, &data->desc ); + + thiz->AddRef = IDirectFBDisplayLayer_AddRef; + thiz->Release = IDirectFBDisplayLayer_Release; + thiz->GetID = IDirectFBDisplayLayer_GetID; + thiz->GetDescription = IDirectFBDisplayLayer_GetDescription; + thiz->GetSurface = IDirectFBDisplayLayer_GetSurface; + thiz->GetScreen = IDirectFBDisplayLayer_GetScreen; + thiz->SetCooperativeLevel = IDirectFBDisplayLayer_SetCooperativeLevel; + thiz->SetOpacity = IDirectFBDisplayLayer_SetOpacity; + thiz->GetCurrentOutputField = IDirectFBDisplayLayer_GetCurrentOutputField; + thiz->SetSourceRectangle = IDirectFBDisplayLayer_SetSourceRectangle; + thiz->SetScreenLocation = IDirectFBDisplayLayer_SetScreenLocation; + thiz->SetSrcColorKey = IDirectFBDisplayLayer_SetSrcColorKey; + thiz->SetDstColorKey = IDirectFBDisplayLayer_SetDstColorKey; + thiz->GetLevel = IDirectFBDisplayLayer_GetLevel; + thiz->SetLevel = IDirectFBDisplayLayer_SetLevel; + thiz->GetConfiguration = IDirectFBDisplayLayer_GetConfiguration; + thiz->TestConfiguration = IDirectFBDisplayLayer_TestConfiguration; + thiz->SetConfiguration = IDirectFBDisplayLayer_SetConfiguration; + thiz->SetBackgroundMode = IDirectFBDisplayLayer_SetBackgroundMode; + thiz->SetBackgroundColor = IDirectFBDisplayLayer_SetBackgroundColor; + thiz->SetBackgroundImage = IDirectFBDisplayLayer_SetBackgroundImage; + thiz->GetColorAdjustment = IDirectFBDisplayLayer_GetColorAdjustment; + thiz->SetColorAdjustment = IDirectFBDisplayLayer_SetColorAdjustment; + thiz->CreateWindow = IDirectFBDisplayLayer_CreateWindow; + thiz->GetWindow = IDirectFBDisplayLayer_GetWindow; + thiz->WarpCursor = IDirectFBDisplayLayer_WarpCursor; + thiz->SetCursorAcceleration = IDirectFBDisplayLayer_SetCursorAcceleration; + thiz->EnableCursor = IDirectFBDisplayLayer_EnableCursor; + thiz->GetCursorPosition = IDirectFBDisplayLayer_GetCursorPosition; + thiz->SetCursorShape = IDirectFBDisplayLayer_SetCursorShape; + thiz->SetCursorOpacity = IDirectFBDisplayLayer_SetCursorOpacity; + thiz->SetFieldParity = IDirectFBDisplayLayer_SetFieldParity; + thiz->SetClipRegions = IDirectFBDisplayLayer_SetClipRegions; + thiz->WaitForSync = IDirectFBDisplayLayer_WaitForSync; + thiz->GetSourceDescriptions = IDirectFBDisplayLayer_GetSourceDescriptions; + thiz->SetScreenPosition = IDirectFBDisplayLayer_SetScreenPosition; + thiz->SetScreenRectangle = IDirectFBDisplayLayer_SetScreenRectangle; + thiz->SwitchContext = IDirectFBDisplayLayer_SwitchContext; + thiz->SetRotation = IDirectFBDisplayLayer_SetRotation; + thiz->GetRotation = IDirectFBDisplayLayer_GetRotation; + thiz->GetWindowByResourceID = IDirectFBDisplayLayer_GetWindowByResourceID; + + return DFB_OK; +} + diff --git a/Source/DirectFB/src/display/idirectfbdisplaylayer.h b/Source/DirectFB/src/display/idirectfbdisplaylayer.h new file mode 100755 index 0000000..9b39468 --- /dev/null +++ b/Source/DirectFB/src/display/idirectfbdisplaylayer.h @@ -0,0 +1,43 @@ +/* + (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org) + (c) Copyright 2000-2004 Convergence (integrated media) GmbH + + All rights reserved. + + Written by Denis Oliver Kropp , + Andreas Hundt , + Sven Neumann , + Ville Syrjälä and + Claudio Ciccani . + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#ifndef __IDIRECTFBDISPLAYLAYER_H__ +#define __IDIRECTFBDISPLAYLAYER_H__ + +#include +#include + +/* + * initializes interface struct and private data + */ +DFBResult IDirectFBDisplayLayer_Construct( IDirectFBDisplayLayer *thiz, + CoreLayer *layer, + CoreDFB *core ); + + +#endif diff --git a/Source/DirectFB/src/display/idirectfbpalette.c b/Source/DirectFB/src/display/idirectfbpalette.c new file mode 100755 index 0000000..213af4d --- /dev/null +++ b/Source/DirectFB/src/display/idirectfbpalette.c @@ -0,0 +1,365 @@ +/* + (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org) + (c) Copyright 2000-2004 Convergence (integrated media) GmbH + + All rights reserved. + + Written by Denis Oliver Kropp , + Andreas Hundt , + Sven Neumann , + Ville Syrjälä and + Claudio Ciccani . + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include + +#include +#include +#include +#include + +#include + + +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include "idirectfbpalette.h" + + + +static void +IDirectFBPalette_Destruct( IDirectFBPalette *thiz ) +{ + IDirectFBPalette_data *data = (IDirectFBPalette_data*)thiz->priv; + + if (data->palette) + dfb_palette_unref( data->palette ); + + DIRECT_DEALLOCATE_INTERFACE( thiz ); +} + +static DirectResult +IDirectFBPalette_AddRef( IDirectFBPalette *thiz ) +{ + DIRECT_INTERFACE_GET_DATA(IDirectFBPalette) + + data->ref++; + + return DFB_OK; +} + +static DirectResult +IDirectFBPalette_Release( IDirectFBPalette *thiz ) +{ + DIRECT_INTERFACE_GET_DATA(IDirectFBPalette) + + if (--data->ref == 0) + IDirectFBPalette_Destruct( thiz ); + + return DFB_OK; +} + +static DFBResult +IDirectFBPalette_GetCapabilities( IDirectFBPalette *thiz, + DFBPaletteCapabilities *caps ) +{ + CorePalette *palette; + + DIRECT_INTERFACE_GET_DATA(IDirectFBPalette) + + palette = data->palette; + if (!palette) + return DFB_DESTROYED; + + if (!caps) + return DFB_INVARG; + + /* FIXME: no caps yet */ + *caps = DPCAPS_NONE; + + return DFB_OK; +} + +static DFBResult +IDirectFBPalette_GetSize( IDirectFBPalette *thiz, + unsigned int *size ) +{ + CorePalette *palette; + + DIRECT_INTERFACE_GET_DATA(IDirectFBPalette) + + palette = data->palette; + if (!palette) + return DFB_DESTROYED; + + if (!size) + return DFB_INVARG; + + *size = palette->num_entries; + + return DFB_OK; +} + +static DFBResult +IDirectFBPalette_SetEntries( IDirectFBPalette *thiz, + const DFBColor *entries, + unsigned int num_entries, + unsigned int offset ) +{ + int i; + CorePalette *palette; + + DIRECT_INTERFACE_GET_DATA(IDirectFBPalette) + + palette = data->palette; + if (!palette) + return DFB_DESTROYED; + + if (!entries || offset + num_entries > palette->num_entries) + return DFB_INVARG; + + if (num_entries) { + direct_memcpy( palette->entries + offset, entries, num_entries * sizeof(DFBColor)); + + for (i=offset; ientries_yuv[i].a = palette->entries[i].a; + + RGB_TO_YCBCR( palette->entries[i].r, palette->entries[i].g, palette->entries[i].b, + palette->entries_yuv[i].y, palette->entries_yuv[i].u, palette->entries_yuv[i].v ); + } + + dfb_palette_update( palette, offset, offset + num_entries - 1 ); + } + + return DFB_OK; +} + +static DFBResult +IDirectFBPalette_GetEntries( IDirectFBPalette *thiz, + DFBColor *entries, + unsigned int num_entries, + unsigned int offset ) +{ + CorePalette *palette; + + DIRECT_INTERFACE_GET_DATA(IDirectFBPalette) + + palette = data->palette; + if (!palette) + return DFB_DESTROYED; + + if (!entries || offset + num_entries > palette->num_entries) + return DFB_INVARG; + + direct_memcpy( entries, palette->entries + offset, num_entries * sizeof(DFBColor)); + + return DFB_OK; +} + +static DFBResult +IDirectFBPalette_FindBestMatch( IDirectFBPalette *thiz, + u8 r, + u8 g, + u8 b, + u8 a, + unsigned int *index ) +{ + CorePalette *palette; + + DIRECT_INTERFACE_GET_DATA(IDirectFBPalette) + + if (!index) + return DFB_INVARG; + + palette = data->palette; + if (!palette) + return DFB_DESTROYED; + + *index = dfb_palette_search( palette, r, g, b, a ); + + return DFB_OK; +} + +static DFBResult +IDirectFBPalette_CreateCopy( IDirectFBPalette *thiz, + IDirectFBPalette **interface ) +{ + DFBResult ret; + IDirectFBPalette *iface; + CorePalette *palette = NULL; + + DIRECT_INTERFACE_GET_DATA(IDirectFBPalette) + + if (!data->palette) + return DFB_DESTROYED; + + if (!interface) + return DFB_INVARG; + + ret = dfb_palette_create( NULL, /* FIXME */ + data->palette->num_entries, &palette ); + if (ret) + return ret; + + direct_memcpy( palette->entries, data->palette->entries, + palette->num_entries * sizeof(DFBColor)); + + dfb_palette_update( palette, 0, palette->num_entries - 1 ); + + + DIRECT_ALLOCATE_INTERFACE( iface, IDirectFBPalette ); + + ret = IDirectFBPalette_Construct( iface, palette ); + + dfb_palette_unref( palette ); + + if (!ret) + *interface = iface; + + return ret; +} + +static DFBResult +IDirectFBPalette_SetEntriesYUV( IDirectFBPalette *thiz, + const DFBColorYUV *entries, + unsigned int num_entries, + unsigned int offset ) +{ + int i; + CorePalette *palette; + + DIRECT_INTERFACE_GET_DATA(IDirectFBPalette) + + palette = data->palette; + if (!palette) + return DFB_DESTROYED; + + if (!entries || offset + num_entries > palette->num_entries) + return DFB_INVARG; + + if (num_entries) { + direct_memcpy( palette->entries_yuv + offset, entries, num_entries * sizeof(DFBColorYUV)); + + for (i=offset; ientries[i].a = palette->entries_yuv[i].a; + + YCBCR_TO_RGB( palette->entries_yuv[i].y, palette->entries_yuv[i].u, palette->entries_yuv[i].v, + palette->entries[i].r, palette->entries[i].g, palette->entries[i].b ); + } + + dfb_palette_update( palette, offset, offset + num_entries - 1 ); + } + + return DFB_OK; +} + +static DFBResult +IDirectFBPalette_GetEntriesYUV( IDirectFBPalette *thiz, + DFBColorYUV *ret_entries, + unsigned int num_entries, + unsigned int offset ) +{ + CorePalette *palette; + + DIRECT_INTERFACE_GET_DATA(IDirectFBPalette) + + palette = data->palette; + if (!palette) + return DFB_DESTROYED; + + if (!ret_entries || offset + num_entries > palette->num_entries) + return DFB_INVARG; + + direct_memcpy( ret_entries, palette->entries_yuv + offset, num_entries * sizeof(DFBColorYUV)); + + return DFB_OK; +} + +static DFBResult +IDirectFBPalette_FindBestMatchYUV( IDirectFBPalette *thiz, + u8 y, + u8 u, + u8 v, + u8 a, + unsigned int *ret_index ) +{ + int r, g, b; + CorePalette *palette; + + DIRECT_INTERFACE_GET_DATA(IDirectFBPalette) + + if (!ret_index) + return DFB_INVARG; + + palette = data->palette; + if (!palette) + return DFB_DESTROYED; + + YCBCR_TO_RGB( y, u, v, r, g, b ); + + *ret_index = dfb_palette_search( palette, r, g, b, a ); + + return DFB_OK; +} + +/******/ + +DFBResult IDirectFBPalette_Construct( IDirectFBPalette *thiz, + CorePalette *palette ) +{ + DIRECT_ALLOCATE_INTERFACE_DATA(thiz, IDirectFBPalette) + + if (dfb_palette_ref( palette )) { + DIRECT_DEALLOCATE_INTERFACE(thiz); + return DFB_FAILURE; + } + + data->ref = 1; + data->palette = palette; + + + thiz->AddRef = IDirectFBPalette_AddRef; + thiz->Release = IDirectFBPalette_Release; + + thiz->GetCapabilities = IDirectFBPalette_GetCapabilities; + thiz->GetSize = IDirectFBPalette_GetSize; + + thiz->SetEntries = IDirectFBPalette_SetEntries; + thiz->GetEntries = IDirectFBPalette_GetEntries; + thiz->FindBestMatch = IDirectFBPalette_FindBestMatch; + + thiz->CreateCopy = IDirectFBPalette_CreateCopy; + + thiz->SetEntriesYUV = IDirectFBPalette_SetEntriesYUV; + thiz->GetEntriesYUV = IDirectFBPalette_GetEntriesYUV; + thiz->FindBestMatchYUV = IDirectFBPalette_FindBestMatchYUV; + + return DFB_OK; +} + diff --git a/Source/DirectFB/src/display/idirectfbpalette.h b/Source/DirectFB/src/display/idirectfbpalette.h new file mode 100755 index 0000000..2bedfa2 --- /dev/null +++ b/Source/DirectFB/src/display/idirectfbpalette.h @@ -0,0 +1,51 @@ +/* + (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org) + (c) Copyright 2000-2004 Convergence (integrated media) GmbH + + All rights reserved. + + Written by Denis Oliver Kropp , + Andreas Hundt , + Sven Neumann , + Ville Syrjälä and + Claudio Ciccani . + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#ifndef __IDIRECTFBPALETTE_H__ +#define __IDIRECTFBPALETTE_H__ + +#include +#include + +/* + * private data struct of IDirectFBPalette + */ +typedef struct { + int ref; /* reference counter */ + + CorePalette *palette; /* the palette object */ +} IDirectFBPalette_data; + +/* + * initializes interface struct and private data + */ +DFBResult IDirectFBPalette_Construct( IDirectFBPalette *thiz, + CorePalette *palette ); + + +#endif diff --git a/Source/DirectFB/src/display/idirectfbscreen.c b/Source/DirectFB/src/display/idirectfbscreen.c new file mode 100755 index 0000000..9fcebdc --- /dev/null +++ b/Source/DirectFB/src/display/idirectfbscreen.c @@ -0,0 +1,722 @@ +/* + (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org) + (c) Copyright 2000-2004 Convergence (integrated media) GmbH + + All rights reserved. + + Written by Denis Oliver Kropp , + Andreas Hundt , + Sven Neumann , + Ville Syrjälä and + Claudio Ciccani . + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include + +#include +#include +#include + +#include + +#include + +#include +#include +#include + +#include + +#include + +#include "idirectfbscreen.h" + +/* + * private data struct of IDirectFBScreen + */ +typedef struct { + int ref; /* reference counter */ + + CoreScreen *screen; + + DFBScreenID id; + DFBScreenDescription description; +} IDirectFBScreen_data; + +/******************************************************************************/ + +static DFBResult PatchMixerConfig ( DFBScreenMixerConfig *patched, + const DFBScreenMixerConfig *patch ); +static DFBResult PatchEncoderConfig( DFBScreenEncoderConfig *patched, + const DFBScreenEncoderConfig *patch ); +static DFBResult PatchOutputConfig ( DFBScreenOutputConfig *patched, + const DFBScreenOutputConfig *patch ); + +/******************************************************************************/ + +typedef struct { + CoreScreen *screen; + + DFBDisplayLayerCallback callback; + void *callback_ctx; +} EnumDisplayLayers_Context; + +static DFBEnumerationResult EnumDisplayLayers_Callback( CoreLayer *layer, + void *ctx ); + +/******************************************************************************/ + +static void +IDirectFBScreen_Destruct( IDirectFBScreen *thiz ) +{ +// IDirectFBScreen_data *data = (IDirectFBScreen_data*)thiz->priv; + + DIRECT_DEALLOCATE_INTERFACE( thiz ); +} + +static DirectResult +IDirectFBScreen_AddRef( IDirectFBScreen *thiz ) +{ + DIRECT_INTERFACE_GET_DATA(IDirectFBScreen) + + data->ref++; + + return DFB_OK; +} + +static DirectResult +IDirectFBScreen_Release( IDirectFBScreen *thiz ) +{ + DIRECT_INTERFACE_GET_DATA(IDirectFBScreen) + + if (--data->ref == 0) + IDirectFBScreen_Destruct( thiz ); + + return DFB_OK; +} + +static DFBResult +IDirectFBScreen_GetID( IDirectFBScreen *thiz, + DFBScreenID *id ) +{ + DIRECT_INTERFACE_GET_DATA(IDirectFBScreen) + + if (!id) + return DFB_INVARG; + + *id = data->id; + + return DFB_OK; +} + +static DFBResult +IDirectFBScreen_GetDescription( IDirectFBScreen *thiz, + DFBScreenDescription *desc ) +{ + DIRECT_INTERFACE_GET_DATA(IDirectFBScreen) + + if (!desc) + return DFB_INVARG; + + *desc = data->description; + + return DFB_OK; +} + +static DFBResult +IDirectFBScreen_GetSize( IDirectFBScreen *thiz, + int *ret_width, + int *ret_height ) +{ + DFBResult ret; + int width = 0; + int height = 0; + + DIRECT_INTERFACE_GET_DATA(IDirectFBScreen) + + if (!ret_width && !ret_height) + return DFB_INVARG; + + ret = dfb_screen_get_screen_size( data->screen, &width, &height ); + + if (ret_width) + *ret_width = width; + + if (ret_height) + *ret_height = height; + + return ret; +} + +static DFBResult +IDirectFBScreen_EnumDisplayLayers( IDirectFBScreen *thiz, + DFBDisplayLayerCallback callbackfunc, + void *callbackdata ) +{ + EnumDisplayLayers_Context context; + + DIRECT_INTERFACE_GET_DATA(IDirectFBScreen) + + if (!callbackfunc) + return DFB_INVARG; + + context.screen = data->screen; + context.callback = callbackfunc; + context.callback_ctx = callbackdata; + + dfb_layers_enumerate( EnumDisplayLayers_Callback, &context ); + + return DFB_OK; +} + +static DFBResult +IDirectFBScreen_SetPowerMode( IDirectFBScreen *thiz, + DFBScreenPowerMode mode ) +{ + DIRECT_INTERFACE_GET_DATA(IDirectFBScreen) + + switch (mode) { + case DSPM_ON: + case DSPM_STANDBY: + case DSPM_SUSPEND: + case DSPM_OFF: + break; + + default: + return DFB_INVARG; + } + + return dfb_screen_set_powermode( data->screen, mode ); +} + +static DFBResult +IDirectFBScreen_WaitForSync( IDirectFBScreen *thiz ) +{ + DIRECT_INTERFACE_GET_DATA(IDirectFBScreen) + + return dfb_screen_wait_vsync( data->screen ); +} + +static DFBResult +IDirectFBScreen_GetMixerDescriptions( IDirectFBScreen *thiz, + DFBScreenMixerDescription *descriptions ) +{ + int i; + + DIRECT_INTERFACE_GET_DATA(IDirectFBScreen) + + if (!descriptions) + return DFB_INVARG; + + if (! (data->description.caps & DSCCAPS_MIXERS)) + return DFB_UNSUPPORTED; + + for (i=0; idescription.mixers; i++) + dfb_screen_get_mixer_info( data->screen, i, &descriptions[i] ); + + return DFB_OK; +} + +static DFBResult +IDirectFBScreen_GetMixerConfiguration( IDirectFBScreen *thiz, + int mixer, + DFBScreenMixerConfig *config ) +{ + DIRECT_INTERFACE_GET_DATA(IDirectFBScreen) + + if (!config) + return DFB_INVARG; + + if (! (data->description.caps & DSCCAPS_MIXERS)) + return DFB_UNSUPPORTED; + + if (mixer < 0 || mixer >= data->description.mixers) + return DFB_INVARG; + + return dfb_screen_get_mixer_config( data->screen, mixer, config ); +} + +static DFBResult +IDirectFBScreen_TestMixerConfiguration( IDirectFBScreen *thiz, + int mixer, + const DFBScreenMixerConfig *config, + DFBScreenMixerConfigFlags *failed ) +{ + DFBResult ret; + DFBScreenMixerConfig patched; + + DIRECT_INTERFACE_GET_DATA(IDirectFBScreen) + + if (!config || (config->flags & ~DSMCONF_ALL)) + return DFB_INVARG; + + if (! (data->description.caps & DSCCAPS_MIXERS)) + return DFB_UNSUPPORTED; + + if (mixer < 0 || mixer >= data->description.mixers) + return DFB_INVARG; + + /* Get the current configuration. */ + ret = dfb_screen_get_mixer_config( data->screen, mixer, &patched ); + if (ret) + return ret; + + /* Patch the configuration. */ + ret = PatchMixerConfig( &patched, config ); + if (ret) + return ret; + + /* Test the patched configuration. */ + return dfb_screen_test_mixer_config( data->screen, + mixer, &patched, failed ); +} + +static DFBResult +IDirectFBScreen_SetMixerConfiguration( IDirectFBScreen *thiz, + int mixer, + const DFBScreenMixerConfig *config ) +{ + DFBResult ret; + DFBScreenMixerConfig patched; + + DIRECT_INTERFACE_GET_DATA(IDirectFBScreen) + + if (!config || (config->flags & ~DSMCONF_ALL)) + return DFB_INVARG; + + if (! (data->description.caps & DSCCAPS_MIXERS)) + return DFB_UNSUPPORTED; + + if (mixer < 0 || mixer >= data->description.mixers) + return DFB_INVARG; + + /* Get the current configuration. */ + ret = dfb_screen_get_mixer_config( data->screen, mixer, &patched ); + if (ret) + return ret; + + /* Patch the configuration. */ + ret = PatchMixerConfig( &patched, config ); + if (ret) + return ret; + + /* Set the patched configuration. */ + return dfb_screen_set_mixer_config( data->screen, mixer, &patched ); +} + +static DFBResult +IDirectFBScreen_GetEncoderDescriptions( IDirectFBScreen *thiz, + DFBScreenEncoderDescription *descriptions ) +{ + int i; + + DIRECT_INTERFACE_GET_DATA(IDirectFBScreen) + + if (!descriptions) + return DFB_INVARG; + + if (! (data->description.caps & DSCCAPS_ENCODERS)) + return DFB_UNSUPPORTED; + + for (i=0; idescription.encoders; i++) + dfb_screen_get_encoder_info( data->screen, i, &descriptions[i] ); + + return DFB_OK; +} + +static DFBResult +IDirectFBScreen_GetEncoderConfiguration( IDirectFBScreen *thiz, + int encoder, + DFBScreenEncoderConfig *config ) +{ + DIRECT_INTERFACE_GET_DATA(IDirectFBScreen) + + if (!config) + return DFB_INVARG; + + if (! (data->description.caps & DSCCAPS_ENCODERS)) + return DFB_UNSUPPORTED; + + if (encoder < 0 || encoder >= data->description.encoders) + return DFB_INVARG; + + return dfb_screen_get_encoder_config( data->screen, encoder, config ); +} + +static DFBResult +IDirectFBScreen_TestEncoderConfiguration( IDirectFBScreen *thiz, + int encoder, + const DFBScreenEncoderConfig *config, + DFBScreenEncoderConfigFlags *failed ) +{ + DFBResult ret; + DFBScreenEncoderConfig patched; + + DIRECT_INTERFACE_GET_DATA(IDirectFBScreen) + + if (!config || (config->flags & ~DSECONF_ALL)) + return DFB_INVARG; + + if (! (data->description.caps & DSCCAPS_ENCODERS)) + return DFB_UNSUPPORTED; + + if (encoder < 0 || encoder >= data->description.encoders) + return DFB_INVARG; + + /* Get the current configuration. */ + ret = dfb_screen_get_encoder_config( data->screen, encoder, &patched ); + if (ret) + return ret; + + /* Patch the configuration. */ + ret = PatchEncoderConfig( &patched, config ); + if (ret) + return ret; + + /* Test the patched configuration. */ + return dfb_screen_test_encoder_config( data->screen, + encoder, &patched, failed ); +} + +static DFBResult +IDirectFBScreen_SetEncoderConfiguration( IDirectFBScreen *thiz, + int encoder, + const DFBScreenEncoderConfig *config ) +{ + DFBResult ret; + DFBScreenEncoderConfig patched; + + DIRECT_INTERFACE_GET_DATA(IDirectFBScreen) + + if (!config || (config->flags & ~DSECONF_ALL)) + return DFB_INVARG; + + if (! (data->description.caps & DSCCAPS_ENCODERS)) + return DFB_UNSUPPORTED; + + if (encoder < 0 || encoder >= data->description.encoders) + return DFB_INVARG; + + /* Get the current configuration. */ + ret = dfb_screen_get_encoder_config( data->screen, encoder, &patched ); + if (ret) + return ret; + + /* Patch the configuration. */ + ret = PatchEncoderConfig( &patched, config ); + if (ret) + return ret; + + /* Set the patched configuration. */ + return dfb_screen_set_encoder_config( data->screen, encoder, &patched ); +} + +static DFBResult +IDirectFBScreen_GetOutputDescriptions( IDirectFBScreen *thiz, + DFBScreenOutputDescription *descriptions ) +{ + int i; + + DIRECT_INTERFACE_GET_DATA(IDirectFBScreen) + + if (!descriptions) + return DFB_INVARG; + + if (!data->description.caps & DSCCAPS_OUTPUTS) + return DFB_UNSUPPORTED; + + for (i=0; idescription.outputs; i++) + dfb_screen_get_output_info( data->screen, i, &descriptions[i] ); + + return DFB_OK; +} + +static DFBResult +IDirectFBScreen_GetOutputConfiguration( IDirectFBScreen *thiz, + int output, + DFBScreenOutputConfig *config ) +{ + DIRECT_INTERFACE_GET_DATA(IDirectFBScreen) + + if (!config) + return DFB_INVARG; + + if (! (data->description.caps & DSCCAPS_OUTPUTS)) + return DFB_UNSUPPORTED; + + if (output < 0 || output >= data->description.outputs) + return DFB_INVARG; + + return dfb_screen_get_output_config( data->screen, output, config ); +} + +static DFBResult +IDirectFBScreen_TestOutputConfiguration( IDirectFBScreen *thiz, + int output, + const DFBScreenOutputConfig *config, + DFBScreenOutputConfigFlags *failed ) +{ + DFBResult ret; + DFBScreenOutputConfig patched; + + DIRECT_INTERFACE_GET_DATA(IDirectFBScreen) + + if (!config || (config->flags & ~DSOCONF_ALL)) + return DFB_INVARG; + + if (! (data->description.caps & DSCCAPS_OUTPUTS)) + return DFB_UNSUPPORTED; + + if (output < 0 || output >= data->description.outputs) + return DFB_INVARG; + + /* Get the current configuration. */ + ret = dfb_screen_get_output_config( data->screen, output, &patched ); + if (ret) + return ret; + + /* Patch the configuration. */ + ret = PatchOutputConfig( &patched, config ); + if (ret) + return ret; + + /* Test the patched configuration. */ + return dfb_screen_test_output_config( data->screen, + output, &patched, failed ); +} + +static DFBResult +IDirectFBScreen_SetOutputConfiguration( IDirectFBScreen *thiz, + int output, + const DFBScreenOutputConfig *config ) +{ + DFBResult ret; + DFBScreenOutputConfig patched; + + DIRECT_INTERFACE_GET_DATA(IDirectFBScreen) + + if (!config || (config->flags & ~DSOCONF_ALL)) + return DFB_INVARG; + + if (! (data->description.caps & DSCCAPS_OUTPUTS)) + return DFB_UNSUPPORTED; + + if (output < 0 || output >= data->description.outputs) + return DFB_INVARG; + + /* Get the current configuration. */ + ret = dfb_screen_get_output_config( data->screen, output, &patched ); + if (ret) + return ret; + + /* Patch the configuration. */ + ret = PatchOutputConfig( &patched, config ); + if (ret) + return ret; + + /* Set the patched configuration. */ + return dfb_screen_set_output_config( data->screen, output, &patched ); +} + +/******************************************************************************/ + +DFBResult +IDirectFBScreen_Construct( IDirectFBScreen *thiz, + CoreScreen *screen ) +{ + DIRECT_ALLOCATE_INTERFACE_DATA(thiz, IDirectFBScreen) + + data->ref = 1; + data->screen = screen; + + dfb_screen_get_info( screen, NULL, &data->description ); + data->id = dfb_screen_id_translated( data->screen ); + + thiz->AddRef = IDirectFBScreen_AddRef; + thiz->Release = IDirectFBScreen_Release; + thiz->GetID = IDirectFBScreen_GetID; + thiz->GetDescription = IDirectFBScreen_GetDescription; + thiz->GetSize = IDirectFBScreen_GetSize; + thiz->EnumDisplayLayers = IDirectFBScreen_EnumDisplayLayers; + thiz->SetPowerMode = IDirectFBScreen_SetPowerMode; + thiz->WaitForSync = IDirectFBScreen_WaitForSync; + thiz->GetMixerDescriptions = IDirectFBScreen_GetMixerDescriptions; + thiz->GetMixerConfiguration = IDirectFBScreen_GetMixerConfiguration; + thiz->TestMixerConfiguration = IDirectFBScreen_TestMixerConfiguration; + thiz->SetMixerConfiguration = IDirectFBScreen_SetMixerConfiguration; + thiz->GetEncoderDescriptions = IDirectFBScreen_GetEncoderDescriptions; + thiz->GetEncoderConfiguration = IDirectFBScreen_GetEncoderConfiguration; + thiz->TestEncoderConfiguration = IDirectFBScreen_TestEncoderConfiguration; + thiz->SetEncoderConfiguration = IDirectFBScreen_SetEncoderConfiguration; + thiz->GetOutputDescriptions = IDirectFBScreen_GetOutputDescriptions; + thiz->GetOutputConfiguration = IDirectFBScreen_GetOutputConfiguration; + thiz->TestOutputConfiguration = IDirectFBScreen_TestOutputConfiguration; + thiz->SetOutputConfiguration = IDirectFBScreen_SetOutputConfiguration; + + return DFB_OK; +} + +/******************************************************************************/ + +static DFBResult +PatchMixerConfig( DFBScreenMixerConfig *patched, + const DFBScreenMixerConfig *patch ) +{ + /* Check for unsupported flags. */ + if (patch->flags & ~patched->flags) + return DFB_UNSUPPORTED; + + if (patch->flags & DSMCONF_TREE) + patched->tree = patch->tree; + + if (patch->flags & DSMCONF_LEVEL) + patched->level = patch->level; + + if (patch->flags & DSMCONF_LAYERS) + patched->layers = patch->layers; + + if (patch->flags & DSMCONF_BACKGROUND) + patched->background = patch->background; + + return DFB_OK; +} + +static DFBResult +PatchEncoderConfig( DFBScreenEncoderConfig *patched, + const DFBScreenEncoderConfig *patch ) +{ + /* Check for unsupported flags. */ + if (patch->flags & ~patched->flags) + return DFB_UNSUPPORTED; + + if (patch->flags & DSECONF_RESOLUTION) + patched->resolution = patch->resolution; + + if (patch->flags & DSECONF_FREQUENCY) + patched->frequency = patch->frequency; + + /** + * Need to be backwards compatible with these so that + * they specify resolution and frequency as well. + * If you have set a TV_STANDARD + * (and set the flag) it will override the resolution and + * frequency chosen above.*/ + if (patch->flags & DSECONF_TV_STANDARD) { + patched->tv_standard = patch->tv_standard; + switch (patched->tv_standard) { + case DSETV_PAL: + case DSETV_PAL_BG: + case DSETV_PAL_I: + case DSETV_PAL_N: + case DSETV_PAL_NC: + patched->resolution = DSOR_720_576; + patched->frequency = DSEF_50HZ; + break; + + case DSETV_PAL_60: + case DSETV_PAL_M: + patched->resolution = DSOR_720_480; + patched->frequency = DSEF_60HZ; + break; + + case DSETV_SECAM: + patched->resolution = DSOR_720_576; + patched->frequency = DSEF_50HZ; + break; + + case DSETV_NTSC: + case DSETV_NTSC_M_JPN: + case DSETV_NTSC_443: + patched->resolution = DSOR_720_480; + patched->frequency = DSEF_60HZ; + break; + + default: + break; + } + } + if (patch->flags & DSECONF_TEST_PICTURE) + patched->test_picture = patch->test_picture; + + if (patch->flags & DSECONF_MIXER) + patched->mixer = patch->mixer; + + if (patch->flags & DSECONF_OUT_SIGNALS) + patched->out_signals = patch->out_signals; + + if (patch->flags & DSECONF_SCANMODE) + patched->scanmode = patch->scanmode; + + if (patch->flags & DSECONF_ADJUSTMENT) + patched->adjustment = patch->adjustment; + + if (patch->flags & DSECONF_CONNECTORS) + patched->out_connectors = patch->out_connectors; + + if (patch->flags & DSECONF_SLOW_BLANKING) + patched->slow_blanking = patch->slow_blanking; + + return DFB_OK; +} + +static DFBResult +PatchOutputConfig( DFBScreenOutputConfig *patched, + const DFBScreenOutputConfig *patch ) +{ + /* Check for unsupported flags. */ + if (patch->flags & ~patched->flags) + return DFB_UNSUPPORTED; + + if (patch->flags & DSOCONF_RESOLUTION) + patched->resolution = patch->resolution; + + if (patch->flags & DSOCONF_ENCODER) + patched->encoder = patch->encoder; + + if (patch->flags & DSOCONF_SIGNALS) + patched->out_signals = patch->out_signals; + + if (patch->flags & DSOCONF_CONNECTORS) + patched->out_connectors = patch->out_connectors; + + if (patch->flags & DSOCONF_SLOW_BLANKING) + patched->slow_blanking = patch->slow_blanking; + + return DFB_OK; +} + +static DFBEnumerationResult +EnumDisplayLayers_Callback( CoreLayer *layer, void *ctx ) +{ + DFBDisplayLayerDescription desc; + DFBDisplayLayerID id; + EnumDisplayLayers_Context *context = (EnumDisplayLayers_Context*) ctx; + + if (dfb_layer_screen( layer ) != context->screen) + return DFENUM_OK; + + id = dfb_layer_id_translated( layer ); + + if (dfb_config->primary_only && id != DLID_PRIMARY) + return DFENUM_OK; + + dfb_layer_get_description( layer, &desc ); + + return context->callback( id, desc, context->callback_ctx ); +} + diff --git a/Source/DirectFB/src/display/idirectfbscreen.h b/Source/DirectFB/src/display/idirectfbscreen.h new file mode 100755 index 0000000..682ee8b --- /dev/null +++ b/Source/DirectFB/src/display/idirectfbscreen.h @@ -0,0 +1,42 @@ +/* + (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org) + (c) Copyright 2000-2004 Convergence (integrated media) GmbH + + All rights reserved. + + Written by Denis Oliver Kropp , + Andreas Hundt , + Sven Neumann , + Ville Syrjälä and + Claudio Ciccani . + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#ifndef __IDIRECTFBSCREEN_H__ +#define __IDIRECTFBSCREEN_H__ + +#include +#include + +/* + * initializes interface struct and private data + */ +DFBResult IDirectFBScreen_Construct( IDirectFBScreen *thiz, + CoreScreen *screen ); + + +#endif diff --git a/Source/DirectFB/src/display/idirectfbsurface.c b/Source/DirectFB/src/display/idirectfbsurface.c new file mode 100755 index 0000000..bd23975 --- /dev/null +++ b/Source/DirectFB/src/display/idirectfbsurface.c @@ -0,0 +1,2841 @@ +/* + (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org) + (c) Copyright 2000-2004 Convergence (integrated media) GmbH + + All rights reserved. + + Written by Denis Oliver Kropp , + Andreas Hundt , + Sven Neumann , + Ville Syrjälä and + Claudio Ciccani . + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include + +#include +#include +#include +#include +#include + +#include + + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + + +D_DEBUG_DOMAIN( Surface, "IDirectFBSurface", "IDirectFBSurface Interface" ); + +/**********************************************************************************************************************/ + +static ReactionResult IDirectFBSurface_listener( const void *msg_data, void *ctx ); + +/**********************************************************************************************************************/ + +void +IDirectFBSurface_Destruct( IDirectFBSurface *thiz ) +{ + IDirectFBSurface_data *data; + IDirectFBSurface *parent; + + D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz ); + + D_ASSERT( thiz != NULL ); + + data = thiz->priv; + + D_ASSERT( data != NULL ); + D_ASSERT( data->children_data == NULL ); + + parent = data->parent; + if (parent) { + IDirectFBSurface_data *parent_data; + + D_MAGIC_ASSERT( (IAny*) parent, DirectInterface ); + + parent_data = parent->priv; + D_ASSERT( parent_data != NULL ); + + pthread_mutex_lock( &parent_data->children_lock ); + + direct_list_remove( &parent_data->children_data, &data->link ); + + pthread_mutex_unlock( &parent_data->children_lock ); + } + + if (data->surface) + dfb_surface_detach( data->surface, &data->reaction ); + + dfb_state_stop_drawing( &data->state ); + + dfb_state_set_destination( &data->state, NULL ); + dfb_state_set_source( &data->state, NULL ); + dfb_state_set_source_mask( &data->state, NULL ); + + dfb_state_destroy( &data->state ); + + if (data->font) + data->font->Release( data->font ); + + if (data->surface) { + if (data->locked) + dfb_surface_unlock_buffer( data->surface, &data->lock ); + + dfb_surface_unref( data->surface ); + } + + pthread_mutex_destroy( &data->children_lock ); + + DIRECT_DEALLOCATE_INTERFACE( thiz ); + + if (parent) + parent->Release( parent ); +} + +static DirectResult +IDirectFBSurface_AddRef( IDirectFBSurface *thiz ) +{ + DIRECT_INTERFACE_GET_DATA(IDirectFBSurface) + + D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz ); + + data->ref++; + + return DFB_OK; +} + +static DirectResult +IDirectFBSurface_Release( IDirectFBSurface *thiz ) +{ + DIRECT_INTERFACE_GET_DATA(IDirectFBSurface) + + D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz ); + + if (--data->ref == 0) + IDirectFBSurface_Destruct( thiz ); + + return DFB_OK; +} + + +static DFBResult +IDirectFBSurface_GetPixelFormat( IDirectFBSurface *thiz, + DFBSurfacePixelFormat *format ) +{ + DIRECT_INTERFACE_GET_DATA(IDirectFBSurface) + + D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz ); + + if (!data->surface) + return DFB_DESTROYED; + + if (!format) + return DFB_INVARG; + + *format = data->surface->config.format; + + return DFB_OK; +} + +static DFBResult +IDirectFBSurface_GetAccelerationMask( IDirectFBSurface *thiz, + IDirectFBSurface *source, + DFBAccelerationMask *ret_mask ) +{ + DFBAccelerationMask mask = DFXL_NONE; + + DIRECT_INTERFACE_GET_DATA(IDirectFBSurface) + + D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz ); + + if (!data->surface) + return DFB_DESTROYED; + + if (!ret_mask) + return DFB_INVARG; + + dfb_state_lock( &data->state ); + + /* Check drawing functions */ + if (dfb_gfxcard_state_check( &data->state, DFXL_FILLRECTANGLE )) + mask |= DFXL_FILLRECTANGLE; + + if (dfb_gfxcard_state_check( &data->state, DFXL_DRAWRECTANGLE )) + mask |= DFXL_DRAWRECTANGLE; + + if (dfb_gfxcard_state_check( &data->state, DFXL_DRAWLINE )) + mask |= DFXL_DRAWLINE; + + if (dfb_gfxcard_state_check( &data->state, DFXL_FILLTRIANGLE )) + mask |= DFXL_FILLTRIANGLE; + + dfb_state_unlock( &data->state ); + + /* Check blitting functions */ + if (source) { + IDirectFBSurface_data *src_data = source->priv; + + dfb_state_set_source( &data->state, src_data->surface ); + + dfb_state_lock( &data->state ); + + if (dfb_gfxcard_state_check( &data->state, DFXL_BLIT )) + mask |= DFXL_BLIT; + + if (dfb_gfxcard_state_check( &data->state, DFXL_STRETCHBLIT )) + mask |= DFXL_STRETCHBLIT; + + if (dfb_gfxcard_state_check( &data->state, DFXL_TEXTRIANGLES )) + mask |= DFXL_TEXTRIANGLES; + + dfb_state_unlock( &data->state ); + } + + /* Check text rendering function */ + if (data->font) { + IDirectFBFont_data *font_data = data->font->priv; + + if (dfb_gfxcard_drawstring_check_state( font_data->font, &data->state )) + mask |= DFXL_DRAWSTRING; + } + + *ret_mask = mask; + + return DFB_OK; +} + +static DFBResult +IDirectFBSurface_GetPosition( IDirectFBSurface *thiz, + int *x, + int *y ) +{ + DIRECT_INTERFACE_GET_DATA(IDirectFBSurface) + + D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz ); + + if (!x && !y) + return DFB_INVARG; + + if (x) + *x = data->area.wanted.x; + + if (y) + *y = data->area.wanted.y; + + return DFB_OK; +} + +static DFBResult +IDirectFBSurface_GetSize( IDirectFBSurface *thiz, + int *width, + int *height ) +{ + DIRECT_INTERFACE_GET_DATA(IDirectFBSurface) + + D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz ); + + if (!width && !height) + return DFB_INVARG; + + if (width) + *width = data->area.wanted.w; + + if (height) + *height = data->area.wanted.h; + + return DFB_OK; +} + +static DFBResult +IDirectFBSurface_GetVisibleRectangle( IDirectFBSurface *thiz, + DFBRectangle *rect ) +{ + DIRECT_INTERFACE_GET_DATA(IDirectFBSurface) + + D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz ); + + if (!rect) + return DFB_INVARG; + + rect->x = data->area.current.x - data->area.wanted.x; + rect->y = data->area.current.y - data->area.wanted.y; + rect->w = data->area.current.w; + rect->h = data->area.current.h; + + return DFB_OK; +} + +static DFBResult +IDirectFBSurface_GetCapabilities( IDirectFBSurface *thiz, + DFBSurfaceCapabilities *caps ) +{ + DIRECT_INTERFACE_GET_DATA(IDirectFBSurface) + + D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz ); + + if (!caps) + return DFB_INVARG; + + *caps = data->caps; + + return DFB_OK; +} + +static DFBResult +IDirectFBSurface_GetPalette( IDirectFBSurface *thiz, + IDirectFBPalette **interface ) +{ + DFBResult ret; + CoreSurface *surface; + IDirectFBPalette *palette; + + DIRECT_INTERFACE_GET_DATA(IDirectFBSurface) + + D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz ); + + surface = data->surface; + if (!surface) + return DFB_DESTROYED; + + if (!surface->palette) + return DFB_UNSUPPORTED; + + if (!interface) + return DFB_INVARG; + + DIRECT_ALLOCATE_INTERFACE( palette, IDirectFBPalette ); + + ret = IDirectFBPalette_Construct( palette, surface->palette ); + if (ret) + return ret; + + *interface = palette; + + return DFB_OK; +} + +static DFBResult +IDirectFBSurface_SetPalette( IDirectFBSurface *thiz, + IDirectFBPalette *palette ) +{ + CoreSurface *surface; + IDirectFBPalette_data *palette_data; + + DIRECT_INTERFACE_GET_DATA(IDirectFBSurface) + + D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz ); + + surface = data->surface; + if (!surface) + return DFB_DESTROYED; + + if (!palette) + return DFB_INVARG; + + if (! DFB_PIXELFORMAT_IS_INDEXED( surface->config.format )) + return DFB_UNSUPPORTED; + + palette_data = (IDirectFBPalette_data*) palette->priv; + if (!palette_data) + return DFB_DEAD; + + if (!palette_data->palette) + return DFB_DESTROYED; + + dfb_surface_set_palette( surface, palette_data->palette ); + + return DFB_OK; +} + +static DFBResult +IDirectFBSurface_SetAlphaRamp( IDirectFBSurface *thiz, + u8 a0, + u8 a1, + u8 a2, + u8 a3 ) +{ + DIRECT_INTERFACE_GET_DATA(IDirectFBSurface) + + D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz ); + + if (!data->surface) + return DFB_DESTROYED; + + dfb_surface_set_alpha_ramp( data->surface, a0, a1, a2, a3 ); + + return DFB_OK; +} + +static DFBResult +IDirectFBSurface_Lock( IDirectFBSurface *thiz, + DFBSurfaceLockFlags flags, + void **ret_ptr, int *ret_pitch ) +{ + DFBResult ret; + CoreSurfaceBufferRole role = CSBR_FRONT; + CoreSurfaceAccessFlags access = CSAF_NONE; + + DIRECT_INTERFACE_GET_DATA(IDirectFBSurface) + + D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz ); + + if (!data->surface) + return DFB_DESTROYED; + + if (data->locked) + return DFB_LOCKED; + + if (!flags || !ret_ptr || !ret_pitch) + return DFB_INVARG; + + if (!data->area.current.w || !data->area.current.h) + return DFB_INVAREA; + + if (flags & DSLF_READ) + access |= CSAF_READ; + + if (flags & DSLF_WRITE) { + access |= CSAF_WRITE; + role = CSBR_BACK; + } + + ret = dfb_surface_lock_buffer( data->surface, role, CSAID_CPU, access, &data->lock ); + if (ret) + return ret; + + data->locked = true; + + *ret_ptr = data->lock.addr + data->lock.pitch * data->area.current.y + + DFB_BYTES_PER_LINE( data->surface->config.format, data->area.current.x ); + *ret_pitch = data->lock.pitch; + + return DFB_OK; +} + +static DFBResult +IDirectFBSurface_GetFramebufferOffset( IDirectFBSurface *thiz, + int *offset ) +{ + DIRECT_INTERFACE_GET_DATA(IDirectFBSurface) + + if (!data->surface) + return DFB_DESTROYED; + + if (!offset) + return DFB_INVARG; + + if (!data->locked) + return DFB_ACCESSDENIED; + + if (!data->lock.phys) { + /* The surface is probably in a system buffer if there's no physical address. */ + return DFB_UNSUPPORTED; + } + + *offset = data->lock.offset; + + return DFB_OK; +} + +static DFBResult +IDirectFBSurface_Unlock( IDirectFBSurface *thiz ) +{ + DIRECT_INTERFACE_GET_DATA(IDirectFBSurface) + + D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz ); + + if (!data->surface) + return DFB_DESTROYED; + + if (data->locked) { + dfb_surface_unlock_buffer( data->surface, &data->lock ); + + data->locked = false; + } + + return DFB_OK; +} + +static DFBResult +IDirectFBSurface_Write( IDirectFBSurface *thiz, + const DFBRectangle *rect, + const void *ptr, + int pitch ) +{ + CoreSurface *surface; + + DIRECT_INTERFACE_GET_DATA(IDirectFBSurface) + + D_DEBUG_AT( Surface, "%s( %p, %p, %p [%d] )\n", __FUNCTION__, thiz, rect, ptr, pitch ); + + surface = data->surface; + if (!surface) + return DFB_DESTROYED; + + if (!rect || !ptr || pitch < DFB_BYTES_PER_LINE(surface->config.format,rect->w ) ) + return DFB_INVARG; + + if (data->locked) + return DFB_LOCKED; + + if (!data->area.current.w || !data->area.current.h) + return DFB_INVAREA; + + D_DEBUG_AT( Surface, " -> %4d,%4d-%4dx%4d\n", DFB_RECTANGLE_VALS( rect ) ); + + //FIXME: check rectangle + + return dfb_surface_write_buffer( data->surface, CSBR_BACK, ptr, pitch, rect ); +} + +static DFBResult +IDirectFBSurface_Read( IDirectFBSurface *thiz, + const DFBRectangle *rect, + void *ptr, + int pitch ) +{ + CoreSurface *surface; + + DIRECT_INTERFACE_GET_DATA(IDirectFBSurface) + + D_DEBUG_AT( Surface, "%s( %p, %p, %p [%d] )\n", __FUNCTION__, thiz, rect, ptr, pitch ); + + surface = data->surface; + if (!surface) + return DFB_DESTROYED; + + if (!rect || !ptr || pitch < DFB_BYTES_PER_LINE(surface->config.format,rect->w ) ) + return DFB_INVARG; + + if (data->locked) + return DFB_LOCKED; + + if (!data->area.current.w || !data->area.current.h) + return DFB_INVAREA; + + D_DEBUG_AT( Surface, " -> %4d,%4d-%4dx%4d\n", DFB_RECTANGLE_VALS( rect ) ); + + //FIXME: check rectangle + + return dfb_surface_read_buffer( data->surface, CSBR_FRONT, ptr, pitch, rect ); +} + +static DFBResult +IDirectFBSurface_Flip( IDirectFBSurface *thiz, + const DFBRegion *region, + DFBSurfaceFlipFlags flags ) +{ + DFBResult ret; + DFBRegion reg; + CoreSurface *surface; + + DIRECT_INTERFACE_GET_DATA(IDirectFBSurface) + + D_DEBUG_AT( Surface, "%s( %p, %p, 0x%08x )\n", __FUNCTION__, thiz, region, flags ); + + surface = data->surface; + if (!surface) + return DFB_DESTROYED; + + if (data->locked) + return DFB_LOCKED; + + if (!(surface->config.caps & DSCAPS_FLIPPING)) + return DFB_UNSUPPORTED; + + if (!data->area.current.w || !data->area.current.h || + (region && (region->x1 > region->x2 || region->y1 > region->y2))) + return DFB_INVAREA; + + IDirectFBSurface_StopAll( data ); + + /* FIXME: This is a temporary workaround for LiTE. */ + if (data->parent) { + IDirectFBSurface_data *parent_data; + + DIRECT_INTERFACE_GET_DATA_FROM( data->parent, parent_data, IDirectFBSurface ); + + /* Signal end of sequence of operations. */ + dfb_state_lock( &parent_data->state ); + dfb_state_stop_drawing( &parent_data->state ); + dfb_state_unlock( &parent_data->state ); + } + + dfb_region_from_rectangle( ®, &data->area.current ); + + if (region) { + DFBRegion clip = DFB_REGION_INIT_TRANSLATED( region, + data->area.wanted.x, + data->area.wanted.y ); + + if (!dfb_region_region_intersect( ®, &clip )) + return DFB_INVAREA; + } + + D_DEBUG_AT( Surface, " -> %4d,%4d-%4dx%4d\n", DFB_RECTANGLE_VALS_FROM_REGION( ® ) ); + + if (!(flags & DSFLIP_BLIT) && reg.x1 == 0 && reg.y1 == 0 && + reg.x2 == surface->config.size.w - 1 && reg.y2 == surface->config.size.h - 1) + { + ret = dfb_surface_lock( data->surface ); + if (ret) + return ret; + + dfb_surface_flip( data->surface, false ); + + dfb_surface_unlock( data->surface ); + } + else + dfb_back_to_front_copy( data->surface, ® ); + + return DFB_OK; +} + +static DFBResult +IDirectFBSurface_SetField( IDirectFBSurface *thiz, + int field ) +{ + DIRECT_INTERFACE_GET_DATA(IDirectFBSurface) + + D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz ); + + if (!data->surface) + return DFB_DESTROYED; + + if (!(data->surface->config.caps & DSCAPS_INTERLACED)) + return DFB_UNSUPPORTED; + + if (field < 0 || field > 1) + return DFB_INVARG; + + dfb_surface_set_field( data->surface, field ); + + return DFB_OK; +} + +static DFBResult +IDirectFBSurface_Clear( IDirectFBSurface *thiz, + u8 r, u8 g, u8 b, u8 a ) +{ + DFBColor old_color; + unsigned int old_index; + DFBSurfaceDrawingFlags old_flags; + DFBSurfaceRenderOptions old_options; + CoreSurface *surface; + DFBColor color = { a, r, g, b }; + + DIRECT_INTERFACE_GET_DATA(IDirectFBSurface) + + D_DEBUG_AT( Surface, "%s( %p, 0x%08x )\n", __FUNCTION__, thiz, PIXEL_ARGB(a,r,g,b) ); + + surface = data->surface; + if (!surface) + return DFB_DESTROYED; + + if (!data->area.current.w || !data->area.current.h) + return DFB_INVAREA; + + if (data->locked) + return DFB_LOCKED; + + /* save current color and drawing flags */ + old_color = data->state.color; + old_index = data->state.color_index; + old_flags = data->state.drawingflags; + old_options = data->state.render_options; + + /* set drawing flags */ + dfb_state_set_drawing_flags( &data->state, DSDRAW_NOFX ); + + /* set render options */ + dfb_state_set_render_options( &data->state, DSRO_NONE ); + + /* set color */ + if (DFB_PIXELFORMAT_IS_INDEXED( surface->config.format )) + dfb_state_set_color_index( &data->state, + dfb_palette_search( surface->palette, r, g, b, a ) ); + + dfb_state_set_color( &data->state, &color ); + + /* fill the visible rectangle */ + dfb_gfxcard_fillrectangles( &data->area.current, 1, &data->state ); + + /* clear the depth buffer */ + if (data->caps & DSCAPS_DEPTH) + dfb_clear_depth( data->surface, &data->state.clip ); + + /* restore drawing flags */ + dfb_state_set_drawing_flags( &data->state, old_flags ); + + /* restore render options */ + dfb_state_set_render_options( &data->state, old_options ); + + /* restore color */ + if (DFB_PIXELFORMAT_IS_INDEXED( surface->config.format )) + dfb_state_set_color_index( &data->state, old_index ); + + dfb_state_set_color( &data->state, &old_color ); + + return DFB_OK; +} + +static DFBResult +IDirectFBSurface_SetClip( IDirectFBSurface *thiz, const DFBRegion *clip ) +{ + DFBRegion newclip; + + DIRECT_INTERFACE_GET_DATA(IDirectFBSurface) + + D_DEBUG_AT( Surface, "%s( %p, %p )\n", __FUNCTION__, thiz, clip ); + + + if (!data->area.current.w || !data->area.current.h) + return DFB_INVAREA; + + if (clip) { + newclip = DFB_REGION_INIT_TRANSLATED( clip, data->area.wanted.x, data->area.wanted.y ); + + D_DEBUG_AT( Surface, " <- %4d,%4d-%4dx%4d\n", DFB_RECTANGLE_VALS_FROM_REGION(&newclip) ); + + if (!dfb_unsafe_region_rectangle_intersect( &newclip, + &data->area.wanted )) + return DFB_INVARG; + + D_DEBUG_AT( Surface, " -> %4d,%4d-%4dx%4d\n", DFB_RECTANGLE_VALS_FROM_REGION(&newclip) ); + + data->clip_set = true; + data->clip_wanted = newclip; + + if (!dfb_region_rectangle_intersect( &newclip, &data->area.current )) + return DFB_INVAREA; + } + else { + dfb_region_from_rectangle( &newclip, &data->area.current ); + data->clip_set = false; + } + + D_DEBUG_AT( Surface, " => CLIP %4d,%4d-%4dx%4d\n", DFB_RECTANGLE_VALS_FROM_REGION(&newclip) ); + + dfb_state_set_clip( &data->state, &newclip ); + + return DFB_OK; +} + +static DFBResult +IDirectFBSurface_GetClip( IDirectFBSurface *thiz, DFBRegion *ret_clip ) +{ + DIRECT_INTERFACE_GET_DATA(IDirectFBSurface) + + D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz ); + + if (!ret_clip) + return DFB_INVARG; + + if (!data->area.current.w || !data->area.current.h) + return DFB_INVAREA; + + *ret_clip = DFB_REGION_INIT_TRANSLATED( &data->state.clip, -data->area.wanted.x, -data->area.wanted.y ); + + D_DEBUG_AT( Surface, " -> %4d,%4d-%4dx%4d\n", DFB_RECTANGLE_VALS_FROM_REGION(ret_clip) ); + + return DFB_OK; +} + +static DFBResult +IDirectFBSurface_SetColor( IDirectFBSurface *thiz, + u8 r, u8 g, u8 b, u8 a ) +{ + CoreSurface *surface; + DFBColor color = { a, r, g, b }; + + DIRECT_INTERFACE_GET_DATA(IDirectFBSurface) + + D_DEBUG_AT( Surface, "%s( %p, COLOR 0x%08x )\n", __FUNCTION__, thiz, PIXEL_ARGB(a, r, g, b) ); + + surface = data->surface; + if (!surface) + return DFB_DESTROYED; + + dfb_state_set_color( &data->state, &color ); + + if (DFB_PIXELFORMAT_IS_INDEXED( surface->config.format )) + dfb_state_set_color_index( &data->state, + dfb_palette_search( surface->palette, r, g, b, a ) ); + + data->state.colors[0] = data->state.color; + data->state.color_indices[0] = data->state.color_index; + + return DFB_OK; +} + +static DFBResult +IDirectFBSurface_SetColors( IDirectFBSurface *thiz, + const DFBColorID *ids, + const DFBColor *colors, + unsigned int num ) +{ + unsigned int i; + CoreSurface *surface; + + DIRECT_INTERFACE_GET_DATA(IDirectFBSurface) + + D_DEBUG_AT( Surface, "%s( %p, %p, %p, %u )\n", __FUNCTION__, thiz, ids, colors, num ); + + surface = data->surface; + if (!surface) + return DFB_DESTROYED; + + for (i=0; i [%d] id %d = %02x %02x %02x %02x\n", + i, ids[i], colors[i].a, colors[i].r, colors[i].g, colors[i].b ); + + if (ids[i] >= DFB_COLOR_IDS_MAX) + return DFB_INVARG; + + data->state.colors[ids[i]] = colors[i]; + + if (DFB_PIXELFORMAT_IS_INDEXED( surface->config.format )) + data->state.color_indices[ids[i]] = dfb_palette_search( surface->palette, + colors[i].r, colors[i].g, colors[i].b, colors[i].a ); + } + + dfb_state_set_color( &data->state, &data->state.colors[0] ); + dfb_state_set_color_index( &data->state, data->state.color_indices[0] ); + + return DFB_OK; +} + +static DFBResult +IDirectFBSurface_SetColorIndex( IDirectFBSurface *thiz, + unsigned int index ) +{ + CoreSurface *surface; + CorePalette *palette; + + DIRECT_INTERFACE_GET_DATA(IDirectFBSurface) + + D_DEBUG_AT( Surface, "%s( %p, COLOR INDEX %3u )\n", __FUNCTION__, thiz, index ); + + surface = data->surface; + if (!surface) + return DFB_DESTROYED; + + if (! DFB_PIXELFORMAT_IS_INDEXED( surface->config.format )) + return DFB_UNSUPPORTED; + + palette = surface->palette; + if (!palette) + return DFB_UNSUPPORTED; + + if (index > palette->num_entries) + return DFB_INVARG; + + dfb_state_set_color( &data->state, &palette->entries[index] ); + + dfb_state_set_color_index( &data->state, index ); + + data->state.colors[0] = data->state.color; + data->state.color_indices[0] = data->state.color_index; + + return DFB_OK; +} + +static DFBResult +IDirectFBSurface_SetSrcBlendFunction( IDirectFBSurface *thiz, + DFBSurfaceBlendFunction src ) +{ + DIRECT_INTERFACE_GET_DATA(IDirectFBSurface) + + D_DEBUG_AT( Surface, "%s( %p, %d )\n", __FUNCTION__, thiz, src ); + + switch (src) { + case DSBF_ZERO: + case DSBF_ONE: + case DSBF_SRCCOLOR: + case DSBF_INVSRCCOLOR: + case DSBF_SRCALPHA: + case DSBF_INVSRCALPHA: + case DSBF_DESTALPHA: + case DSBF_INVDESTALPHA: + case DSBF_DESTCOLOR: + case DSBF_INVDESTCOLOR: + case DSBF_SRCALPHASAT: + dfb_state_set_src_blend( &data->state, src ); + return DFB_OK; + + default: + break; + } + + return DFB_INVARG; +} + +static DFBResult +IDirectFBSurface_SetDstBlendFunction( IDirectFBSurface *thiz, + DFBSurfaceBlendFunction dst ) +{ + DIRECT_INTERFACE_GET_DATA(IDirectFBSurface) + + D_DEBUG_AT( Surface, "%s( %p, %d )\n", __FUNCTION__, thiz, dst ); + + switch (dst) { + case DSBF_ZERO: + case DSBF_ONE: + case DSBF_SRCCOLOR: + case DSBF_INVSRCCOLOR: + case DSBF_SRCALPHA: + case DSBF_INVSRCALPHA: + case DSBF_DESTALPHA: + case DSBF_INVDESTALPHA: + case DSBF_DESTCOLOR: + case DSBF_INVDESTCOLOR: + case DSBF_SRCALPHASAT: + dfb_state_set_dst_blend( &data->state, dst ); + return DFB_OK; + + default: + break; + } + + return DFB_INVARG; +} + +static DFBResult +IDirectFBSurface_SetPorterDuff( IDirectFBSurface *thiz, + DFBSurfacePorterDuffRule rule ) +{ + DFBSurfaceBlendFunction src; + DFBSurfaceBlendFunction dst; + + DIRECT_INTERFACE_GET_DATA(IDirectFBSurface) + + D_DEBUG_AT( Surface, "%s( %p, %d )\n", __FUNCTION__, thiz, rule ); + + + switch (rule) { + case DSPD_NONE: + src = DSBF_SRCALPHA; + dst = DSBF_INVSRCALPHA; + break; + case DSPD_CLEAR: + src = DSBF_ZERO; + dst = DSBF_ZERO; + break; + case DSPD_SRC: + src = DSBF_ONE; + dst = DSBF_ZERO; + break; + case DSPD_SRC_OVER: + src = DSBF_ONE; + dst = DSBF_INVSRCALPHA; + break; + case DSPD_DST_OVER: + src = DSBF_INVDESTALPHA; + dst = DSBF_ONE; + break; + case DSPD_SRC_IN: + src = DSBF_DESTALPHA; + dst = DSBF_ZERO; + break; + case DSPD_DST_IN: + src = DSBF_ZERO; + dst = DSBF_SRCALPHA; + break; + case DSPD_SRC_OUT: + src = DSBF_INVDESTALPHA; + dst = DSBF_ZERO; + break; + case DSPD_DST_OUT: + src = DSBF_ZERO; + dst = DSBF_INVSRCALPHA; + break; + case DSPD_SRC_ATOP: + src = DSBF_DESTALPHA; + dst = DSBF_INVSRCALPHA; + break; + case DSPD_DST_ATOP: + src = DSBF_INVDESTALPHA; + dst = DSBF_SRCALPHA; + break; + case DSPD_ADD: + src = DSBF_ONE; + dst = DSBF_ONE; + break; + case DSPD_XOR: + src = DSBF_INVDESTALPHA; + dst = DSBF_INVSRCALPHA; + break; + default: + return DFB_INVARG; + } + + dfb_state_set_src_blend( &data->state, src ); + dfb_state_set_dst_blend( &data->state, dst ); + + return DFB_OK; +} + +static DFBResult +IDirectFBSurface_SetSrcColorKey( IDirectFBSurface *thiz, + u8 r, + u8 g, + u8 b ) +{ + CoreSurface *surface; + + DIRECT_INTERFACE_GET_DATA(IDirectFBSurface) + + D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz ); + + surface = data->surface; + if (!surface) + return DFB_DESTROYED; + + data->src_key.r = r; + data->src_key.g = g; + data->src_key.b = b; + + if (DFB_PIXELFORMAT_IS_INDEXED( surface->config.format )) + data->src_key.value = dfb_palette_search( surface->palette, + r, g, b, 0x80 ); + else + data->src_key.value = dfb_color_to_pixel( surface->config.format, r, g, b ); + + /* The new key won't be applied to this surface's state. + The key will be taken by the destination surface to apply it + to its state when source color keying is used. */ + + return DFB_OK; +} + +static DFBResult +IDirectFBSurface_SetSrcColorKeyIndex( IDirectFBSurface *thiz, + unsigned int index ) +{ + CoreSurface *surface; + CorePalette *palette; + + DIRECT_INTERFACE_GET_DATA(IDirectFBSurface) + + D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz ); + + surface = data->surface; + if (!surface) + return DFB_DESTROYED; + + if (! DFB_PIXELFORMAT_IS_INDEXED( surface->config.format )) + return DFB_UNSUPPORTED; + + palette = surface->palette; + if (!palette) + return DFB_UNSUPPORTED; + + if (index > palette->num_entries) + return DFB_INVARG; + + data->src_key.r = palette->entries[index].r; + data->src_key.g = palette->entries[index].g; + data->src_key.b = palette->entries[index].b; + + data->src_key.value = index; + + /* The new key won't be applied to this surface's state. + The key will be taken by the destination surface to apply it + to its state when source color keying is used. */ + + return DFB_OK; +} + +static DFBResult +IDirectFBSurface_SetDstColorKey( IDirectFBSurface *thiz, + u8 r, + u8 g, + u8 b ) +{ + CoreSurface *surface; + + DIRECT_INTERFACE_GET_DATA(IDirectFBSurface) + + D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz ); + + surface = data->surface; + if (!surface) + return DFB_DESTROYED; + + data->dst_key.r = r; + data->dst_key.g = g; + data->dst_key.b = b; + + if (DFB_PIXELFORMAT_IS_INDEXED( surface->config.format )) + data->dst_key.value = dfb_palette_search( surface->palette, + r, g, b, 0x80 ); + else + data->dst_key.value = dfb_color_to_pixel( surface->config.format, r, g, b ); + + dfb_state_set_dst_colorkey( &data->state, data->dst_key.value ); + + return DFB_OK; +} + +static DFBResult +IDirectFBSurface_SetDstColorKeyIndex( IDirectFBSurface *thiz, + unsigned int index ) +{ + CoreSurface *surface; + CorePalette *palette; + + DIRECT_INTERFACE_GET_DATA(IDirectFBSurface) + + D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz ); + + surface = data->surface; + if (!surface) + return DFB_DESTROYED; + + if (! DFB_PIXELFORMAT_IS_INDEXED( surface->config.format )) + return DFB_UNSUPPORTED; + + palette = surface->palette; + if (!palette) + return DFB_UNSUPPORTED; + + if (index > palette->num_entries) + return DFB_INVARG; + + data->dst_key.r = palette->entries[index].r; + data->dst_key.g = palette->entries[index].g; + data->dst_key.b = palette->entries[index].b; + + data->dst_key.value = index; + + dfb_state_set_dst_colorkey( &data->state, data->dst_key.value ); + + return DFB_OK; +} + +static DFBResult +IDirectFBSurface_SetIndexTranslation( IDirectFBSurface *thiz, + const int *indices, + int num_indices ) +{ + CoreSurface *surface; + + DIRECT_INTERFACE_GET_DATA(IDirectFBSurface) + + surface = data->surface; + if (!surface) + return DFB_DESTROYED; + + if (! DFB_PIXELFORMAT_IS_INDEXED( surface->config.format )) + return DFB_UNSUPPORTED; + + if (!indices && num_indices > 0) + return DFB_INVAREA; + + if (num_indices < 0 || num_indices > 256) + return DFB_INVARG; + + return dfb_state_set_index_translation( &data->state, indices, num_indices ); +} + +static DFBResult +IDirectFBSurface_SetFont( IDirectFBSurface *thiz, + IDirectFBFont *font ) +{ + DFBResult ret; + + DIRECT_INTERFACE_GET_DATA(IDirectFBSurface) + + D_DEBUG_AT( Surface, "%s( %p, %p )\n", __FUNCTION__, thiz, font ); + + if (data->font != font) { + if (font) { + IDirectFBFont_data *font_data; + + ret = font->AddRef( font ); + if (ret) + return ret; + + DIRECT_INTERFACE_GET_DATA_FROM( font, font_data, IDirectFBFont ); + + data->encoding = font_data->encoding; + } + + if (data->font) + data->font->Release( data->font ); + + data->font = font; + } + + return DFB_OK; +} + +static DFBResult +IDirectFBSurface_GetFont( IDirectFBSurface *thiz, + IDirectFBFont **ret_font ) +{ + DFBResult ret; + IDirectFBFont *font; + + DIRECT_INTERFACE_GET_DATA(IDirectFBSurface) + + D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz ); + + if (!ret_font) + return DFB_INVARG; + + font = data->font; + if (!font) { + *ret_font = NULL; + return DFB_MISSINGFONT; + } + + ret = font->AddRef( font ); + if (ret) + return ret; + + *ret_font = font; + + return DFB_OK; +} + +static DFBResult +IDirectFBSurface_SetDrawingFlags( IDirectFBSurface *thiz, + DFBSurfaceDrawingFlags flags ) +{ + DIRECT_INTERFACE_GET_DATA(IDirectFBSurface) + + D_DEBUG_AT( Surface, "%s( %p, 0x%08x )\n", __FUNCTION__, thiz, flags ); + + dfb_state_set_drawing_flags( &data->state, flags ); + + return DFB_OK; +} + +static DFBResult +IDirectFBSurface_FillRectangle( IDirectFBSurface *thiz, + int x, int y, int w, int h ) +{ + DFBRectangle rect = { x, y, w, h }; + + DIRECT_INTERFACE_GET_DATA(IDirectFBSurface) + + D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz ); + D_DEBUG_AT( Surface, " -> [%2d] %4d,%4d-%4dx%4d\n", 0, x, y, w, h ); + + if (!data->surface) + return DFB_DESTROYED; + + + if (!data->area.current.w || !data->area.current.h) + return DFB_INVAREA; + + if (data->locked) + return DFB_LOCKED; + + if (w<=0 || h<=0) + return DFB_INVARG; + + rect.x += data->area.wanted.x; + rect.y += data->area.wanted.y; + + dfb_gfxcard_fillrectangles( &rect, 1, &data->state ); + + return DFB_OK; +} + + +static DFBResult +IDirectFBSurface_DrawLine( IDirectFBSurface *thiz, + int x1, int y1, int x2, int y2 ) +{ + DIRECT_INTERFACE_GET_DATA(IDirectFBSurface) + + D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz ); + D_DEBUG_AT( Surface, " -> [%2d] %4d,%4d-%4d,%4d\n", 0, x1, y1, x2, y2 ); + + if (!data->surface) + return DFB_DESTROYED; + + + if (!data->area.current.w || !data->area.current.h) + return DFB_INVAREA; + + if (data->locked) + return DFB_LOCKED; + + if ((x1 == x2 || y1 == y2) && !(data->state.render_options & DSRO_MATRIX)) { + DFBRectangle rect; + + if (x1 <= x2) { + rect.x = x1; + rect.w = x2 - x1 + 1; + } + else { + rect.x = x2; + rect.w = x1 - x2 + 1; + } + + if (y1 <= y2) { + rect.y = y1; + rect.h = y2 - y1 + 1; + } + else { + rect.y = y2; + rect.h = y1 - y2 + 1; + } + + rect.x += data->area.wanted.x; + rect.y += data->area.wanted.y; + + dfb_gfxcard_fillrectangles( &rect, 1, &data->state ); + } + else { + DFBRegion line = { x1, y1, x2, y2 }; + + line.x1 += data->area.wanted.x; + line.x2 += data->area.wanted.x; + line.y1 += data->area.wanted.y; + line.y2 += data->area.wanted.y; + + dfb_gfxcard_drawlines( &line, 1, &data->state ); + } + + return DFB_OK; +} + +static DFBResult +IDirectFBSurface_DrawLines( IDirectFBSurface *thiz, + const DFBRegion *lines, + unsigned int num_lines ) +{ + unsigned int i; + + DIRECT_INTERFACE_GET_DATA(IDirectFBSurface) + + D_DEBUG_AT( Surface, "%s( %p, %p [%d] )\n", __FUNCTION__, thiz, lines, num_lines ); + + if (!data->surface) + return DFB_DESTROYED; + + + if (!data->area.current.w || !data->area.current.h) + return DFB_INVAREA; + + if (data->locked) + return DFB_LOCKED; + + if (!lines || !num_lines) + return DFB_INVARG; + + /* Check if all lines are either horizontal or vertical */ + for (i=0; iarea.wanted.x || data->area.wanted.y) { + for (i=0; iarea.wanted.x; + local_lines[i].x2 = lines[i].x2 + data->area.wanted.x; + local_lines[i].y1 = lines[i].y1 + data->area.wanted.y; + local_lines[i].y2 = lines[i].y2 + data->area.wanted.y; + } + } + else + /* clipping may modify lines, so we copy them */ + direct_memcpy( local_lines, lines, sizeof(DFBRegion) * num_lines ); + + dfb_gfxcard_drawlines( local_lines, num_lines, &data->state ); + } + /* Optimized rectangle drawing */ + else { + DFBRectangle *local_rects = alloca(sizeof(DFBRectangle) * num_lines); + + for (i=0; iarea.wanted.x + lines[i].x1; + local_rects[i].y = data->area.wanted.y + MIN( lines[i].y1, lines[i].y2 ); + local_rects[i].w = 1; + local_rects[i].h = ABS( lines[i].y2 - lines[i].y1 ) + 1; + } + /* Horizontal line */ + else { + local_rects[i].x = data->area.wanted.x + MIN( lines[i].x1, lines[i].x2 ); + local_rects[i].y = data->area.wanted.y + lines[i].y1; + local_rects[i].w = ABS( lines[i].x2 - lines[i].x1 ) + 1; + local_rects[i].h = 1; + } + } + + dfb_gfxcard_fillrectangles( local_rects, num_lines, &data->state ); + } + + return DFB_OK; +} + +static DFBResult +IDirectFBSurface_DrawRectangle( IDirectFBSurface *thiz, + int x, int y, int w, int h ) +{ + DFBRectangle rect = { x, y, w, h }; + + DIRECT_INTERFACE_GET_DATA(IDirectFBSurface) + + D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz ); + D_DEBUG_AT( Surface, " -> [%2d] %4d,%4d-%4dx%4d\n", 0, x, y, w, h ); + + if (!data->surface) + return DFB_DESTROYED; + + + if (!data->area.current.w || !data->area.current.h) + return DFB_INVAREA; + + if (data->locked) + return DFB_LOCKED; + + if (w<=0 || h<=0) + return DFB_INVARG; + + rect.x += data->area.wanted.x; + rect.y += data->area.wanted.y; + + dfb_gfxcard_drawrectangle( &rect, &data->state ); + + return DFB_OK; +} + +static DFBResult +IDirectFBSurface_FillTriangle( IDirectFBSurface *thiz, + int x1, int y1, + int x2, int y2, + int x3, int y3 ) +{ + DFBTriangle tri = { x1, y1, x2, y2, x3, y3 }; + + DIRECT_INTERFACE_GET_DATA(IDirectFBSurface) + + D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz ); + D_DEBUG_AT( Surface, " -> [%2d] %4d,%4d-%4d,%4d-%4d,%4d\n", 0, x1, y1, x2, y2, x3, y3 ); + + if (!data->surface) + return DFB_DESTROYED; + + + if (!data->area.current.w || !data->area.current.h) + return DFB_INVAREA; + + if (data->locked) + return DFB_LOCKED; + + tri.x1 += data->area.wanted.x; + tri.y1 += data->area.wanted.y; + tri.x2 += data->area.wanted.x; + tri.y2 += data->area.wanted.y; + tri.x3 += data->area.wanted.x; + tri.y3 += data->area.wanted.y; + + dfb_gfxcard_filltriangles( &tri, 1, &data->state ); + + return DFB_OK; +} + +static DFBResult +IDirectFBSurface_FillRectangles( IDirectFBSurface *thiz, + const DFBRectangle *rects, + unsigned int num_rects ) +{ + DIRECT_INTERFACE_GET_DATA(IDirectFBSurface) + + D_DEBUG_AT( Surface, "%s( %p, %p [%d] )\n", __FUNCTION__, thiz, rects, num_rects ); + + DFB_RECTANGLES_DEBUG_AT( Surface, rects, num_rects ); + + + if (!data->surface) + return DFB_DESTROYED; + + + if (!data->area.current.w || !data->area.current.h) + return DFB_INVAREA; + + if (data->locked) + return DFB_LOCKED; + + if (!rects || !num_rects) + return DFB_INVARG; + + if (data->area.wanted.x || data->area.wanted.y) { + unsigned int i; + DFBRectangle *local_rects; + bool malloced = (num_rects > 256); + + if (malloced) + local_rects = D_MALLOC( sizeof(DFBRectangle) * num_rects ); + else + local_rects = alloca( sizeof(DFBRectangle) * num_rects ); + + for (i=0; iarea.wanted.x; + local_rects[i].y = rects[i].y + data->area.wanted.y; + local_rects[i].w = rects[i].w; + local_rects[i].h = rects[i].h; + } + + dfb_gfxcard_fillrectangles( local_rects, num_rects, &data->state ); + + if (malloced) + D_FREE( local_rects ); + } + else + dfb_gfxcard_fillrectangles( rects, num_rects, &data->state ); + + return DFB_OK; +} + +static DFBResult +IDirectFBSurface_FillSpans( IDirectFBSurface *thiz, + int y, + const DFBSpan *spans, + unsigned int num_spans ) +{ + DFBSpan *local_spans = alloca(sizeof(DFBSpan) * num_spans); + + DIRECT_INTERFACE_GET_DATA(IDirectFBSurface) + + D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz ); + + if (!data->surface) + return DFB_DESTROYED; + + + if (!data->area.current.w || !data->area.current.h) + return DFB_INVAREA; + + if (data->locked) + return DFB_LOCKED; + + if (!spans || !num_spans) + return DFB_INVARG; + + if (data->area.wanted.x || data->area.wanted.y) { + unsigned int i; + + for (i=0; iarea.wanted.x; + local_spans[i].w = spans[i].w; + } + } + else + /* clipping may modify spans, so we copy them */ + direct_memcpy( local_spans, spans, sizeof(DFBSpan) * num_spans ); + + dfb_gfxcard_fillspans( y + data->area.wanted.y, local_spans, num_spans, &data->state ); + + return DFB_OK; +} + +static DFBResult +IDirectFBSurface_FillTriangles( IDirectFBSurface *thiz, + const DFBTriangle *tris, + unsigned int num_tris ) +{ + DIRECT_INTERFACE_GET_DATA(IDirectFBSurface) + + D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz ); + + if (!data->surface) + return DFB_DESTROYED; + + + if (!data->area.current.w || !data->area.current.h) + return DFB_INVAREA; + + if (data->locked) + return DFB_LOCKED; + + if (!tris || !num_tris) + return DFB_INVARG; + + if (data->area.wanted.x || data->area.wanted.y) { + unsigned int i; + DFBTriangle *local_tris; + bool malloced = (num_tris > 170); + + if (malloced) + local_tris = D_MALLOC( sizeof(DFBTriangle) * num_tris ); + else + local_tris = alloca( sizeof(DFBTriangle) * num_tris ); + + for (i=0; iarea.wanted.x; + local_tris[i].y1 = tris[i].y1 + data->area.wanted.y; + local_tris[i].x2 = tris[i].x2 + data->area.wanted.x; + local_tris[i].y2 = tris[i].y2 + data->area.wanted.y; + local_tris[i].x3 = tris[i].x3 + data->area.wanted.x; + local_tris[i].y3 = tris[i].y3 + data->area.wanted.y; + } + + dfb_gfxcard_filltriangles( local_tris, num_tris, &data->state ); + + if (malloced) + D_FREE( local_tris ); + } + else + dfb_gfxcard_filltriangles( tris, num_tris, &data->state ); + + return DFB_OK; +} + +static DFBResult +IDirectFBSurface_SetBlittingFlags( IDirectFBSurface *thiz, + DFBSurfaceBlittingFlags flags ) +{ + DIRECT_INTERFACE_GET_DATA(IDirectFBSurface) + + D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz ); + + dfb_state_set_blitting_flags( &data->state, flags ); + + return DFB_OK; +} + +static DFBResult +IDirectFBSurface_Blit( IDirectFBSurface *thiz, + IDirectFBSurface *source, + const DFBRectangle *sr, + int dx, int dy ) +{ + DFBRectangle srect; + IDirectFBSurface_data *src_data; + + DIRECT_INTERFACE_GET_DATA(IDirectFBSurface) + + D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz ); + + if (sr) + D_DEBUG_AT( Surface, " -> [%2d] %4d,%4d-%4dx%4d <- %4d,%4d\n", 0, dx, dy, sr->w, sr->h, sr->x, sr->y ); + + if (!data->surface) + return DFB_DESTROYED; + + if (!source) + return DFB_INVARG; + + if (!data->area.current.w || !data->area.current.h) + return DFB_INVAREA; + + if (data->locked) + return DFB_LOCKED; + + + src_data = (IDirectFBSurface_data*)source->priv; + + if (!src_data->area.current.w || !src_data->area.current.h) + return DFB_INVAREA; + + if (sr) { + if (sr->w < 1 || sr->h < 1) + return DFB_OK; + + srect = *sr; + + srect.x += src_data->area.wanted.x; + srect.y += src_data->area.wanted.y; + + if (!dfb_rectangle_intersect( &srect, &src_data->area.current )) + return DFB_INVAREA; + + dx += srect.x - (sr->x + src_data->area.wanted.x); + dy += srect.y - (sr->y + src_data->area.wanted.y); + } + else { + srect = src_data->area.current; + + dx += srect.x - src_data->area.wanted.x; + dy += srect.y - src_data->area.wanted.y; + } + + dfb_state_set_source( &data->state, src_data->surface ); + + /* fetch the source color key from the source if necessary */ + if (data->state.blittingflags & DSBLIT_SRC_COLORKEY) + dfb_state_set_src_colorkey( &data->state, src_data->src_key.value ); + + dfb_gfxcard_blit( &srect, + data->area.wanted.x + dx, + data->area.wanted.y + dy, &data->state ); + + return DFB_OK; +} + +static DFBResult +IDirectFBSurface_TileBlit( IDirectFBSurface *thiz, + IDirectFBSurface *source, + const DFBRectangle *sr, + int dx, int dy ) +{ + DFBRectangle srect; + IDirectFBSurface_data *src_data; + + DIRECT_INTERFACE_GET_DATA(IDirectFBSurface) + + D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz ); + + if (sr) + D_DEBUG_AT( Surface, " -> [%2d] %4d,%4d-%4dx%4d <- %4d,%4d\n", 0, dx, dy, sr->w, sr->h, sr->x, sr->y ); + + if (!data->surface) + return DFB_DESTROYED; + + + if (!data->area.current.w || !data->area.current.h) + return DFB_INVAREA; + + if (data->locked) + return DFB_LOCKED; + + if (!source) + return DFB_INVARG; + + + src_data = (IDirectFBSurface_data*)source->priv; + + if (!src_data->area.current.w || !src_data->area.current.h) + return DFB_INVAREA; + + + if (sr) { + if (sr->w < 1 || sr->h < 1) + return DFB_OK; + + srect = *sr; + + srect.x += src_data->area.wanted.x; + srect.y += src_data->area.wanted.y; + + if (!dfb_rectangle_intersect( &srect, &src_data->area.current )) + return DFB_INVAREA; + + dx += srect.x - (sr->x + src_data->area.wanted.x); + dy += srect.y - (sr->y + src_data->area.wanted.y); + } + else { + srect = src_data->area.current; + + dx += srect.x - src_data->area.wanted.x; + dy += srect.y - src_data->area.wanted.y; + } + + dfb_state_set_source( &data->state, src_data->surface ); + + /* fetch the source color key from the source if necessary */ + if (data->state.blittingflags & DSBLIT_SRC_COLORKEY) + dfb_state_set_src_colorkey( &data->state, src_data->src_key.value ); + + dx %= srect.w; + if (dx > 0) + dx -= srect.w; + + dy %= srect.h; + if (dy > 0) + dy -= srect.h; + + dx += data->area.wanted.x; + dy += data->area.wanted.y; + + dfb_gfxcard_tileblit( &srect, dx, dy, + dx + data->area.wanted.w + srect.w - 1, + dy + data->area.wanted.h + srect.h - 1, &data->state ); + + return DFB_OK; +} + +static DFBResult +IDirectFBSurface_BatchBlit( IDirectFBSurface *thiz, + IDirectFBSurface *source, + const DFBRectangle *source_rects, + const DFBPoint *dest_points, + int num ) +{ + int i, dx, dy, sx, sy; + DFBRectangle *rects; + DFBPoint *points; + IDirectFBSurface_data *src_data; + + DIRECT_INTERFACE_GET_DATA(IDirectFBSurface) + + D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz ); + + if (!data->surface) + return DFB_DESTROYED; + + if (!source || !source_rects || !dest_points || num < 1) + return DFB_INVARG; + + if (!data->area.current.w || !data->area.current.h) + return DFB_INVAREA; + + if (data->locked) + return DFB_LOCKED; + + + src_data = (IDirectFBSurface_data*)source->priv; + + if (!src_data->area.current.w || !src_data->area.current.h) + return DFB_INVAREA; + + dx = data->area.wanted.x; + dy = data->area.wanted.y; + + sx = src_data->area.wanted.x; + sy = src_data->area.wanted.y; + + rects = alloca( sizeof(DFBRectangle) * num ); + points = alloca( sizeof(DFBPoint) * num ); + + direct_memcpy( rects, source_rects, sizeof(DFBRectangle) * num ); + direct_memcpy( points, dest_points, sizeof(DFBPoint) * num ); + + for (i=0; iarea.current )) + rects[i].w = rects[i].h = 0; + + points[i].x += rects[i].x - (source_rects[i].x + sx); + points[i].y += rects[i].y - (source_rects[i].y + sy); + } + + dfb_state_set_source( &data->state, src_data->surface ); + + /* fetch the source color key from the source if necessary */ + if (data->state.blittingflags & DSBLIT_SRC_COLORKEY) + dfb_state_set_src_colorkey( &data->state, src_data->src_key.value ); + + dfb_gfxcard_batchblit( rects, points, num, &data->state ); + + return DFB_OK; +} + +static DFBResult +IDirectFBSurface_StretchBlit( IDirectFBSurface *thiz, + IDirectFBSurface *source, + const DFBRectangle *source_rect, + const DFBRectangle *destination_rect ) +{ + DFBRectangle srect, drect; + IDirectFBSurface_data *src_data; + + DIRECT_INTERFACE_GET_DATA(IDirectFBSurface) + + D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz ); + + if (!data->surface) + return DFB_DESTROYED; + + + if (!data->area.current.w || !data->area.current.h) + return DFB_INVAREA; + + if (data->locked) + return DFB_LOCKED; + + if (!source) + return DFB_INVARG; + + + src_data = (IDirectFBSurface_data*)source->priv; + + if (!src_data->area.current.w || !src_data->area.current.h) + return DFB_INVAREA; + + + /* do destination rectangle */ + if (destination_rect) { + if (destination_rect->w < 1 || destination_rect->h < 1) + return DFB_INVARG; + + drect = *destination_rect; + + drect.x += data->area.wanted.x; + drect.y += data->area.wanted.y; + } + else + drect = data->area.wanted; + + /* do source rectangle */ + if (source_rect) { + if (source_rect->w < 1 || source_rect->h < 1) + return DFB_INVARG; + + srect = *source_rect; + + srect.x += src_data->area.wanted.x; + srect.y += src_data->area.wanted.y; + } + else + srect = src_data->area.wanted; + + + /* clipping of the source rectangle must be applied to the destination */ + { + DFBRectangle orig_src = srect; + + if (!dfb_rectangle_intersect( &srect, &src_data->area.current )) + return DFB_INVAREA; + + if (srect.x != orig_src.x) + drect.x += (int)( (srect.x - orig_src.x) * + (drect.w / (float)orig_src.w) + 0.5f); + + if (srect.y != orig_src.y) + drect.y += (int)( (srect.y - orig_src.y) * + (drect.h / (float)orig_src.h) + 0.5f); + + if (srect.w != orig_src.w) + drect.w = D_ICEIL(drect.w * (srect.w / (float)orig_src.w)); + if (srect.h != orig_src.h) + drect.h = D_ICEIL(drect.h * (srect.h / (float)orig_src.h)); + } + + dfb_state_set_source( &data->state, src_data->surface ); + + /* fetch the source color key from the source if necessary */ + if (data->state.blittingflags & DSBLIT_SRC_COLORKEY) + dfb_state_set_src_colorkey( &data->state, src_data->src_key.value ); + + dfb_gfxcard_stretchblit( &srect, &drect, &data->state ); + + return DFB_OK; +} + +#define SET_VERTEX(v,X,Y,Z,W,S,T) \ + do { \ + (v)->x = X; \ + (v)->y = Y; \ + (v)->z = Z; \ + (v)->w = W; \ + (v)->s = S; \ + (v)->t = T; \ + } while (0) + +static DFBResult +IDirectFBSurface_TextureTriangles( IDirectFBSurface *thiz, + IDirectFBSurface *source, + const DFBVertex *vertices, + const int *indices, + int num, + DFBTriangleFormation formation ) +{ + int i; + DFBVertex *translated; + IDirectFBSurface_data *src_data; + bool src_sub; + float x0 = 0; + float y0 = 0; + + DIRECT_INTERFACE_GET_DATA(IDirectFBSurface) + + D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz ); + + if (!data->surface) + return DFB_DESTROYED; + + + if (!data->area.current.w || !data->area.current.h) + return DFB_INVAREA; + + if (data->locked) + return DFB_LOCKED; + + if (!source || !vertices || num < 3) + return DFB_INVARG; + + src_data = (IDirectFBSurface_data*)source->priv; + + if ((src_sub = (src_data->caps & DSCAPS_SUBSURFACE))) { + D_ONCE( "sub surface texture not fully working with 'repeated' mapping" ); + + x0 = data->area.wanted.x; + y0 = data->area.wanted.y; + } + + switch (formation) { + case DTTF_LIST: + if (num % 3) + return DFB_INVARG; + break; + + case DTTF_STRIP: + case DTTF_FAN: + break; + + default: + return DFB_INVARG; + } + + translated = alloca( num * sizeof(DFBVertex) ); + if (!translated) + return DFB_NOSYSTEMMEMORY; + + /* TODO: pass indices through to driver */ + if (src_sub) { + float oowidth = 1.0f / src_data->surface->config.size.w; + float ooheight = 1.0f / src_data->surface->config.size.h; + + float s0 = src_data->area.wanted.x * oowidth; + float t0 = src_data->area.wanted.y * ooheight; + + float fs = src_data->area.wanted.w * oowidth; + float ft = src_data->area.wanted.h * ooheight; + + for (i=0; ix, y0 + in->y, in->z, in->w, + s0 + fs * in->s, t0 + ft * in->t ); + } + } + else { + if (indices) { + for (i=0; ix, y0 + in->y, in->z, in->w, in->s, in->t ); + } + } + else { + direct_memcpy( translated, vertices, num * sizeof(DFBVertex) ); + + for (i=0; istate, src_data->surface ); + + /* fetch the source color key from the source if necessary */ + if (data->state.blittingflags & DSBLIT_SRC_COLORKEY) + dfb_state_set_src_colorkey( &data->state, src_data->src_key.value ); + + dfb_gfxcard_texture_triangles( translated, num, formation, &data->state ); + + return DFB_OK; +} + +static DFBResult +IDirectFBSurface_DrawString( IDirectFBSurface *thiz, + const char *text, int bytes, + int x, int y, + DFBSurfaceTextFlags flags ) +{ + DFBResult ret; + IDirectFBFont *font; + IDirectFBFont_data *font_data; + CoreFont *core_font; + unsigned int layers = 1; + + DIRECT_INTERFACE_GET_DATA(IDirectFBSurface) + + D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz ); + + if (!data->surface) + return DFB_DESTROYED; + + if (!text) + return DFB_INVARG; + + if (!data->area.current.w || !data->area.current.h) + return DFB_INVAREA; + + if (data->locked) + return DFB_LOCKED; + + if (!data->font) + return DFB_MISSINGFONT; + + if (bytes < 0) + bytes = strlen (text); + + if (bytes == 0) + return DFB_OK; + + font = data->font; + + DIRECT_INTERFACE_GET_DATA_FROM( font, font_data, IDirectFBFont ); + + core_font = font_data->font; + + if (flags & DSTF_OUTLINE) { + if (!(core_font->attributes & DFFA_OUTLINED)) + return DFB_UNSUPPORTED; + + layers = 2; + } + + if (!(flags & DSTF_TOP)) { + x += core_font->ascender * core_font->up_unit_x; + y += core_font->ascender * core_font->up_unit_y; + + if (flags & DSTF_BOTTOM) { + x -= core_font->descender * core_font->up_unit_x; + y -= core_font->descender * core_font->up_unit_y; + } + } + + if (flags & (DSTF_RIGHT | DSTF_CENTER)) { + int i, num, kx, ky; + int xsize = 0; + int ysize = 0; + unsigned int prev = 0; + unsigned int indices[bytes]; + + /* FIXME: Avoid double locking and decoding. */ + dfb_font_lock( core_font ); + + /* Decode string to character indices. */ + ret = dfb_font_decode_text( core_font, data->encoding, text, bytes, indices, &num ); + if (ret) { + dfb_font_unlock( core_font ); + return ret; + } + + /* Calculate string width. */ + for (i=0; ixadvance; + ysize += glyph->yadvance; + + if (prev && core_font->GetKerning && + core_font->GetKerning( core_font, prev, current, &kx, &ky ) == DFB_OK) { + xsize += kx; + ysize += ky; + } + } + + prev = current; + } + + dfb_font_unlock( core_font ); + + /* Justify. */ + if (flags & DSTF_RIGHT) { + x -= xsize; + y -= ysize; + } + else if (flags & DSTF_CENTER) { + x -= xsize >> 1; + y -= ysize >> 1; + } + } + + dfb_gfxcard_drawstring( (const unsigned char*) text, bytes, data->encoding, + data->area.wanted.x + x, data->area.wanted.y + y, + core_font, layers, &data->state ); + + return DFB_OK; +} + +static DFBResult +IDirectFBSurface_DrawGlyph( IDirectFBSurface *thiz, + unsigned int character, int x, int y, + DFBSurfaceTextFlags flags ) +{ + DFBResult ret; + int l; + IDirectFBFont *font; + IDirectFBFont_data *font_data; + CoreFont *core_font; + CoreGlyphData *glyph[DFB_FONT_MAX_LAYERS]; + unsigned int index; + unsigned int layers = 1; + + DIRECT_INTERFACE_GET_DATA(IDirectFBSurface) + + D_DEBUG_AT( Surface, "%s( %p, 0x%x, %d,%d, 0x%x )\n", + __FUNCTION__, thiz, character, x, y, flags ); + + if (!data->surface) + return DFB_DESTROYED; + + if (!character) + return DFB_INVARG; + + if (!data->area.current.w || !data->area.current.h) + return DFB_INVAREA; + + if (data->locked) + return DFB_LOCKED; + + if (!data->font) + return DFB_MISSINGFONT; + + font = data->font; + + DIRECT_INTERFACE_GET_DATA_FROM( font, font_data, IDirectFBFont ); + + core_font = font_data->font; + + if (flags & DSTF_OUTLINE) { + if (!(core_font->attributes & DFFA_OUTLINED)) + return DFB_UNSUPPORTED; + + layers = 2; + } + + dfb_font_lock( core_font ); + + ret = dfb_font_decode_character( core_font, data->encoding, character, &index ); + if (ret) { + dfb_font_unlock( core_font ); + return ret; + } + + for (l=0; lascender * core_font->up_unit_x; + y += core_font->ascender * core_font->up_unit_y; + + if (flags & DSTF_BOTTOM) { + x -= core_font->descender * core_font->up_unit_x; + y -= core_font->descender * core_font->up_unit_y; + } + } + + if (flags & (DSTF_RIGHT | DSTF_CENTER)) { + if (flags & DSTF_RIGHT) { + x -= glyph[0]->xadvance; + y -= glyph[0]->yadvance; + } + else if (flags & DSTF_CENTER) { + x -= glyph[0]->xadvance >> 1; + y -= glyph[0]->yadvance >> 1; + } + } + + dfb_gfxcard_drawglyph( glyph, + data->area.wanted.x + x, data->area.wanted.y + y, + core_font, layers, &data->state ); + + dfb_font_unlock( core_font ); + + return DFB_OK; +} + +static DFBResult +IDirectFBSurface_SetEncoding( IDirectFBSurface *thiz, + DFBTextEncodingID encoding ) +{ + DIRECT_INTERFACE_GET_DATA(IDirectFBSurface) + + D_DEBUG_AT( Surface, "%s( %p, %d )\n", __FUNCTION__, thiz, encoding ); + + /* TODO: check for support or fail later? */ + data->encoding = encoding; + + return DFB_OK; +} + +static DFBResult +IDirectFBSurface_GetSubSurface( IDirectFBSurface *thiz, + const DFBRectangle *rect, + IDirectFBSurface **surface ) +{ + DFBResult ret; + + DIRECT_INTERFACE_GET_DATA(IDirectFBSurface) + + D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz ); + + /* Check arguments */ + if (!data->surface) + return DFB_DESTROYED; + + if (!surface) + return DFB_INVARG; + + /* Allocate interface */ + DIRECT_ALLOCATE_INTERFACE( *surface, IDirectFBSurface ); + + if (rect || data->limit_set) { + DFBRectangle wanted, granted; + + /* Compute wanted rectangle */ + if (rect) { + wanted = *rect; + + wanted.x += data->area.wanted.x; + wanted.y += data->area.wanted.y; + + if (wanted.w <= 0 || wanted.h <= 0) { + wanted.w = 0; + wanted.h = 0; + } + } + else { + wanted = data->area.wanted; + } + + /* Compute granted rectangle */ + granted = wanted; + + dfb_rectangle_intersect( &granted, &data->area.granted ); + + /* Construct */ + ret = IDirectFBSurface_Construct( *surface, thiz, + &wanted, &granted, &data->area.insets, + data->surface, + data->caps | DSCAPS_SUBSURFACE, data->core ); + } + else { + /* Construct */ + ret = IDirectFBSurface_Construct( *surface, thiz, + NULL, NULL, &data->area.insets, + data->surface, + data->caps | DSCAPS_SUBSURFACE, data->core ); + } + + return ret; +} + +static DFBResult +IDirectFBSurface_MakeSubSurface( IDirectFBSurface *thiz, + IDirectFBSurface *from, + const DFBRectangle *rect ) +{ + CoreSurface *surface; + DFBRectangle wanted, granted; + DFBRectangle full_rect; + IDirectFBSurface_data *from_data; + + DIRECT_INTERFACE_GET_DATA(IDirectFBSurface) + + D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz ); + + /* Check arguments */ + if (!from) + return DFB_INVARG; + + surface = data->surface; + if (!surface) + return DFB_DESTROYED; + + DIRECT_INTERFACE_GET_DATA_FROM(from, from_data, IDirectFBSurface); + + /* Check if CoreSurface is the same */ + if (from_data->surface != surface) + return DFB_UNSUPPORTED; + + + full_rect.x = 0; + full_rect.y = 0; + full_rect.w = surface->config.size.w; + full_rect.h = surface->config.size.h; + + if (rect || from_data->limit_set) { + /* Compute wanted rectangle */ + if (rect) { + wanted = *rect; + + wanted.x += from_data->area.wanted.x; + wanted.y += from_data->area.wanted.y; + + if (wanted.w <= 0 || wanted.h <= 0) { + wanted.w = 0; + wanted.h = 0; + } + } + else { + wanted = from_data->area.wanted; + } + + /* Compute granted rectangle */ + granted = wanted; + + dfb_rectangle_intersect( &granted, &from_data->area.granted ); + } + else { + wanted = full_rect; + granted = full_rect; + } + + + data->caps |= DSCAPS_SUBSURFACE; + + + data->area.wanted = wanted; + data->area.granted = granted; + + data->area.current = data->area.granted; + dfb_rectangle_intersect( &data->area.current, &full_rect ); + + + data->state.clip.x1 = data->area.current.x; + data->state.clip.y1 = data->area.current.y; + data->state.clip.x2 = data->area.current.x + (data->area.current.w ? : 1) - 1; + data->state.clip.y2 = data->area.current.y + (data->area.current.h ? : 1) - 1; + + data->state.modified |= SMF_CLIP; + + + return DFB_OK; +} + +static DFBResult +IDirectFBSurface_GetGL( IDirectFBSurface *thiz, + IDirectFBGL **interface ) +{ + DFBResult ret; + DirectInterfaceFuncs *funcs = NULL; + + DIRECT_INTERFACE_GET_DATA(IDirectFBSurface) + + D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz ); + + if (!data->surface) + return DFB_DESTROYED; + + if (!interface) + return DFB_INVARG; + + if (!data->area.current.w || !data->area.current.h) + return DFB_INVAREA; + + + ret = DirectGetInterface( &funcs, "IDirectFBGL", NULL, DirectProbeInterface, thiz ); + if (ret) + return ret; + + ret = funcs->Allocate( (void**)interface ); + if (ret) + return ret; + + ret = funcs->Construct( *interface, thiz ); + if (ret) + *interface = NULL; + + return ret; +} + +static DFBResult +IDirectFBSurface_Dump( IDirectFBSurface *thiz, + const char *directory, + const char *prefix ) +{ + CoreSurface *surface; + + DIRECT_INTERFACE_GET_DATA(IDirectFBSurface) + + D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz ); + + if (!directory) + return DFB_INVARG; + + if (!data->area.current.w || !data->area.current.h) + return DFB_INVAREA; + + if (data->caps & DSCAPS_SUBSURFACE) { + D_ONCE( "sub surface dumping not supported yet" ); + return DFB_UNSUPPORTED; + } + + surface = data->surface; + if (!surface) + return DFB_DESTROYED; + + return dfb_surface_dump_buffer( surface, CSBR_FRONT, directory, prefix ); +} + +static DFBResult +IDirectFBSurface_DisableAcceleration( IDirectFBSurface *thiz, + DFBAccelerationMask mask ) +{ + DIRECT_INTERFACE_GET_DATA(IDirectFBSurface) + + D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz ); + + if (D_FLAGS_INVALID( mask, DFXL_ALL )) + return DFB_INVARG; + + data->state.disabled = mask; + + return DFB_OK; +} + +static DFBResult +IDirectFBSurface_ReleaseSource( IDirectFBSurface *thiz ) +{ + DIRECT_INTERFACE_GET_DATA(IDirectFBSurface) + + D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz ); + + dfb_state_set_source( &data->state, NULL ); + dfb_state_set_source_mask( &data->state, NULL ); + + return DFB_OK; +} + +static DFBResult +IDirectFBSurface_SetRenderOptions( IDirectFBSurface *thiz, + DFBSurfaceRenderOptions options ) +{ + DIRECT_INTERFACE_GET_DATA(IDirectFBSurface) + + D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz ); + + dfb_state_set_render_options( &data->state, options ); + + return DFB_OK; +} + +static DFBResult +IDirectFBSurface_SetMatrix( IDirectFBSurface *thiz, + const s32 *matrix ) +{ + DIRECT_INTERFACE_GET_DATA(IDirectFBSurface) + + D_DEBUG_AT( Surface, "%s( %p, %p )\n", __FUNCTION__, thiz, matrix ); + + if (!matrix) + return DFB_INVARG; + + dfb_state_set_matrix( &data->state, matrix ); + + return DFB_OK; +} + +static DFBResult +IDirectFBSurface_SetSourceMask( IDirectFBSurface *thiz, + IDirectFBSurface *mask, + int x, + int y, + DFBSurfaceMaskFlags flags ) +{ + DFBResult ret; + DFBPoint offset = { x, y }; + IDirectFBSurface_data *mask_data; + + DIRECT_INTERFACE_GET_DATA(IDirectFBSurface) + + D_DEBUG_AT( Surface, "%s( %p, %p, %d,%d, 0x%04x )\n", __FUNCTION__, thiz, mask, x, y, flags ); + + if (!mask || flags & ~DSMF_ALL) + return DFB_INVARG; + + DIRECT_INTERFACE_GET_DATA_FROM(mask, mask_data, IDirectFBSurface); + + if (!mask_data->surface) + return DFB_DESTROYED; + + ret = dfb_state_set_source_mask( &data->state, mask_data->surface ); + if (ret) + return ret; + + dfb_state_set_source_mask_vals( &data->state, &offset, flags ); + + return DFB_OK; +} + +/******/ + +DFBResult IDirectFBSurface_Construct( IDirectFBSurface *thiz, + IDirectFBSurface *parent, + DFBRectangle *wanted, + DFBRectangle *granted, + DFBInsets *insets, + CoreSurface *surface, + DFBSurfaceCapabilities caps, + CoreDFB *core ) +{ + DFBRectangle rect = { 0, 0, surface->config.size.w, surface->config.size.h }; + + DIRECT_ALLOCATE_INTERFACE_DATA(thiz, IDirectFBSurface) + + D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz ); + + data->ref = 1; + data->caps = caps | surface->config.caps; + data->core = core; + + if (dfb_surface_ref( surface )) { + DIRECT_DEALLOCATE_INTERFACE(thiz); + return DFB_FAILURE; + } + + if (parent && dfb_config->startstop) { + IDirectFBSurface_data *parent_data; + + if (parent->AddRef( parent )) { + dfb_surface_unref( surface ); + DIRECT_DEALLOCATE_INTERFACE(thiz); + return DFB_FAILURE; + } + + DIRECT_INTERFACE_GET_DATA_FROM( parent, parent_data, IDirectFBSurface ); + + pthread_mutex_lock( &parent_data->children_lock ); + + direct_list_append( &parent_data->children_data, &data->link ); + + pthread_mutex_unlock( &parent_data->children_lock ); + + data->parent = parent; + } + + pthread_mutex_init( &data->children_lock, NULL ); + + /* The area insets */ + if (insets) { + data->area.insets = *insets; + dfb_rectangle_subtract( &rect, insets ); + } + + /* The area that was requested */ + if (wanted) + data->area.wanted = *wanted; + else + data->area.wanted = rect; + + /* The area that will never be exceeded */ + if (granted) + data->area.granted = *granted; + else + data->area.granted = data->area.wanted; + + /* The currently accessible rectangle */ + data->area.current = data->area.granted; + dfb_rectangle_intersect( &data->area.current, &rect ); + + /* Whether granted rectangle is meaningful */ + data->limit_set = (granted != NULL); + + data->surface = surface; + + dfb_state_init( &data->state, NULL ); + dfb_state_set_destination( &data->state, surface ); + + data->state.clip.x1 = data->area.current.x; + data->state.clip.y1 = data->area.current.y; + data->state.clip.x2 = data->area.current.x + (data->area.current.w ? : 1) - 1; + data->state.clip.y2 = data->area.current.y + (data->area.current.h ? : 1) - 1; + + data->state.modified = SMF_ALL; + + thiz->AddRef = IDirectFBSurface_AddRef; + thiz->Release = IDirectFBSurface_Release; + + thiz->GetCapabilities = IDirectFBSurface_GetCapabilities; + thiz->GetPosition = IDirectFBSurface_GetPosition; + thiz->GetSize = IDirectFBSurface_GetSize; + thiz->GetVisibleRectangle = IDirectFBSurface_GetVisibleRectangle; + thiz->GetPixelFormat = IDirectFBSurface_GetPixelFormat; + thiz->GetAccelerationMask = IDirectFBSurface_GetAccelerationMask; + + thiz->GetPalette = IDirectFBSurface_GetPalette; + thiz->SetPalette = IDirectFBSurface_SetPalette; + thiz->SetAlphaRamp = IDirectFBSurface_SetAlphaRamp; + + thiz->Lock = IDirectFBSurface_Lock; + thiz->GetFramebufferOffset = IDirectFBSurface_GetFramebufferOffset; + thiz->Unlock = IDirectFBSurface_Unlock; + thiz->Flip = IDirectFBSurface_Flip; + thiz->SetField = IDirectFBSurface_SetField; + thiz->Clear = IDirectFBSurface_Clear; + + thiz->SetClip = IDirectFBSurface_SetClip; + thiz->GetClip = IDirectFBSurface_GetClip; + thiz->SetColor = IDirectFBSurface_SetColor; + thiz->SetColorIndex = IDirectFBSurface_SetColorIndex; + thiz->SetSrcBlendFunction = IDirectFBSurface_SetSrcBlendFunction; + thiz->SetDstBlendFunction = IDirectFBSurface_SetDstBlendFunction; + thiz->SetPorterDuff = IDirectFBSurface_SetPorterDuff; + thiz->SetSrcColorKey = IDirectFBSurface_SetSrcColorKey; + thiz->SetSrcColorKeyIndex = IDirectFBSurface_SetSrcColorKeyIndex; + thiz->SetDstColorKey = IDirectFBSurface_SetDstColorKey; + thiz->SetDstColorKeyIndex = IDirectFBSurface_SetDstColorKeyIndex; + thiz->SetIndexTranslation = IDirectFBSurface_SetIndexTranslation; + + thiz->SetBlittingFlags = IDirectFBSurface_SetBlittingFlags; + thiz->Blit = IDirectFBSurface_Blit; + thiz->TileBlit = IDirectFBSurface_TileBlit; + thiz->BatchBlit = IDirectFBSurface_BatchBlit; + thiz->StretchBlit = IDirectFBSurface_StretchBlit; + thiz->TextureTriangles = IDirectFBSurface_TextureTriangles; + + thiz->SetDrawingFlags = IDirectFBSurface_SetDrawingFlags; + thiz->FillRectangle = IDirectFBSurface_FillRectangle; + thiz->DrawLine = IDirectFBSurface_DrawLine; + thiz->DrawLines = IDirectFBSurface_DrawLines; + thiz->DrawRectangle = IDirectFBSurface_DrawRectangle; + thiz->FillTriangle = IDirectFBSurface_FillTriangle; + thiz->FillRectangles = IDirectFBSurface_FillRectangles; + thiz->FillSpans = IDirectFBSurface_FillSpans; + thiz->FillTriangles = IDirectFBSurface_FillTriangles; + + thiz->SetFont = IDirectFBSurface_SetFont; + thiz->GetFont = IDirectFBSurface_GetFont; + thiz->DrawString = IDirectFBSurface_DrawString; + thiz->DrawGlyph = IDirectFBSurface_DrawGlyph; + thiz->SetEncoding = IDirectFBSurface_SetEncoding; + + thiz->GetSubSurface = IDirectFBSurface_GetSubSurface; + + thiz->GetGL = IDirectFBSurface_GetGL; + + thiz->Dump = IDirectFBSurface_Dump; + thiz->DisableAcceleration = IDirectFBSurface_DisableAcceleration; + thiz->ReleaseSource = IDirectFBSurface_ReleaseSource; + + thiz->SetRenderOptions = IDirectFBSurface_SetRenderOptions; + thiz->SetMatrix = IDirectFBSurface_SetMatrix; + thiz->SetSourceMask = IDirectFBSurface_SetSourceMask; + + thiz->MakeSubSurface = IDirectFBSurface_MakeSubSurface; + + thiz->Write = IDirectFBSurface_Write; + thiz->Read = IDirectFBSurface_Read; + + thiz->SetColors = IDirectFBSurface_SetColors; + + dfb_surface_attach( surface, + IDirectFBSurface_listener, thiz, &data->reaction ); + + return DFB_OK; +} + + +/* internal */ + +static ReactionResult +IDirectFBSurface_listener( const void *msg_data, void *ctx ) +{ + const CoreSurfaceNotification *notification = msg_data; + IDirectFBSurface *thiz = ctx; + IDirectFBSurface_data *data = thiz->priv; + CoreSurface *surface = data->surface; + + D_DEBUG_AT( Surface, "%s( %p, %p )\n", __FUNCTION__, msg_data, ctx ); + + if (notification->flags & CSNF_DESTROY) { + if (data->surface) { + data->surface = NULL; + dfb_surface_unref( surface ); + } + return RS_REMOVE; + } + + if (notification->flags & CSNF_SIZEFORMAT) { + DFBRectangle rect = { 0, 0, surface->config.size.w, surface->config.size.h }; + + dfb_rectangle_subtract( &rect, &data->area.insets ); + + if (data->limit_set) { + data->area.current = data->area.granted; + + dfb_rectangle_intersect( &data->area.current, &rect ); + } + else + data->area.wanted = data->area.granted = data->area.current = rect; + + /* Reset clip to avoid crashes caused by drawing out of bounds. */ + if (data->clip_set) + thiz->SetClip( thiz, &data->clip_wanted ); + else + thiz->SetClip( thiz, NULL ); + } + + return RS_OK; +} + +void +IDirectFBSurface_StopAll( IDirectFBSurface_data *data ) +{ + if (!dfb_config->startstop) + return; + + if (data->children_data) { + IDirectFBSurface_data *child; + + pthread_mutex_lock( &data->children_lock ); + + direct_list_foreach (child, data->children_data) + IDirectFBSurface_StopAll( child ); + + pthread_mutex_unlock( &data->children_lock ); + } + + /* Signal end of sequence of operations. */ + dfb_state_lock( &data->state ); + dfb_state_stop_drawing( &data->state ); + dfb_state_unlock( &data->state ); +} + diff --git a/Source/DirectFB/src/display/idirectfbsurface.h b/Source/DirectFB/src/display/idirectfbsurface.h new file mode 100755 index 0000000..a350054 --- /dev/null +++ b/Source/DirectFB/src/display/idirectfbsurface.h @@ -0,0 +1,123 @@ +/* + (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org) + (c) Copyright 2000-2004 Convergence (integrated media) GmbH + + All rights reserved. + + Written by Denis Oliver Kropp , + Andreas Hundt , + Sven Neumann , + Ville Syrjälä and + Claudio Ciccani . + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#ifndef __IDIRECTFBSURFACE_H__ +#define __IDIRECTFBSURFACE_H__ + +#include + +#include + +#include + +#include +#include + + +/* + * private data struct of IDirectFBSurface + */ +typedef struct { + DirectLink link; + + int ref; /* reference counter */ + + DFBSurfaceCapabilities caps; /* capabilities */ + + struct { + DFBRectangle wanted; /* passed to GetSubSurface */ + DFBRectangle granted; /* clipped by parent on creation */ + DFBRectangle current; /* currently available area */ + DFBInsets insets; /* actually set by the window manager */ + } area; + + bool limit_set; /* greanted rectangle set? + (GetSubSurface called with rect != NULL) */ + + bool clip_set; /* fixed clip set? (SetClip called + with clip != NULL) */ + DFBRegion clip_wanted; /* last region passed to SetClip + intersected by wanted area, + only valid if clip_set != 0 */ + + CoreSurface *surface; /* buffer to show */ + bool locked; /* which buffer is locked? */ + CoreSurfaceBufferLock lock; + + IDirectFBFont *font; /* font to use */ + CardState state; /* render state to use */ + DFBTextEncodingID encoding; /* text encoding */ + + struct { + u8 r; /* red component */ + u8 g; /* green component */ + u8 b; /* blue component */ + u32 value; /* r/g/b in surface's format */ + } src_key; /* src key for blitting from + this surface */ + + struct { + u8 r; /* red component */ + u8 g; /* green component */ + u8 b; /* blue component */ + u32 value; /* r/g/b in surface's format */ + } dst_key; /* dst key for blitting to + this surface */ + + Reaction reaction; + + CoreDFB *core; + + IDirectFBSurface *parent; + DirectLink *children_data; + pthread_mutex_t children_lock; +} IDirectFBSurface_data; + +/* + * initializes interface struct and private data + */ +DFBResult IDirectFBSurface_Construct( IDirectFBSurface *thiz, + IDirectFBSurface *parent, + DFBRectangle *req_rect, + DFBRectangle *clip_rect, + DFBInsets *insets, + CoreSurface *surface, + DFBSurfaceCapabilities caps, + CoreDFB *core ); + +/* + * destroys surface(s) and frees private data + */ +void IDirectFBSurface_Destruct( IDirectFBSurface *thiz ); + +/* + * internal + */ +void IDirectFBSurface_StopAll( IDirectFBSurface_data *data ); + +#endif diff --git a/Source/DirectFB/src/display/idirectfbsurface_layer.c b/Source/DirectFB/src/display/idirectfbsurface_layer.c new file mode 100755 index 0000000..4507a56 --- /dev/null +++ b/Source/DirectFB/src/display/idirectfbsurface_layer.c @@ -0,0 +1,244 @@ +/* + (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org) + (c) Copyright 2000-2004 Convergence (integrated media) GmbH + + All rights reserved. + + Written by Denis Oliver Kropp , + Andreas Hundt , + Sven Neumann , + Ville Syrjälä and + Claudio Ciccani . + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include + +#include +#include +#include + +#include + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "idirectfbsurface.h" +#include "idirectfbsurface_layer.h" + +#include + +#include +#include + +#include + + +D_DEBUG_DOMAIN( Surface, "IDirectFBSurfaceL", "IDirectFBSurface_Layer Interface" ); + +/**********************************************************************************************************************/ + +static void +IDirectFBSurface_Layer_Destruct( IDirectFBSurface *thiz ) +{ + IDirectFBSurface_Layer_data *data = (IDirectFBSurface_Layer_data*) thiz->priv; + + D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz ); + + dfb_layer_region_unref( data->region ); + IDirectFBSurface_Destruct( thiz ); +} + +static DirectResult +IDirectFBSurface_Layer_Release( IDirectFBSurface *thiz ) +{ + DIRECT_INTERFACE_GET_DATA(IDirectFBSurface_Layer) + + D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz ); + + if (--data->base.ref == 0) + IDirectFBSurface_Layer_Destruct( thiz ); + + return DFB_OK; +} + +static DFBResult +IDirectFBSurface_Layer_Flip( IDirectFBSurface *thiz, + const DFBRegion *region, + DFBSurfaceFlipFlags flags ) +{ + DFBRegion reg; + + DIRECT_INTERFACE_GET_DATA(IDirectFBSurface_Layer) + + D_DEBUG_AT( Surface, "%s( %p, %p, 0x%08x )\n", __FUNCTION__, thiz, region, flags ); + + if (!data->base.surface) + return DFB_DESTROYED; + + if (data->base.locked) + return DFB_LOCKED; + + if (!data->base.area.current.w || !data->base.area.current.h || + (region && (region->x1 > region->x2 || region->y1 > region->y2))) + return DFB_INVAREA; + + + IDirectFBSurface_StopAll( &data->base ); + + if (data->base.parent) { + IDirectFBSurface_data *parent_data; + + DIRECT_INTERFACE_GET_DATA_FROM( data->base.parent, parent_data, IDirectFBSurface ); + + /* Signal end of sequence of operations. */ + dfb_state_lock( &parent_data->state ); + dfb_state_stop_drawing( &parent_data->state ); + dfb_state_unlock( &parent_data->state ); + } + + + dfb_region_from_rectangle( ®, &data->base.area.current ); + + if (region) { + DFBRegion clip = DFB_REGION_INIT_TRANSLATED( region, + data->base.area.wanted.x, + data->base.area.wanted.y ); + + if (!dfb_region_region_intersect( ®, &clip )) + return DFB_INVAREA; + } + + D_DEBUG_AT( Surface, " -> FLIP %4d,%4d-%4dx%4d\n", DFB_RECTANGLE_VALS_FROM_REGION( ® ) ); + + return dfb_layer_region_flip_update( data->region, ®, flags ); +} + +static DFBResult +IDirectFBSurface_Layer_GetSubSurface( IDirectFBSurface *thiz, + const DFBRectangle *rect, + IDirectFBSurface **surface ) +{ + DFBResult ret; + + DIRECT_INTERFACE_GET_DATA(IDirectFBSurface_Layer) + + D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz ); + + /* Check arguments */ + if (!data->base.surface) + return DFB_DESTROYED; + + if (!surface) + return DFB_INVARG; + + /* Allocate interface */ + DIRECT_ALLOCATE_INTERFACE( *surface, IDirectFBSurface ); + + if (rect || data->base.limit_set) { + DFBRectangle wanted, granted; + + /* Compute wanted rectangle */ + if (rect) { + wanted = *rect; + + wanted.x += data->base.area.wanted.x; + wanted.y += data->base.area.wanted.y; + + if (wanted.w <= 0 || wanted.h <= 0) { + wanted.w = 0; + wanted.h = 0; + } + } + else { + wanted = data->base.area.wanted; + } + + /* Compute granted rectangle */ + granted = wanted; + + dfb_rectangle_intersect( &granted, &data->base.area.granted ); + + /* Construct */ + ret = IDirectFBSurface_Layer_Construct( *surface, thiz, &wanted, &granted, + data->region, data->base.caps | + DSCAPS_SUBSURFACE, data->base.core ); + } + else { + /* Construct */ + ret = IDirectFBSurface_Layer_Construct( *surface, thiz, NULL, NULL, + data->region, data->base.caps | + DSCAPS_SUBSURFACE, data->base.core ); + } + + return ret; +} + +DFBResult +IDirectFBSurface_Layer_Construct( IDirectFBSurface *thiz, + IDirectFBSurface *parent, + DFBRectangle *wanted, + DFBRectangle *granted, + CoreLayerRegion *region, + DFBSurfaceCapabilities caps, + CoreDFB *core ) +{ + DFBResult ret; + CoreSurface *surface; + + DIRECT_ALLOCATE_INTERFACE_DATA(thiz, IDirectFBSurface_Layer); + + D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz ); + + if (dfb_layer_region_ref( region )) + return DFB_FUSION; + + ret = dfb_layer_region_get_surface( region, &surface ); + if (ret) { + dfb_layer_region_unref( region ); + DIRECT_DEALLOCATE_INTERFACE(thiz); + return ret; + } + + ret = IDirectFBSurface_Construct( thiz, parent, wanted, granted, NULL, + surface, surface->config.caps | caps, core ); + if (ret) { + dfb_surface_unref( surface ); + dfb_layer_region_unref( region ); + return ret; + } + + dfb_surface_unref( surface ); + + data->region = region; + + thiz->Release = IDirectFBSurface_Layer_Release; + thiz->Flip = IDirectFBSurface_Layer_Flip; + thiz->GetSubSurface = IDirectFBSurface_Layer_GetSubSurface; + + return DFB_OK; +} + diff --git a/Source/DirectFB/src/display/idirectfbsurface_layer.h b/Source/DirectFB/src/display/idirectfbsurface_layer.h new file mode 100755 index 0000000..c2ddb8c --- /dev/null +++ b/Source/DirectFB/src/display/idirectfbsurface_layer.h @@ -0,0 +1,57 @@ +/* + (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org) + (c) Copyright 2000-2004 Convergence (integrated media) GmbH + + All rights reserved. + + Written by Denis Oliver Kropp , + Andreas Hundt , + Sven Neumann , + Ville Syrjälä and + Claudio Ciccani . + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#ifndef __DIRECTFBSURFACE_LAYER_H__ +#define __DIRECTFBSURFACE_LAYER_H__ + +#include +#include + +/* + * private data struct of IDirectFBSurface_Layer + */ +typedef struct { + IDirectFBSurface_data base; /* base Surface implementation */ + + CoreLayerRegion *region; /* the region this surface belongs to */ +} IDirectFBSurface_Layer_data; + +/* + * sets buffer mode according to capabilities, calls base classes + * IDirectFBSurface_Construct, reallocates private data and + * overloads functions of the interface + */ +DFBResult IDirectFBSurface_Layer_Construct( IDirectFBSurface *thiz, + IDirectFBSurface *parent, + DFBRectangle *req_rect, + DFBRectangle *clip_rect, + CoreLayerRegion *region, + DFBSurfaceCapabilities caps, + CoreDFB *core ); + +#endif diff --git a/Source/DirectFB/src/display/idirectfbsurface_window.c b/Source/DirectFB/src/display/idirectfbsurface_window.c new file mode 100755 index 0000000..c76eb3d --- /dev/null +++ b/Source/DirectFB/src/display/idirectfbsurface_window.c @@ -0,0 +1,353 @@ +/* + (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org) + (c) Copyright 2000-2004 Convergence (integrated media) GmbH + + All rights reserved. + + Written by Denis Oliver Kropp , + Andreas Hundt , + Sven Neumann , + Ville Syrjälä and + Claudio Ciccani . + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include + +#include +#include +#include + +#include + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include /* FIXME */ +#include + +#include +#include + +#include +#include +#include + +#include + + +D_DEBUG_DOMAIN( Surface, "IDirectFBSurfaceW", "IDirectFBSurface_Window Interface" ); + +/**********************************************************************************************************************/ + +/* + * private data struct of IDirectFBSurface_Window + */ +typedef struct { + IDirectFBSurface_data base; /* base Surface implementation */ + + CoreWindow *window; /* pointer to core data */ + + pthread_t flip_thread; /* thread for non-flipping primary + surfaces, to make changes visible */ + +// CoreGraphicsSerial serial; +} IDirectFBSurface_Window_data; + +/**********************************************************************************************************************/ + +static void *Flipping_Thread( void *arg ); + +/**********************************************************************************************************************/ + +static void +IDirectFBSurface_Window_Destruct( IDirectFBSurface *thiz ) +{ + IDirectFBSurface_Window_data *data; + + D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz ); + + D_ASSERT( thiz != NULL ); + + data = thiz->priv; + + if ((int) data->flip_thread != -1) { + pthread_cancel( data->flip_thread ); + pthread_join( data->flip_thread, NULL ); + } + + dfb_window_unref( data->window ); + + IDirectFBSurface_Destruct( thiz ); +} + +static DirectResult +IDirectFBSurface_Window_Release( IDirectFBSurface *thiz ) +{ + DIRECT_INTERFACE_GET_DATA(IDirectFBSurface_Window) + + D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz ); + + if (--data->base.ref == 0) + IDirectFBSurface_Window_Destruct( thiz ); + + return DFB_OK; +} + +static DFBResult +IDirectFBSurface_Window_Flip( IDirectFBSurface *thiz, + const DFBRegion *region, + DFBSurfaceFlipFlags flags ) +{ + DFBResult ret; + DFBRegion reg; + + DIRECT_INTERFACE_GET_DATA(IDirectFBSurface_Window) + + D_DEBUG_AT( Surface, "%s( %p, %p, 0x%08x )\n", __FUNCTION__, thiz, region, flags ); + + if (!data->base.surface) + return DFB_DESTROYED; + + if (data->base.locked) + return DFB_LOCKED; + + if (!data->base.area.current.w || !data->base.area.current.h || + (region && (region->x1 > region->x2 || region->y1 > region->y2))) + return DFB_INVAREA; + + + IDirectFBSurface_StopAll( &data->base ); + + if (data->base.parent) { + IDirectFBSurface_data *parent_data; + + DIRECT_INTERFACE_GET_DATA_FROM( data->base.parent, parent_data, IDirectFBSurface ); + + /* Signal end of sequence of operations. */ + dfb_state_lock( &parent_data->state ); + dfb_state_stop_drawing( &parent_data->state ); + dfb_state_unlock( &parent_data->state ); + } + + + + dfb_region_from_rectangle( ®, &data->base.area.current ); + + if (region) { + DFBRegion clip = DFB_REGION_INIT_TRANSLATED( region, + data->base.area.wanted.x, + data->base.area.wanted.y ); + + if (!dfb_region_region_intersect( ®, &clip )) + return DFB_INVAREA; + } + + D_DEBUG_AT( Surface, " -> FLIP %4d,%4d-%4dx%4d\n", DFB_RECTANGLE_VALS_FROM_REGION( ® ) ); + + + if (flags & DSFLIP_PIPELINE) { + dfb_gfxcard_wait_serial( &data->window->serial2 ); + + data->window->serial2 = data->window->serial1; + + dfb_state_get_serial( &data->base.state, &data->window->serial1 ); + } + + + if (data->window->region) { + dfb_layer_region_flip_update( data->window->region, ®, flags ); + } + else { + if (data->base.surface->config.caps & DSCAPS_FLIPPING) { + if (!(flags & DSFLIP_BLIT) && reg.x1 == 0 && reg.y1 == 0 && + reg.x2 == data->base.surface->config.size.w - 1 && + reg.y2 == data->base.surface->config.size.h - 1) + { + ret = dfb_surface_lock( data->base.surface ); + if (ret) + return ret; + + dfb_surface_flip( data->base.surface, false ); + + dfb_surface_unlock( data->base.surface ); + } + else + dfb_back_to_front_copy( data->base.surface, ® ); + } + + dfb_window_repaint( data->window, ®, flags ); + } + + if (!data->window->config.opacity && data->base.caps & DSCAPS_PRIMARY) + dfb_window_set_opacity( data->window, 0xff ); + + return DFB_OK; +} + +static DFBResult +IDirectFBSurface_Window_GetSubSurface( IDirectFBSurface *thiz, + const DFBRectangle *rect, + IDirectFBSurface **surface ) +{ + DFBResult ret; + + DIRECT_INTERFACE_GET_DATA(IDirectFBSurface_Window) + + D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz ); + + /* Check arguments */ + if (!data->base.surface || !data->window || !data->window->surface) + return DFB_DESTROYED; + + if (!surface) + return DFB_INVARG; + + /* Allocate interface */ + DIRECT_ALLOCATE_INTERFACE( *surface, IDirectFBSurface ); + + if (rect || data->base.limit_set) { + DFBRectangle wanted, granted; + + /* Compute wanted rectangle */ + if (rect) { + wanted = *rect; + + wanted.x += data->base.area.wanted.x; + wanted.y += data->base.area.wanted.y; + + if (wanted.w <= 0 || wanted.h <= 0) { + wanted.w = 0; + wanted.h = 0; + } + } + else { + wanted = data->base.area.wanted; + } + + /* Compute granted rectangle */ + granted = wanted; + + dfb_rectangle_intersect( &granted, &data->base.area.granted ); + + /* Construct */ + ret = IDirectFBSurface_Window_Construct( *surface, thiz, &wanted, &granted, + data->window, data->base.caps | + DSCAPS_SUBSURFACE, data->base.core ); + } + else { + /* Construct */ + ret = IDirectFBSurface_Window_Construct( *surface, thiz, NULL, NULL, + data->window, data->base.caps | + DSCAPS_SUBSURFACE, data->base.core ); + } + + return ret; +} + +DFBResult +IDirectFBSurface_Window_Construct( IDirectFBSurface *thiz, + IDirectFBSurface *parent, + DFBRectangle *wanted, + DFBRectangle *granted, + CoreWindow *window, + DFBSurfaceCapabilities caps, + CoreDFB *core ) +{ + DFBResult ret; + DFBInsets insets; + CoreWindowStack *stack; + + DIRECT_ALLOCATE_INTERFACE_DATA(thiz, IDirectFBSurface_Window) + + D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz ); + + stack = window->stack; + D_MAGIC_ASSERT( stack, CoreWindowStack ); + + dfb_layer_context_lock( stack->context ); + + dfb_wm_get_insets( stack, window, &insets ); + + dfb_layer_context_unlock( stack->context ); + + ret = IDirectFBSurface_Construct( thiz, parent, wanted, granted, &insets, + window->surface, caps, core ); + if (ret) + return ret; + + if (dfb_window_ref( window )) { + IDirectFBSurface_Destruct( thiz ); + return DFB_FAILURE; + } + + data->window = window; + data->flip_thread = (pthread_t) -1; + + /* + * Create an auto flipping thread if the application + * requested a (primary) surface that doesn't need to be flipped. + * Window surfaces even need to be flipped when they are single buffered. + */ + if (!(caps & DSCAPS_FLIPPING) && !(caps & DSCAPS_SUBSURFACE)) { + if (dfb_config->autoflip_window) + pthread_create( &data->flip_thread, NULL, Flipping_Thread, thiz ); + else + D_WARN( "Non-flipping window surface and no 'autoflip-window' option used" ); + } + + thiz->Release = IDirectFBSurface_Window_Release; + thiz->Flip = IDirectFBSurface_Window_Flip; + thiz->GetSubSurface = IDirectFBSurface_Window_GetSubSurface; + + return DFB_OK; +} + + +/* file internal */ + +static void * +Flipping_Thread( void *arg ) +{ + IDirectFBSurface *thiz = (IDirectFBSurface*) arg; + IDirectFBSurface_Window_data *data = (IDirectFBSurface_Window_data*) thiz->priv; + + D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz ); + + while (data->base.surface && data->window->surface) { + pthread_testcancel(); + + /* + * OPTIMIZE: only call if surface has been touched in the meantime + */ + thiz->Flip( thiz, NULL, 0 ); + + usleep(40000); + } + + return NULL; +} + diff --git a/Source/DirectFB/src/display/idirectfbsurface_window.h b/Source/DirectFB/src/display/idirectfbsurface_window.h new file mode 100755 index 0000000..92ca56e --- /dev/null +++ b/Source/DirectFB/src/display/idirectfbsurface_window.h @@ -0,0 +1,48 @@ +/* + (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org) + (c) Copyright 2000-2004 Convergence (integrated media) GmbH + + All rights reserved. + + Written by Denis Oliver Kropp , + Andreas Hundt , + Sven Neumann , + Ville Syrjälä and + Claudio Ciccani . + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#ifndef __DIRECTFBSURFACE_WINDOW_H__ +#define __DIRECTFBSURFACE_WINDOW_H__ + +#include + +#include + +/* + * calls base classes IDirectFBSurface_Construct, + * reallocates private data and overloads functions of the interface + */ +DFBResult IDirectFBSurface_Window_Construct( IDirectFBSurface *thiz, + IDirectFBSurface *parent, + DFBRectangle *req_rect, + DFBRectangle *clip_rect, + CoreWindow *window, + DFBSurfaceCapabilities caps, + CoreDFB *core ); + +#endif -- cgit