#
# Global setup
TOP    = .
SOURCE = $(TOP)/Source
KERNEL = $(TOP)/Kernel

CONFIG ?= jag

NM ?= nm

#
# Version definition
MAJOR   = 1
MINOR   = 1
TINY    = 0
VERSION = $(MAJOR).$(MINOR).$(TINY)

FD_MAJOR = 0
FD_MINOR = 1
FD_TINY  = 1

# Default target
default: all

#
# Compiler flags
CFLAGS += -fpic -pipe -O2 -Wall -Werror

#
# Linker flags
LDFLAGS += -L.

#
# Configuration header files
INCLUDES += -I$(TOP)/Config_$(CONFIG)

#
# Fusion Kernel module headers
INCLUDES += -I$(KERNEL)/linux-fusion/linux/include

#
# Preprocessor flags
CPPFLAGS += \
	-DPIC								\
	-DHAVE_CONFIG_H							\
	-DHAVE_STDBOOL_H						\
	-D_GNU_SOURCE							\
	-D_REENTRANT							\
	-DVERSION=\"$(VERSION)\"					\
        -DBUILDTIME="\"$(buildtime)\""

#
# Debug option
ifeq ($(DEBUG),yes)
  CPPFLAGS += -DENABLE_DEBUG=1
  CFLAGS   += -g3
else
  CPPFLAGS += -DENABLE_DEBUG=0
endif

#
# Trace option
ifeq ($(TRACE),yes)
  CFLAGS   += -finstrument-functions
  CPPFLAGS += -DENABLE_TRACE=1
else
  CPPFLAGS += -DENABLE_TRACE=0
endif

#
# Include the specific configuration #########################
-include $(TOP)/Config_$(CONFIG)/makefile

#
# Installation paths
prefix     ?= /opt/directfb
bindir     ?= $(prefix)/bin
datadir    ?= $(prefix)/share
libdir     ?= $(prefix)/lib
moddir     ?= $(libdir)/directfb
sysconfdir ?= $(prefix)/etc

CPPFLAGS += \
	-DDATADIR=\"$(datadir)\"	\
	-DMODULEDIR=\"$(moddir)\"	\
	-DSYSCONFDIR=\"$(sysconfdir)\"

buildtime = $(shell sh -c date -u +%Y-%m-%d %H:%M)

#
# libdirect object files
LIB_DIRECT_OBJECTS = \
	$(SOURCE)/DirectFB/lib/direct/clock.o				\
	$(SOURCE)/DirectFB/lib/direct/conf.o				\
	$(SOURCE)/DirectFB/lib/direct/debug.o				\
	$(SOURCE)/DirectFB/lib/direct/direct.o				\
	$(SOURCE)/DirectFB/lib/direct/hash.o				\
	$(SOURCE)/DirectFB/lib/direct/interface.o			\
	$(SOURCE)/DirectFB/lib/direct/log.o				\
	$(SOURCE)/DirectFB/lib/direct/list.o				\
	$(SOURCE)/DirectFB/lib/direct/mem.o				\
	$(SOURCE)/DirectFB/lib/direct/memcpy.o				\
	$(SOURCE)/DirectFB/lib/direct/messages.o			\
	$(SOURCE)/DirectFB/lib/direct/modules.o				\
	$(SOURCE)/DirectFB/lib/direct/signals.o				\
	$(SOURCE)/DirectFB/lib/direct/stream.o				\
	$(SOURCE)/DirectFB/lib/direct/system.o				\
	$(SOURCE)/DirectFB/lib/direct/thread.o				\
	$(SOURCE)/DirectFB/lib/direct/trace.o				\
	$(SOURCE)/DirectFB/lib/direct/tree.o				\
	$(SOURCE)/DirectFB/lib/direct/utf8.o				\
	$(SOURCE)/DirectFB/lib/direct/util.o

