diff options
author | Pierre GRANDIN <pgrandin@users.noreply.github.com> | 2017-02-23 06:35:25 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-02-23 06:35:25 -0800 |
commit | 20cf85a6d57e847335ee82485ebcd76a20d37320 (patch) | |
tree | 56eee88bfef3915351367826830df230fbce6bc3 | |
parent | 777824d098288d3199cda82bbffe9ffeded7e527 (diff) | |
parent | 8363731af73d71afec3aad1c6145f759570e3e7f (diff) | |
download | navit-add_linux_tests.tar.gz |
Merge branch 'trunk' into add_linux_testsadd_linux_tests
-rwxr-xr-x | CMakeLists.txt | 13 | ||||
-rw-r--r-- | ci/basic_upload_apks.py | 82 | ||||
-rw-r--r-- | ci/build.sh | 2 | ||||
-rw-r--r-- | ci/build_android.sh | 6 | ||||
-rw-r--r-- | ci/build_android_x86.sh | 6 | ||||
-rw-r--r-- | ci/build_tomtom_minimal.sh | 6 | ||||
-rw-r--r-- | ci/build_tomtom_plugin.sh | 6 | ||||
-rw-r--r-- | ci/publish.sh | 12 | ||||
-rw-r--r-- | ci/setup_tomtom_requirements.sh | 208 | ||||
-rw-r--r-- | circle.yml | 6 | ||||
-rw-r--r-- | contrib/tomtom/espeakdsp.c | 101 | ||||
-rw-r--r-- | navit/android/AndroidManifest.xml.cmake | 10 | ||||
-rw-r--r-- | navit/android/AndroidManifest.xml.in | 37 | ||||
-rw-r--r-- | navit/android/libs/acra-4.3.0b2.jar | bin | 96994 -> 0 bytes | |||
-rw-r--r-- | navit/android/libs/acra-4.8.5.jar | bin | 0 -> 154375 bytes | |||
-rw-r--r-- | navit/android/libs/android-support-v4.jar | bin | 0 -> 1364299 bytes | |||
-rw-r--r-- | navit/android/src/org/navitproject/navit/Navit.java | 8 | ||||
-rwxr-xr-x | navit/android/src/org/navitproject/navit/NavitAppConfig.java | 8 | ||||
-rw-r--r-- | navit/event.c | 9 | ||||
-rw-r--r-- | navit/graphics/egl/CMakeLists.txt | 2 | ||||
-rw-r--r-- | navit/graphics/egl/graphics_egl.c | 1458 | ||||
-rw-r--r-- | navit/navit.c | 100 |
22 files changed, 1970 insertions, 110 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index d154e1e6c..926fcb8b2 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -85,6 +85,7 @@ add_module(graphics/gd "FreeType library not found" FALSE) add_module(graphics/gtk_drawing_area "FreeType library not found" FALSE) add_module(graphics/opengl "FreeType library not found" FALSE) add_module(graphics/sdl "Required library not found" FALSE) +add_module(graphics/egl "Required library not found" FALSE) add_module(graphics/qt_qpainter "Qt libraries not found" FALSE) add_module(gui/qml "Qt Declarative not found" FALSE) add_module(gui/gtk "GTK libs not found" FALSE) @@ -136,6 +137,9 @@ find_package(Glib) find_package(Gmodule) find_package(ZLIB) find_package(Freetype) +find_library(SDL2MAIN SDL2) +find_library(SDL2IMAGE SDL2_image) +find_library(GLES2 GLESv2) find_package(SDL) find_package(SDL_ttf) find_package(SDL_image) @@ -274,6 +278,7 @@ else(FREETYPE_FOUND) set_with_reason(graphics/gtk_drawing_area "FreeType library not found" FALSE) set_with_reason(graphics/opengl "FreeType library not found" FALSE) set_with_reason(graphics/sdl "FreeType library not found" FALSE) + set_with_reason(graphics/egl "FreeType library not found" FALSE) endif(FREETYPE_FOUND) if(FONTCONFIG_FOUND) @@ -346,6 +351,11 @@ if(SDL_FOUND AND SDLIMAGE_FOUND AND FREETYPE_FOUND) set_with_reason(graphics/sdl "SDL/SDL_image libs found" TRUE ${SDL_LIBRARY} ${SDLIMAGE_LIBRARY}) endif(SDL_FOUND AND SDLIMAGE_FOUND AND FREETYPE_FOUND) +if(SDL2MAIN AND SDL2IMAGE AND GLES2) + set_with_reason(graphics/egl "SDL2/SDL2_image libs found" TRUE ${SDL2MAIN} ${SDL2IMAGE} ${GLES2}) + message(STATUS "EGL libs found : ${SDL2MAIN} ${SDL2IMAGE} ${GLES2}") +endif(SDL2_FOUND AND SDL2IMAGE_FOUND AND GLES2) + if (LIBGPS_FOUND) if (LIBGPS_NEW_FOUND) set(VEHICLE_GPSD_REASON "gpsd lib found") @@ -600,9 +610,6 @@ if (SAMPLE_MAP) endif(SAMPLE_MAP) if(ANDROID) - # for android API 3 compatiblity - SET(CMAKE_SHARED_LIBRARY_SONAME_C_FLAG "-Wl,-soname,/data/data/org.navitproject.navit/lib/") - find_program(ANDROID_LOCATION NAMES android android.bat) find_program(ANT_LOCATION NAMES ant) if (NOT ANT_LOCATION) diff --git a/ci/basic_upload_apks.py b/ci/basic_upload_apks.py new file mode 100644 index 000000000..b4b439536 --- /dev/null +++ b/ci/basic_upload_apks.py @@ -0,0 +1,82 @@ +#!/usr/bin/python +# +# Copyright 2014 Google Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the 'License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Uploads an apk to the beta track.""" + +import argparse +import sys +from apiclient import sample_tools +from oauth2client import client + +TRACK = 'beta' # Can be 'alpha', beta', 'production' or 'rollout' + +# Declare command-line flags. +argparser = argparse.ArgumentParser(add_help=False) +argparser.add_argument('package_name', + help='The package name. Example: com.android.sample') +argparser.add_argument('apk_file', + nargs='?', + default='test.apk', + help='The path to the APK file to upload.') + + +def main(argv): + # Authenticate and construct service. + service, flags = sample_tools.init( + argv, + 'androidpublisher', + 'v2', + __doc__, + __file__, parents=[argparser], + scope='https://www.googleapis.com/auth/androidpublisher') + + # Process flags and read their values. + package_name = flags.package_name + apk_file = flags.apk_file + + try: + edit_request = service.edits().insert(body={}, packageName=package_name) + result = edit_request.execute() + edit_id = result['id'] + + apk_response = service.edits().apks().upload( + editId=edit_id, + packageName=package_name, + media_body=apk_file).execute() + + print 'Version code %d has been uploaded' % apk_response['versionCode'] + + track_response = service.edits().tracks().update( + editId=edit_id, + track=TRACK, + packageName=package_name, + body={u'versionCodes': [apk_response['versionCode']]}).execute() + + print 'Track %s is set for version code(s) %s' % ( + track_response['track'], str(track_response['versionCodes'])) + + commit_request = service.edits().commit( + editId=edit_id, packageName=package_name).execute() + + print 'Edit "%s" has been committed' % (commit_request['id']) + + except client.AccessTokenRefreshError: + print ('The credentials have been revoked or expired, please re-run the ' + 'application to re-authorize') + +if __name__ == '__main__': + main(sys.argv) + diff --git a/ci/build.sh b/ci/build.sh index 7f8f46279..b5d81e9dc 100644 --- a/ci/build.sh +++ b/ci/build.sh @@ -1,3 +1,5 @@ +set -e + echo "$# build script (s) to run" for i in $(seq 1 $#); do diff --git a/ci/build_android.sh b/ci/build_android.sh index 610dbc6e2..dc858e2ca 100644 --- a/ci/build_android.sh +++ b/ci/build_android.sh @@ -5,15 +5,15 @@ export ARCH="arm" export START_PATH=~/ export SOURCE_PATH=$START_PATH"/"${CIRCLE_PROJECT_REPONAME}"/" export CMAKE_FILE=$SOURCE_PATH"/Toolchain/arm-eabi.cmake" -export ANDROID_NDK=~/android-ndk-r13 +export ANDROID_NDK=~/android-ndk-r11c export ANDROID_NDK_BIN=$ANDROID_NDK"/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin" export ANDROID_SDK="/usr/local/android-sdk-linux/" export ANDROID_SDK_PLATFORM_TOOLS=$ANDROID_SDK"/platform-tools" export PATH=$ANDROID_NDK_BIN:$ANDROID_SDK_PLATFORM_TOOLS:$PATH export BUILD_PATH=$START_PATH"/android-${ARCH}" -wget -nv -c http://dl.google.com/android/repository/android-ndk-r13-linux-x86_64.zip -[ -d ~/android-ndk-r13 ] || unzip -q -d ~ android-ndk-r13-linux-x86_64.zip +wget -nv -c http://dl.google.com/android/repository/android-ndk-r11c-linux-x86_64.zip +[ -d ~/android-ndk-r11c ] || unzip -q -d ~ android-ndk-r11c-linux-x86_64.zip [ -d $BUILD_PATH ] || mkdir -p $BUILD_PATH cd $BUILD_PATH diff --git a/ci/build_android_x86.sh b/ci/build_android_x86.sh index b42d03d9f..c5a421cbe 100644 --- a/ci/build_android_x86.sh +++ b/ci/build_android_x86.sh @@ -5,15 +5,15 @@ export arch="x86" export START_PATH=~/ export SOURCE_PATH=$START_PATH"/"${CIRCLE_PROJECT_REPONAME}"/" export CMAKE_FILE=$SOURCE_PATH"/Toolchain/i686-android.cmake" -export ANDROID_NDK=~/android-ndk-r13 +export ANDROID_NDK=~/android-ndk-r11c export ANDROID_NDK_BIN=$ANDROID_NDK"/toolchains/x86-4.9/prebuilt/linux-x86_64/bin" export ANDROID_SDK="/usr/local/android-sdk-linux/" export ANDROID_SDK_PLATFORM_TOOLS=$ANDROID_SDK"/platform-tools" export PATH=$ANDROID_NDK_BIN:$ANDROID_SDK_PLATFORM_TOOLS:$PATH export BUILD_PATH=$START_PATH"/android-${ARCH}" -wget -nv -c http://dl.google.com/android/repository/android-ndk-r13-linux-x86_64.zip -[ -d ~/android-ndk-r13 ] || unzip -q -d ~ android-ndk-r13-linux-x86_64.zip +wget -nv -c http://dl.google.com/android/repository/android-ndk-r11c-linux-x86_64.zip +[ -d ~/android-ndk-r11c ] || unzip -q -d ~ android-ndk-r11c-linux-x86_64.zip [ -d $BUILD_PATH ] || mkdir -p $BUILD_PATH cd $BUILD_PATH diff --git a/ci/build_tomtom_minimal.sh b/ci/build_tomtom_minimal.sh index 9b344adfb..8cf0c735a 100644 --- a/ci/build_tomtom_minimal.sh +++ b/ci/build_tomtom_minimal.sh @@ -53,9 +53,9 @@ tar xzf ~/tomtom_assets/toolchain_redhat_gcc-3.3.4_glibc-2.3.2-20060131a.tar.gz # zlib cd /tmp -wget -nv -c https://github.com/madler/zlib/archive/v1.2.9.zip -O zlib-1.2.9.zip -unzip zlib-1.2.9.zip -cd zlib-1.2.9 +wget -nv -c http://zlib.net/zlib-1.2.11.tar.gz +tar xzf zlib-1.2.11.tar.gz +cd zlib-1.2.11 ./configure --prefix=$PREFIX make -j$JOBS make install diff --git a/ci/build_tomtom_plugin.sh b/ci/build_tomtom_plugin.sh index 834601eb9..548109877 100644 --- a/ci/build_tomtom_plugin.sh +++ b/ci/build_tomtom_plugin.sh @@ -177,9 +177,9 @@ arm-linux-gcc -O2 -I$PREFIX/include -I$PREFIX/usr/include espeakdsp.c -o espeakd # zlib cd /tmp -wget -nv -c https://github.com/madler/zlib/archive/v1.2.9.zip -O zlib-1.2.9.zip -unzip zlib-1.2.9.zip -cd zlib-1.2.9 +wget -nv -c http://zlib.net/zlib-1.2.11.tar.gz +tar xzf zlib-1.2.11.tar.gz +cd zlib-1.2.11 ./configure --prefix=$PREFIX make -j$JOBS make install diff --git a/ci/publish.sh b/ci/publish.sh new file mode 100644 index 000000000..2f880f339 --- /dev/null +++ b/ci/publish.sh @@ -0,0 +1,12 @@ +cd ~/ +git clone git@github.com:navit-gps/infrastructure-blackbox.git +cd infrastructure-blackbox/keyrings/ +openssl aes-256-cbc -d -in keystore.gpg -k $KEY > ~/.keystore +openssl aes-256-cbc -d -in client_secrets.gpg -k $KEY > ~/navit/ci/client_secrets.json +openssl aes-256-cbc -d -in androidpublisher.gpg -k $KEY > androidpublisher.dat + +pip install google-api-python-client + +/usr/lib/jvm/java-8-openjdk-amd64/bin/jarsigner -storepass $SP $CIRCLE_ARTIFACTS/navit-$CIRCLE_SHA1-${ARCH}-release-unsigned.apk $key_name +/usr/local/android-sdk-linux/build-tools/25.0.1/zipalign 4 $CIRCLE_ARTIFACTS/navit-$CIRCLE_SHA1-${ARCH}-release-unsigned.apk $CIRCLE_ARTIFACTS/navit-$CIRCLE_SHA1-${ARCH}-release-signed.apk +python ~/navit/ci/basic_upload_apks.py org.navitproject.navit $CIRCLE_ARTIFACTS/navit-$CIRCLE_SHA1-${ARCH}-release-signed.apk diff --git a/ci/setup_tomtom_requirements.sh b/ci/setup_tomtom_requirements.sh new file mode 100644 index 000000000..bf07211c6 --- /dev/null +++ b/ci/setup_tomtom_requirements.sh @@ -0,0 +1,208 @@ +#!/bin/sh +# this builds navit for tomtom +# in case you want to build a plugin for tomtom use build_tomtom_plugin.sh instead +# in case you want to build a standalone system +# https://github.com/george-hopkins/opentom +# https://github.com/gefin/opentom + +set -e + +export ARCH=arm-linux +cp Toolchain/$ARCH.cmake /tmp + +# toolchain +export TOMTOM_SDK_DIR=/opt/tomtom-sdk +mkdir -p $TOMTOM_SDK_DIR >/dev/null 2>&1 || export TOMTOM_SDK_DIR=$HOME/tomtom-sdk +export PREFIX=$TOMTOM_SDK_DIR/gcc-3.3.4_glibc-2.3.2/$ARCH/sys-root +export PATH=$TOMTOM_SDK_DIR/gcc-3.3.4_glibc-2.3.2/bin:$PREFIX/bin/:$PATH +export CFLAGS="-O2 -I$PREFIX/include -I$PREFIX/usr/include" +export CPPFLAGS="-I$PREFIX/include -I$PREFIX/usr/include" +export LDFLAGS="-L$PREFIX/lib -L$PREFIX/usr/lib" +export CC=$ARCH-gcc +export CXX=$ARCH-g++ +export LD=$ARCH-ld +export NM="$ARCH-nm -B" +export AR=$ARCH-ar +export RANLIB=$ARCH-ranlib +export STRIP=$ARCH-strip +export OBJCOPY=$ARCH-objcopy +export LN_S="ln -s" +export PKG_CONFIG_LIBDIR=$PREFIX/lib/pkgconfig +JOBS=`getconf _NPROCESSORS_ONLN` + +echo "Jobs" +echo $JOBS + +mkdir -p ~/assets/tomtom/ + +if ! [ -e "~/assets/tomtom/toolchain_redhat_gcc-3.3.4_glibc-2.3.2-20060131a.tar.gz" ] + then + wget -nv -c http://www.tomtom.com/gpl/toolchain_redhat_gcc-3.3.4_glibc-2.3.2-20060131a.tar.gz -P ~/assets/tomtom +fi + +if ! test -f "~/assets/tomtom/libpng-1.6.27.tar.gz" +then + wget -nv -c ftp://ftp.simplesystems.org/pub/libpng/png/src/libpng16/libpng-1.6.27.tar.gz -P ~/assets/tomtom +fi + +# toolchain +cd /tmp +mkdir -p $TOMTOM_SDK_DIR +tar xzf ~/assets/tomtom/toolchain_redhat_gcc-3.3.4_glibc-2.3.2-20060131a.tar.gz -C $TOMTOM_SDK_DIR + +# zlib +cd /tmp +wget -nv -c http://zlib.net/zlib-1.2.9.tar.gz +tar xzf zlib-1.2.9.tar.gz +cd zlib-1.2.9 +./configure --prefix=$PREFIX +make -j$JOBS +make install + +# libxml +cd /tmp/ +wget -nv -c http://xmlsoft.org/sources/libxml2-2.7.8.tar.gz +tar xzf libxml2-2.7.8.tar.gz +cd libxml2-2.7.8/ +./configure --prefix=$PREFIX --host=$ARCH --without-python +make -j$JOBS +make install + +# libpng +cd /tmp/ +tar xzf ~/assets/tomtom/libpng-1.6.27.tar.gz +cd libpng-1.6.27/ +./configure --prefix=$PREFIX --host=$ARCH +make -j$JOBS +make install + + +cd /tmp +wget -nv -c http://download.savannah.gnu.org/releases/freetype/freetype-2.5.0.tar.gz +tar xzf freetype-2.5.0.tar.gz +cd freetype-2.5.0 +./configure --prefix=$PREFIX --host=$ARCH +make -j$JOBS +make install + +freetype-config --cflags + +# glib +cd /tmp +wget -nv -c http://ftp.gnome.org/pub/gnome/sources/glib/2.25/glib-2.25.17.tar.gz +tar xzf glib-2.25.17.tar.gz +cd glib-2.25.17 +cat > tomtom.cache << EOF +glib_cv_long_long_format=ll +glib_cv_stack_grows=no +glib_cv_uscore=no +ac_cv_func_posix_getgrgid_r=yes +ac_cv_func_posix_getpwuid_r=yes +EOF +chmod a-w tomtom.cache +./configure --prefix=$PREFIX --host=$ARCH --cache-file=tomtom.cache +sed -i "s|cp xgen-gmc gmarshal.c |cp xgen-gmc gmarshal.c \&\& sed -i \"s\|g_value_get_schar\|g_value_get_char\|g\" gmarshal.c |g" gobject/Makefile +make -j$JOBS +make install + + +# tslib +cd /tmp +rm -rf tslib-svn +git clone https://github.com/playya/tslib-svn.git +cd tslib-svn +sed -i "s|AM_CONFIG_HEADER|AC_CONFIG_HEADERS|g" configure.ac +sed -i "119i\#ifdef EVIOCGRAB" plugins/input-raw.c +sed -i "124i\#endif" plugins/input-raw.c +sed -i "290i\#ifdef EVIOCGRAB" plugins/input-raw.c +sed -i "294i\#endif" plugins/input-raw.c +sed -i "s|# module_raw h3600|module_raw h3600|g" etc/ts.conf # tomtom go 710 +./autogen.sh +./configure --prefix=$PREFIX --host=$ARCH +make -j$JOBS +make install + + +cd /tmp +wget -nv -c http://www.libsdl.org/release/SDL-1.2.15.tar.gz +tar xzf SDL-1.2.15.tar.gz +cd SDL-1.2.15 +wget -nv -c http://tracks.yaina.de/source/sdl-fbcon-notty.patch +patch -p0 -i sdl-fbcon-notty.patch +./configure --prefix=$PREFIX --host=$ARCH \ + --disable-esd --disable-cdrom --disable-joystick --disable-video-x11 \ + --disable-x11-vm --disable-dga --disable-video-x11-dgamouse \ + --disable-video-x11-xv --disable-video-x11-xinerama --disable-video-directfb \ + --enable-video-fbcon --disable-audio CFLAGS="$CFLAGS -DFBCON_NOTTY" +make -j$JOBS +make install + +# sdl test utilities +cd test +./configure --prefix=$PREFIX --host=$ARCH +make testvidinfo +cp testvidinfo $PREFIX/usr/bin/ + +# to find sdl-config +export PATH=$PREFIX/bin:$PATH + +# sdl image +cd /tmp +wget -nv -c http://www.libsdl.org/projects/SDL_image/release/SDL_image-1.2.12.tar.gz +tar xzf SDL_image-1.2.12.tar.gz +cd SDL_image-1.2.12 +./configure --prefix=$PREFIX --host=$ARCH +make -j$JOBS +make install + + + +# espeak +cd /tmp +# this one includes the precompiled voices +wget -nv -c http://freefr.dl.sourceforge.net/project/espeak/espeak/espeak-1.48/espeak-1.48.04-source.zip +unzip espeak-1.48.04-source.zip +cd espeak-1.48.04-source +sed -i "s/PREFIX=\/usr//g" src/Makefile +sed -i "s/DATADIR=\/usr\/share\/espeak-data/DATADIR=~\/share\/espeak-data/g" src/Makefile +sed -i "s/AUDIO = portaudio/#AUDIO = portaudio/g" src/Makefile +sed -i "s/-fvisibility=hidden//g" src/Makefile +cat src/Makefile +make -C src +cd src +sudo make install + +# http://forum.navit-project.org/viewtopic.php?f=17&t=568 +cd /tmp +arm-linux-gcc -O2 -I$PREFIX/include -I$PREFIX/usr/include ~/navit/contrib/tomtom/espeakdsp.c -o espeakdsp + + + +# in the end we only want Navit locale +rm -r $PREFIX/share/locale + +# navit +cd ~/navit +sed -i "s|set ( TOMTOM_SDK_DIR /opt/tomtom-sdk )|set ( TOMTOM_SDK_DIR $TOMTOM_SDK_DIR )|g" /tmp/$ARCH.cmake +mkdir -p build +cd build +cmake ../ -DCMAKE_INSTALL_PREFIX=$PREFIX -DFREETYPE_INCLUDE_DIRS=$PREFIX/include/freetype2/ -Dsupport/gettext_intl=TRUE \ +-DHAVE_API_TOMTOM=TRUE -DXSLTS=tomtom -DAVOID_FLOAT=TRUE -Dmap/mg=FALSE -DUSE_PLUGINS=0 -DCMAKE_TOOLCHAIN_FILE=/tmp/$ARCH.cmake \ +-DDISABLE_QT=ON -DSAMPLE_MAP=n -DBUILD_MAPTOOL=n +make -j$JOBS +make install +cd .. + + +# creating directories +OUT_PATH="/tmp/tomtom/sdcard" +rm -rf $OUT_PATH +mkdir -p $OUT_PATH +cd $OUT_PATH +mkdir -p navit SDKRegistry +cd navit +mkdir -p bin lib share sdl ts +cd share +mkdir -p fonts +cd .. + diff --git a/circle.yml b/circle.yml index 4b296a25c..9321c75b1 100644 --- a/circle.yml +++ b/circle.yml @@ -6,7 +6,6 @@ dependencies: - ~/.android - ~/android - "~/assets/" - - ~/tomtom_assets pre: - "[ -d ~/assets ] || mkdir ~/assets" - "[ -d ~/android ] || mkdir ~/android" @@ -31,6 +30,11 @@ test: files: - ci/build_*.sh deployment: + publish_to_playstore: + branch: master + owner: navit-gps + commands: + - bash ci/publish.sh merge_into_master: branch: trunk owner: navit-gps diff --git a/contrib/tomtom/espeakdsp.c b/contrib/tomtom/espeakdsp.c new file mode 100644 index 000000000..bd6689a1f --- /dev/null +++ b/contrib/tomtom/espeakdsp.c @@ -0,0 +1,101 @@ +#include <fcntl.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/soundcard.h> +#include <sys/wait.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <libgen.h> + +#define espeakpath "/mnt/sdcard/navit/bin/espeak" +#define IBUFFERLEN 1024 +#define MAXARGC 30 + + +int main(int argc, char *argv[],char *envp[]) +{ + int pipefd[2]; + pid_t cpid; + char buf; + int co,wp,l,fh; + short bufi[IBUFFERLEN],bufo[IBUFFERLEN*2]; + int rate=22050; + + char *newargv[MAXARGC+2]; + + for(co=0;co<argc;co++) + { + if(co>=MAXARGC)break; + newargv[co]=argv[co]; + } + newargv[co++]="--stdout"; + newargv[co++]=NULL; + + if (pipe(pipefd) == -1) + { + perror("pipe"); + exit(EXIT_FAILURE); + } + + if(setpriority(PRIO_PROCESS,0,-10)) + perror ("setpriority"); + + cpid = fork(); + if (cpid == -1) + { + perror("fork"); + exit(EXIT_FAILURE); + } + + if (cpid == 0) + { /* Child writes to pipe */ + + close(pipefd[0]); /* Close unused read end */ + dup2(pipefd[1],1); + execve(espeakpath,newargv,envp); + perror(espeakpath); + close(pipefd[1]); /* Reader will see EOF */ + wait(NULL); /* Wait for child */ + exit(EXIT_SUCCESS); + + } else { /* Parent read from pipe */ + + close(pipefd[1]); /* Close unused write end */ + + l=read(pipefd[0],bufi,64); + if(memcmp(bufi,"RIFF",4)) + { + while(l>0) + { + write(1,bufi,l); + l=read(pipefd[0],bufi,IBUFFERLEN); + } + exit(EXIT_SUCCESS); + } + l=read(pipefd[0],bufi,IBUFFERLEN); + + fh=open("/dev/dsp",O_WRONLY); + if(fh<0) + { + perror("open /dev/dsp"); + exit(EXIT_FAILURE); + } + ioctl(fh, SNDCTL_DSP_SPEED , &rate); + ioctl(fh, SNDCTL_DSP_SYNC, 0); + while(l) + { + for(co=0,wp=0;(co<IBUFFERLEN)&&(co<l);co++) + { + bufo[wp++]=bufi[co]; /* mono->stereo */ + bufo[wp++]=bufi[co]; + } + write (fh,bufo,wp); + l=read(pipefd[0],bufi,IBUFFERLEN); + } + ioctl(fh, SNDCTL_DSP_SYNC, 0); + close(pipefd[0]); + exit(EXIT_SUCCESS); + } +} diff --git a/navit/android/AndroidManifest.xml.cmake b/navit/android/AndroidManifest.xml.cmake index b5bd757cb..7aa882bb8 100644 --- a/navit/android/AndroidManifest.xml.cmake +++ b/navit/android/AndroidManifest.xml.cmake @@ -37,5 +37,15 @@ <activity android:name=".NavitDownloadSelectMapActivity"></activity> <activity android:name=".NavitAddressResultListActivity"></activity> <activity android:name=".FileBrowserActivity"></activity> + <activity + android:name="org.acra.dialog.CrashReportDialog" + android:theme="@android:style/Theme.Dialog" + android:launchMode="singleInstance" + android:excludeFromRecents="true" + android:finishOnTaskLaunch="true"/> + <service + android:name="org.acra.sender.SenderService" + android:exported="false" + android:process=":acra" /> </application> </manifest> diff --git a/navit/android/AndroidManifest.xml.in b/navit/android/AndroidManifest.xml.in deleted file mode 100644 index 085276623..000000000 --- a/navit/android/AndroidManifest.xml.in +++ /dev/null @@ -1,37 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="org.navitproject.navit" - android:sharedUserId="org.navitproject.navit" - android:versionCode="@ANDROID_VERSION_INT@" - android:versionName="@ANDROID_VERSION_NAME@" - android:installLocation="auto"> - <application android:label="@string/app_name" - android:icon="@drawable/icon" - android:name=".NavitAppConfig" - android:theme="@style/NavitTheme"> - <activity android:name="Navit" - android:label="@string/app_name" - android:configChanges="locale|touchscreen|keyboard|keyboardHidden|navigation|orientation|fontScale|screenSize"> - <intent-filter> - <action android:name="android.intent.action.MAIN" /> - <category android:name="android.intent.category.LAUNCHER" /> - </intent-filter> - <intent-filter> - <action android:name="android.intent.action.VIEW" /> - <category android:name="android.intent.category.DEFAULT" /> - <data android:scheme="google.navigation" /> - </intent-filter> - </activity> - <activity android:name=".NavitAddressSearchActivity"></activity> - <activity android:name=".NavitDownloadSelectMapActivity"></activity> - <activity android:name=".NavitAddressResultListActivity"></activity> - <activity android:name=".FileBrowserActivity"></activity> - </application> - <uses-sdk android:minSdkVersion="7" android:targetSdkVersion="19"/> - <supports-screens android:smallScreens="true" android:normalScreens="true" android:largeScreens="true" android:resizeable="true" android:anyDensity="true"/> - <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> - <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> - <uses-permission android:name="android.permission.WAKE_LOCK" /> - <uses-permission android:name="android.permission.INTERNET" /> - <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> -</manifest> diff --git a/navit/android/libs/acra-4.3.0b2.jar b/navit/android/libs/acra-4.3.0b2.jar Binary files differdeleted file mode 100644 index 259a69581..000000000 --- a/navit/android/libs/acra-4.3.0b2.jar +++ /dev/null diff --git a/navit/android/libs/acra-4.8.5.jar b/navit/android/libs/acra-4.8.5.jar Binary files differnew file mode 100644 index 000000000..f0044ece8 --- /dev/null +++ b/navit/android/libs/acra-4.8.5.jar diff --git a/navit/android/libs/android-support-v4.jar b/navit/android/libs/android-support-v4.jar Binary files differnew file mode 100644 index 000000000..aa0b1a5cc --- /dev/null +++ b/navit/android/libs/android-support-v4.jar diff --git a/navit/android/src/org/navitproject/navit/Navit.java b/navit/android/src/org/navitproject/navit/Navit.java index c8578df07..11a1919b7 100644 --- a/navit/android/src/org/navitproject/navit/Navit.java +++ b/navit/android/src/org/navitproject/navit/Navit.java @@ -303,8 +303,8 @@ public class Navit extends Activity PendingIntent appIntent = PendingIntent.getActivity(getApplicationContext(), 0, getIntent(), 0);
// FIXME : needs a fix for sdk 23
// NavitNotification.setLatestEventInfo(getApplicationContext(), "Navit", getString(R.string.notification_event_default), appIntent); // Set the text in the notification
- NavitNotification.flags|=Notification.FLAG_ONGOING_EVENT; // Ensure that the notification appears in Ongoing
- nm.notify(R.string.app_name, NavitNotification); // Set the notification
+// NavitNotification.flags|=Notification.FLAG_ONGOING_EVENT; // Ensure that the notification appears in Ongoing
+// nm.notify(R.string.app_name, NavitNotification); // Set the notification
// Status and navigation bar sizes
// These are platform defaults and do not change with rotation, but we have to figure out which ones apply
@@ -864,8 +864,8 @@ public class Navit extends Activity public void exit()
{
- NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
- nm.cancel(R.string.app_name);
+// NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
+// nm.cancel(R.string.app_name);
NavitVehicle.removeListener();
NavitDestroy();
}
diff --git a/navit/android/src/org/navitproject/navit/NavitAppConfig.java b/navit/android/src/org/navitproject/navit/NavitAppConfig.java index 32f003f18..13ccc9bb4 100755 --- a/navit/android/src/org/navitproject/navit/NavitAppConfig.java +++ b/navit/android/src/org/navitproject/navit/NavitAppConfig.java @@ -8,10 +8,14 @@ import org.navitproject.navit.NavitAddressSearchActivity.NavitAddress; import android.app.Application;
import android.content.SharedPreferences;
import android.util.Log;
-
+import org.acra.*;
import org.acra.annotation.*;
-@ReportsCrashes(formKey = "dGlrNVRIOVVKYjB0UGVoLUZPanlzWFE6MQ")
+//@ReportsCrashes(formKey = "dGlrNVRIOVVKYjB0UGVoLUZPanlzWFE6MQ")
+@ReportsCrashes(mailTo = "android@navit-project.org",
+ mode = ReportingInteractionMode.TOAST,
+ resToastText = R.string.app_name)
+
public class NavitAppConfig extends Application {
private static final int MAX_LAST_ADDRESSES = 10;
diff --git a/navit/event.c b/navit/event.c index 667e5bdc3..5aee40689 100644 --- a/navit/event.c +++ b/navit/event.c @@ -77,6 +77,15 @@ event_remove_watch(struct event_watch *ev) event_methods.remove_watch(ev); } +/** + * Add an event timeout + * + * @param the timeout itself in msec + * @param multi 0 means that the timeout will fire only once, 1 means that it will repeat + * @param the callback to call when the timeout expires + * + * @returns the result of the event_methods.add_timeout() call + */ struct event_timeout * event_add_timeout(int timeout, int multi, struct callback *cb) { diff --git a/navit/graphics/egl/CMakeLists.txt b/navit/graphics/egl/CMakeLists.txt new file mode 100644 index 000000000..1943f2bc0 --- /dev/null +++ b/navit/graphics/egl/CMakeLists.txt @@ -0,0 +1,2 @@ +module_add_library(graphics_egl graphics_egl.c) + diff --git a/navit/graphics/egl/graphics_egl.c b/navit/graphics/egl/graphics_egl.c new file mode 100644 index 000000000..4d7780ff4 --- /dev/null +++ b/navit/graphics/egl/graphics_egl.c @@ -0,0 +1,1458 @@ +/** + * Navit, a modular navigation system. + * Copyright (C) 2005-2010 Navit Team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include <glib.h> +#include <unistd.h> +#include <math.h> +#include <stdio.h> + +#include <time.h> + +#include "item.h" +#include "attr.h" +#include "config.h" +#include "point.h" +#include "graphics.h" +#include "color.h" +#include "plugin.h" +#include "event.h" +#include "debug.h" +#include "callback.h" +#include "keys.h" +#include "window.h" +#include "navit/font/freetype/font_freetype.h" + +#include <SDL2/SDL_image.h> +#include <GLES2/gl2.h> +#include <EGL/egl.h> + +/* + * This is work in progress * + * Remainng issues : + * - SDL mouse cursor sometimes raise an SDL assertion + * - Dashed lines to implement + * - Full Keyboard handling +*/ + +#define SCREEN_WIDTH 800 +#define SCREEN_HEIGHT 600 + +#define glF(x) x +#define glD(x) x +#define GL_F GL_FLOAT +typedef GLfloat GLf; + +struct graphics_gc_priv { + struct graphics_priv *gr; + float fr, fg, fb, fa; + float br, bg, bb, ba; + int linewidth; + unsigned char *dash_list; + int dash_count; + int dash_mask; +} graphics_gc_priv; + +struct graphics_priv { + int fill_poly; + int show_overlays; + int button_timeout; + struct point p; + int width; + int height; + int library_init; + int visible; + int overlay_enabled; + int overlay_autodisabled; + int wraparound; + GLuint framebuffer_name; + GLuint overlay_texture; + struct graphics_priv *parent; + struct graphics_priv *overlays; + struct graphics_priv *next; + struct graphics_gc_priv *background_gc; + enum draw_mode_num mode; + GLuint program; + GLint mvp_location, position_location, color_location, texture_position_location, use_texture_location, texture_location; + struct callback_list *cbl; + struct font_freetype_methods freetype_methods; + struct navit *nav; + int timeout; + int delay; + struct window window; + int dirty; //display needs to be redrawn (draw on root graphics or overlay is done) + int force_redraw; //display needs to be redrawn (draw on root graphics or overlay is done) + time_t last_refresh_time; //last display refresh time + struct graphics_opengl_platform *platform; + struct graphics_opengl_platform_methods *platform_methods; +}; + +struct graphics_image_priv { + SDL_Surface *img; +} graphics_image_priv; + + +struct graphics_opengl_platform { + SDL_Window* eglwindow; + SDL_GLContext eglcontext; + EGLDisplay egldisplay; + EGLConfig config[1]; +}; + +struct contour +{ + struct point *p; + unsigned int count; +}; + +static GHashTable *hImageData; +static int USERWANTSTOQUIT = 0; +static struct graphics_priv *graphics_priv_root; +static struct graphics_priv *graphics_opengl_new_helper(struct + graphics_methods + *meth); + +/* + * GLES 2 Compatible vertex and fragment shaders + * Taken from opengl driver + */ +const char vertex_src [] = +" \ + attribute vec2 position; \ + attribute vec2 texture_position; \ + uniform mat4 mvp; \ + varying vec2 v_texture_position; \ + \ + void main() \ + { \ + v_texture_position=texture_position; \ + gl_Position = mvp*vec4(position, 0.0, 1.0); \ + } \ +"; + +const char fragment_src [] = +" \ + uniform lowp vec4 avcolor; \ + uniform sampler2D texture; \ + uniform bool use_texture; \ + varying vec2 v_texture_position; \ + void main() \ + { \ + if (use_texture) { \ + gl_FragColor = texture2D(texture, v_texture_position); \ + } else { \ + gl_FragColor = avcolor; \ + } \ + } \ +"; + +/* +* C conversion of Efficient Polygon Triangulation +* Found at http://www.flipcode.com/archives/Efficient_Polygon_Triangulation.shtml +* Adapted and debugged for this use +*/ +float area(const struct contour* contour) +{ + int p, q; + int n = contour->count - 1; + float A = 0.f; + + for (p=n-1, q=0; q < n; p=q++) + { + A += contour->p[p].x * contour->p[q].y - contour->p[q].x * contour->p[p].y; + } + return A * .5f; +} + +int +inside_triangle(float Ax, float Ay, + float Bx, float By, + float Cx, float Cy, + float Px, float Py) +{ + float ax, ay, bx, by, cx, cy, apx, apy, bpx, bpy, cpx, cpy; + float cCROSSap, bCROSScp, aCROSSbp; + + ax = Cx - Bx; ay = Cy - By; + bx = Ax - Cx; by = Ay - Cy; + cx = Bx - Ax; cy = By - Ay; + apx= Px - Ax; apy= Py - Ay; + bpx= Px - Bx; bpy= Py - By; + cpx= Px - Cx; cpy= Py - Cy; + + aCROSSbp = ax*bpy - ay*bpx; + cCROSSap = cx*apy - cy*apx; + bCROSScp = bx*cpy - by*cpx; + + return ((aCROSSbp >= 0.0f) && (bCROSScp >= 0.0f) && (cCROSSap >= 0.0f)); +} + +int +snip(const struct point* pnt,int u,int v,int w,int n,int *V) +{ + int p; + float Ax, Ay, Bx, By, Cx, Cy, Px, Py; + + Ax = pnt[V[u]].x; + Ay = pnt[V[u]].y; + + Bx = pnt[V[v]].x; + By = pnt[V[v]].y; + + Cx = pnt[V[w]].x; + Cy = pnt[V[w]].y; + + if ( (((Bx-Ax)*(Cy-Ay)) - ((By-Ay)*(Cx-Ax))) < 0.f ) + return 0; + + for (p=0;p<n;p++) + { + if( (p == u) || (p == v) || (p == w) ) + continue; + Px = pnt[V[p]].x; + Py = pnt[V[p]].y; + if (inside_triangle(Ax,Ay,Bx,By,Cx,Cy,Px,Py)) + return 0; + } + + return 1; +} + +int +process_triangles(const struct contour* contour, struct contour* result) +{ + int v; + int contour_size = contour->count - 1; + int polygon_temp_size = contour_size * 80; + int final_count = 0; + result->p = malloc(sizeof(struct point) * polygon_temp_size); + + int n = contour_size; + if ( n < 3 ) return 0; + + int *V = alloca(sizeof(int)*n); + + if ( 0.0f < area(contour) ) + for (v=0; v<n; v++) V[v] = v; + else + for(v=0; v<n; v++) V[v] = (n-1)-v; + + int nv = n; + + int count = 2*nv; + + for(v=nv-1; nv>2; ) + { + /* if we loop, it is probably a non-simple polygon */ + if (0 >= (count--)) + { + //** Triangulate: ERROR - probable bad polygon! + break; + } + + /* three consecutive vertices in current polygon, <u,v,w> */ + int u = v ; if (nv <= u) u = 0; /* previous */ + v = u+1; if (nv <= v) v = 0; /* new v */ + int w = v+1; if (nv <= w) w = 0; /* next */ + + if ( snip(contour->p,u,v,w,nv,V) ) + { + int a,b,c,s,t; + + /* true names of the vertices */ + a = V[u]; b = V[v]; c = V[w]; + + /* output Triangle */ + result->p[final_count++] = contour->p[a]; + result->p[final_count++] = contour->p[b]; + result->p[final_count++] = contour->p[c]; + + if (final_count >= polygon_temp_size){ + free(result->p); + return 0; + } + + /* remove v from remaining polygon */ + for(s=v,t=v+1;t<nv;s++,t++) + V[s] = V[t]; + nv--; + + /* resest error detection counter */ + count = 2*nv; + } + } + + result->count = final_count; + + return 1; +} + +// ** Efficient Polygon Triangulation ** + +/* + * Destroys SDL/EGL context + */ +static void +sdl_egl_destroy(struct graphics_opengl_platform *egl) +{ + if (egl->eglwindow){ + SDL_GL_DeleteContext(egl->eglcontext); + SDL_DestroyWindow(egl->eglwindow); + } + g_free(egl); + SDL_Quit(); +} + +/* + * Swap EGL buffer + */ +static void +sdl_egl_swap_buffers(struct graphics_opengl_platform *egl) +{ + SDL_GL_SwapWindow(egl->eglwindow); +} + +/* + * Main graphic destroy + */ +static void +graphics_destroy(struct graphics_priv *gr) +{ + /*FIXME graphics_destroy is never called */ + gr->freetype_methods.destroy(); + g_free(gr); + gr = NULL; + sdl_egl_destroy(gr->platform); + SDL_Quit(); +} + +static void +gc_destroy(struct graphics_gc_priv *gc) +{ + g_free(gc); + gc = NULL; +} + +static void +gc_set_linewidth(struct graphics_gc_priv *gc, int w) +{ + gc->linewidth = w; +} + +static void +gc_set_dashes(struct graphics_gc_priv *gc, int width, int offset, + unsigned char *dash_list, int n) +{ + int i; + const int cOpenglMaskBits = 16; + gc->dash_count = n; + if (1 == n) { + gc->dash_mask = 0; + for (i = 0; i < cOpenglMaskBits; ++i) { + gc->dash_mask <<= 1; + gc->dash_mask |= (i / n) % 2; + } + } else if (1 < n) { + unsigned char *curr = dash_list; + int cnt = 0; //dot counter + int dcnt = 0; //dash element counter + int sum_dash = 0; + gc->dash_mask = 0; + + for (i = 0; i < n; ++i) { + sum_dash += dash_list[i]; + } + + //scale dashlist elements to max size + if (sum_dash > cOpenglMaskBits) { + int num_error[2] = { 0, 0 }; //count elements rounded to 0 for odd(drawn) and even(masked) for compensation + double factor = (1.0 * cOpenglMaskBits) / sum_dash; + for (i = 0; i < n; ++i) { //calculate dashlist max and largest common denomiator for scaling + dash_list[i] *= factor; + if (dash_list[i] == 0) { + ++dash_list[i]; + ++num_error[i % 2]; + } else if (0 < num_error[i % 2] + && 2 < dash_list[i]) { + ++dash_list[i]; + --num_error[i % 2]; + } + } + } + //calculate mask + for (i = 0; i < cOpenglMaskBits; ++i) { + gc->dash_mask <<= 1; + gc->dash_mask |= 1 - dcnt % 2; + ++cnt; + if (cnt == *curr) { + cnt = 0; + ++curr; + ++dcnt; + if (dcnt == n) { + curr = dash_list; + } + } + } + } +} + + +static void +gc_set_foreground(struct graphics_gc_priv *gc, struct color *c) +{ + gc->fr = c->r / 65535.0; + gc->fg = c->g / 65535.0; + gc->fb = c->b / 65535.0; + gc->fa = c->a / 65535.0; +} + +static void +gc_set_background(struct graphics_gc_priv *gc, struct color *c) +{ + gc->br = c->r / 65535.0; + gc->bg = c->g / 65535.0; + gc->bb = c->b / 65535.0; + gc->ba = c->a / 65535.0; +} + +static struct graphics_gc_methods gc_methods = { + gc_destroy, + gc_set_linewidth, + gc_set_dashes, + gc_set_foreground, + gc_set_background +}; + +static struct graphics_gc_priv * +gc_new(struct graphics_priv *gr, struct graphics_gc_methods *meth) +{ + struct graphics_gc_priv *gc = g_new0(struct graphics_gc_priv, 1); + + *meth = gc_methods; + gc->gr = gr; + gc->linewidth = 1; + return gc; +} + +static struct graphics_image_priv image_error; + +static struct graphics_image_priv * +image_new(struct graphics_priv *gr, struct graphics_image_methods *meth, char *name, int *w, int *h, + struct point *hot, int rotation) +{ + struct graphics_image_priv *gi; + + /* FIXME: meth is not used yet.. so gi leaks. at least xpm is small */ + + struct graphics_image_priv *curr_elem = + g_hash_table_lookup(hImageData, name); + + if (curr_elem == &image_error) { + //found but couldn't be loaded + return NULL; + } else if (curr_elem) { + //found and OK -> use hastable entry + *w = curr_elem->img->w; + *h = curr_elem->img->h; + hot->x = *w / 2; + hot->y = *h / 2; + return curr_elem; + } + + if (strlen(name) < 4) { + g_hash_table_insert(hImageData, g_strdup(name), + &image_error); + return NULL; + } + + gi = g_new0(struct graphics_image_priv, 1); + gi->img = IMG_Load(name); + if(gi->img) + { + *w=gi->img->w; + *h=gi->img->h; + hot->x=*w/2; + hot->y=*h/2; + } + else + { + /* TODO: debug "colour parse errors" on xpm */ + dbg(lvl_error,"image_new on '%s' failed: %s\n", name, IMG_GetError()); + g_free(gi); + gi = NULL; + g_hash_table_insert(hImageData, + g_strdup(name), + &image_error); + return gi; + } + + g_hash_table_insert(hImageData, g_strdup(name), gi); + return gi; +} + +static void +image_free(struct graphics_priv *gr, struct graphics_image_priv * gi) +{ +// SDL_FreeSurface(gi->img); +// g_free(gi); +} + +static void +set_color(struct graphics_priv *gr, struct graphics_gc_priv *gc) +{ + GLfloat col[4]; + col[0]=gc->fr; + col[1]=gc->fg; + col[2]=gc->fb; + col[3]=gc->fa; + glUniform4fv(gr->color_location, 1, col); +} + +static void +draw_array(struct graphics_priv *gr, struct point *p, int count, GLenum mode) +{ + int i; + GLf *x;//[count*2]; + x = alloca(sizeof(GLf)*count*2); + for (i = 0 ; i < count ; i++) { + x[i*2]=glF(p[i].x); + x[i*2+1]=glF(p[i].y); + } + + glVertexAttribPointer (gr->position_location, 2, GL_FLOAT, 0, 0, x ); + glDrawArrays(mode, 0, count); +} + +static void +draw_rectangle_do(struct graphics_priv *gr, struct point *p, int w, int h) +{ + struct point pa[4]; + pa[0]=pa[1]=pa[2]=pa[3]=*p; + pa[0].x+=w; + pa[1].x+=w; + pa[1].y+=h; + pa[3].y+=h; + draw_array(gr, pa, 4, GL_TRIANGLE_STRIP); +} + + +static void +draw_image_es(struct graphics_priv *gr, struct point *p, int w, int h, unsigned char *data) +{ + GLf x[8]; + GLuint texture; + memset(x, 0, sizeof(x)); + + glGenTextures(1, &texture); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, texture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); + + x[0]+=glF(1); + x[2]+=glF(1); + x[3]+=glF(1); + x[7]+=glF(1); + glUniform1i(gr->use_texture_location, 1); + glEnableVertexAttribArray(gr->texture_position_location); + glVertexAttribPointer (gr->texture_position_location, 2, GL_FLOAT, 0, 0, x ); + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + draw_rectangle_do(gr, p, w, h); + + glUniform1i(gr->use_texture_location, 0); + glDisableVertexAttribArray(gr->texture_position_location); + + glDisable(GL_BLEND); + glDeleteTextures(1, &texture); +} + +inline void +get_overlay_pos(struct graphics_priv *gr, struct point *point_out) +{ + if (gr->parent == NULL) { + point_out->x = 0; + point_out->y = 0; + return; + } + point_out->x = gr->p.x; + if (point_out->x < 0) { + point_out->x += gr->parent->width; + } + + point_out->y = gr->p.y; + if (point_out->y < 0) { + point_out->y += gr->parent->height; + } +} + +inline void +draw_overlay(struct graphics_priv *gr) +{ + struct point p_eff; + GLf x[8]; + + get_overlay_pos(gr, &p_eff); + + memset(x, 0, 8*sizeof(GLf)); + x[0]+=glF(1); + x[1]+=glF(1); + x[2]+=glF(1); + x[5]+=glF(1); + + glUniform1i(gr->use_texture_location, 1); + glEnableVertexAttribArray(gr->texture_position_location); + glVertexAttribPointer (gr->texture_position_location, 2, GL_FLOAT, 0, 0, x); + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBindTexture(GL_TEXTURE_2D, gr->overlay_texture); + + draw_rectangle_do(graphics_priv_root, &p_eff, gr->width, gr->height); + + glUniform1i(gr->use_texture_location, 0); + glDisableVertexAttribArray(gr->texture_position_location); + + glDisable(GL_BLEND); +} + +static void +draw_lines(struct graphics_priv *gr, struct graphics_gc_priv *gc, + struct point *p, int count) +{ + if ((gr->parent && !gr->parent->overlay_enabled) + || (gr->parent && gr->parent->overlay_enabled + && !gr->overlay_enabled)) { + return; + } + + glLineWidth(gc->linewidth); + + set_color(gr, gc); + graphics_priv_root->dirty = 1; + + draw_array(gr, p, count, GL_LINE_STRIP); +} + + +static void +draw_polygon(struct graphics_priv *gr, struct graphics_gc_priv *gc, + struct point *p, int count) +{ + int ok; + if ((gr->parent && !gr->parent->overlay_enabled) + || (gr->parent && gr->parent->overlay_enabled + && !gr->overlay_enabled)) { + return; + } + set_color(gr, gc); + graphics_priv_root->dirty = 1; + struct contour contour, result; + contour.count = count; + contour.p = p; + ok = process_triangles(&contour, &result); + if (ok && gr->fill_poly){ + draw_array(gr, result.p, result.count, GL_TRIANGLES); + free(result.p); + } else { + draw_array(gr, p, count, GL_LINE_STRIP); + } +} + +static void +draw_rectangle(struct graphics_priv *gr, struct graphics_gc_priv *gc, + struct point *p, int w, int h) +{ + if ((gr->parent && !gr->parent->overlay_enabled) + || (gr->parent && gr->parent->overlay_enabled + && !gr->overlay_enabled)) { + return; + } + set_color(gr, gc); + draw_rectangle_do(gr, p, w, h); + graphics_priv_root->dirty = 1; +} + +static void +display_text_draw(struct font_freetype_text *text, + struct graphics_priv *gr, struct graphics_gc_priv *fg, + struct graphics_gc_priv *bg, int color, struct point *p) +{ + int i, x, y, stride; + struct font_freetype_glyph *g, **gp; + unsigned char *shadow, *glyph; + struct color transparent = { 0x0000, 0x0000, 0x0000, 0x0000 }; + struct color black = + { fg->fr * 65535, fg->fg * 65535, fg->fb * 65535, + fg->fa * 65535 }; + struct color white = { 0xffff, 0xffff, 0xffff, 0xffff }; + + if (bg) { + if (COLOR_IS_WHITE(black) && COLOR_IS_BLACK(white)) { + black.r = 65535; + black.g = 65535; + black.b = 65535; + black.a = 65535; + + white.r = 0; + white.g = 0; + white.b = 0; + white.a = 65535; + } else if (COLOR_IS_BLACK(black) && COLOR_IS_WHITE(white)) { + white.r = 65535; + white.g = 65535; + white.b = 65535; + white.a = 65535; + + black.r = 0; + black.g = 0; + black.b = 0; + black.a = 65535; + } else { + white.r = bg->fr; + white.g = bg->fg; + white.b = bg->fb; + white.a = bg->fa; + } + } else { + white.r = 0; + white.g = 0; + white.b = 0; + white.a = 0; + } + + gp = text->glyph; + i = text->glyph_count; + x = p->x << 6; + y = p->y << 6; + while (i-- > 0) { + g = *gp++; + if (g->w && g->h && bg) { + stride = (g->w + 2) * 4; + if (color) { + shadow = g_malloc(stride * (g->h + 2)); + gr->freetype_methods.get_shadow(g, shadow, + stride, + &white, + &transparent); + + struct point p; + p.x=((x + g->x) >> 6)-1; + p.y=((y + g->y) >> 6)-1; + draw_image_es(gr, &p, g->w+2, g->h+2, shadow); + + g_free(shadow); + } + } + x += g->dx; + y += g->dy; + } + + x = p->x << 6; + y = p->y << 6; + gp = text->glyph; + i = text->glyph_count; + while (i-- > 0) { + g = *gp++; + if (g->w && g->h) { + if (color) { + stride = g->w; + if (bg) { + glyph = + g_malloc(stride * g->h * 4); + gr->freetype_methods.get_glyph(g, + glyph, + stride + * 4, + &black, + &white, + &transparent); + struct point p; + p.x=(x + g->x) >> 6; + p.y=(y + g->y) >> 6; + draw_image_es(gr, &p, g->w, g->h, glyph); + + g_free(glyph); + } + stride *= 4; + glyph = g_malloc(stride * g->h); + gr->freetype_methods.get_glyph(g, glyph, + stride, + &black, + &white, + &transparent); + struct point p; + p.x=(x + g->x) >> 6; + p.y=(y + g->y) >> 6; + draw_image_es(gr, &p, g->w, g->h, glyph); + + g_free(glyph); + } + } + x += g->dx; + y += g->dy; + } +} + +static void +draw_text(struct graphics_priv *gr, struct graphics_gc_priv *fg, + struct graphics_gc_priv *bg, struct graphics_font_priv *font, + char *text, struct point *p, int dx, int dy) +{ + if ((gr->parent && !gr->parent->overlay_enabled) + || (gr->parent && gr->parent->overlay_enabled + && !gr->overlay_enabled)) { + return; + } + + struct font_freetype_text *t; + int color = 1; + + if (!font) { + dbg(lvl_error, "no font, returning\n"); + return; + } + graphics_priv_root->dirty = 1; + + t = gr->freetype_methods.text_new(text, + (struct font_freetype_font *) + font, dx, dy); + + struct point p_eff; + p_eff.x = p->x; + p_eff.y = p->y; + + display_text_draw(t, gr, fg, bg, color, &p_eff); + gr->freetype_methods.text_destroy(t); +} + + +static void +draw_image(struct graphics_priv *gr, struct graphics_gc_priv *fg, + struct point *p, struct graphics_image_priv *img) +{ + draw_image_es(gr, p, img->img->w, img->img->h, img->img->pixels); +} + +static void +draw_drag(struct graphics_priv *gr, struct point *p) +{ + if (p) { + gr->p.x = p->x; + gr->p.y = p->y; + } +} + +static void +background_gc(struct graphics_priv *gr, struct graphics_gc_priv *gc) +{ + gr->background_gc = gc; +} + +/* + * Draws map in background + */ +static void +draw_background(struct graphics_priv *gr) +{ + struct point p_eff; + GLf x[8]; + + glBindFramebuffer(GL_FRAMEBUFFER, 0); + glViewport(0, 0, gr->width, gr->height); + //get_overlay_pos(gr, &p_eff); + p_eff.x = gr->p.x; + p_eff.y = gr->p.y; + + memset(x, 0, 8*sizeof(GLf)); + x[0]+=glF(1); + x[1]+=glF(1); + x[2]+=glF(1); + x[5]+=glF(1); + + glUniform1i(gr->use_texture_location, 1); + glEnableVertexAttribArray(gr->texture_position_location); + glVertexAttribPointer (gr->texture_position_location, 2, GL_FLOAT, 0, 0, x); + + glDisable(GL_BLEND); + glBindTexture(GL_TEXTURE_2D, gr->overlay_texture); + + draw_rectangle_do(gr, &p_eff, gr->width, gr->height); + + glUniform1i(gr->use_texture_location, 0); + glDisableVertexAttribArray(gr->texture_position_location); +} + +/* + Drawing method : + Map and overlays are rendered in an offscreen buffer (See render to texture) + and are recomposed altogether at draw_mode_end request for root +*/ +static void +draw_mode(struct graphics_priv *gr, enum draw_mode_num mode) +{ + GLfloat matrix[16]; + struct graphics_priv *overlay = NULL; + int i; + + if (mode == draw_mode_begin){ + // Should not be necessary... + // SDL_GL_MakeCurrent(gr->platform->eglwindow, gr->platform->eglcontext); + + if (gr->parent == NULL){ + // Full redraw, reset drag position + gr->p.x = 0; + gr->p.y = 0; + } + + // Need to setup appropriate projection matrix + for (i = 0; i < 16 ; i++){ + matrix[i] = 0.0; + } + + matrix[0]=2.0 / gr->width; + matrix[5]=-2.0 / gr->height; + matrix[10]=1; + matrix[12]=-1; + matrix[13]=1; + matrix[15]=1; + glUniformMatrix4fv(gr->mvp_location, 1, GL_FALSE, matrix); + + glBindFramebuffer(GL_FRAMEBUFFER, gr->framebuffer_name); + glViewport(0,0,gr->width,gr->height); + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + } + + if (mode == draw_mode_end && gr->parent == NULL) { + overlay = gr->overlays; + draw_background(gr); + while(overlay){ + if (gr->overlay_enabled) + draw_overlay(overlay); + overlay = overlay->next; + } + sdl_egl_swap_buffers(gr->platform); + } + + gr->mode = mode; +} + +static int +graphics_opengl_fullscreen(struct window *w, int on) +{ + return 1; +} + +static void +graphics_opengl_disable_suspend(struct window *w) +{ + // No op +} + + +static GLuint +load_shader(const char *shader_source, GLenum type) +{ + GLuint shader = glCreateShader(type); + + glShaderSource(shader, 1, &shader_source, NULL); + glCompileShader(shader); + + return shader; +} + +static void * +get_data(struct graphics_priv *this, const char *type) +{ + GLuint vertexShader; + GLuint fragmentShader; + struct window* win; + int i; + + if (!strcmp(type, "gtk_widget")) { + fprintf(stderr, + "Currently GTK gui is not yet supported with EGL graphics driver\n"); + return NULL; + } + + if(strcmp(type, "window") == 0) { + SDL_GL_MakeCurrent(this->platform->eglwindow, this->platform->eglcontext); + + glClearColor ( 0 , 0 , 0 , 1); + glClear ( GL_COLOR_BUFFER_BIT ); + + callback_list_call_attr_2(graphics_priv_root->cbl, attr_resize, + GINT_TO_POINTER(this->width), GINT_TO_POINTER(this->height)); + + this->program = glCreateProgram(); + vertexShader = load_shader(vertex_src, GL_VERTEX_SHADER); + fragmentShader = load_shader(fragment_src, GL_FRAGMENT_SHADER); + + glAttachShader(this->program, vertexShader); + glAttachShader(this->program, fragmentShader); + glLinkProgram(this->program); + glUseProgram(this->program); + + this->mvp_location = glGetUniformLocation(this->program, "mvp"); + this->position_location = glGetAttribLocation(this->program, "position"); + glEnableVertexAttribArray(this->position_location); + this->texture_position_location = glGetAttribLocation(this->program, "texture_position"); + this->color_location = glGetUniformLocation(this->program, "avcolor"); + this->texture_location = glGetUniformLocation(this->program, "texture"); + this->use_texture_location = glGetUniformLocation(this->program, "use_texture"); + + glUniform1i(this->use_texture_location, 0); + glUniform1i(this->texture_location, 0); + + win=g_new(struct window, 1); + win->priv=this; + win->disable_suspend=NULL; + win->fullscreen = graphics_opengl_fullscreen; + win->disable_suspend = graphics_opengl_disable_suspend; + return win; + } + + return NULL; + +} + +static void +overlay_disable(struct graphics_priv *gr, int disable) +{ + gr->overlay_enabled = !disable; + gr->force_redraw = 1; + draw_mode(gr, draw_mode_end); +} + +// Need more testing +static void +overlay_resize(struct graphics_priv *gr, struct point *p, int w, int h, + int wraparound) +{ + int changed = 0; + int w2, h2; + + if (w == 0) { + w2 = 1; + } else { + w2 = w; + } + + if (h == 0) { + h2 = 1; + } else { + h2 = h; + } + + gr->p = *p; + if (gr->width != w2) { + gr->width = w2; + changed = 1; + } + + if (gr->height != h2) { + gr->height = h2; + changed = 1; + } + + gr->wraparound = wraparound; + + if (changed) { + if ((w == 0) || (h == 0)) { + gr->overlay_autodisabled = 1; + } else { + gr->overlay_autodisabled = 0; + // Reset overlay texture + glDeleteTextures(1, &gr->overlay_texture); + glGenTextures(1, &gr->overlay_texture); + glBindTexture(GL_TEXTURE_2D, gr->overlay_texture); + glTexImage2D(GL_TEXTURE_2D, 0,GL_RGBA, gr->width, gr->height, 0,GL_RGBA, GL_UNSIGNED_BYTE, 0); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, gr->overlay_texture, 0); + } + + callback_list_call_attr_2(gr->cbl, attr_resize, + GINT_TO_POINTER(gr->width), + GINT_TO_POINTER(gr->height)); + } +} + + +static struct graphics_priv *overlay_new(struct graphics_priv *gr, + struct graphics_methods *meth, + struct point *p, int w, int h, + int wraparound); + +static struct graphics_methods graphics_methods = { + graphics_destroy, + draw_mode, + draw_lines, + draw_polygon, + draw_rectangle, + NULL, + draw_text, + draw_image, + NULL, + draw_drag, + NULL, + gc_new, + background_gc, + overlay_new, + image_new, + get_data, + image_free, + NULL, + overlay_disable, + overlay_resize, + NULL, /* set_attr, */ + NULL, /* show_native_keyboard */ + NULL, /* hide_native_keyboard */ +}; + +static struct graphics_priv * +graphics_opengl_new_helper(struct graphics_methods *meth) +{ + struct font_priv *(*font_freetype_new) (void *meth); + font_freetype_new = plugin_get_category_font("freetype"); + + if (!font_freetype_new) { + return NULL; + } + + struct graphics_priv *this = g_new0(struct graphics_priv, 1); + + font_freetype_new(&this->freetype_methods); + *meth = graphics_methods; + + meth->font_new = + (struct graphics_font_priv * + (*)(struct graphics_priv *, struct graphics_font_methods *, + char *, int, int)) this->freetype_methods.font_new; + meth->get_text_bbox = + (void (*) (struct graphics_priv *, struct graphics_font_priv *, + char *, int, int, struct point*, int)) this->freetype_methods.get_text_bbox; + return this; +} + +static void +create_framebuffer_texture(struct graphics_priv *gr) +{ + GLenum status; + // Prepare a new framebuffer object + glGenFramebuffers(1, &gr->framebuffer_name); + glBindFramebuffer(GL_FRAMEBUFFER, gr->framebuffer_name); + + glGenTextures(1, &gr->overlay_texture); + glBindTexture(GL_TEXTURE_2D, gr->overlay_texture); + glTexImage2D(GL_TEXTURE_2D, 0,GL_RGBA, gr->width, gr->height, 0,GL_RGBA, GL_UNSIGNED_BYTE, 0); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, gr->overlay_texture, 0); + + status = glCheckFramebufferStatus(GL_FRAMEBUFFER); + if (status != GL_FRAMEBUFFER_COMPLETE) { + printf("Error creating texture framebuffer for overlay, exiting.\n"); + SDL_Quit(); + exit(1); + } +} + +static struct graphics_priv * +overlay_new(struct graphics_priv *gr, struct graphics_methods *meth, + struct point *p, int w, int h, int wraparound) +{ + struct graphics_priv *this = graphics_opengl_new_helper(meth); + + this->p.x = p->x; + this->p.y = p->y; + + this->width = w; + this->height = h; + this->parent = gr; + this->overlays = NULL; + this->fill_poly = 1; + + // Copy shader locations parameters + this->mvp_location = graphics_priv_root->mvp_location; + this->position_location = graphics_priv_root->position_location; + this->texture_position_location = graphics_priv_root->texture_position_location; + this->color_location = graphics_priv_root->color_location; + this->texture_location = graphics_priv_root->texture_location; + this->use_texture_location = graphics_priv_root->use_texture_location; + + if ((w == 0) || (h == 0)) { + this->overlay_autodisabled = 1; + } else { + this->overlay_autodisabled = 0; + } + this->overlay_enabled = 1; + + this->next = gr->overlays; + gr->overlays = this; + + create_framebuffer_texture(this); + + return this; +} + + +static gboolean graphics_sdl_idle(void *data) +{ + struct graphics_priv *gr = (struct graphics_priv *)data; + struct point p; + SDL_Event ev; + int ret; + char key_mod = 0; + char keybuf[8]; + char keycode; + + // Process SDL events (KEYS + MOUSE) + while(1) + { + ret = SDL_PollEvent(&ev); + + if(!ret) + break; + + switch(ev.type) + { + case SDL_MOUSEMOTION: + { + p.x = ev.motion.x; + p.y = ev.motion.y; + //gr->force_redraw = 1; + callback_list_call_attr_1(gr->cbl, attr_motion, (void *)&p); + break; + } + + case SDL_KEYDOWN: + { + memset(keybuf, 0, sizeof(keybuf)); + switch(ev.key.keysym.sym) + { + case SDLK_F1: + graphics_priv_root->fill_poly = !graphics_priv_root->fill_poly; + break; + case SDLK_F2: + graphics_priv_root->show_overlays = !graphics_priv_root->show_overlays; + break; + case SDLK_LEFT: + { + keybuf[0] = NAVIT_KEY_LEFT; + break; + } + case SDLK_RIGHT: + { + keybuf[0] = NAVIT_KEY_RIGHT; + break; + } + case SDLK_BACKSPACE: + { + keybuf[0] = NAVIT_KEY_BACKSPACE; + break; + } + case SDLK_RETURN: + { + keybuf[0] = NAVIT_KEY_RETURN; + break; + } + case SDLK_DOWN: + { + keybuf[0] = NAVIT_KEY_DOWN; + break; + } + case SDLK_PAGEUP: + { + keybuf[0] = NAVIT_KEY_ZOOM_OUT; + break; + } + case SDLK_UP: + { + keybuf[0] = NAVIT_KEY_UP; + break; + } + case SDLK_PAGEDOWN: + { + keybuf[0] = NAVIT_KEY_ZOOM_IN; + break; + } + case SDLK_ESCAPE: + { + USERWANTSTOQUIT = 1; + break; + } + default: + { + /* return unicode chars when they can be converted to ascii */ + // Need more work... + keycode = ev.key.keysym.sym; + keybuf[0] = keycode <= 127 ? keycode : 0; + break; + } + } + if (keybuf[0]) { + callback_list_call_attr_1(gr->cbl, attr_keypress, (void *)keybuf); + } + break; + } + case SDL_KEYUP: + { + break; + } + case SDL_MOUSEBUTTONDOWN: + { + p.x = ev.button.x; + p.y = ev.button.y; + graphics_priv_root->force_redraw = 1; + callback_list_call_attr_3(gr->cbl, attr_button, GINT_TO_POINTER(1), GINT_TO_POINTER((int)ev.button.button), (void *)&p); + break; + } + + case SDL_MOUSEBUTTONUP: + { + p.x = ev.button.x; + p.y = ev.button.y; + callback_list_call_attr_3(gr->cbl, attr_button, GINT_TO_POINTER(0), GINT_TO_POINTER((int)ev.button.button), (void *)&p); + break; + } + + case SDL_QUIT: + { + break; + } + default: + { + break; + } + } + } + + if (USERWANTSTOQUIT){ + SDL_Quit(); + exit(0); + } + + return TRUE; +} + + +static struct graphics_priv * +graphics_opengl_new(struct navit *nav, struct graphics_methods *meth, + struct attr **attrs, struct callback_list *cbl) +{ + struct attr *attr; + if (!event_request_system("glib", "graphics_opengl_new")) + return NULL; + + hImageData = g_hash_table_new(g_str_hash, g_str_equal); + struct graphics_priv *this = graphics_opengl_new_helper(meth); + graphics_priv_root = this; + + this->nav = nav; + this->parent = NULL; + this->overlay_enabled = 1; + this->framebuffer_name = 0; + this->overlays = NULL; + this->fill_poly = 1; + this->show_overlays = 1; + + this->width = SCREEN_WIDTH; + if ((attr = attr_search(attrs, NULL, attr_w))) + this->width = attr->u.num; + this->height = SCREEN_HEIGHT; + if ((attr = attr_search(attrs, NULL, attr_h))) + this->height = attr->u.num; + this->timeout = 100; + if ((attr = attr_search(attrs, NULL, attr_timeout))) + this->timeout = attr->u.num; + this->delay = 0; + if ((attr = attr_search(attrs, NULL, attr_delay))) + this->delay = attr->u.num; + this->cbl = cbl; + + this->framebuffer_name = 0; + + graphics_priv_root->cbl = cbl; + graphics_priv_root->width = this->width; + graphics_priv_root->height = this->height; + + struct graphics_opengl_platform *ret=g_new0(struct graphics_opengl_platform,1); + + // SDL Init + int sdl_status = SDL_Init(SDL_INIT_VIDEO|SDL_INIT_EVENTS); + + if (sdl_status != 0){ + fprintf(stderr, "\nUnable to initialize SDL: %i %s\n", sdl_status, SDL_GetError() ); + exit(1); + } + + Uint32 flags = SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL | SDL_WINDOW_FULLSCREEN; + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES); + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); + SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 0); + // I think it's not necessary to sync vblank, update is quite slow + SDL_GL_SetSwapInterval(0); + + ret->eglwindow = SDL_CreateWindow( + "Navit EGL", // window title + SDL_WINDOWPOS_UNDEFINED, // initial x position + SDL_WINDOWPOS_UNDEFINED, // initial y position + this->width, // width, in pixels + this->height, // height, in pixels + flags + ); + + if (ret->eglwindow == NULL) { + fprintf(stderr, "\nUnable to initialize SDL window: %s\n", SDL_GetError() ); + goto error; + } + + ret->eglcontext = SDL_GL_CreateContext(ret->eglwindow); + if (ret->eglcontext == NULL){ + printf("EGL context creation failed\n"); + goto error; + } + + this->platform = ret; + create_framebuffer_texture(this); + g_timeout_add(G_PRIORITY_DEFAULT+10, graphics_sdl_idle, this); + glDisable(GL_DEPTH_TEST); + return this; +error: + SDL_Quit(); + return NULL; +} + +void +plugin_init(void) +{ + plugin_register_category_graphics("egl", graphics_opengl_new); +} + diff --git a/navit/navit.c b/navit/navit.c index 9e4ea421b..3f4678032 100644 --- a/navit/navit.c +++ b/navit/navit.c @@ -3403,61 +3403,59 @@ navit_layout_switch(struct navit *n) if (l->dayname || l->nightname) { //Ok, we know that we have profile to switch - //Check that we aren't calculating too fast - if (vehicle_get_attr(n->vehicle->vehicle, attr_position_time_iso8601,&iso8601_attr,NULL)==1) { - currTs=iso8601_to_secs(iso8601_attr.u.str); - dbg(lvl_debug,"currTs: %u:%u\n",currTs%86400/3600,((currTs%86400)%3600)/60); - } - dbg(lvl_debug,"prevTs: %u:%u\n",n->prevTs%86400/3600,((n->prevTs%86400)%3600)/60); - if (currTs-(n->prevTs)<60) { - //We've have to wait a little - return; - } - if (n->auto_switch == FALSE) - return; - if (sscanf(iso8601_attr.u.str,"%d-%02d-%02dT",&year,&month,&day) != 3) - return; - if (vehicle_get_attr(n->vehicle->vehicle, attr_position_valid, &valid_attr,NULL) && valid_attr.u.num==attr_position_valid_invalid) { - return; //No valid fix yet - } - if (vehicle_get_attr(n->vehicle->vehicle, attr_position_coord_geo,&geo_attr,NULL)!=1) { + //Check that we aren't calculating too fast + if (vehicle_get_attr(n->vehicle->vehicle, attr_position_time_iso8601,&iso8601_attr,NULL)==1) { + currTs=iso8601_to_secs(iso8601_attr.u.str); + dbg(lvl_debug,"currTs: %u:%u\n",currTs%86400/3600,((currTs%86400)%3600)/60); + } + dbg(lvl_debug,"prevTs: %u:%u\n",n->prevTs%86400/3600,((n->prevTs%86400)%3600)/60); + + if (n->auto_switch == FALSE) + return; + + if (currTs-(n->prevTs)<60) { + //We've have to wait a little + return; + } + + if (sscanf(iso8601_attr.u.str,"%d-%02d-%02dT",&year,&month,&day) != 3) + return; + if (vehicle_get_attr(n->vehicle->vehicle, attr_position_valid, &valid_attr,NULL) && valid_attr.u.num==attr_position_valid_invalid) { + return; //No valid fix yet + } + if (vehicle_get_attr(n->vehicle->vehicle, attr_position_coord_geo,&geo_attr,NULL)!=1) { //No position - no sun return; - } - //We calculate sunrise anyway, cause it is needed both for day and for night - if (__sunriset__(year,month,day,geo_attr.u.coord_geo->lng,geo_attr.u.coord_geo->lat,-5,1,&trise,&tset)!=0) { - //near the pole sun never rises/sets, so we should never switch profiles - dbg(lvl_debug,"trise: %u:%u, sun never visible, never switch profile\n",HOURS(trise),MINUTES(trise)); - n->prevTs=currTs; - return; } - trise_actual=trise; - dbg(lvl_debug,"trise: %u:%u\n",HOURS(trise),MINUTES(trise)); - dbg(lvl_debug,"dayname = %s, name =%s \n",l->dayname, l->name); - if (HOURS(trise)*60+MINUTES(trise)<(currTs%86400)/60) { - after_sunrise = TRUE; - } - dbg(lvl_debug,"nightname = %s, name = %s \n",l->nightname, l->name); - if (__sunriset__(year,month,day,geo_attr.u.coord_geo->lng,geo_attr.u.coord_geo->lat,-5,1,&trise,&tset)!=0) { - //near the pole sun never rises/sets, so we should never switch profiles - dbg(lvl_debug,"tset: %u:%u, sun always visible, never switch profile\n",HOURS(tset),MINUTES(tset)); - n->prevTs=currTs; - return; - } - dbg(lvl_debug,"tset: %u:%u\n",HOURS(tset),MINUTES(tset)); - if (((HOURS(tset)*60+MINUTES(tset)<(currTs%86400)/60)) || - ((HOURS(trise_actual)*60+MINUTES(trise_actual)>(currTs%86400)/60))) { - after_sunset = TRUE; - } - if (after_sunrise && !after_sunset && l->dayname) { - navit_set_layout_by_name(n,l->dayname); + //We calculate sunrise anyway, cause it is needed both for day and for night + if (__sunriset__(year,month,day,geo_attr.u.coord_geo->lng,geo_attr.u.coord_geo->lat,-5,1,&trise,&tset)!=0) { + dbg(lvl_debug,"near the pole sun never rises/sets, so we should never switch profiles\n"); + dbg(lvl_debug,"trise: %u:%u\n",HOURS(trise),MINUTES(trise)); + dbg(lvl_debug,"tset: %u:%u\n",HOURS(tset),MINUTES(tset)); + n->prevTs=currTs; + return; + } + trise_actual=trise; + dbg(lvl_debug,"trise: %u:%u\n",HOURS(trise),MINUTES(trise)); + dbg(lvl_debug,"tset: %u:%u\n",HOURS(tset),MINUTES(tset)); + dbg(lvl_debug,"dayname = %s, name =%s \n",l->dayname, l->name); + dbg(lvl_debug,"nightname = %s, name = %s \n",l->nightname, l->name); + if (HOURS(trise)*60+MINUTES(trise)<(currTs%86400)/60) { + after_sunrise = TRUE; + } + + if (((HOURS(tset)*60+MINUTES(tset)<(currTs%86400)/60)) || + ((HOURS(trise_actual)*60+MINUTES(trise_actual)>(currTs%86400)/60))) { + after_sunset = TRUE; + } + if (after_sunrise && !after_sunset && l->dayname) { + navit_set_layout_by_name(n,l->dayname); dbg(lvl_debug,"layout set to day\n"); - } - else if (after_sunset && l->nightname) { - navit_set_layout_by_name(n,l->nightname); - dbg(lvl_debug,"layout set to night\n"); - } - n->prevTs=currTs; + }else if (after_sunset && l->nightname) { + navit_set_layout_by_name(n,l->nightname); + dbg(lvl_debug,"layout set to night\n"); + } + n->prevTs=currTs; } } |