#
# libfusion object files
LIB_FUSION_OBJECTS = \
	$(SOURCE)/DirectFB/lib/fusion/arena.o				\
	$(SOURCE)/DirectFB/lib/fusion/call.o				\
	$(SOURCE)/DirectFB/lib/fusion/conf.o				\
	$(SOURCE)/DirectFB/lib/fusion/fusion.o				\
	$(SOURCE)/DirectFB/lib/fusion/hash.o				\
	$(SOURCE)/DirectFB/lib/fusion/lock.o				\
	$(SOURCE)/DirectFB/lib/fusion/object.o				\
	$(SOURCE)/DirectFB/lib/fusion/property.o			\
	$(SOURCE)/DirectFB/lib/fusion/reactor.o				\
	$(SOURCE)/DirectFB/lib/fusion/ref.o				\
	$(SOURCE)/DirectFB/lib/fusion/shmalloc.o			\
	$(SOURCE)/DirectFB/lib/fusion/vector.o

LIB_FUSION_OBJECTS_SINGLE = \
	$(SOURCE)/DirectFB/lib/fusion/shm/fake.o

LIB_FUSION_OBJECTS_MULTI = \
	$(SOURCE)/DirectFB/lib/fusion/shm/heap.o			\
	$(SOURCE)/DirectFB/lib/fusion/shm/pool.o			\
	$(SOURCE)/DirectFB/lib/fusion/shm/shm.o

#
# New surface core object files
SURFACE_CORE_OBJECTS_NEW = \
	$(SOURCE)/DirectFB/src/core/local_surface_pool.o		\
	$(SOURCE)/DirectFB/src/core/prealloc_surface_pool.o		\
	$(SOURCE)/DirectFB/src/core/shared_surface_pool.o		\
	$(SOURCE)/DirectFB/src/core/surface.o				\
	$(SOURCE)/DirectFB/src/core/surface_buffer.o			\
	$(SOURCE)/DirectFB/src/core/surface_core.o			\
	$(SOURCE)/DirectFB/src/core/surface_pool.o

#
# Old surface core object files
SURFACE_CORE_OBJECTS_OLD = \
	$(SOURCE)/DirectFB/src/core/surfacemanager.o			\
	$(SOURCE)/DirectFB/src/core/surfaces.o

#
# DirectFB object files
DIRECTFB_OBJECTS = \
	$(SURFACE_CORE_OBJECTS_NEW)					\
	$(SOURCE)/DirectFB/src/core/clipboard.o				\
	$(SOURCE)/DirectFB/src/core/colorhash.o				\
	$(SOURCE)/DirectFB/src/core/core.o				\
	$(SOURCE)/DirectFB/src/core/core_parts.o			\
	$(SOURCE)/DirectFB/src/core/fonts.o				\
	$(SOURCE)/DirectFB/src/core/gfxcard.o				\
	$(SOURCE)/DirectFB/src/core/input.o				\
	$(SOURCE)/DirectFB/src/core/layer_context.o			\
	$(SOURCE)/DirectFB/src/core/layer_control.o			\
	$(SOURCE)/DirectFB/src/core/layer_region.o			\
	$(SOURCE)/DirectFB/src/core/layers.o				\
	$(SOURCE)/DirectFB/src/core/palette.o				\
	$(SOURCE)/DirectFB/src/core/screen.o				\
	$(SOURCE)/DirectFB/src/core/screens.o				\
	$(SOURCE)/DirectFB/src/core/state.o				\
	$(SOURCE)/DirectFB/src/core/system.o				\
	$(SOURCE)/DirectFB/src/core/windows.o				\
	$(SOURCE)/DirectFB/src/core/windowstack.o			\
	$(SOURCE)/DirectFB/src/core/wm.o				\
	$(SOURCE)/DirectFB/src/directfb.o				\
	$(SOURCE)/DirectFB/src/display/idirectfbdisplaylayer.o		\
	$(SOURCE)/DirectFB/src/display/idirectfbpalette.o		\
	$(SOURCE)/DirectFB/src/display/idirectfbscreen.o		\
	$(SOURCE)/DirectFB/src/display/idirectfbsurface.o		\
	$(SOURCE)/DirectFB/src/display/idirectfbsurface_layer.o		\
	$(SOURCE)/DirectFB/src/display/idirectfbsurface_window.o	\
	$(SOURCE)/DirectFB/src/gfx/clip.o				\
	$(SOURCE)/DirectFB/src/gfx/convert.o				\
	$(SOURCE)/DirectFB/src/gfx/generic/generic.o			\
	$(SOURCE)/DirectFB/src/gfx/util.o				\
	$(SOURCE)/DirectFB/src/idirectfb.o				\
	$(SOURCE)/DirectFB/src/input/idirectfbinputbuffer.o		\
	$(SOURCE)/DirectFB/src/input/idirectfbinputdevice.o		\
	$(SOURCE)/DirectFB/src/media/idirectfbdatabuffer.o		\
	$(SOURCE)/DirectFB/src/media/idirectfbdatabuffer_file.o		\
	$(SOURCE)/DirectFB/src/media/idirectfbdatabuffer_memory.o	\
	$(SOURCE)/DirectFB/src/media/idirectfbdatabuffer_streamed.o	\
	$(SOURCE)/DirectFB/src/media/idirectfbfont.o			\
	$(SOURCE)/DirectFB/src/media/idirectfbimageprovider.o		\
	$(SOURCE)/DirectFB/src/media/idirectfbvideoprovider.o		\
	$(SOURCE)/DirectFB/src/misc/conf.o				\
	$(SOURCE)/DirectFB/src/misc/gfx_util.o				\
	$(SOURCE)/DirectFB/src/misc/util.o				\
	$(SOURCE)/DirectFB/src/windows/idirectfbwindow.o

#
# DirectFB header files
DIRECTFB_INCLUDES += \
	-I$(SOURCE)/DirectFB/include					\
	-I$(SOURCE)/DirectFB/lib					\
	-I$(SOURCE)/DirectFB/src					\
	-I$(SOURCE)/DirectFB/systems


#
# DiVine object files
DIVINE_OBJECTS = \
	$(SOURCE)/DiVine/driver/divine.o				\
	$(SOURCE)/DiVine/lib/divine.o

#
# FusionDale header files and defines
DIVINE_INCLUDES += \
	-I$(SOURCE)/DiVine/include

CPPFLAGS += -DDIVINE_MAJOR_VERSION=0 -DDIVINE_MINOR_VERSION=0

#
# SaWMan object files
SAWMAN_OBJECTS = \
	$(SOURCE)/SaWMan/src/isawman.o					\
	$(SOURCE)/SaWMan/src/isawmanmanager.o				\
	$(SOURCE)/SaWMan/src/sawman.o					\
	$(SOURCE)/SaWMan/src/sawman_config.o				\
	$(SOURCE)/SaWMan/wm/sawman/sawman_draw.o			\
	$(SOURCE)/SaWMan/wm/sawman/sawman_wm.o				\
	$(SOURCE)/SaWMan/wm/sawman/stretch_algos.o

#
# SaWMan header files
SAWMAN_INCLUDES += \
	-I$(SOURCE)/SaWMan/include					\
	-I$(SOURCE)/SaWMan/src

#
# FusionDale object files
FUSIONDALE_OBJECTS = \
	$(SOURCE)/FusionDale/src/ifusiondale.o				\
	$(SOURCE)/FusionDale/src/fusiondale.o				\
	$(SOURCE)/FusionDale/src/messenger/ifusiondalemessenger.o	\
	$(SOURCE)/FusionDale/src/core/dale_core.o			\
	$(SOURCE)/FusionDale/src/core/messenger.o			\
	$(SOURCE)/FusionDale/src/core/messenger_port.o			\
	$(SOURCE)/FusionDale/src/coma/coma.o				\
	$(SOURCE)/FusionDale/src/coma/component.o			\
	$(SOURCE)/FusionDale/src/coma/icoma.o				\
	$(SOURCE)/FusionDale/src/coma/icomacomponent.o			\
	$(SOURCE)/FusionDale/src/misc/dale_config.o

#
# FusionDale header files
FUSIONDALE_INCLUDES += \
	-I$(SOURCE)/FusionDale/include					\
	-I$(SOURCE)/FusionDale/src


#
# Build list of all objects
OBJECTS += \
	$(LIB_DIRECT_OBJECTS)						\
	$(LIB_FUSION_OBJECTS)						\
	$(LIB_FUSION_OBJECTS_MULTI)					\
	$(DIRECTFB_OBJECTS)						\
	$(DIVINE_OBJECTS)						\
	$(SAWMAN_OBJECTS)						\
	$(FUSIONDALE_OBJECTS)

#
# Build complete include path
INCLUDES += \
	$(DIRECTFB_INCLUDES)						\
	$(DIVINE_INCLUDES)						\
	$(SAWMAN_INCLUDES)						\
	$(FUSIONDALE_INCLUDES)



#
# All libraries
LIBS += \
	-lfreetype							\
	-lpng								\
	-ljpeg								\
	-lz								\
	-lm								\
	-lpthread							\
	-ldl


#
# All tools and tests
#	$(SOURCE)/DirectFB/tools/dfbdump
TOOLS += \
	$(SOURCE)/DirectFB/tools/dfbinfo				\
	$(SOURCE)/DirectFB/tools/dfbdump				\
	$(SOURCE)/DirectFB/tools/fusion_bench				\
	$(SOURCE)/DirectFB/tests/fusion_reactor

#
# List of generated header files
GEN_HEADERS = \
	$(SOURCE)/DirectFB/include/directfb_keynames.h			\
	$(SOURCE)/DirectFB/include/directfb_strings.h			\
	$(SOURCE)/DirectFB/include/directfb_version.h			\
	$(SOURCE)/FusionDale/include/fusiondale_version.h


#
# Rules
all: $(GEN_HEADERS) libdirectfb.o libdirectfb.so libdirectfb.so.nm $(TOOLS) $(TOOLS:%=%.nm)

libdirectfb.o: $(OBJECTS)
	$(LD) $(LDFLAGS) -r -o $@ $+

libdirectfb.so: $(OBJECTS)
	$(CC) -shared -Wl,-soname,libdirectfb.so $(LDFLAGS) $(LIBS) -o $@ $+
	
libdirectfb.so.nm: libdirectfb.so
	$(NM) -n libdirectfb.so > libdirectfb.so.nm

%.o: %.c
	$(CC) $(CFLAGS) -c $(CPPFLAGS) $(INCLUDES) -o $@ $<

$(SOURCE)/DirectFB/tests/%: $(SOURCE)/DirectFB/tests/%.o libdirectfb.so
	$(CC) $(LDFLAGS) -o $@ $< -ldirectfb $(LIBS)

$(SOURCE)/DirectFB/tools/%: $(SOURCE)/DirectFB/tools/%.o libdirectfb.so
	$(CC) $(LDFLAGS) -o $@ $< -ldirectfb $(LIBS)

%.nm: %
	$(NM) -n $< > $@


.PHONY: clean install

clean:
	rm -f libdirectfb.*o* $(TOOLS) $(GEN_HEADERS)
	find -name "*.o" | xargs rm -f

install:: all
	@(if test -z "$(DESTDIR)"; then echo "**** DESTDIR not set! ****"; exit 1; fi)
	install -d $(DESTDIR)$(bindir)
	install -d $(DESTDIR)$(libdir)
	install -d $(DESTDIR)$(moddir)
	install -d $(DESTDIR)$(moddir)/inputdrivers
	install -d $(DESTDIR)$(moddir)/interfaces
	install -d $(DESTDIR)$(moddir)/gfxdrivers
	install -d $(DESTDIR)$(moddir)/systems
	install -d $(DESTDIR)$(moddir)/wm
	install -c -m 755 $(TOOLS) $(TOOLS:%=%.nm) $(DESTDIR)$(bindir)/
	install -c -m 755 libdirectfb.so $(DESTDIR)$(libdir)/
	install -c -m 644 libdirectfb.so.nm $(DESTDIR)$(libdir)/




DFBINC  = $(SOURCE)/DirectFB/include
MKNAMES = $(SOURCE)/DirectFB/include/mknames.sh


$(DFBINC)/directfb_version.h: makefile
	@echo '#ifndef __DIRECTFB_VERSION_H__' > $@
	@echo '#define __DIRECTFB_VERSION_H__' >> $@
	@echo '' >> $@
	@echo '#define DIRECTFB_MAJOR_VERSION  (' $(MAJOR) ')' >> $@
	@echo '#define DIRECTFB_MINOR_VERSION  (' $(MINOR) ')' >> $@
	@echo '#define DIRECTFB_MICRO_VERSION  (' $(TINY) ')' >> $@
	@echo '#define DIRECTFB_BINARY_AGE     (0)' >> $@
	@echo '#define DIRECTFB_INTERFACE_AGE  (0)' >> $@
	@echo '' >> $@
	@echo '' >> $@
	@echo '#endif' >> $@


$(DFBINC)/directfb_keynames.h: $(DFBINC)/directfb_keyboard.h $(MKNAMES) makefile
	@echo '#ifndef __DIRECTFB_KEYNAMES_H__' > $@
	@echo '#define __DIRECTFB_KEYNAMES_H__' >> $@

	$(MKNAMES) DFBInputDeviceKeySymbol DIKS NULL KeySymbol symbol $(DFBINC)/directfb_keyboard.h \
	   | grep -v DIKS_ENTER >> $@

	$(MKNAMES) DFBInputDeviceKeyIdentifier DIKI UNKNOWN KeyIdentifier identifier $(DFBINC)/directfb_keyboard.h \
	   | grep -v DIKI_NUMBER_OF_KEYS | grep -v DIKI_KEYDEF_END >> $@

	@echo '' >> $@
	@echo '#endif' >> $@


$(DFBINC)/directfb_strings.h: $(DFBINC)/directfb.h $(MKNAMES) makefile
	@echo '#ifndef __DIRECTFB_STRINGS_H__' > $@
	@echo '#define __DIRECTFB_STRINGS_H__' >> $@

	$(MKNAMES) DFBSurfacePixelFormat DSPF UNKNOWN PixelFormat format $(DFBINC)/directfb.h >> $@

	$(MKNAMES) DFBInputDeviceTypeFlags DIDTF NONE InputDeviceTypeFlags type $(DFBINC)/directfb.h \
	   | grep -v DIDTF_ALL >> $@

	$(MKNAMES) DFBSurfaceDrawingFlags DSDRAW NOFX SurfaceDrawingFlags flag $(DFBINC)/directfb.h \
	   | grep -v DSDRAW_ALL >> $@

	$(MKNAMES) DFBSurfaceBlittingFlags DSBLIT NOFX SurfaceBlittingFlags flag $(DFBINC)/directfb.h \
	   | grep -v DSBLIT_ALL >> $@

	@echo FIXME: Use DIMCAPS prefix for DFBImageCapabilities
	$(MKNAMES) DFBInputDeviceCapabilities DICAPS NONE InputDeviceCapabilities capability $(DFBINC)/directfb.h \
	   | grep -v DICAPS_ALL | grep -v DICAPS_ALPHACHANNEL | grep -v DICAPS_COLORKEY >> $@

	$(MKNAMES) DFBDisplayLayerTypeFlags DLTF NONE DisplayLayerTypeFlags type $(DFBINC)/directfb.h \
	   | grep -v DLTF_ALL >> $@

	$(MKNAMES) DFBDisplayLayerCapabilities DLCAPS NONE DisplayLayerCapabilities capability $(DFBINC)/directfb.h \
	   | grep -v DLCAPS_ALL >> $@

	$(MKNAMES) DFBDisplayLayerBufferMode DLBM UNKNOWN DisplayLayerBufferMode mode $(DFBINC)/directfb.h \
	   | grep -v DLBM_DONTCARE | grep -v DLBM_COLOR | grep -v DLBM_IMAGE | grep -v DLBM_TILE >> $@

	$(MKNAMES) DFBScreenCapabilities DSCCAPS NONE ScreenCapabilities capability $(DFBINC)/directfb.h \
	   | grep -v DSCCAPS_ALL >> $@

	$(MKNAMES) DFBScreenEncoderCapabilities DSECAPS NONE ScreenEncoderCapabilities capability $(DFBINC)/directfb.h \
	   | grep -v DSECAPS_ALL >> $@

	$(MKNAMES) DFBScreenEncoderType DSET UNKNOWN ScreenEncoderType type $(DFBINC)/directfb.h \
	   | grep -v DSET_ALL >> $@

	$(MKNAMES) DFBScreenEncoderTVStandards DSETV UNKNOWN ScreenEncoderTVStandards standard $(DFBINC)/directfb.h \
	   | grep -v DSETV_ALL >> $@

	$(MKNAMES) DFBScreenOutputCapabilities DSOCAPS NONE ScreenOutputCapabilities capability $(DFBINC)/directfb.h \
	   | grep -v DSOCAPS_ALL >> $@

	$(MKNAMES) DFBScreenOutputConnectors DSOC UNKNOWN ScreenOutputConnectors connector $(DFBINC)/directfb.h \
	   | grep -v DSOC_ALL >> $@

	$(MKNAMES) DFBScreenOutputSignals DSOS NONE ScreenOutputSignals signal $(DFBINC)/directfb.h \
	   | grep -v DSOS_ALL >> $@

	$(MKNAMES) DFBScreenOutputSlowBlankingSignals DSOSB OFF ScreenOutputSlowBlankingSignals slow_signal $(DFBINC)/directfb.h \
	   | grep -v DSOSB_ALL >> $@

	$(MKNAMES) DFBScreenOutputResolution DSOR UNKNOWN ScreenOutputResolution resolution $(INCP)/directfb.h \
	   | grep -v DSOR_ALL >> $@

	$(MKNAMES) DFBScreenMixerCapabilities DSMCAPS NONE ScreenMixerCapabilities capability $(DFBINC)/directfb.h \
	   | grep -v DSMCAPS_ALL >> $@

	$(MKNAMES) DFBScreenMixerTree DSMT UNKNOWN ScreenMixerTree tree $(DFBINC)/directfb.h \
	   | grep -v DSMT_ALL >> $@

	$(MKNAMES) DFBScreenEncoderTestPicture DSETP OFF ScreenEncoderTestPicture test_picture $(DFBINC)/directfb.h \
	   | grep -v DSETP_ALL >> $@

	$(MKNAMES) DFBScreenEncoderScanMode DSESM UNKNOWN ScreenEncoderScanMode scan_mode $(DFBINC)/directfb.h \
	   | grep -v DSESM_ALL >> $@

	$(MKNAMES) DFBAccelerationMask DFXL NONE AccelerationMask mask $(DFBINC)/directfb.h \
	   | grep -v DFXL_ALL >> $@

	@echo '' >> $@
	@echo '#endif' >> $@


$(SOURCE)/FusionDale/include/fusiondale_version.h: makefile
	@echo '#ifndef __FUSIONDALE_VERSION_H__' > $@
	@echo '#define __FUSIONDALE_VERSION_H__' >> $@
	@echo '' >> $@
	@echo '#define FUSIONDALE_MAJOR_VERSION  (' $(FD_MAJOR) ')' >> $@
	@echo '#define FUSIONDALE_MINOR_VERSION  (' $(FD_MINOR) ')' >> $@
	@echo '#define FUSIONDALE_MICRO_VERSION  (' $(FD_TINY) ')' >> $@
	@echo '#define FUSIONDALE_BINARY_AGE     (0)' >> $@
	@echo '#define FUSIONDALE_INTERFACE_AGE  (0)' >> $@
	@echo '' >> $@
	@echo '' >> $@
	@echo '#endif' >> $@

