[DEV] fisrt step or rework backend of ewol

This commit is contained in:
Edouard DUPIN 2015-07-15 08:34:16 +02:00
parent 93afc6cb07
commit 7c605538ca
84 changed files with 14372 additions and 0 deletions

57
.travis.yml Normal file
View File

@ -0,0 +1,57 @@
# language type:
language:
- cpp
- Objective-c
# compilator system:
compiler:
- clang
- gcc
# build branch requested
branches:
only:
- master
- dev
# previous actions:
before_script:
- cd ..
- mkdir bin
- curl https://storage.googleapis.com/git-repo-downloads/repo > bin/repo
- chmod a+x bin/repo
- git config --global user.email "travis@travis.com"
- git config --global user.name "Travis"
- git config --global color.ui "auto"
- git config --global core.editor "vi"
- mkdir WORKING_DIRECTORY
- cd WORKING_DIRECTORY
- ../bin/repo init -u https://github.com/atria-soft/manifest.git
- ../bin/repo sync -j8
- rm -rf atria-soft/ewol
- cd ..
- pwd
- ls -l
- if [ "$CXX" == "clang++" ]; then BUILDER=clang; else BUILDER=gcc; fi
install:
- sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y
- sudo apt-get update -qq
- sudo apt-get install -qq libstdc++-4.9-dev
- sudo apt-get install -qq g++-4.9
- sudo rm /usr/bin/gcc /usr/bin/g++
- sudo ln -s /usr/bin/gcc-4.9 /usr/bin/gcc
- sudo ln -s /usr/bin/g++-4.9 /usr/bin/g++
- sudo pip install lutin
# build sequence with Lutin :
script:
- lutin -C -P -c$BUILDER -mdebug -p ewol etk-test exml-test ejson-test enet-test 0XX_customwidget 001_HelloWord
- ./out/Linux_x86_64/debug/staging/$BUILDER/etk-test/usr/bin/etk-test
- ./out/Linux_x86_64/debug/staging/$BUILDER/ejson-test/usr/bin/ejson-test
- ./out/Linux_x86_64/debug/staging/$BUILDER/exml-test/usr/bin/exml-test
#send e-mail on compilation result:
notifications:
email:
- yui.heero@gmail.com

View File

@ -0,0 +1,142 @@
/**
* @author Edouard DUPIN, Kevin BILLONNEAU
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
package org.gale;
import android.app.Activity;
import android.service.wallpaper.WallpaperService;
import android.service.wallpaper.WallpaperService.Engine;
import android.util.Log;
public class Gale {
private int m_instanceID = -1; // local and private instance ID
private boolean m_hardKeyboardHidden = true;
public <T extends GaleCallback> Gale(T _activityInstance, int _typeApplication) {
m_instanceID = -1;
m_hardKeyboardHidden = true;
m_instanceID = EWsetJavaVirtualMachineStart(_activityInstance, _typeApplication);
Log.d("Gale", "new : " + m_instanceID);
}
public void setJavaVirtualMachineStop() {
EWsetJavaVirtualMachineStop(m_instanceID);
}
public void paramSetArchiveDir(int _mode, String _myString) {
EWparamSetArchiveDir(m_instanceID, _mode, _myString);
}
public boolean getHardKeyboardHidden() {
return m_hardKeyboardHidden;
}
public void setHardKeyboardHidden(boolean _val) {
m_hardKeyboardHidden = _val;
}
// activity status
public void onCreate() {
EWonCreate(m_instanceID);
}
public void onStart() {
EWonStart(m_instanceID);
}
public void onReStart() {
EWonReStart(m_instanceID);
}
public void onResume() {
EWonResume(m_instanceID);
}
public void onPause() {
EWonPause(m_instanceID);
}
public void onStop() {
EWonStop(m_instanceID);
}
public void onDestroy() {
EWonDestroy(m_instanceID);
}
// set display properties :
public void displayPropertyMetrics(float _ratioX, float _ratioY) {
EWdisplayPropertyMetrics(m_instanceID, _ratioX, _ratioY);
}
// IO native function :
// Specific for the type of input : TOOL_TYPE_FINGER and TOOL_TYPE_STYLUS (work as the same)
public void inputEventMotion(int _pointerID, float _x, float _y) {
EWinputEventMotion(m_instanceID, _pointerID, _x, _y);
}
public void inputEventState(int _pointerID, boolean _isDown, float _x, float _y) {
EWinputEventState(m_instanceID, _pointerID, _isDown, _x, _y);
}
// Specific for the type of input : TOOL_TYPE_MOUSE
public void mouseEventMotion(int _pointerID, float _x, float _y) {
EWmouseEventMotion(m_instanceID, _pointerID, _x, _y);
}
public void mouseEventState(int _pointerID, boolean _isDown, float _x, float _y) {
EWmouseEventState(m_instanceID, _pointerID, _isDown, _x, _y);
}
// other unknow event ...
public void unknowEvent(int _eventID) {
EWunknowEvent(m_instanceID, _eventID);
}
public void keyboardEventMove(int _type, boolean _isDown) {
EWkeyboardEventMove(m_instanceID, _type, _isDown);
}
public void keyboardEventKey(int _uniChar, boolean _isDown) {
EWkeyboardEventKey(m_instanceID, _uniChar, _isDown);
}
public boolean keyboardEventKeySystem(int _keyVal, boolean _isDown) {
return EWkeyboardEventKeySystem(m_instanceID, _keyVal, _isDown);
}
// renderer Event :
public void renderInit() {
EWrenderInit(m_instanceID);
}
public void renderResize(int _w, int _h) {
EWrenderResize(m_instanceID, _w, _h);
}
public void renderDraw() {
EWrenderDraw(m_instanceID);
}
private native <T extends GaleCallback> int EWsetJavaVirtualMachineStart(T _activityInstance, int _typeApplication);
private native void EWsetJavaVirtualMachineStop(int _instanceId);
private native void EWparamSetArchiveDir(int _instanceId, int _mode, String _myString);
// activity status
private native void EWonCreate(int _instanceId);
private native void EWonStart(int _instanceId);
private native void EWonReStart(int _instanceId);
private native void EWonResume(int _instanceId);
private native void EWonPause(int _instanceId);
private native void EWonStop(int _instanceId);
private native void EWonDestroy(int _instanceId);
// set display properties :
private native void EWdisplayPropertyMetrics(int _instanceId, float _ratioX, float _ratioY);
// IO native function :
// Specific for the type of input : TOOL_TYPE_FINGER and TOOL_TYPE_STYLUS (work as the same)
private native void EWinputEventMotion(int _instanceId, int _pointerID, float _x, float _y);
private native void EWinputEventState(int _instanceId, int _pointerID, boolean _isDown, float _x, float _y);
// Specific for the type of input : TOOL_TYPE_MOUSE
private native void EWmouseEventMotion(int _instanceId, int _pointerID, float _x, float _y);
private native void EWmouseEventState(int _instanceId, int _pointerID, boolean _isDown, float _x, float _y);
// other unknow event ...
private native void EWunknowEvent(int _instanceId, int _eventID);
private native void EWkeyboardEventMove(int _instanceId, int _type, boolean _isDown);
private native void EWkeyboardEventKey(int _instanceId, int _uniChar, boolean _isDown);
private native boolean EWkeyboardEventKeySystem(int _instanceId, int _keyVal, boolean _isDown);
// renderer Event :
private native void EWrenderInit(int _instanceId);
private native void EWrenderResize(int _instanceId, int _w, int _h);
private native void EWrenderDraw(int _instanceId);
}

View File

@ -0,0 +1,317 @@
/**
* @author Edouard DUPIN, Kevin BILLONNEAU
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
package org.gale;
import android.app.Activity;
import android.content.Context;
import android.Manifest;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.KeyEvent;
// For No Title :
import android.view.Window;
// For the full screen :
import android.view.WindowManager;
// for the keyboard event :
import android.view.inputmethod.InputMethodManager;
import android.Manifest;
import java.io.File;
import android.content.Context;
import android.content.res.Configuration;
// For the getting apk name :
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.AssetFileDescriptor;
import android.content.res.AssetManager;
import android.util.DisplayMetrics;
import android.util.Log;
// copy past events :
import android.content.ClipboardManager;
import android.content.ClipData;
import android.net.Uri;
import android.content.Intent;
import android.content.ActivityNotFoundException;
import java.io.IOException;
//import activityRootView
import org.gale.Gale;
/**
* @brief Class :
*
*/
public abstract class GaleActivity extends Activity implements GaleCallback, GaleConstants {
private static Context m_context;
protected GaleSurfaceViewGL m_glView = null;
private Gale m_galeNative;
// clipboard section
private String tmpClipBoard; // TODO : Remove this ==> clipboard acces does not work
public static Context getAppContext() {
return GaleActivity.m_context;
}
public GaleActivity() {
// set the java evironement in the C sources :
m_galeNative = new Gale(this, GALE_APPL_TYPE_ACTIVITY);
tmpClipBoard = "";
}
protected void initApkPath(String _org, String _vendor, String _project) {
StringBuilder sb = new StringBuilder();
sb.append(_org).append(".");
sb.append(_vendor).append(".");
sb.append(_project);
String apkFilePath = null;
ApplicationInfo appInfo = null;
PackageManager packMgmr = getPackageManager();
try {
appInfo = packMgmr.getApplicationInfo(sb.toString(), 0);
} catch (NameNotFoundException e) {
e.printStackTrace();
throw new RuntimeException("Unable to locate assets, aborting...");
}
apkFilePath = appInfo.sourceDir;
m_galeNative.paramSetArchiveDir(0, apkFilePath);
}
@Override protected void onCreate(Bundle _savedInstanceState) {
super.onCreate(_savedInstanceState);
//setListnerToRootView();
GaleActivity.m_context = getApplicationContext();
// Load the application directory
m_galeNative.paramSetArchiveDir(1, getFilesDir().toString());
m_galeNative.paramSetArchiveDir(2, getCacheDir().toString());
// to enable extarnal storage: add in the manifest the restriction needed ...
//packageManager.checkPermission("android.permission.READ_SMS", myPackage) == PERMISSION_GRANTED;
//Gale.paramSetArchiveDir(3, getExternalCacheDir().toString());
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
m_galeNative.displayPropertyMetrics(metrics.xdpi, metrics.ydpi);
// call C init ...
m_galeNative.onCreate();
// Remove the title of the current display :
requestWindowFeature(Window.FEATURE_NO_TITLE);
// set full screen Mode:
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
// display keyboard:
//getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
// hide keyboard:
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
// create bsurface system
m_glView = new GaleSurfaceViewGL(this, m_galeNative);
setContentView(m_glView);
}
@Override protected void onStart() {
Log.w("GaleActivity", "onStart (START)");
super.onStart();
m_galeNative.onStart();
Log.w("GaleActivity", "onStart (STOP)");
}
@Override protected void onRestart() {
Log.w("GaleActivity", "onRestart (START)");
super.onRestart();
m_galeNative.onReStart();
Log.w("GaleActivity", "onRestart (STOP)");
}
@Override protected void onResume() {
Log.w("GaleActivity", "onResume (START)");
super.onResume();
m_glView.onResume();
m_galeNative.onResume();
Log.w("GaleActivity", "onResume (STOP)");
}
@Override protected void onPause() {
Log.w("GaleActivity", "onPause (START)");
super.onPause();
m_glView.onPause();
m_galeNative.onPause();
Log.w("GaleActivity", "onPause (STOP)");
}
@Override protected void onStop() {
Log.w("GaleActivity", "onStop (START)");
super.onStop();
// call C
m_galeNative.onStop();
Log.w("GaleActivity", "onStop (STOP)");
}
@Override protected void onDestroy() {
Log.w("GaleActivity", "onDestroy (START)");
super.onDestroy();
// call C
m_galeNative.onDestroy();
// Remove the java Virtual machine pointer form the C code
m_galeNative.setJavaVirtualMachineStop();
Log.w("GaleActivity", "onDestroy (STOP)");
}
@Override protected void finalize() throws Throwable {
super.finalize();
// cleanup your object here
}
@Override
public void onConfigurationChanged(Configuration _newConfig) {
Log.e("GaleActivity", "Receive event ... ");
super.onConfigurationChanged(_newConfig);
// Checks whether a hardware keyboard is available
if (_newConfig.hardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_NO) {
m_galeNative.setHardKeyboardHidden(false);
Log.e("GaleActivity", "HARD Keyboard active = " + !m_galeNative.getHardKeyboardHidden() + " (visible)");
} else if (_newConfig.hardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_YES) {
m_galeNative.setHardKeyboardHidden(true);
Log.e("GaleActivity", "HARD Keyboard active = " + !m_galeNative.getHardKeyboardHidden() + " (hidden)");
}
}
public void keyboardUpdate(boolean _show) {
Log.i("GaleActivity", "set keyboard status visibility :" + _show);
final InputMethodManager imm;
try {
imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
} catch(Exception e) {
Log.e("GaleActivity", "Can not get keyboard manager ...");
return;
}
Log.i("GaleActivity", "Get input manager done");
if(_show == true) {
try {
imm.showSoftInput(m_glView, InputMethodManager.SHOW_IMPLICIT);
} catch(Exception e) {
Log.e("GaleActivity", "Can not set keyboard state ... (exeption !!!!)");
}
Log.i("GaleActivity", "Display it Done");
} else {
// this is a little sutid this ==> display keyboard to be sure that it toggle in the hide state ...
try {
imm.showSoftInput(m_glView, InputMethodManager.SHOW_IMPLICIT);
} catch(Exception e) {
Log.e("GaleActivity", "Can not set keyboard state ... (exeption !!!!)");
}
Log.i("GaleActivity", "Display it Done");
try {
imm.toggleSoftInput(0 ,InputMethodManager.HIDE_IMPLICIT_ONLY + InputMethodManager.HIDE_NOT_ALWAYS);
} catch(Exception e) {
Log.e("GaleActivity", "Can not set keyboard state ... (exeption !!!!)");
}
Log.i("GaleActivity", "Toggle it Done");
}
}
public void eventNotifier(String[] _args) {
// TODO : ...
}
public void orientationUpdate(int _screenMode) {
Context localContext = getAppContext();
int result = localContext.checkCallingOrSelfPermission(Manifest.permission.SET_ORIENTATION);
if (result != PackageManager.PERMISSION_GRANTED) {
if (_screenMode == GALE_ORIENTATION_LANDSCAPE) {
//Force landscape
//setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE);
} else if (_screenMode == GALE_ORIENTATION_PORTRAIT) {
//Force portrait
//setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT);
} else {
//Force auto Rotation
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);
}
} else {
Log.e("GaleActivity", "Not the right 'SET_ORIENTATION' to access on the screen orientation...");
}
}
public void titleSet(String _value) {
setTitle(_value);
}
public void openURI(String _uri) {
try {
Intent myIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(_uri));
startActivity(myIntent);
} catch (ActivityNotFoundException e) {
Log.e("GaleActivity", "Can not request an URL");
}
}
public void stop() {
Log.w("GaleActivity", "Application stop requested (START)");
// end application is requested ...
finish();
Log.w("GaleActivity", "Application stop requested (STOP)");
}
//http://developer.android.com/guide/topics/text/copy-paste.html
public String getClipBoardString() {
return tmpClipBoard;
// TODO : Rework this it does not work
/*
// Gets a handle to the clipboard service.
ClipboardManager clipboard = (ClipboardManager)getSystemService(Context.CLIPBOARD_SERVICE);
// If the clipboard doesn't contain data, disable the paste menu item.
// If it does contain data, decide if you can handle the data.
if (!(clipboard.hasPrimaryClip())) {
return "";
}
// Examines the item on the clipboard. If getText() does not return null, the clip item contains the
// text. Assumes that this application can only handle one item at a time.
ClipData.Item item = clipboard.getPrimaryClip().getItemAt(0);
if (item == null) {
return "";
}
// Gets the clipboard as text.
String pasteData = item.getText().toString();;
// If the string contains data, then the paste operation is done
if (pasteData != null) {
return pasteData;
}
return "";
*/
}
public void setClipBoardString(String _data) {
tmpClipBoard = _data;
return;
// TODO : Rework this it does not work
/*
// Gets a handle to the clipboard service.
ClipboardManager clipboard = (ClipboardManager)getSystemService(Context.CLIPBOARD_SERVICE);
// Creates a new text clip to put on the clipboard
ClipData clip = ClipData.newPlainText("simple text", data);
// Set the clipboard's primary clip.
clipboard.setPrimaryClip(clip);
*/
}
}

View File

@ -0,0 +1,19 @@
/**
* @author Edouard DUPIN, Kevin BILLONNEAU
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
package org.gale;
import android.util.Log;
public interface GaleCallback {
public void openURI(String _uri);
public void keyboardUpdate(boolean _show);
public void eventNotifier(String[] _args);
public void orientationUpdate(int _screenMode);
public void titleSet(String _value);
public void stop();
}

View File

@ -0,0 +1,67 @@
/**
* @author Edouard DUPIN, Kevin BILLONNEAU
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
package org.gale;
public interface GaleConstants {
public static final int GALE_SYSTEM_KEY_VOLUME_UP = 1;
public static final int GALE_SYSTEM_KEY_VOLUME_DOWN = 2;
public static final int GALE_SYSTEM_KEY_MENU = 3;
public static final int GALE_SYSTEM_KEY_CAMERA = 4;
public static final int GALE_SYSTEM_KEY_HOME = 5;
public static final int GALE_SYSTEM_KEY_POWER = 6;
// the back key is wrapped in the <esc> key to simplify PC validation ...
public static final int GALE_SYSTEM_KEY_BACK = 0x1B;
public static final int GALE_SYSTEM_KEY_DEL = 0x08;
public static final int GALE_ORIENTATION_AUTO = 0;
public static final int GALE_ORIENTATION_LANDSCAPE = 1;
public static final int GALE_ORIENTATION_PORTRAIT = 2;
public static final int GALE_APPL_TYPE_ACTIVITY = 0;
public static final int GALE_APPL_TYPE_WALLPAPER = 1;
// Key binding of the element gale::key::keyboard :
public static final int GALE_MOVE_KEY_LEFT = 2;
public static final int GALE_MOVE_KEY_RIGHT = 3;
public static final int GALE_MOVE_KEY_UP = 4;
public static final int GALE_MOVE_KEY_DOWN = 5;
public static final int GALE_MOVE_KEY_PAGE_UP = 6;
public static final int GALE_MOVE_KEY_PAGE_DOWN = 7;
public static final int GALE_MOVE_KEY_START = 8;
public static final int GALE_MOVE_KEY_END = 9;
public static final int GALE_MOVE_KEY_PRINT = 10;
public static final int GALE_MOVE_KEY_STOP_DEFIL = 11;
public static final int GALE_MOVE_KEY_WAIT = 12;
public static final int GALE_MOVE_KEY_INSERT = 13;
public static final int GALE_MOVE_KEY_F1 = 14;
public static final int GALE_MOVE_KEY_F2 = 15;
public static final int GALE_MOVE_KEY_F3 = 16;
public static final int GALE_MOVE_KEY_F4 = 17;
public static final int GALE_MOVE_KEY_F5 = 18;
public static final int GALE_MOVE_KEY_F6 = 19;
public static final int GALE_MOVE_KEY_F7 = 20;
public static final int GALE_MOVE_KEY_F8 = 21;
public static final int GALE_MOVE_KEY_F9 = 22;
public static final int GALE_MOVE_KEY_F10 = 23;
public static final int GALE_MOVE_KEY_F11 = 24;
public static final int GALE_MOVE_KEY_F12 = 25;
public static final int GALE_MOVE_KEY_CAP_LOCK = 26;
public static final int GALE_MOVE_KEY_SHIFT_LEFT = 27;
public static final int GALE_MOVE_KEY_SHIFT_RIGHT = 28;
public static final int GALE_MOVE_KEY_CTRL_LEFT = 29;
public static final int GALE_MOVE_KEY_CTRL_RIGHT = 30;
public static final int GALE_MOVE_KEY_META_LEFT = 31;
public static final int GALE_MOVE_KEY_META_RIGHT = 32;
public static final int GALE_MOVE_KEY_ALT = 33;
public static final int GALE_MOVE_KEY_ALT_GR = 34;
public static final int GALE_MOVE_KEY_CONTEXT_MENU = 35;
public static final int GALE_MOVE_KEY_NUM_LOCK = 36;
}

View File

@ -0,0 +1,44 @@
/**
* @author Edouard DUPIN, Kevin BILLONNEAU
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
package org.gale;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import android.opengl.GLES20;
import android.opengl.GLSurfaceView;
// import the gale package :
/* no need in same package... */
//import org.gale.Gale;
import org.gale.Gale;
/**
* @brief Class :
*
*/
public class GaleRendererGL implements GLSurfaceView.Renderer
{
private Gale m_galeNative;
public GaleRendererGL(Gale _galeInstance) {
m_galeNative = _galeInstance;
}
public void onSurfaceCreated(GL10 _gl, EGLConfig _config) {
m_galeNative.renderInit();
}
public void onSurfaceChanged(GL10 _gl, int _w, int _h) {
m_galeNative.renderResize(_w, _h);
}
public void onDrawFrame(GL10 _gl) {
m_galeNative.renderDraw();
}
}

View File

@ -0,0 +1,302 @@
/**
* @author Edouard DUPIN, Kevin BILLONNEAU
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
package org.gale;
import android.content.Context;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.KeyEvent;
import android.util.Log;
import org.gale.Gale;
/**
* @brief Class :
*
*/
public class GaleSurfaceViewGL extends GLSurfaceView implements GaleConstants {
public static final int SDK_VERSION = android.os.Build.VERSION.SDK_INT;
private GaleRendererGL m_galeDrawer = null;
private boolean inputDown1 = false;
private boolean inputDown2 = false;
private boolean inputDown3 = false;
private Gale m_galeNative;
public GaleSurfaceViewGL(Context _context, Gale _galeInstance) {
// super must be first statement in constructor
super(_context);
m_galeNative = _galeInstance;
/*
List of the Android API :
Android 4.1, 4.1.1 16 JELLY_BEAN Platform Highlights
Android 4.0.3, 4.0.4 15 ICE_CREAM_SANDWICH_MR1 Platform Highlights
Android 4.0, 4.0.1, 4.0.2 14 ICE_CREAM_SANDWICH
Android 3.2 13 HONEYCOMB_MR2
Android 3.1.x 12 HONEYCOMB_MR1 Platform Highlights
Android 3.0.x 11 HONEYCOMB Platform Highlights
Android 2.3.4
Android 2.3.3 10 GINGERBREAD_MR1 Platform Highlights
Android 2.3.2
Android 2.3.1
Android 2.3 9 GINGERBREAD
Android 2.2.x 8 FROYO Platform Highlights
Android 2.1.x 7 ECLAIR_MR1 Platform Highlights
Android 2.0.1 6 ECLAIR_0_1
Android 2.0 5 ECLAIR
Android 1.6 4 DONUT Platform Highlights
Android 1.5 3 CUPCAKE Platform Highlights
Android 1.1 2 BASE_1_1
Android 1.0 1 BASE
*/
// Create an OpenGL ES 2.0 context
setEGLContextClientVersion(2);
// je n'ai pas compris ...
m_galeDrawer = new GaleRendererGL(m_galeNative);
setRenderer(m_galeDrawer);
// Can get the focus ==> get keyboard from JAVA :
setFocusable(true);
setFocusableInTouchMode(true);
}
public boolean onTouchEvent(final MotionEvent _event) {
// Wrapper on input events :
int tmpActionType = _event.getAction();
if (tmpActionType == MotionEvent.ACTION_MOVE) {
final int pointerCount = _event.getPointerCount();
for (int p = 0; p < pointerCount; p++) {
if (SDK_VERSION>=14) {
final int typeOfPointer = _event.getToolType(p);
if( typeOfPointer == MotionEvent.TOOL_TYPE_FINGER
|| typeOfPointer == MotionEvent.TOOL_TYPE_STYLUS) {
m_galeNative.inputEventMotion(_event.getPointerId(p), (float)_event.getX(p), (float)_event.getY(p));
} else if(typeOfPointer == MotionEvent.TOOL_TYPE_MOUSE) {
m_galeNative.mouseEventMotion(_event.getPointerId(p), (float)_event.getX(p), (float)_event.getY(p));
}
} else {
m_galeNative.inputEventMotion(_event.getPointerId(p), (float)_event.getX(p), (float)_event.getY(p));
}
}
} else if( tmpActionType == MotionEvent.ACTION_POINTER_1_DOWN
|| tmpActionType == MotionEvent.ACTION_DOWN) {
if (SDK_VERSION>=14) {
final int typeOfPointer = _event.getToolType(0);
if( typeOfPointer == MotionEvent.TOOL_TYPE_FINGER
|| typeOfPointer == MotionEvent.TOOL_TYPE_STYLUS) {
m_galeNative.inputEventState(_event.getPointerId(0), true, (float)_event.getX(0), (float)_event.getY(0));
} else if(typeOfPointer == MotionEvent.TOOL_TYPE_MOUSE) {
m_galeNative.mouseEventState(_event.getPointerId(0), true, (float)_event.getX(0), (float)_event.getY(0));
}
} else {
m_galeNative.inputEventState(_event.getPointerId(0), true, (float)_event.getX(0), (float)_event.getY(0));
}
inputDown1 = true;
} else if(tmpActionType == MotionEvent.ACTION_POINTER_1_UP) {
if (SDK_VERSION>=14) {
final int typeOfPointer = _event.getToolType(0);
if( typeOfPointer == MotionEvent.TOOL_TYPE_FINGER
|| typeOfPointer == MotionEvent.TOOL_TYPE_STYLUS) {
m_galeNative.inputEventState(_event.getPointerId(0), false, (float)_event.getX(0), (float)_event.getY(0));
} else if(typeOfPointer == MotionEvent.TOOL_TYPE_MOUSE) {
m_galeNative.mouseEventState(_event.getPointerId(0), false, (float)_event.getX(0), (float)_event.getY(0));
}
} else {
m_galeNative.inputEventState(_event.getPointerId(0), false, (float)_event.getX(0), (float)_event.getY(0));
}
inputDown1 = false;
} else if (tmpActionType == MotionEvent.ACTION_POINTER_2_DOWN) {
if (SDK_VERSION>=14) {
final int typeOfPointer = _event.getToolType(1);
if( typeOfPointer == MotionEvent.TOOL_TYPE_FINGER
|| typeOfPointer == MotionEvent.TOOL_TYPE_STYLUS) {
m_galeNative.inputEventState(_event.getPointerId(1), true, (float)_event.getX(1), (float)_event.getY(1));
} else if(typeOfPointer == MotionEvent.TOOL_TYPE_MOUSE) {
m_galeNative.mouseEventState(_event.getPointerId(1), true, (float)_event.getX(1), (float)_event.getY(1));
}
} else {
m_galeNative.inputEventState(_event.getPointerId(1), true, (float)_event.getX(1), (float)_event.getY(1));
}
inputDown2 = true;
} else if (tmpActionType == MotionEvent.ACTION_POINTER_2_UP) {
if (SDK_VERSION>=14) {
final int typeOfPointer = _event.getToolType(1);
if( typeOfPointer == MotionEvent.TOOL_TYPE_FINGER
|| typeOfPointer == MotionEvent.TOOL_TYPE_STYLUS) {
m_galeNative.inputEventState(_event.getPointerId(1), false, (float)_event.getX(1), (float)_event.getY(1));
} else if(typeOfPointer == MotionEvent.TOOL_TYPE_MOUSE) {
m_galeNative.mouseEventState(_event.getPointerId(1), false, (float)_event.getX(1), (float)_event.getY(1));
}
} else {
m_galeNative.inputEventState(_event.getPointerId(1), false, (float)_event.getX(1), (float)_event.getY(1));
}
inputDown2 = false;
} else if (tmpActionType == MotionEvent.ACTION_POINTER_3_DOWN) {
if (SDK_VERSION>=14) {
final int typeOfPointer = _event.getToolType(2);
if( typeOfPointer == MotionEvent.TOOL_TYPE_FINGER
|| typeOfPointer == MotionEvent.TOOL_TYPE_STYLUS) {
m_galeNative.inputEventState(_event.getPointerId(2), true, (float)_event.getX(2), (float)_event.getY(2));
} else if(typeOfPointer == MotionEvent.TOOL_TYPE_MOUSE) {
m_galeNative.mouseEventState(_event.getPointerId(2), true, (float)_event.getX(2), (float)_event.getY(2));
}
} else {
m_galeNative.inputEventState(_event.getPointerId(2), true, (float)_event.getX(2), (float)_event.getY(2));
}
inputDown3 = true;
} else if (tmpActionType == MotionEvent.ACTION_POINTER_3_UP) {
if (SDK_VERSION>=14) {
final int typeOfPointer = _event.getToolType(2);
if( typeOfPointer == MotionEvent.TOOL_TYPE_FINGER
|| typeOfPointer == MotionEvent.TOOL_TYPE_STYLUS) {
m_galeNative.inputEventState(_event.getPointerId(2), false, (float)_event.getX(2), (float)_event.getY(2));
} else if(typeOfPointer == MotionEvent.TOOL_TYPE_MOUSE) {
m_galeNative.mouseEventState(_event.getPointerId(2), false, (float)_event.getX(2), (float)_event.getY(2));
}
} else {
m_galeNative.inputEventState(_event.getPointerId(2), false, (float)_event.getX(2), (float)_event.getY(2));
}
inputDown3 = false;
} else if(tmpActionType == MotionEvent.ACTION_UP){
if (inputDown1) {
if (SDK_VERSION>=14) {
final int typeOfPointer = _event.getToolType(0);
if( typeOfPointer == MotionEvent.TOOL_TYPE_FINGER
|| typeOfPointer == MotionEvent.TOOL_TYPE_STYLUS) {
m_galeNative.inputEventState(_event.getPointerId(0), false, (float)_event.getX(0), (float)_event.getY(0));
} else if(typeOfPointer == MotionEvent.TOOL_TYPE_MOUSE) {
m_galeNative.mouseEventState(_event.getPointerId(0), false, (float)_event.getX(0), (float)_event.getY(0));
}
} else {
m_galeNative.inputEventState(_event.getPointerId(0), false, (float)_event.getX(0), (float)_event.getY(0));
}
inputDown1 = false;
} else if (inputDown2) {
if (SDK_VERSION>=14) {
final int typeOfPointer = _event.getToolType(0);
if( typeOfPointer == MotionEvent.TOOL_TYPE_FINGER
|| typeOfPointer == MotionEvent.TOOL_TYPE_STYLUS) {
m_galeNative.inputEventState(_event.getPointerId(0), false, (float)_event.getX(0), (float)_event.getY(0));
} else if(typeOfPointer == MotionEvent.TOOL_TYPE_MOUSE) {
m_galeNative.mouseEventState(_event.getPointerId(0), false, (float)_event.getX(0), (float)_event.getY(0));
}
} else {
m_galeNative.inputEventState(_event.getPointerId(0), false, (float)_event.getX(0), (float)_event.getY(0));
}
inputDown2 = false;
} else {
if (SDK_VERSION>=14) {
final int typeOfPointer = _event.getToolType(0);
if( typeOfPointer == MotionEvent.TOOL_TYPE_FINGER
|| typeOfPointer == MotionEvent.TOOL_TYPE_STYLUS) {
m_galeNative.inputEventState(_event.getPointerId(0), false, (float)_event.getX(0), (float)_event.getY(0));
} else if(typeOfPointer == MotionEvent.TOOL_TYPE_MOUSE) {
m_galeNative.mouseEventState(_event.getPointerId(0), false, (float)_event.getX(0), (float)_event.getY(0));
}
} else {
m_galeNative.inputEventState(_event.getPointerId(0), false, (float)_event.getX(0), (float)_event.getY(0));
}
inputDown3 = false;
}
}
return true;
}
private boolean keyboardEvent(int keyCode, KeyEvent _event, boolean _isDown) {
int actionDone = _event.getAction();
Log.i("Surface GL", "get event : " + keyCode + " is down : " + _isDown);
switch(keyCode) {
case KeyEvent.KEYCODE_VOLUME_DOWN:
return m_galeNative.keyboardEventKeySystem(GALE_SYSTEM_KEY_VOLUME_DOWN, _isDown);
case KeyEvent.KEYCODE_VOLUME_UP:
return m_galeNative.keyboardEventKeySystem(GALE_SYSTEM_KEY_VOLUME_UP, _isDown);
case KeyEvent.KEYCODE_MENU:
return m_galeNative.keyboardEventKeySystem(GALE_SYSTEM_KEY_MENU, _isDown);
case KeyEvent.KEYCODE_CAMERA:
return m_galeNative.keyboardEventKeySystem(GALE_SYSTEM_KEY_CAMERA, _isDown);
case KeyEvent.KEYCODE_HOME:
return m_galeNative.keyboardEventKeySystem(GALE_SYSTEM_KEY_HOME, _isDown);
case KeyEvent.KEYCODE_POWER:
return m_galeNative.keyboardEventKeySystem(GALE_SYSTEM_KEY_POWER, _isDown);
case KeyEvent.KEYCODE_BACK:
// the back key is wrapped in the <esc> key to simplify PC validation ...
return m_galeNative.keyboardEventKeySystem(GALE_SYSTEM_KEY_BACK, _isDown);
/*
m_galeNative.keyboardEventKey(GALE_SYSTEM_KEY_BACK, _isDown);
return false;
*/
case KeyEvent.KEYCODE_DEL:
m_galeNative.keyboardEventKey(GALE_SYSTEM_KEY_DEL, _isDown);
return true;
// Joystick event :
case KeyEvent.KEYCODE_DPAD_UP: m_galeNative.keyboardEventMove(GALE_MOVE_KEY_UP, _isDown); return true;
case KeyEvent.KEYCODE_DPAD_DOWN: m_galeNative.keyboardEventMove(GALE_MOVE_KEY_DOWN, _isDown); return true;
case KeyEvent.KEYCODE_DPAD_LEFT: m_galeNative.keyboardEventMove(GALE_MOVE_KEY_LEFT, _isDown); return true;
case KeyEvent.KEYCODE_DPAD_RIGHT: m_galeNative.keyboardEventMove(GALE_MOVE_KEY_RIGHT, _isDown); return true;
case KeyEvent.KEYCODE_PAGE_UP: m_galeNative.keyboardEventMove(GALE_MOVE_KEY_PAGE_UP, _isDown); return true;
case KeyEvent.KEYCODE_PAGE_DOWN: m_galeNative.keyboardEventMove(GALE_MOVE_KEY_PAGE_DOWN, _isDown); return true;
case KeyEvent.KEYCODE_MOVE_HOME: m_galeNative.keyboardEventMove(GALE_MOVE_KEY_START, _isDown); return true;
case KeyEvent.KEYCODE_MOVE_END: m_galeNative.keyboardEventMove(GALE_MOVE_KEY_END, _isDown); return true;
case KeyEvent.KEYCODE_SYSRQ: m_galeNative.keyboardEventMove(GALE_MOVE_KEY_PRINT, _isDown); return true;
//case KeyEvent.: m_galeNative.keyboardEventMove(GALE_MOVE_KEY_STOP_DEFIL, _isDown); return true;
case KeyEvent.KEYCODE_BREAK: m_galeNative.keyboardEventMove(GALE_MOVE_KEY_WAIT, _isDown); return true;
case KeyEvent.KEYCODE_INSERT: m_galeNative.keyboardEventMove(GALE_MOVE_KEY_INSERT, _isDown); return true;
case KeyEvent.KEYCODE_F1: m_galeNative.keyboardEventMove(GALE_MOVE_KEY_F1, _isDown); return true;
case KeyEvent.KEYCODE_F2: m_galeNative.keyboardEventMove(GALE_MOVE_KEY_F2, _isDown); return true;
case KeyEvent.KEYCODE_F3: m_galeNative.keyboardEventMove(GALE_MOVE_KEY_F3, _isDown); return true;
case KeyEvent.KEYCODE_F4: m_galeNative.keyboardEventMove(GALE_MOVE_KEY_F4, _isDown); return true;
case KeyEvent.KEYCODE_F5: m_galeNative.keyboardEventMove(GALE_MOVE_KEY_F5, _isDown); return true;
case KeyEvent.KEYCODE_F6: m_galeNative.keyboardEventMove(GALE_MOVE_KEY_F6, _isDown); return true;
case KeyEvent.KEYCODE_F7: m_galeNative.keyboardEventMove(GALE_MOVE_KEY_F7, _isDown); return true;
case KeyEvent.KEYCODE_F8: m_galeNative.keyboardEventMove(GALE_MOVE_KEY_F8, _isDown); return true;
case KeyEvent.KEYCODE_F9: m_galeNative.keyboardEventMove(GALE_MOVE_KEY_F9, _isDown); return true;
case KeyEvent.KEYCODE_F10: m_galeNative.keyboardEventMove(GALE_MOVE_KEY_F10, _isDown); return true;
case KeyEvent.KEYCODE_F11: m_galeNative.keyboardEventMove(GALE_MOVE_KEY_F11, _isDown); return true;
case KeyEvent.KEYCODE_F12: m_galeNative.keyboardEventMove(GALE_MOVE_KEY_F12, _isDown); return true;
case KeyEvent.KEYCODE_CAPS_LOCK: m_galeNative.keyboardEventMove(GALE_MOVE_KEY_CAP_LOCK, _isDown); return true;
case KeyEvent.KEYCODE_SHIFT_LEFT: m_galeNative.keyboardEventMove(GALE_MOVE_KEY_SHIFT_LEFT, _isDown); return true;
case KeyEvent.KEYCODE_SHIFT_RIGHT: m_galeNative.keyboardEventMove(GALE_MOVE_KEY_SHIFT_RIGHT, _isDown); return true;
case KeyEvent.KEYCODE_CTRL_LEFT: m_galeNative.keyboardEventMove(GALE_MOVE_KEY_CTRL_LEFT, _isDown); return true;
case KeyEvent.KEYCODE_CTRL_RIGHT: m_galeNative.keyboardEventMove(GALE_MOVE_KEY_CTRL_RIGHT, _isDown); return true;
case KeyEvent.KEYCODE_META_LEFT: m_galeNative.keyboardEventMove(GALE_MOVE_KEY_META_LEFT, _isDown); return true;
case KeyEvent.KEYCODE_META_RIGHT: m_galeNative.keyboardEventMove(GALE_MOVE_KEY_META_RIGHT, _isDown); return true;
case KeyEvent.KEYCODE_ALT_LEFT: m_galeNative.keyboardEventMove(GALE_MOVE_KEY_ALT, _isDown); return true;
case KeyEvent.KEYCODE_ALT_RIGHT: m_galeNative.keyboardEventMove(GALE_MOVE_KEY_ALT_GR, _isDown); return true;
case KeyEvent.KEYCODE_NUM_LOCK: m_galeNative.keyboardEventMove(GALE_MOVE_KEY_NUM_LOCK, _isDown); return true;
default:
break;
}
// key wrapping :
if ( (actionDone == KeyEvent.ACTION_DOWN)
|| (actionDone == KeyEvent.ACTION_MULTIPLE)
|| (actionDone == KeyEvent.ACTION_UP)) {
// convert the key in UniChar to prevent errors ...
int uchar = _event.getUnicodeChar();
// pb on the return methode ... in java it is like windows ...
if (uchar == '\r') {
uchar = '\n';
}
// send it to gale ...
m_galeNative.keyboardEventKey(uchar, _isDown);
return true;
}
return false;
}
public boolean onKeyDown(int _keyCode, KeyEvent _event) {
return keyboardEvent(_keyCode, _event, true);
}
public boolean onKeyUp(int _keyCode, KeyEvent _event) {
return keyboardEvent(_keyCode, _event, false);
}
}

View File

@ -0,0 +1,203 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
package org.gale;
import android.app.ActivityManager;
import android.content.pm.ApplicationInfo;
import android.content.pm.ConfigurationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.Context;
import android.opengl.GLSurfaceView;
import android.opengl.GLSurfaceView.Renderer;
import android.os.Build;
import android.service.wallpaper.WallpaperService;
import android.util.Log;
import android.view.SurfaceHolder;
import org.gale.GaleSurfaceViewGL;
import android.view.MotionEvent;
import android.net.Uri;
import android.content.Intent;
import android.content.ActivityNotFoundException;
import org.gale.Gale;
public abstract class GaleWallpaper extends WallpaperService implements GaleCallback, GaleConstants
{
private GLEngine mGLView;
private Gale m_galeNative;
protected void initApkPath(String _org, String _vendor, String _project) {
StringBuilder sb = new StringBuilder();
sb.append(_org).append(".");
sb.append(_vendor).append(".");
sb.append(_project);
String apkFilePath = null;
ApplicationInfo appInfo = null;
PackageManager packMgmr = getPackageManager();
try {
appInfo = packMgmr.getApplicationInfo(sb.toString(), 0);
} catch (NameNotFoundException e) {
e.printStackTrace();
throw new RuntimeException("Unable to locate assets, aborting...");
}
apkFilePath = appInfo.sourceDir;
m_galeNative.paramSetArchiveDir(0, apkFilePath);
}
@Override public Engine onCreateEngine() {
// set the java evironement in the C sources :
m_galeNative = new Gale(this, GALE_APPL_TYPE_WALLPAPER);
// Load the application directory
m_galeNative.paramSetArchiveDir(1, getFilesDir().toString());
m_galeNative.paramSetArchiveDir(2, getCacheDir().toString());
// to enable extarnal storage: add in the manifest the restriction needed ...
//packageManager.checkPermission("android.permission.READ_SMS", myPackage) == PERMISSION_GRANTED;
//Gale.paramSetArchiveDir(3, getExternalCacheDir().toString());
//! DisplayMetrics metrics = new DisplayMetrics();
//! getWindowManager().getDefaultDisplay().getMetrics(metrics);
//! m_galeNative.displayPropertyMetrics(metrics.xdpi, metrics.ydpi);
// call C init ...
m_galeNative.onCreate();
// create bsurface system
mGLView = new GLEngine(m_galeNative);
return mGLView;
}
public class GLEngine extends Engine {
private Gale m_galeNative;
public GLEngine(Gale _galeInstance) {
m_galeNative = _galeInstance;
}
class WallpaperGLSurfaceView extends GaleSurfaceViewGL {
private static final String TAG = "WallpaperGLSurfaceView";
WallpaperGLSurfaceView(Context _context, Gale _galeInstance) {
super(_context, _galeInstance);
Log.d(TAG, "WallpaperGLSurfaceView(" + _context + ")");
}
@Override public SurfaceHolder getHolder() {
Log.d(TAG, "getHolder(): returning " + getSurfaceHolder());
return getSurfaceHolder();
}
public void onDestroy() {
Log.d(TAG, "onDestroy()");
super.onDetachedFromWindow();
}
}
private static final String TAG = "GLEngine";
private WallpaperGLSurfaceView glSurfaceView;
@Override public void onCreate(SurfaceHolder _surfaceHolder) {
Log.d(TAG, "onCreate(" + _surfaceHolder + ")");
super.onCreate(_surfaceHolder);
glSurfaceView = new WallpaperGLSurfaceView(GaleWallpaper.this, m_galeNative);
// Check if the system supports OpenGL ES 2.0.
final ActivityManager activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
final ConfigurationInfo configurationInfo = activityManager.getDeviceConfigurationInfo();
final boolean supportsEs2 = configurationInfo.reqGlEsVersion >= 0x20000;
if (supportsEs2 == false) {
Log.d("LiveWallpaper", "does not support board with only open GL ES 1");
return;
}
// Request an OpenGL ES 2.0 compatible context.
//setEGLContextClientVersion(2);
// On Honeycomb+ devices, this improves the performance when
// leaving and resuming the live wallpaper.
//setPreserveEGLContextOnPause(true);
}
@Override public void onTouchEvent(MotionEvent _event) {
glSurfaceView.onTouchEvent(_event);
}
@Override public void onVisibilityChanged(boolean _visible) {
Log.d(TAG, "onVisibilityChanged(" + _visible + ")");
super.onVisibilityChanged(_visible);
if (_visible == true) {
glSurfaceView.onResume();
// call C
m_galeNative.onResume();
} else {
glSurfaceView.onPause();
// call C
m_galeNative.onPause();
}
}
@Override public void onDestroy() {
Log.d(TAG, "onDestroy()");
super.onDestroy();
// call C
m_galeNative.onStop();
m_galeNative.onDestroy();
glSurfaceView.onDestroy();
}
protected void setPreserveEGLContextOnPause(boolean _preserve) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
Log.d(TAG, "setPreserveEGLContextOnPause(" + _preserve + ")");
glSurfaceView.setPreserveEGLContextOnPause(_preserve);
}
}
protected void setEGLContextClientVersion(int _version) {
Log.d(TAG, "setEGLContextClientVersion(" + _version + ")");
glSurfaceView.setEGLContextClientVersion(_version);
}
}
public void keyboardUpdate(boolean _show) {
// never display keyboard on wallpaer...
Log.d("GaleCallback", "KEABOARD UPDATE is not implemented ...");
}
public void eventNotifier(String[] _args) {
// just for the test ...
Log.d("GaleCallback", "EVENT NOTIFIER is not implemented ...");
}
public void orientationUpdate(int _screenMode) {
Log.d("GaleCallback", "SET ORIENTATION is not implemented ...");
}
public void titleSet(String _value) {
// no title in the wallpaper ...
Log.d("GaleCallback", "SET TITLE is not implemented ...");
}
public void openURI(String _uri) {
try {
Intent myIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(_uri));
startActivity(myIntent);
} catch (ActivityNotFoundException e) {
Log.e("GaleActivity", "Can not request an URL");
}
}
public void stop() {
Log.d("GaleCallback", "STOP is not implemented ...");
}
}

0
gale/Application.cpp Normal file
View File

49
gale/Application.h Normal file
View File

@ -0,0 +1,49 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#ifndef __GALE_CONTEXT_APPLICATION_H__
#define __GALE_CONTEXT_APPLICATION_H__
namespace gale {
class Context;
class Application : public std::enable_shared_from_this<gale::Application> {
public:
Application() {};
virtual ~Application() {};
public:
/**
* @brief Initialize the Application
* @param[in] _context Current gale context
* @param[in] _initId Initialzation ID (start at 0 and will increment wile returning true)
* @return true if the init is fisnished
* @return false need more inits
*/
virtual bool init(gale::Context& _context, size_t _initId) = 0;
/**
* @brief The application is ended ==> call this function before ended
*/
virtual void unInit(gale::Context& _context) = 0;
public:
/**
* @brief Event on an input (finger, mouse, stilet)
* @param[in] _event Event properties
*/
virtual void onEventInput(const ewol::event::Input& _event);
/**
* @brief Entry event.
* represent the physical event :
* - Keyboard (key event and move event)
* - Accelerometer
* - Joystick
* @param[in] _event Event properties
*/
virtual void onEventEntry(const ewol::event::Entry& _event);
};
}
#endif

316
gale/Dimension.cpp Normal file
View File

@ -0,0 +1,316 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#include <gale/Dimension.h>
#include <gale/debug.h>
#undef __class__
#define __class__ "Dimension"
// TODO : set this in a super class acced in a statin fuction...
// ratio in milimeter :
static bool isInit = false;
static vec2 ratio(9999999,888888);
static vec2 invRatio(1,1);
static gale::Dimension windowsSize(vec2(9999999,888888), gale::Dimension::Pixel);
static const float inchToMillimeter = 1.0f/25.4f;
static const float footToMillimeter = 1.0f/304.8f;
static const float meterToMillimeter = 1.0f/1000.0f;
static const float centimeterToMillimeter = 1.0f/10.0f;
static const float kilometerToMillimeter = 1.0f/1000000.0f;
static const float millimeterToInch = 25.4f;
static const float millimeterToFoot = 304.8f;
static const float millimeterToMeter =1000.0f;
static const float millimeterToCentimeter = 10.0f;
static const float millimeterToKilometer = 1000000.0f;
void gale::Dimension::init() {
if (true == isInit) {
return;
}
gale::Dimension conversion(vec2(72,72), gale::Dimension::Inch);
ratio = conversion.getMillimeter();
invRatio.setValue(1.0f/ratio.x(),1.0f/ratio.y());
windowsSize.set(vec2(200,200), gale::Dimension::Pixel);
isInit = true;
}
void gale::Dimension::unInit() {
isInit = false;
ratio.setValue(9999999,888888);
invRatio.setValue(1.0f/ratio.x(),1.0f/ratio.y());
windowsSize.set(vec2(9999999,88888), gale::Dimension::Pixel);
}
void gale::Dimension::setPixelRatio(const vec2& _ratio, enum gale::Dimension::distance _type) {
gale::Dimension::init();
GALE_INFO("Set a new screen ratio for the screen : ratio=" << _ratio << " type=" << _type);
gale::Dimension conversion(_ratio, _type);
GALE_INFO(" == > " << conversion);
ratio = conversion.getMillimeter();
invRatio.setValue(1.0f/ratio.x(),1.0f/ratio.y());
GALE_INFO("Set a new screen ratio for the screen : ratioMm=" << ratio);
}
void gale::Dimension::setPixelWindowsSize(const vec2& _size) {
windowsSize = _size;
GALE_VERBOSE("Set a new Windows property size " << windowsSize << "px");
}
vec2 gale::Dimension::getWindowsSize(enum gale::Dimension::distance _type) {
return windowsSize.get(_type);
}
float gale::Dimension::getWindowsDiag(enum gale::Dimension::distance _type) {
vec2 size = gale::Dimension::getWindowsSize(_type);
return size.length();
}
gale::Dimension::Dimension() :
m_data(0,0),
m_type(gale::Dimension::Pixel) {
// notinh to do ...
}
gale::Dimension::Dimension(const vec2& _size, enum gale::Dimension::distance _type) :
m_data(0,0),
m_type(gale::Dimension::Pixel) {
set(_size, _type);
}
void gale::Dimension::set(std::string _config) {
m_data.setValue(0,0);
m_type = gale::Dimension::Pixel;
enum distance type = gale::Dimension::Pixel;
if (etk::end_with(_config, "%", false) == true) {
type = gale::Dimension::Pourcent;
_config.erase(_config.size()-1, 1);
} else if (etk::end_with(_config, "px",false) == true) {
type = gale::Dimension::Pixel;
_config.erase(_config.size()-2, 2);
} else if (etk::end_with(_config, "ft",false) == true) {
type = gale::Dimension::foot;
_config.erase(_config.size()-2, 2);
} else if (etk::end_with(_config, "in",false) == true) {
type = gale::Dimension::Inch;
_config.erase(_config.size()-2, 2);
} else if (etk::end_with(_config, "km",false) == true) {
type = gale::Dimension::Kilometer;
_config.erase(_config.size()-2, 2);
} else if (etk::end_with(_config, "mm",false) == true) {
type = gale::Dimension::Millimeter;
_config.erase(_config.size()-2, 2);
} else if (etk::end_with(_config, "cm",false) == true) {
type = gale::Dimension::Centimeter;
_config.erase(_config.size()-2, 2);
} else if (etk::end_with(_config, "m",false) == true) {
type = gale::Dimension::Meter;
_config.erase(_config.size()-1, 1);
} else {
GALE_CRITICAL("Can not parse dimention : \"" << _config << "\"");
return;
}
vec2 tmp = _config;
set(tmp, type);
GALE_VERBOSE(" config dimention : \"" << _config << "\" == > " << *this );
}
gale::Dimension::~Dimension() {
// nothing to do ...
}
gale::Dimension::operator std::string() const {
std::string str;
str = get(getType());
switch(getType()) {
case gale::Dimension::Pourcent:
str += "%";
break;
case gale::Dimension::Pixel:
str += "px";
break;
case gale::Dimension::Meter:
str += "m";
break;
case gale::Dimension::Centimeter:
str += "cm";
break;
case gale::Dimension::Millimeter:
str += "mm";
break;
case gale::Dimension::Kilometer:
str += "km";
break;
case gale::Dimension::Inch:
str += "in";
break;
case gale::Dimension::foot:
str += "ft";
break;
}
return str;
}
vec2 gale::Dimension::get(enum gale::Dimension::distance _type) const {
switch(_type) {
case gale::Dimension::Pourcent:
return getPourcent();
case gale::Dimension::Pixel:
return getPixel();
case gale::Dimension::Meter:
return getMeter();
case gale::Dimension::Centimeter:
return getCentimeter();
case gale::Dimension::Millimeter:
return getMillimeter();
case gale::Dimension::Kilometer:
return getKilometer();
case gale::Dimension::Inch:
return getInch();
case gale::Dimension::foot:
return getFoot();
}
return vec2(0,0);
}
void gale::Dimension::set(const vec2& _size, enum gale::Dimension::distance _type) {
// set min max on input to limit error :
vec2 size(std::avg(0.0f,_size.x(),9999999.0f),
std::avg(0.0f,_size.y(),9999999.0f));
switch(_type) {
case gale::Dimension::Pourcent: {
vec2 size2(std::avg(0.0f,_size.x(),100.0f),
std::avg(0.0f,_size.y(),100.0f));
m_data = vec2(size2.x()*0.01f, size2.y()*0.01f);
//GALE_VERBOSE("Set % : " << size2 << " == > " << m_data);
break;
}
case gale::Dimension::Pixel:
m_data = size;
break;
case gale::Dimension::Meter:
m_data = vec2(size.x()*meterToMillimeter*ratio.x(), size.y()*meterToMillimeter*ratio.y());
break;
case gale::Dimension::Centimeter:
m_data = vec2(size.x()*centimeterToMillimeter*ratio.x(), size.y()*centimeterToMillimeter*ratio.y());
break;
case gale::Dimension::Millimeter:
m_data = vec2(size.x()*ratio.x(), size.y()*ratio.y());
break;
case gale::Dimension::Kilometer:
m_data = vec2(size.x()*kilometerToMillimeter*ratio.x(), size.y()*kilometerToMillimeter*ratio.y());
break;
case gale::Dimension::Inch:
m_data = vec2(size.x()*inchToMillimeter*ratio.x(), size.y()*inchToMillimeter*ratio.y());
break;
case gale::Dimension::foot:
m_data = vec2(size.x()*footToMillimeter*ratio.x(), size.y()*footToMillimeter*ratio.y());
break;
}
m_type = _type;
}
vec2 gale::Dimension::getPixel() const {
if (m_type!=gale::Dimension::Pourcent) {
return m_data;
} else {
vec2 windDim = windowsSize.getPixel();
vec2 res = vec2(windDim.x()*m_data.x(), windDim.y()*m_data.y());
//GALE_DEBUG("Get % : " << m_data << " / " << windDim << " == > " << res);
return res;
}
}
vec2 gale::Dimension::getPourcent() const {
if (m_type!=gale::Dimension::Pourcent) {
vec2 windDim = windowsSize.getPixel();
//GALE_DEBUG(" windows dimention : " /*<< windowsSize*/ << " == > " << windDim << "px"); // ==> infinite loop ...
//printf(" windows dimention : %f,%f", windDim.x(),windDim.y());
//printf(" data : %f,%f", m_data.x(),m_data.y());
return vec2((m_data.x()/windDim.x())*100.0f, (m_data.y()/windDim.y())*100.0f);
}
return vec2(m_data.x()*100.0f, m_data.y()*100.0f);;
}
vec2 gale::Dimension::getMeter() const {
return gale::Dimension::getMillimeter()*millimeterToMeter;
}
vec2 gale::Dimension::getCentimeter() const {
return gale::Dimension::getMillimeter()*millimeterToCentimeter;
}
vec2 gale::Dimension::getMillimeter() const {
return gale::Dimension::getPixel()*invRatio;
}
vec2 gale::Dimension::getKilometer() const {
return gale::Dimension::getMillimeter()*millimeterToKilometer;
}
vec2 gale::Dimension::getInch() const {
return gale::Dimension::getMillimeter()*millimeterToInch;
}
vec2 gale::Dimension::getFoot() const {
return gale::Dimension::getMillimeter()*millimeterToFoot;
}
std::ostream& gale::operator <<(std::ostream& _os, enum gale::Dimension::distance _obj) {
switch(_obj) {
case gale::Dimension::Pourcent:
_os << "%";
break;
case gale::Dimension::Pixel:
_os << "px";
break;
case gale::Dimension::Meter:
_os << "m";
break;
case gale::Dimension::Centimeter:
_os << "cm";
break;
case gale::Dimension::Millimeter:
_os << "mm";
break;
case gale::Dimension::Kilometer:
_os << "km";
break;
case gale::Dimension::Inch:
_os << "in";
break;
case gale::Dimension::foot:
_os << "ft";
break;
}
return _os;
}
std::ostream& gale::operator <<(std::ostream& _os, const gale::Dimension& _obj) {
_os << _obj.get(_obj.getType()) << _obj.getType();
return _os;
}
namespace etk {
template<> std::string to_string<gale::Dimension>(const gale::Dimension& _obj) {
return _obj;
}
template<> std::u32string to_u32string<gale::Dimension>(const gale::Dimension& _obj) {
return etk::to_u32string(etk::to_string(_obj));
}
template<> bool from_string<gale::Dimension>(gale::Dimension& _variableRet, const std::string& _value) {
_variableRet = gale::Dimension(_value);
return true;
}
template<> bool from_string<gale::Dimension>(gale::Dimension& _variableRet, const std::u32string& _value) {
return from_string(_variableRet, etk::to_string(_value));
}
};

212
gale/Dimension.h Normal file
View File

@ -0,0 +1,212 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#ifndef __GALE_DIMENSION_H__
#define __GALE_DIMENSION_H__
#include <etk/types.h>
#include <etk/types.h>
#include <etk/math/Vector2D.h>
namespace gale {
/**
* @brief in the dimention class we store the data as the more usefull unit (pixel)
* but one case need to be dynamic the %, then when requested in % the register the % value
*/
class Dimension {
public:
enum distance {
Pourcent=0,
Pixel,
Meter,
Centimeter,
Millimeter,
Kilometer,
Inch,
foot,
};
private:
vec2 m_data;
enum distance m_type;
public:
/**
* @brief Constructor (default :0,0 mode pixel)
*/
Dimension();
/**
* @brief Constructor
* @param[in] _size Requested dimention
* @param[in] _type Unit of the Dimention
*/
Dimension(const vec2& _size, enum gale::Dimension::distance _type=gale::Dimension::Pixel);
/**
* @brief Constructor
* @param[in] _config dimension configuration.
*/
Dimension(const std::string& _config) :
m_data(0,0),
m_type(gale::Dimension::Pixel) {
set(_config);
};
/**
* @brief Constructor
* @param[in] _config dimension configuration.
*/
Dimension(const char* _config) :
m_data(0,0),
m_type(gale::Dimension::Pixel) {
set(_config);
};
/**
* @brief Destructor
*/
~Dimension();
/**
* @brief string cast :
*/
operator std::string() const;
/**
* @brief get the current dimention in requested type
* @param[in] _type Type of unit requested.
* @return dimention requested.
*/
vec2 get(enum distance _type) const;
/**
* @brief set the current dimention in requested type
* @param[in] _size Dimention to set
* @param[in] _type Type of unit requested.
*/
void set(const vec2& _size, enum distance _type);
private:
/**
* @brief set the current dimention in requested type
* @param[in] _config dimension configuration.
*/
void set(std::string _config);
public:
/**
* @brief get the current dimention in pixel
* @return dimention in Pixel
*/
vec2 getPixel() const;
/**
* @brief get the current dimention in Pourcent
* @return dimention in Pourcent
*/
vec2 getPourcent() const;
/**
* @brief get the current dimention in Meter
* @return dimention in Meter
*/
vec2 getMeter() const;
/**
* @brief get the current dimention in Centimeter
* @return dimention in Centimeter
*/
vec2 getCentimeter() const;
/**
* @brief get the current dimention in Millimeter
* @return dimention in Millimeter
*/
vec2 getMillimeter() const;
/**
* @brief get the current dimention in Kilometer
* @return dimention in Kilometer
*/
vec2 getKilometer() const;
/**
* @brief get the current dimention in Inch
* @return dimention in Inch
*/
vec2 getInch() const;
/**
* @brief get the current dimention in Foot
* @return dimention in Foot
*/
vec2 getFoot() const;
/*****************************************************
* = assigment
*****************************************************/
const Dimension& operator= (const Dimension& _obj ) {
if (this!=&_obj) {
m_data = _obj.m_data;
m_type = _obj.m_type;
}
return *this;
}
/*****************************************************
* == operator
*****************************************************/
bool operator == (const Dimension& _obj) const {
if( m_data == _obj.m_data
&& m_type == _obj.m_type) {
return true;
}
return false;
}
/*****************************************************
* != operator
*****************************************************/
bool operator!= (const Dimension& _obj) const {
if( m_data != _obj.m_data
|| m_type != _obj.m_type) {
return true;
}
return false;
}
/**
* @breif get the dimension type
* @return the type
*/
enum distance getType() const {
return m_type;
};
public : // Global static access :
/**
* @brief basic init
*/
static void init();
/**
* @brief basic un-init
*/
static void unInit();
/**
* @brief set the Milimeter ratio for calculation
* @param[in] Ratio Milimeter ration for the screen calculation interpolation
* @param[in] type Unit type requested.
* @note: same as @ref setPixelPerInch (internal manage convertion)
*/
static void setPixelRatio(const vec2& _ratio, enum gale::Dimension::distance _type);
/**
* @brief set the current Windows size
* @param[in] size size of the current windows in pixel.
*/
static void setPixelWindowsSize(const vec2& _size);
/**
* @brief get the Windows size in the request unit
* @param[in] type Unit type requested.
* @return the requested size
*/
static vec2 getWindowsSize(enum gale::Dimension::distance _type);
/**
* @brief get the Windows diagonal size in the request unit
* @param[in] type Unit type requested.
* @return the requested size
*/
static float getWindowsDiag(enum gale::Dimension::distance _type);
};
std::ostream& operator <<(std::ostream& _os, enum gale::Dimension::distance _obj);
std::ostream& operator <<(std::ostream& _os, const gale::Dimension& _obj);
};
#endif

299
gale/Windows.cpp Normal file
View File

@ -0,0 +1,299 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#include <etk/types.h>
#include <etk/types.h>
#include <gale/gale.h>
#include <gale/openGL/openGL.h>
#include <gale/context/Context.h>
#include <gale/widget/Widget.h>
#include <gale/widget/Windows.h>
#include <gale/widget/Manager.h>
#include <gale/widget/meta/StdPopUp.h>
#undef __class__
#define __class__ "Windows"
//list of local events :
extern const char * const galeEventWindowsHideKeyboard = "gale Windows hideKeyboard";
gale::widget::Windows::Windows() :
m_colorProperty(nullptr),
m_colorBg(-1) {
addResourceType("gale::widget::Windows");
setCanHaveFocus(true);
m_colorProperty = gale::resource::ColorFile::create("THEME:COLOR:Windows.json");
if (m_colorProperty != nullptr) {
m_colorBg = m_colorProperty->request("background");
}
//KeyboardShow(KEYBOARD_MODE_CODE);
}
gale::widget::Windows::~Windows() {
m_subWidget.reset();
m_popUpWidgetList.clear();
}
void gale::widget::Windows::calculateSize(const vec2& _availlable) {
GALE_DEBUG(" _availlable : " << _availlable);
m_size = _availlable;
if (m_subWidget != nullptr) {
m_subWidget->calculateMinMaxSize();
// TODO : Check if min size is possible ...
// TODO : Herited from MinSize .. and expand ???
m_subWidget->calculateSize(m_size);
}
for (auto &it : m_popUpWidgetList) {
if(it != nullptr) {
it->calculateMinMaxSize();
it->calculateSize(m_size);
}
}
}
std::shared_ptr<gale::Widget> gale::widget::Windows::getWidgetAtPos(const vec2& _pos) {
// calculate relative position
vec2 relativePos = relativePosition(_pos);
// event go directly on the pop-up
if (0 < m_popUpWidgetList.size()) {
return m_popUpWidgetList.back()->getWidgetAtPos(_pos);
// otherwise in the normal windows
} else if (nullptr != m_subWidget) {
return m_subWidget->getWidgetAtPos(_pos);
}
// otherwise the event go to this widget ...
return std::dynamic_pointer_cast<gale::Widget>(shared_from_this());
}
void gale::widget::Windows::sysDraw() {
//GALE_DEBUG("Drow on (" << m_size.x << "," << m_size.y << ")");
// set the size of the open GL system
glViewport(0,0,m_size.x(),m_size.y());
gale::openGL::disable(gale::openGL::FLAG_DITHER);
//gale::openGL::disable(gale::openGL::FLAG_BLEND);
gale::openGL::disable(gale::openGL::FLAG_STENCIL_TEST);
gale::openGL::disable(gale::openGL::FLAG_ALPHA_TEST);
gale::openGL::disable(gale::openGL::FLAG_FOG);
#if (!defined(__TARGET_OS__Android) && !defined(__TARGET_OS__IOs))
glPixelZoom(1.0,1.0);
#endif
gale::openGL::disable(gale::openGL::FLAG_TEXTURE_2D);
gale::openGL::disable(gale::openGL::FLAG_DEPTH_TEST);
gale::openGL::enable(gale::openGL::FLAG_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// clear the matrix system :
mat4 newOne;
gale::openGL::setBasicMatrix(newOne);
gale::DrawProperty displayProp;
displayProp.m_windowsSize = m_size;
displayProp.m_origin.setValue(0,0);
displayProp.m_size = m_size;
systemDraw(displayProp);
gale::openGL::disable(gale::openGL::FLAG_BLEND);
return;
}
void gale::widget::Windows::onRegenerateDisplay() {
if (nullptr != m_subWidget) {
m_subWidget->onRegenerateDisplay();
}
for (auto &it : m_popUpWidgetList) {
if (it != nullptr) {
it->onRegenerateDisplay();
}
}
}
//#define TEST_PERFO_WINDOWS
void gale::widget::Windows::systemDraw(const gale::DrawProperty& _displayProp) {
gale::Widget::systemDraw(_displayProp);
#ifdef TEST_PERFO_WINDOWS
int64_t ___startTime0 = gale::getTime();
#endif
// clear the screen with transparency ...
etk::Color<float> colorBg(0.5, 0.5, 0.5, 0.5);
if (m_colorProperty != nullptr) {
colorBg = m_colorProperty->get(m_colorBg);
}
glClearColor(colorBg.r(), colorBg.g(), colorBg.b(), colorBg.a());
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
#ifdef TEST_PERFO_WINDOWS
float ___localTime0 = (float)(gale::getTime() - ___startTime0) / 1000.0f;
GALE_ERROR(" Windows000 : " << ___localTime0 << "ms ");
int64_t ___startTime1 = gale::getTime();
#endif
//GALE_WARNING(" WINDOWS draw on " << m_currentDrawId);
// first display the windows on the display
if (nullptr != m_subWidget) {
m_subWidget->systemDraw(_displayProp);
//GALE_DEBUG("Draw Windows");
}
#ifdef TEST_PERFO_WINDOWS
float ___localTime1 = (float)(gale::getTime() - ___startTime1) / 1000.0f;
GALE_ERROR(" Windows111 : " << ___localTime1 << "ms ");
int64_t ___startTime2 = gale::getTime();
#endif
// second display the pop-up
for (auto &it : m_popUpWidgetList) {
if (it != nullptr) {
it->systemDraw(_displayProp);
//GALE_DEBUG("Draw Pop-up");
}
}
#ifdef TEST_PERFO_WINDOWS
float ___localTime2 = (float)(gale::getTime() - ___startTime2) / 1000.0f;
GALE_ERROR(" Windows222 : " << ___localTime2 << "ms ");
#endif
}
void gale::widget::Windows::setSubWidget(std::shared_ptr<gale::Widget> _widget) {
if (m_subWidget != nullptr) {
GALE_INFO("Remove current main windows Widget...");
m_subWidget->removeParent();
m_subWidget.reset();
}
if (_widget != nullptr) {
m_subWidget = _widget;
m_subWidget->setParent(shared_from_this());
}
// Regenerate the size calculation :
calculateSize(m_size);
}
void gale::widget::Windows::popUpWidgetPush(std::shared_ptr<gale::Widget> _widget) {
if (_widget == nullptr) {
// nothing to do an error appear :
GALE_ERROR("can not set widget pop-up (null pointer)");
return;
}
m_popUpWidgetList.push_back(_widget);
_widget->setParent(shared_from_this());
// force the focus on the basic widget ==> this remove many time the virual keyboard area
_widget->keepFocus();
// Regenerate the size calculation :
calculateSize(m_size);
// TODO : it is dangerous to access directly to the system ...
getContext().resetIOEvent();
}
void gale::widget::Windows::popUpWidgetPop() {
if (m_popUpWidgetList.size() == 0) {
return;
}
m_popUpWidgetList.pop_back();
}
void gale::widget::Windows::setBackgroundColor(const etk::Color<float>& _color) {
if (m_backgroundColor != _color) {
m_backgroundColor = _color;
markToRedraw();
}
}
void gale::widget::Windows::setTitle(const std::string& _title) {
// TODO : remove this ...
std::string title = _title;
getContext().setTitle(title);
}
void gale::widget::Windows::createPopUpMessage(enum popUpMessageType _type, const std::string& _message) {
std::shared_ptr<gale::widget::StdPopUp> tmpPopUp = widget::StdPopUp::create();
if (tmpPopUp == nullptr) {
GALE_ERROR("Can not create a simple pop-up");
return;
}
switch(_type) {
case messageTypeInfo:
tmpPopUp->setTitle("<bold>Info</bold>");
break;
case messageTypeWarning:
tmpPopUp->setTitle("<bold><font color=\"orange\">Warning</font></bold>");
break;
case messageTypeError:
tmpPopUp->setTitle("<bold><font color=\"red\">Error</font></bold>");
break;
case messageTypeCritical:
tmpPopUp->setTitle("<bold><font colorBg=\"red\">Critical</font></bold>");
break;
}
tmpPopUp->setComment(_message);
tmpPopUp->addButton("close", true);
tmpPopUp->setRemoveOnExternClick(true);
popUpWidgetPush(tmpPopUp);
}
void gale::widget::Windows::requestDestroyFromChild(const std::shared_ptr<Object>& _child) {
auto it = m_popUpWidgetList.begin();
while (it != m_popUpWidgetList.end()) {
if (*it == _child) {
if (*it == nullptr) {
m_popUpWidgetList.erase(it);
it = m_popUpWidgetList.begin();
continue;
}
(*it)->removeParent();
(*it).reset();
m_popUpWidgetList.erase(it);
it = m_popUpWidgetList.begin();
markToRedraw();
continue;
}
++it;
}
if (m_subWidget == _child) {
if (m_subWidget == nullptr) {
return;
}
m_subWidget->removeParent();
m_subWidget.reset();
markToRedraw();
}
}
std::shared_ptr<gale::Object> gale::widget::Windows::getSubObjectNamed(const std::string& _objectName) {
std::shared_ptr<gale::Object> tmpObject = gale::Widget::getSubObjectNamed(_objectName);
if (tmpObject != nullptr) {
return tmpObject;
}
// check direct subwidget
if (m_subWidget != nullptr) {
tmpObject = m_subWidget->getSubObjectNamed(_objectName);
if (tmpObject != nullptr) {
return tmpObject;
}
}
// get all subwidget "pop-up"
for (auto &it : m_popUpWidgetList) {
if (it != nullptr) {
tmpObject = it->getSubObjectNamed(_objectName);
if (tmpObject != nullptr) {
return tmpObject;
}
}
}
// not find ...
return nullptr;
}
void gale::widget::Windows::sysOnKill() {
if (onKill() == true) {
getContext().stop();
}
}

138
gale/Windows.h Normal file
View File

@ -0,0 +1,138 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#ifndef __GALE_WINDOWS_H__
#define __GALE_WINDOWS_H__
#include <etk/types.h>
#include <gale/debug.h>
#include <gale/widget/Widget.h>
#include <etk/Color.h>
#include <gale/resource/ColorFile.h>
#include <list>
namespace gale {
namespace widget {
/**
* @brief Windows basic interface
*/
class Windows : public gale::Widget {
protected:
std::shared_ptr<gale::resource::ColorFile> m_colorProperty; //!< theme color property
int32_t m_colorBg; //!< Default background color of the windows
protected:
Windows();
void init() {
gale::Widget::init();
};
public:
virtual ~Windows();
// internal event at gale system :
public:
void sysDraw();
void sysOnShow() {};
void sysOnHide() {};
void sysOnKill();
public:
virtual void onShow() { };
virtual void onHide() { };
virtual bool onKill() {
// TODO : Check this in speck for android ...
return false;
};
virtual void onReduce() { };
virtual void onStateBackground() {};
virtual void onStateForeground() {};
virtual void onStateSuspend() {};
virtual void onStateResume() {};
private:
std::shared_ptr<gale::Widget> m_subWidget;
std::list<std::shared_ptr<gale::Widget>> m_popUpWidgetList;
public:
void setSubWidget(std::shared_ptr<gale::Widget> _widget);
void popUpWidgetPush(std::shared_ptr<gale::Widget> _widget);
void popUpWidgetPop();
size_t popUpCount() {
return m_popUpWidgetList.size();
}
private:
etk::Color<float> m_backgroundColor; //!< reset color of the Main windows
public:
/**
* @brief get the background color.
* @return A reference on the color
*/
const etk::Color<float>& getBackgroundColor() {
return m_backgroundColor;
};
/**
* @brief set the background color.
* @param[IN] the new requested color.
*/
void setBackgroundColor(const etk::Color<float>& _color);
protected: // Derived function
virtual void systemDraw(const gale::DrawProperty& _displayProp);
public: // Derived function
virtual void onRegenerateDisplay();
virtual void calculateSize(const vec2& _availlable);
virtual std::shared_ptr<gale::Widget> getWidgetAtPos(const vec2& _pos);
virtual void requestDestroyFromChild(const std::shared_ptr<Object>& _child);
virtual std::shared_ptr<gale::Object> getSubObjectNamed(const std::string& _objectName);
void setTitle(const std::string& _title);
public:
enum popUpMessageType {
messageTypeInfo, //!< information message pop-up
messageTypeWarning, //!< warning message pop-up
messageTypeError, //!< Error message pop-up
messageTypeCritical //!< Critical message pop-up
};
/**
* @brief Create a simple pop-up message on the screen for application error.
* @param[in] _type Type of the error.
* @param[in] _message message to display (decorated text)
*/
virtual void createPopUpMessage(enum popUpMessageType _type, const std::string& _message);
/**
* @brief Create a simple information message
* @param[in] _message message to display (decorated text)
*/
void displayInfoMessage(const std::string& _message) {
createPopUpMessage(messageTypeInfo, _message);
}
/**
* @brief Create a simple warning message
* @param[in] _message message to display (decorated text)
*/
void displayWarningMessage(const std::string& _message) {
createPopUpMessage(messageTypeWarning, _message);
}
/**
* @brief Create a simple error message
* @param[in] _message message to display (decorated text)
*/
void displayErrorMessage(const std::string& _message) {
createPopUpMessage(messageTypeError, _message);
}
/**
* @brief Create a simple critical message
* @param[in] _message message to display (decorated text)
*/
void displayCriticalMessage(const std::string& _message) {
createPopUpMessage(messageTypeCritical, _message);
}
virtual bool onEventHardwareInput(const gale::key::keyboardSystem& _event, bool _down) {
return false;
};
};
};
};
#endif

View File

@ -0,0 +1,904 @@
/**
* @author Edouard DUPIN, Kevin BILLONNEAU
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#include <jni.h>
#include <sys/time.h>
#include <time.h>
#include <stdint.h>
#include <pthread.h>
#include <mutex>
#include <gale/debug.h>
#include <gale/context/Context.h>
#include <gale/Dimension.h>
/* include auto generated file */
#include <org_gale_GaleConstants.h>
#include <jvm-basics/jvm-basics.h>
int64_t gale::getTime() {
struct timeval now;
gettimeofday(&now, nullptr);
//GALE_VERBOSE("current time : " << now.tv_sec << "s " << now.tv_usec << "us");
return (int64_t)((int64_t)now.tv_sec*(int64_t)1000000 + (int64_t)now.tv_usec);
}
// jni doc : /usr/lib/jvm/java-1.6.0-openjdk/include
std::mutex g_interfaceMutex;
class AndroidContext : public gale::Context {
public:
enum application {
appl_unknow,
appl_application,
appl_wallpaper
};
private:
enum application m_javaApplicationType;
// get a resources from the java environement :
JNIEnv* m_JavaVirtualMachinePointer; //!< the JVM
jclass m_javaClassGale; //!< main activity class (android ...)
jclass m_javaClassGaleCallback;
jobject m_javaObjectGaleCallback;
jmethodID m_javaMethodGaleCallbackStop; //!< Stop function identifier
jmethodID m_javaMethodGaleCallbackEventNotifier; //!< basic methode to call ...
jmethodID m_javaMethodGaleCallbackKeyboardUpdate; //!< basic methode to call ...
jmethodID m_javaMethodGaleCallbackOrientationUpdate;
jmethodID m_javaMethodGaleActivitySetTitle;
jmethodID m_javaMethodGaleActivityOpenURI;
jmethodID m_javaMethodGaleActivitySetClipBoardString;
jmethodID m_javaMethodGaleActivityGetClipBoardString;
jclass m_javaDefaultClassString; //!< default string class
int32_t m_currentHeight;
gale::key::Special m_guiKeyBoardSpecialKeyMode;//!< special key of the android system :
bool m_clipBoardOwnerStd;
private:
bool safeInitMethodID(jmethodID& _mid, jclass& _cls, const char* _name, const char* _sign) {
_mid = m_JavaVirtualMachinePointer->GetMethodID(_cls, _name, _sign);
if(_mid == nullptr) {
GALE_ERROR("C->java : Can't find the method " << _name);
/* remove access on the virtual machine : */
m_JavaVirtualMachinePointer = nullptr;
return false;
}
return true;
}
public:
AndroidContext(gale::context::Application* _application, JNIEnv* _env, jclass _classBase, jobject _objCallback, enum application _typeAPPL) :
gale::Context(_application),
m_javaApplicationType(_typeAPPL),
m_JavaVirtualMachinePointer(nullptr),
m_javaClassGale(0),
m_javaClassGaleCallback(0),
m_javaObjectGaleCallback(0),
m_javaMethodGaleCallbackStop(0),
m_javaMethodGaleCallbackEventNotifier(0),
m_javaMethodGaleCallbackKeyboardUpdate(0),
m_javaMethodGaleCallbackOrientationUpdate(0),
m_javaMethodGaleActivitySetTitle(0),
m_javaMethodGaleActivityOpenURI(0),
m_javaMethodGaleActivitySetClipBoardString(0),
m_javaMethodGaleActivityGetClipBoardString(0),
m_javaDefaultClassString(0),
m_currentHeight(0),
m_clipBoardOwnerStd(false) {
GALE_DEBUG("*******************************************");
if (m_javaApplicationType == appl_application) {
GALE_DEBUG("** set JVM Pointer (application) **");
} else {
GALE_DEBUG("** set JVM Pointer (LiveWallpaper) **");
}
GALE_DEBUG("*******************************************");
m_JavaVirtualMachinePointer = _env;
// get default needed all time elements :
if (nullptr != m_JavaVirtualMachinePointer) {
GALE_DEBUG("C->java : try load org/gale/Gale class");
m_javaClassGale = m_JavaVirtualMachinePointer->FindClass("org/gale/Gale" );
if (m_javaClassGale == 0) {
GALE_ERROR("C->java : Can't find org/gale/Gale class");
// remove access on the virtual machine :
m_JavaVirtualMachinePointer = nullptr;
return;
}
/* The object field extends Activity and implement GaleCallback */
m_javaClassGaleCallback = m_JavaVirtualMachinePointer->GetObjectClass(_objCallback);
if(m_javaClassGaleCallback == nullptr) {
GALE_ERROR("C->java : Can't find org/gale/GaleCallback class");
// remove access on the virtual machine :
m_JavaVirtualMachinePointer = nullptr;
return;
}
bool functionCallbackIsMissing = false;
bool ret= false;
ret = safeInitMethodID(m_javaMethodGaleActivitySetTitle,
m_javaClassGaleCallback,
"titleSet",
"(Ljava/lang/String;)V");
if (ret == false) {
jvm_basics::checkExceptionJavaVM(_env);
GALE_ERROR("system can not start without function : titleSet");
functionCallbackIsMissing = true;
}
ret = safeInitMethodID(m_javaMethodGaleActivityOpenURI,
m_javaClassGaleCallback,
"openURI",
"(Ljava/lang/String;)V");
if (ret == false) {
jvm_basics::checkExceptionJavaVM(_env);
GALE_ERROR("system can not start without function : openURI");
functionCallbackIsMissing = true;
}
ret = safeInitMethodID(m_javaMethodGaleCallbackStop,
m_javaClassGaleCallback,
"stop",
"()V");
if (ret == false) {
jvm_basics::checkExceptionJavaVM(_env);
GALE_ERROR("system can not start without function : stop");
functionCallbackIsMissing = true;
}
ret = safeInitMethodID(m_javaMethodGaleCallbackEventNotifier,
m_javaClassGaleCallback,
"eventNotifier",
"([Ljava/lang/String;)V");
if (ret == false) {
jvm_basics::checkExceptionJavaVM(_env);
GALE_ERROR("system can not start without function : eventNotifier");
functionCallbackIsMissing = true;
}
ret = safeInitMethodID(m_javaMethodGaleCallbackKeyboardUpdate,
m_javaClassGaleCallback,
"keyboardUpdate",
"(Z)V");
if (ret == false) {
jvm_basics::checkExceptionJavaVM(_env);
GALE_ERROR("system can not start without function : keyboardUpdate");
functionCallbackIsMissing = true;
}
ret = safeInitMethodID(m_javaMethodGaleCallbackOrientationUpdate,
m_javaClassGaleCallback,
"orientationUpdate",
"(I)V");
if (ret == false) {
jvm_basics::checkExceptionJavaVM(_env);
GALE_ERROR("system can not start without function : orientationUpdate");
functionCallbackIsMissing = true;
}
ret = safeInitMethodID(m_javaMethodGaleActivitySetClipBoardString,
m_javaClassGaleCallback,
"setClipBoardString",
"(Ljava/lang/String;)V");
if (ret == false) {
jvm_basics::checkExceptionJavaVM(_env);
GALE_ERROR("system can not start without function : setClipBoardString");
functionCallbackIsMissing = true;
}
ret = safeInitMethodID(m_javaMethodGaleActivityGetClipBoardString,
m_javaClassGaleCallback,
"getClipBoardString",
"()Ljava/lang/String;");
if (ret == false) {
jvm_basics::checkExceptionJavaVM(_env);
GALE_ERROR("system can not start without function : getClipBoardString");
functionCallbackIsMissing = true;
}
m_javaObjectGaleCallback = _env->NewGlobalRef(_objCallback);
//javaObjectGaleCallbackAndActivity = objCallback;
if (m_javaObjectGaleCallback == nullptr) {
functionCallbackIsMissing = true;
}
m_javaDefaultClassString = m_JavaVirtualMachinePointer->FindClass("java/lang/String" );
if (m_javaDefaultClassString == 0) {
GALE_ERROR("C->java : Can't find java/lang/String" );
// remove access on the virtual machine :
m_JavaVirtualMachinePointer = nullptr;
functionCallbackIsMissing = true;
}
if (functionCallbackIsMissing == true) {
GALE_CRITICAL(" mission one function ==> system can not work withut it...");
}
}
}
~AndroidContext() {
// TODO ...
}
void unInit(JNIEnv* _env) {
_env->DeleteGlobalRef(m_javaObjectGaleCallback);
m_javaObjectGaleCallback = nullptr;
}
int32_t run() {
// might never be called !!!
return -1;
}
void stop() {
GALE_DEBUG("C->java : send message to the java : STOP REQUESTED");
int status;
if(!java_attach_current_thread(&status)) {
return;
}
//Call java ...
m_JavaVirtualMachinePointer->CallVoidMethod(m_javaObjectGaleCallback, m_javaMethodGaleCallbackStop);
// manage execption :
jvm_basics::checkExceptionJavaVM(m_JavaVirtualMachinePointer);
java_detach_current_thread(status);
}
void clipBoardGet(enum gale::context::clipBoard::clipboardListe _clipboardID) {
// this is to force the local system to think we have the buffer
// TODO : remove this 2 line when code will be writen
m_clipBoardOwnerStd = true;
switch (_clipboardID) {
case gale::context::clipBoard::clipboardSelection:
// NOTE : Windows does not support the middle button the we do it internaly
// just transmit an event , we have the data in the system
OS_ClipBoardArrive(_clipboardID);
break;
case gale::context::clipBoard::clipboardStd:
if (false == m_clipBoardOwnerStd) {
// generate a request TO the OS
// TODO : Send the message to the OS "We disire to receive the copy buffer ...
} else {
// just transmit an event , we have the data in the system
OS_ClipBoardArrive(_clipboardID);
}
break;
default:
GALE_ERROR("Request an unknow ClipBoard ...");
break;
}
}
void clipBoardSet(enum gale::context::clipBoard::clipboardListe _clipboardID) {
switch (_clipboardID) {
case gale::context::clipBoard::clipboardSelection:
// NOTE : nothing to do : Windows deas ot supported Middle button
break;
case gale::context::clipBoard::clipboardStd:
// Request the clipBoard :
GALE_DEBUG("C->java : set clipboard");
if (m_javaApplicationType == appl_application) {
int status;
if(!java_attach_current_thread(&status)) {
return;
}
//Call java ...
jstring data = m_JavaVirtualMachinePointer->NewStringUTF(gale::context::clipBoard::get(_clipboardID).c_str());
m_JavaVirtualMachinePointer->CallVoidMethod(m_javaObjectGaleCallback, m_javaMethodGaleActivityGetClipBoardString, data);
m_JavaVirtualMachinePointer->DeleteLocalRef(data);
// manage execption :
jvm_basics::checkExceptionJavaVM(m_JavaVirtualMachinePointer);
java_detach_current_thread(status);
} else {
GALE_ERROR("C->java : can not set clipboard");
}
break;
default:
GALE_ERROR("Request an unknow ClipBoard ...");
break;
}
}
private:
bool java_attach_current_thread(int *_rstatus) {
GALE_DEBUG("C->java : call java");
if (jvm_basics::getJavaVM() == nullptr) {
GALE_ERROR("C->java : JVM not initialised");
m_JavaVirtualMachinePointer = nullptr;
return false;
}
*_rstatus = jvm_basics::getJavaVM()->GetEnv((void **) &m_JavaVirtualMachinePointer, JNI_VERSION_1_6);
if (*_rstatus == JNI_EDETACHED) {
JavaVMAttachArgs lJavaVMAttachArgs;
lJavaVMAttachArgs.version = JNI_VERSION_1_6;
lJavaVMAttachArgs.name = "GaleNativeThread";
lJavaVMAttachArgs.group = nullptr;
int status = jvm_basics::getJavaVM()->AttachCurrentThread(&m_JavaVirtualMachinePointer, &lJavaVMAttachArgs);
jvm_basics::checkExceptionJavaVM(m_JavaVirtualMachinePointer);
if (status != JNI_OK) {
GALE_ERROR("C->java : AttachCurrentThread failed : " << status);
m_JavaVirtualMachinePointer = nullptr;
return false;
}
}
return true;
}
void java_detach_current_thread(int _status) {
if(_status == JNI_EDETACHED) {
jvm_basics::getJavaVM()->DetachCurrentThread();
m_JavaVirtualMachinePointer = nullptr;
}
}
void sendJavaKeyboardUpdate(jboolean _showIt) {
int status;
if(!java_attach_current_thread(&status)) {
return;
}
//Call java ...
m_JavaVirtualMachinePointer->CallVoidMethod(m_javaObjectGaleCallback, m_javaMethodGaleCallbackKeyboardUpdate, _showIt);
// manage execption :
jvm_basics::checkExceptionJavaVM(m_JavaVirtualMachinePointer);
java_detach_current_thread(status);
}
void keyboardShow() {
sendJavaKeyboardUpdate(JNI_TRUE);
};
void keyboardHide() {
sendJavaKeyboardUpdate(JNI_FALSE);
};
// mode 0 : auto; 1 landscape, 2 portrait
void forceOrientation(enum gale::orientation _orientation) {
int status;
if(!java_attach_current_thread(&status)) {
return;
}
jint param = (jint)_orientation;
//Call java ...
m_JavaVirtualMachinePointer->CallVoidMethod(m_javaObjectGaleCallback, m_javaMethodGaleCallbackOrientationUpdate, param);
// manage execption :
jvm_basics::checkExceptionJavaVM(m_JavaVirtualMachinePointer);
java_detach_current_thread(status);
}
void setTitle(const std::string& _title) {
GALE_DEBUG("C->java : send message to the java : \"" << _title << "\"");
if (m_javaApplicationType == appl_application) {
int status;
if(!java_attach_current_thread(&status)) {
return;
}
//Call java ...
jstring title = m_JavaVirtualMachinePointer->NewStringUTF(_title.c_str());
m_JavaVirtualMachinePointer->CallVoidMethod(m_javaObjectGaleCallback, m_javaMethodGaleActivitySetTitle, title);
m_JavaVirtualMachinePointer->DeleteLocalRef(title);
// manage execption :
jvm_basics::checkExceptionJavaVM(m_JavaVirtualMachinePointer);
java_detach_current_thread(status);
} else {
GALE_ERROR("C->java : can not set title on appliation that is not real application");
}
}
void openURL(const std::string& _url) {
GALE_DEBUG("C->java : send message to the java : open URL'" << _url << "'");
int status;
if(!java_attach_current_thread(&status)) {
return;
}
//Call java ...
jstring url = m_JavaVirtualMachinePointer->NewStringUTF(_url.c_str());
m_JavaVirtualMachinePointer->CallVoidMethod(m_javaObjectGaleCallback, m_javaMethodGaleActivityOpenURI, url);
m_JavaVirtualMachinePointer->DeleteLocalRef(url);
// manage execption :
jvm_basics::checkExceptionJavaVM(m_JavaVirtualMachinePointer);
java_detach_current_thread(status);
}
void sendSystemMessage(const char* _dataString) {
GALE_DEBUG("C->java : send message to the java : \"" << _dataString << "\"");
int status;
if(!java_attach_current_thread(&status)) {
return;
}
GALE_DEBUG("C->java : 222");
if (nullptr == _dataString) {
GALE_ERROR("C->java : No data to send ...");
return;
}
GALE_DEBUG("C->java : 333");
// create the string to the java
jstring jstr = m_JavaVirtualMachinePointer->NewStringUTF(_dataString);
if (jstr == 0) {
GALE_ERROR("C->java : Out of memory" );
return;
}
GALE_DEBUG("C->java : 444");
// create argument list
jobjectArray args = m_JavaVirtualMachinePointer->NewObjectArray(1, m_javaDefaultClassString, jstr);
if (args == 0) {
GALE_ERROR("C->java : Out of memory" );
return;
}
GALE_DEBUG("C->java : 555");
//Call java ...
m_JavaVirtualMachinePointer->CallVoidMethod(m_javaObjectGaleCallback, m_javaMethodGaleCallbackEventNotifier, args);
GALE_DEBUG("C->java : 666");
jvm_basics::checkExceptionJavaVM(m_JavaVirtualMachinePointer);
java_detach_current_thread(status);
}
public:
void OS_SetInputMotion(int _pointerID, const vec2& _pos) {
gale::Context::OS_SetInputMotion(_pointerID, vec2(_pos.x(),m_currentHeight-_pos.y()) );
}
void OS_SetInputState(int _pointerID, bool _isDown, const vec2& _pos) {
gale::Context::OS_SetInputState(_pointerID, _isDown, vec2(_pos.x(),m_currentHeight-_pos.y()) );
}
void OS_SetMouseMotion(int _pointerID, const vec2& _pos) {
gale::Context::OS_SetMouseMotion(_pointerID, vec2(_pos.x(),m_currentHeight-_pos.y()) );
}
void OS_SetMouseState(int _pointerID, bool _isDown, const vec2& _pos) {
gale::Context::OS_SetMouseState(_pointerID, _isDown, vec2(_pos.x(),m_currentHeight-_pos.y()) );
}
void ANDROID_SetKeyboard(char32_t _myChar, bool _isDown, bool _isARepeateKey=false) {
OS_SetKeyboard(m_guiKeyBoardSpecialKeyMode, _myChar, _isDown, _isARepeateKey);
}
bool ANDROID_systemKeyboradEvent(enum gale::key::keyboardSystem _key, bool _down) {
return systemKeyboradEvent(_key, _down);
}
void ANDROID_SetKeyboardMove(int _move, bool _isDown, bool _isARepeateKey=false) {
// direct wrapping :
enum gale::key::keyboard move = (enum gale::key::keyboard)_move;
m_guiKeyBoardSpecialKeyMode.update(move, _isDown);
OS_SetKeyboardMove(m_guiKeyBoardSpecialKeyMode, move, _isDown, _isARepeateKey);
}
void OS_Resize(const vec2& _size) {
m_currentHeight = _size.y();
gale::Context::OS_Resize(_size);
}
};
static std::vector<AndroidContext*> s_listInstance;
gale::context::Application* s_applicationInit = NULL;
extern "C" {
/* Call to initialize the graphics state */
void Java_org_gale_Gale_EWparamSetArchiveDir(JNIEnv* _env,
jclass _cls,
jint _id,
jint _mode,
jstring _myString) {
std::unique_lock<std::mutex> lock(g_interfaceMutex);
if( _id >= (int32_t)s_listInstance.size()
|| _id<0
|| nullptr == s_listInstance[_id] ) {
GALE_ERROR("Call C With an incorrect instance _id=" << (int32_t)_id);
// TODO : generate error in java to stop the current instance
return;
}
//GALE_CRITICAL(" call with ID : " << _id);
// direct setting of the date in the string system ...
jboolean isCopy;
const char* str = _env->GetStringUTFChars(_myString, &isCopy);
s_listInstance[_id]->setArchiveDir(_mode, str);
if (isCopy == JNI_TRUE) {
// from here str is reset ...
_env->ReleaseStringUTFChars(_myString, str);
str = nullptr;
}
}
// declare main application instance like an application:
int main(int argc, char**argv);
jint Java_org_gale_Gale_EWsetJavaVirtualMachineStart(JNIEnv* _env,
jclass _classBase,
jobject _objCallback,
int _typeApplication) {
std::unique_lock<std::mutex> lock(g_interfaceMutex);
GALE_DEBUG("*******************************************");
GALE_DEBUG("** Creating GALE context **");
GALE_DEBUG("*******************************************");
AndroidContext* tmpContext = nullptr;
s_applicationInit = NULL;
gale::context::Application* localApplication = NULL;
// call the basic init of all application (that call us ...)
main(0,NULL);
localApplication = s_applicationInit;
s_applicationInit = NULL;
if (org_gale_GaleConstants_GALE_APPL_TYPE_ACTIVITY == _typeApplication) {
tmpContext = new AndroidContext(localApplication, _env, _classBase, _objCallback, AndroidContext::appl_application);
} else if (org_gale_GaleConstants_GALE_APPL_TYPE_WALLPAPER == _typeApplication) {
tmpContext = new AndroidContext(localApplication, _env, _classBase, _objCallback, AndroidContext::appl_wallpaper);
} else {
GALE_CRITICAL(" try to create an instance with no apply type: " << _typeApplication);
return -1;
}
if (nullptr == tmpContext) {
GALE_ERROR("Can not allocate the main context instance _id=" << (s_listInstance.size()-1));
return -1;
}
// for future case : all time this ...
s_listInstance.push_back(tmpContext);
int32_t newID = s_listInstance.size()-1;
return newID;
}
void Java_org_gale_Gale_EWsetJavaVirtualMachineStop(JNIEnv* _env, jclass _cls, jint _id) {
std::unique_lock<std::mutex> lock(g_interfaceMutex);
GALE_DEBUG("*******************************************");
GALE_DEBUG("** remove JVM Pointer **");
GALE_DEBUG("*******************************************");
if( _id >= (int32_t)s_listInstance.size()
|| _id<0) {
GALE_ERROR("Call C With an incorrect instance _id=" << (int32_t)_id);
return;
}
if (nullptr == s_listInstance[_id]) {
GALE_ERROR("the requested instance _id=" << (int32_t)_id << " is already removed ...");
return;
}
s_listInstance[_id]->unInit(_env);
delete(s_listInstance[_id]);
s_listInstance[_id]=nullptr;
}
void Java_org_gale_Gale_EWtouchEvent(JNIEnv* _env, jobject _thiz, jint _id) {
std::unique_lock<std::mutex> lock(g_interfaceMutex);
GALE_DEBUG(" == > Touch Event");
if( _id >= (int32_t)s_listInstance.size()
|| _id<0
|| nullptr == s_listInstance[_id] ) {
GALE_ERROR("Call C With an incorrect instance _id=" << (int32_t)_id);
// TODO : generate error in java to stop the current instance
return;
}
jvm_basics::checkExceptionJavaVM(_env);
}
void Java_org_gale_Gale_EWonCreate(JNIEnv* _env, jobject _thiz, jint _id) {
std::unique_lock<std::mutex> lock(g_interfaceMutex);
GALE_DEBUG("*******************************************");
GALE_DEBUG("** Activity on Create **");
GALE_DEBUG("*******************************************");
if( _id >= (int32_t)s_listInstance.size()
|| _id<0
|| nullptr == s_listInstance[_id] ) {
GALE_ERROR("Call C With an incorrect instance _id=" << (int32_t)_id);
// TODO : generate error in java to stop the current instance
return;
}
//s_listInstance[_id]->init();
}
void Java_org_gale_Gale_EWonStart(JNIEnv* _env, jobject _thiz, jint _id) {
std::unique_lock<std::mutex> lock(g_interfaceMutex);
GALE_DEBUG("*******************************************");
GALE_DEBUG("** Activity on Start **");
GALE_DEBUG("*******************************************");
if( _id >= (int32_t)s_listInstance.size()
|| _id<0
|| nullptr == s_listInstance[_id] ) {
GALE_ERROR("Call C With an incorrect instance _id=" << (int32_t)_id);
// TODO : generate error in java to stop the current instance
return;
}
//SendSystemMessage(" testmessages ... ");
}
void Java_org_gale_Gale_EWonReStart(JNIEnv* _env, jobject _thiz, jint _id) {
std::unique_lock<std::mutex> lock(g_interfaceMutex);
GALE_DEBUG("*******************************************");
GALE_DEBUG("** Activity on Re-Start **");
GALE_DEBUG("*******************************************");
if( _id >= (int32_t)s_listInstance.size()
|| _id<0
|| nullptr == s_listInstance[_id] ) {
GALE_ERROR("Call C With an incorrect instance _id=" << (int32_t)_id);
// TODO : generate error in java to stop the current instance
return;
}
}
void Java_org_gale_Gale_EWonResume(JNIEnv* _env, jobject _thiz, jint _id) {
std::unique_lock<std::mutex> lock(g_interfaceMutex);
GALE_DEBUG("*******************************************");
GALE_DEBUG("** Activity on resume **");
GALE_DEBUG("*******************************************");
if( _id >= (int32_t)s_listInstance.size()
|| _id<0
|| nullptr == s_listInstance[_id] ) {
GALE_ERROR("Call C With an incorrect instance _id=" << (int32_t)_id);
// TODO : generate error in java to stop the current instance
return;
}
s_listInstance[_id]->OS_Resume();
}
void Java_org_gale_Gale_EWonPause(JNIEnv* _env, jobject _thiz, jint _id) {
std::unique_lock<std::mutex> lock(g_interfaceMutex);
GALE_DEBUG("*******************************************");
GALE_DEBUG("** Activity on pause **");
GALE_DEBUG("*******************************************");
if( _id >= (int32_t)s_listInstance.size()
|| _id<0
|| nullptr == s_listInstance[_id] ) {
GALE_ERROR("Call C With an incorrect instance _id=" << (int32_t)_id);
// TODO : generate error in java to stop the current instance
return;
}
// All the openGl has been destroyed ...
s_listInstance[_id]->getResourcesManager().contextHasBeenDestroyed();
s_listInstance[_id]->OS_Suspend();
}
void Java_org_gale_Gale_EWonStop(JNIEnv* _env, jobject _thiz, jint _id) {
std::unique_lock<std::mutex> lock(g_interfaceMutex);
GALE_DEBUG("*******************************************");
GALE_DEBUG("** Activity on Stop **");
GALE_DEBUG("*******************************************");
if( _id >= (int32_t)s_listInstance.size()
|| _id<0
|| nullptr == s_listInstance[_id] ) {
GALE_ERROR("Call C With an incorrect instance _id=" << (int32_t)_id);
// TODO : generate error in java to stop the current instance
return;
}
s_listInstance[_id]->OS_Stop();
}
void Java_org_gale_Gale_EWonDestroy(JNIEnv* _env, jobject _thiz, jint _id) {
std::unique_lock<std::mutex> lock(g_interfaceMutex);
GALE_DEBUG("*******************************************");
GALE_DEBUG("** Activity on Destroy **");
GALE_DEBUG("*******************************************");
if( _id >= (int32_t)s_listInstance.size()
|| _id<0
|| nullptr == s_listInstance[_id] ) {
GALE_ERROR("Call C With an incorrect instance _id=" << (int32_t)_id);
// TODO : generate error in java to stop the current instance
return;
}
//s_listInstance[_id]->UnInit();
}
/* **********************************************************************************************
* ** IO section :
* ********************************************************************************************** */
void Java_org_gale_Gale_EWinputEventMotion(JNIEnv* _env,
jobject _thiz,
jint _id,
jint _pointerID,
jfloat _x,
jfloat _y) {
std::unique_lock<std::mutex> lock(g_interfaceMutex);
if( _id >= (int32_t)s_listInstance.size()
|| _id<0
|| nullptr == s_listInstance[_id] ) {
GALE_ERROR("Call C With an incorrect instance _id=" << (int32_t)_id);
// TODO : generate error in java to stop the current instance
return;
}
s_listInstance[_id]->OS_SetInputMotion(_pointerID+1, vec2(_x,_y));
}
void Java_org_gale_Gale_EWinputEventState(JNIEnv* _env,
jobject _thiz,
jint _id,
jint _pointerID,
jboolean _isUp,
jfloat _x,
jfloat _y) {
std::unique_lock<std::mutex> lock(g_interfaceMutex);
if( _id >= (int32_t)s_listInstance.size()
|| _id<0
|| nullptr == s_listInstance[_id] ) {
GALE_ERROR("Call C With an incorrect instance _id=" << (int32_t)_id);
// TODO : generate error in java to stop the current instance
return;
}
s_listInstance[_id]->OS_SetInputState(_pointerID+1, _isUp, vec2(_x,_y));
}
void Java_org_gale_Gale_EWmouseEventMotion(JNIEnv* _env,
jobject _thiz,
jint _id,
jint _pointerID,
jfloat _x,
jfloat _y) {
std::unique_lock<std::mutex> lock(g_interfaceMutex);
if( _id >= (int32_t)s_listInstance.size()
|| _id<0
|| nullptr == s_listInstance[_id] ) {
GALE_ERROR("Call C With an incorrect instance _id=" << (int32_t)_id);
// TODO : generate error in java to stop the current instance
return;
}
s_listInstance[_id]->OS_SetMouseMotion(_pointerID+1, vec2(_x,_y));
}
void Java_org_gale_Gale_EWmouseEventState(JNIEnv* _env,
jobject _thiz,
jint _id,
jint _pointerID,
jboolean _isUp,
jfloat _x,
jfloat _y) {
std::unique_lock<std::mutex> lock(g_interfaceMutex);
if( _id >= (int32_t)s_listInstance.size()
|| _id<0
|| nullptr == s_listInstance[_id] ) {
GALE_ERROR("Call C With an incorrect instance _id=" << (int32_t)_id);
// TODO : generate error in java to stop the current instance
return;
}
s_listInstance[_id]->OS_SetMouseState(_pointerID+1, _isUp, vec2(_x,_y));
}
void Java_org_gale_Gale_EWunknowEvent(JNIEnv* _env,
jobject _thiz,
jint _id,
jint _pointerID) {
std::unique_lock<std::mutex> lock(g_interfaceMutex);
if( _id >= (int32_t)s_listInstance.size()
|| _id<0
|| nullptr == s_listInstance[_id] ) {
GALE_ERROR("Call C With an incorrect instance _id=" << (int32_t)_id);
// TODO : generate error in java to stop the current instance
return;
}
GALE_DEBUG("Unknown IO event : " << _pointerID << " ???");
}
void Java_org_gale_Gale_EWkeyboardEventMove(JNIEnv* _env,
jobject _thiz,
jint _id,
jint _type,
jboolean _isdown) {
std::unique_lock<std::mutex> lock(g_interfaceMutex);
if( _id >= (int32_t)s_listInstance.size()
|| _id<0
|| nullptr == s_listInstance[_id] ) {
GALE_ERROR("Call C With an incorrect instance _id=" << (int32_t)_id);
// TODO : generate error in java to stop the current instance
return;
}
GALE_DEBUG("IO keyboard Move event : \"" << _type << "\" is down=" << _isdown);
s_listInstance[_id]->ANDROID_SetKeyboardMove(_type, _isdown);
}
void Java_org_gale_Gale_EWkeyboardEventKey(JNIEnv* _env,
jobject _thiz,
jint _id,
jint _uniChar,
jboolean _isdown) {
std::unique_lock<std::mutex> lock(g_interfaceMutex);
if( _id >= (int32_t)s_listInstance.size()
|| _id<0
|| nullptr == s_listInstance[_id] ) {
GALE_ERROR("Call C With an incorrect instance _id=" << (int32_t)_id);
// TODO : generate error in java to stop the current instance
return;
}
GALE_DEBUG("IO keyboard Key event : \"" << _uniChar << "\" is down=" << _isdown);
s_listInstance[_id]->ANDROID_SetKeyboard(_uniChar, _isdown);
}
void Java_org_gale_Gale_EWdisplayPropertyMetrics(JNIEnv* _env,
jobject _thiz,
jint _id,
jfloat _ratioX,
jfloat _ratioY) {
std::unique_lock<std::mutex> lock(g_interfaceMutex);
if( _id >= (int32_t)s_listInstance.size()
|| _id<0
|| nullptr == s_listInstance[_id] ) {
GALE_ERROR("Call C With an incorrect instance _id=" << (int32_t)_id);
// TODO : generate error in java to stop the current instance
return;
}
// set the internal system ratio properties ...
gale::Dimension::setPixelRatio(vec2(_ratioX,_ratioY), gale::Dimension::Inch);
}
// TODO : set a return true or false if we want to grep this event ...
bool Java_org_gale_Gale_EWkeyboardEventKeySystem(JNIEnv* _env,
jobject _thiz,
jint _id,
jint _keyVal,
jboolean _isdown) {
std::unique_lock<std::mutex> lock(g_interfaceMutex);
if( _id >= (int32_t)s_listInstance.size()
|| _id<0
|| nullptr == s_listInstance[_id] ) {
GALE_ERROR("Call C With an incorrect instance _id=" << (int32_t)_id);
// TODO : generate error in java to stop the current instance
return false;
}
switch (_keyVal) {
case org_gale_GaleConstants_GALE_SYSTEM_KEY_VOLUME_UP:
GALE_VERBOSE("IO keyboard Key system \"VOLUME_UP\" is down=" << _isdown);
return s_listInstance[_id]->ANDROID_systemKeyboradEvent(gale::key::keyboardSystemVolumeUp, _isdown);
case org_gale_GaleConstants_GALE_SYSTEM_KEY_VOLUME_DOWN:
GALE_DEBUG("IO keyboard Key system \"VOLUME_DOWN\" is down=" << _isdown);
return s_listInstance[_id]->ANDROID_systemKeyboradEvent(gale::key::keyboardSystemVolumeDown, _isdown);
case org_gale_GaleConstants_GALE_SYSTEM_KEY_MENU:
GALE_DEBUG("IO keyboard Key system \"MENU\" is down=" << _isdown);
return s_listInstance[_id]->ANDROID_systemKeyboradEvent(gale::key::keyboardSystemMenu, _isdown);
case org_gale_GaleConstants_GALE_SYSTEM_KEY_CAMERA:
GALE_DEBUG("IO keyboard Key system \"CAMERA\" is down=" << _isdown);
return s_listInstance[_id]->ANDROID_systemKeyboradEvent(gale::key::keyboardSystemCamera, _isdown);
case org_gale_GaleConstants_GALE_SYSTEM_KEY_HOME:
GALE_DEBUG("IO keyboard Key system \"HOME\" is down=" << _isdown);
return s_listInstance[_id]->ANDROID_systemKeyboradEvent(gale::key::keyboardSystemHome, _isdown);
case org_gale_GaleConstants_GALE_SYSTEM_KEY_POWER:
GALE_DEBUG("IO keyboard Key system \"POWER\" is down=" << _isdown);
return s_listInstance[_id]->ANDROID_systemKeyboradEvent(gale::key::keyboardSystemPower, _isdown);
case org_gale_GaleConstants_GALE_SYSTEM_KEY_BACK:
GALE_DEBUG("IO keyboard Key system \"BACK\" is down=" << _isdown);
return s_listInstance[_id]->ANDROID_systemKeyboradEvent(gale::key::keyboardSystemBack, _isdown);
default:
GALE_ERROR("IO keyboard Key system event : \"" << _keyVal << "\" is down=" << _isdown);
break;
}
return false;
}
/* **********************************************************************************************
* ** Renderer section :
* ********************************************************************************************** */
void Java_org_gale_Gale_EWrenderInit(JNIEnv* _env,
jobject _thiz,
jint _id) {
std::unique_lock<std::mutex> lock(g_interfaceMutex);
if( _id >= (int32_t)s_listInstance.size()
|| _id<0
|| nullptr == s_listInstance[_id] ) {
GALE_ERROR("Call C With an incorrect instance _id=" << (int32_t)_id);
// TODO : generate error in java to stop the current instance
return;
}
}
void Java_org_gale_Gale_EWrenderResize(JNIEnv* _env,
jobject _thiz,
jint _id,
jint _w,
jint _h) {
std::unique_lock<std::mutex> lock(g_interfaceMutex);
if( _id >= (int32_t)s_listInstance.size()
|| _id<0
|| nullptr == s_listInstance[_id] ) {
GALE_ERROR("Call C With an incorrect instance _id=" << (int32_t)_id);
// TODO : generate error in java to stop the current instance
return;
}
s_listInstance[_id]->OS_Resize(vec2(_w, _h));
}
// TODO : Return true or false to not redraw when the under draw has not be done (processing gain of time)
void Java_org_gale_Gale_EWrenderDraw(JNIEnv* _env,
jobject _thiz,
jint _id) {
std::unique_lock<std::mutex> lock(g_interfaceMutex);
if( _id >= (int32_t)s_listInstance.size()
|| _id<0
|| nullptr == s_listInstance[_id] ) {
GALE_ERROR("Call C With an incorrect instance _id=" << (int32_t)_id);
// TODO : generate error in java to stop the current instance
return;
}
s_listInstance[_id]->OS_Draw(true);
}
};
int gale::run(gale::context::Application* _application, int _argc, const char *_argv[]) {
s_applicationInit = _application;
return 0;
}

802
gale/context/Context.cpp Normal file
View File

@ -0,0 +1,802 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#include <unistd.h>
#include <etk/types.h>
#include <etk/etk.h>
#include <etk/tool.h>
#include <etk/os/FSNode.h>
#include <etk/thread/tools.h>
#include <mutex>
#include <date/date.h>
#include <gale/gale.h>
#include <gale/Dimension.h>
#include <gale/debug.h>
#include <gale/renderer/openGL/openGL.h>
#include <gale/context/Context.h>
#include <gale/resource/Manager.h>
/**
* @brief get the main gale mutex (event or periodic call mutex).
* @note due ti the fact that the system can be called for multiple instance, for naw we just limit the acces to one process at a time.
* @return the main inteface Mutex
*/
static std::mutex& mutexInterface() {
static std::mutex s_interfaceMutex;
return s_interfaceMutex;
}
static gale::Context* l_curentInterface=nullptr;
gale::Context& gale::getContext() {
#if DEBUG_LEVEL > 2
if(nullptr == l_curentInterface){
GALE_CRITICAL("[CRITICAL] try acces at an empty interface");
}
#endif
return *l_curentInterface;
}
void gale::Context::setInitImage(const std::string& _fileName) {
//m_initDisplayImageName = _fileName;
}
/**
* @brief set the curent interface.
* @note this lock the main mutex
*/
void gale::Context::lockContext() {
mutexInterface().lock();
l_curentInterface = this;
}
/**
* @brief set the curent interface at nullptr.
* @note this un-lock the main mutex
*/
void gale::Context::unLockContext() {
l_curentInterface = nullptr;
mutexInterface().unlock();
}
namespace gale {
class eSystemMessage {
public:
enum theadMessage {
msgNone,
msgInit,
msgRecalculateSize,
msgResize,
msgHide,
msgShow,
msgInputMotion,
msgInputState,
msgKeyboardKey,
msgKeyboardMove,
msgClipboardArrive
};
public :
// specify the message type
enum theadMessage TypeMessage;
// can not set a union ...
enum gale::context::clipBoard::clipboardListe clipboardID;
// InputId
enum gale::key::type inputType;
int32_t inputId;
// generic dimentions
vec2 dimention;
// keyboard events :
bool repeateKey; //!< special flag for the repeating key on the PC interface
bool stateIsDown;
char32_t keyboardChar;
enum gale::key::keyboard keyboardMove;
gale::key::Special keyboardSpecial;
eSystemMessage() :
TypeMessage(msgNone),
clipboardID(gale::context::clipBoard::clipboardStd),
inputType(gale::key::typeUnknow),
inputId(-1),
dimention(0,0),
repeateKey(false),
stateIsDown(false),
keyboardChar(0),
keyboardMove(gale::key::keyboardUnknow)
{
}
};
};
void gale::Context::inputEventTransfertWidget(std::shared_ptr<gale::Widget> _source,
std::shared_ptr<gale::Widget> _destination) {
m_input.transfertEvent(_source, _destination);
}
void gale::Context::inputEventGrabPointer(std::shared_ptr<gale::Widget> _widget) {
m_input.grabPointer(_widget);
}
void gale::Context::inputEventUnGrabPointer() {
m_input.unGrabPointer();
}
void gale::Context::processEvents() {
int32_t nbEvent = 0;
//GALE_DEBUG(" ******** Event");
gale::eSystemMessage* data = nullptr;
while (m_msgSystem.count()>0) {
nbEvent++;
if (data != nullptr) {
delete(data);
data = nullptr;
}
m_msgSystem.wait(data);
//GALE_DEBUG("EVENT");
switch (data->TypeMessage) {
case eSystemMessage::msgInit:
// this is due to the openGL context
/*bool returnVal = */
m_application->init(*this, m_initStepId);
m_initStepId++;
break;
case eSystemMessage::msgRecalculateSize:
forceRedrawAll();
break;
case eSystemMessage::msgResize:
//GALE_DEBUG("Receive MSG : THREAD_RESIZE");
m_windowsSize = data->dimention;
gale::Dimension::setPixelWindowsSize(m_windowsSize);
forceRedrawAll();
break;
case eSystemMessage::msgInputMotion:
//GALE_DEBUG("Receive MSG : THREAD_INPUT_MOTION");
m_input.motion(data->inputType, data->inputId, data->dimention);
break;
case eSystemMessage::msgInputState:
//GALE_DEBUG("Receive MSG : THREAD_INPUT_STATE");
m_input.state(data->inputType, data->inputId, data->stateIsDown, data->dimention);
break;
case eSystemMessage::msgKeyboardKey:
case eSystemMessage::msgKeyboardMove:
//GALE_DEBUG("Receive MSG : THREAD_KEYBORAD_KEY");
// store the keyboard special key status for mouse event...
m_input.setLastKeyboardSpecial(data->keyboardSpecial);
if (nullptr != m_windowsCurrent) {
if (false == m_windowsCurrent->onEventShortCut(data->keyboardSpecial,
data->keyboardChar,
data->keyboardMove,
data->stateIsDown) ) {
// get the current focused Widget :
std::shared_ptr<gale::Widget> tmpWidget = m_widgetManager.focusGet();
if (nullptr != tmpWidget) {
// check if the widget allow repeating key events.
//GALE_DEBUG("repeating test :" << data->repeateKey << " widget=" << tmpWidget->getKeyboardRepeate() << " state=" << data->stateIsDown);
if( false == data->repeateKey
|| ( true == data->repeateKey
&& true == tmpWidget->getKeyboardRepeate()) ) {
// check Widget shortcut
if (false == tmpWidget->onEventShortCut(data->keyboardSpecial,
data->keyboardChar,
data->keyboardMove,
data->stateIsDown) ) {
// generate the direct event ...
if (data->TypeMessage == eSystemMessage::msgKeyboardKey) {
gale::event::EntrySystem tmpEntryEvent(gale::key::keyboardChar,
gale::key::statusUp,
data->keyboardSpecial,
data->keyboardChar);
if(true == data->stateIsDown) {
tmpEntryEvent.m_event.setStatus(gale::key::statusDown);
}
tmpWidget->systemEventEntry(tmpEntryEvent);
} else { // THREAD_KEYBORAD_MOVE
GALE_DEBUG("THREAD_KEYBORAD_MOVE" << data->keyboardMove << " " << data->stateIsDown);
gale::event::EntrySystem tmpEntryEvent(data->keyboardMove,
gale::key::statusUp,
data->keyboardSpecial,
0);
if(true == data->stateIsDown) {
tmpEntryEvent.m_event.setStatus(gale::key::statusDown);
}
tmpWidget->systemEventEntry(tmpEntryEvent);
}
} else {
GALE_DEBUG("remove Repeate key ...");
}
}
}
}
}
break;
case eSystemMessage::msgClipboardArrive:
{
std::shared_ptr<gale::Widget> tmpWidget = m_widgetManager.focusGet();
if (tmpWidget != nullptr) {
tmpWidget->onEventClipboard(data->clipboardID);
}
}
break;
case eSystemMessage::msgHide:
GALE_DEBUG("Receive MSG : msgHide");
//guiAbstraction::SendKeyboardEventMove(tmpData->isDown, tmpData->move);
//gui_uniqueWindows->SysOnHide();
break;
case eSystemMessage::msgShow:
GALE_DEBUG("Receive MSG : msgShow");
//guiAbstraction::SendKeyboardEventMove(tmpData->isDown, tmpData->move);
//gui_uniqueWindows->SysOnShow();
break;
default:
GALE_DEBUG("Receive MSG : UNKNOW");
break;
}
}
}
void gale::Context::setArchiveDir(int _mode, const char* _str) {
switch(_mode) {
case 0:
GALE_DEBUG("Directory APK : path=" << _str);
etk::setBaseFolderData(_str);
break;
case 1:
GALE_DEBUG("Directory mode=FILE path=" << _str);
etk::setBaseFolderDataUser(_str);
break;
case 2:
GALE_DEBUG("Directory mode=CACHE path=" << _str);
etk::setBaseFolderCache(_str);
break;
case 3:
GALE_DEBUG("Directory mode=EXTERNAL_CACHE path=" << _str);
break;
default:
GALE_DEBUG("Directory mode=???? path=" << _str);
break;
}
}
gale::Context::Context(gale::context::Application* _application, int32_t _argc, const char* _argv[]) :
//m_application(std::make_shared<gale::context::Application>(_application)),
m_application(_application),
m_objectManager(*this),
m_previousDisplayTime(0),
m_input(*this),
#if (defined(__TARGET_OS__Android) || defined(__TARGET_OS__IOs))
m_displayFps(true),
#else
m_displayFps(false),
#endif
m_FpsSystemEvent( "Event ", false),
m_FpsSystemContext("Context ", false),
m_FpsSystem( "Draw ", true),
m_FpsFlush( "Flush ", false),
m_windowsCurrent(nullptr),
m_windowsSize(320,480),
m_initStepId(0) {
// set a basic
etk::thread::setName("gale");
if (m_application == nullptr) {
GALE_CRITICAL("Can not start context with no Application ==> rtfm ...");
}
m_commandLine.parse(_argc, _argv);
GALE_INFO(" == > Gale system init (BEGIN)");
// Reset the random system to be sure have real random values...
etk::tool::resetRandom();
// set the curent interface :
lockContext();
// By default we set 2 themes (1 color and 1 shape ...) :
etk::theme::setNameDefault("GUI", "shape/square/");
etk::theme::setNameDefault("COLOR", "color/black/");
// parse the debug level:
for(int32_t iii = 0; iii < m_commandLine.size() ; ++iii) {
if (m_commandLine.get(iii) == "--gale-fps") {
m_displayFps=true;
} else if ( m_commandLine.get(iii) == "-h"
|| m_commandLine.get(iii) == "--help") {
GALE_PRINT("gale - help : ");
GALE_PRINT(" " << etk::getApplicationName() << " [options]");
GALE_PRINT(" --gale-fps: Display the current fps of the display");
GALE_PRINT(" -h/--help: Display this help");
GALE_PRINT(" example:");
GALE_PRINT(" " << etk::getApplicationName() << " --gale-fps");
// this is a global help system does not remove it
continue;
} else {
continue;
}
m_commandLine.remove(iii);
--iii;
}
//etk::cout.setOutputFile(true);
GALE_INFO("GALE v:" << gale::getVersion());
GALE_INFO("Build Date: " << date::getYear() << "/" << date::getMonth() << "/" << date::getDay() << " " << date::getHour() << "h" << date::getMinute());
// TODO : remove this ...
etk::initDefaultFolder("galeApplNoName");
// request the init of the application in the main context of openGL ...
{
gale::eSystemMessage *data = new gale::eSystemMessage();
if (data == nullptr) {
GALE_ERROR("allocationerror of message");
} else {
data->TypeMessage = eSystemMessage::msgInit;
m_msgSystem.post(data);
}
}
// force a recalculation
requestUpdateSize();
#if defined(__GALE_ANDROID_ORIENTATION_LANDSCAPE__)
forceOrientation(gale::screenLandscape);
#elif defined(__GALE_ANDROID_ORIENTATION_PORTRAIT__)
forceOrientation(gale::screenPortrait);
#else
forceOrientation(gale::screenAuto);
#endif
// release the curent interface :
unLockContext();
GALE_INFO(" == > Gale system init (END)");
}
gale::Context::~Context() {
GALE_INFO(" == > Gale system Un-Init (BEGIN)");
// TODO : Clean the message list ...
// set the curent interface :
lockContext();
// Remove current windows
m_windowsCurrent.reset();
// clean all widget and sub widget with their resources:
m_objectManager.cleanInternalRemoved();
// call application to uninit
m_application->unInit(*this);
m_application.reset();
// clean all messages
m_msgSystem.clean();
// internal clean elements
m_objectManager.cleanInternalRemoved();
m_resourceManager.cleanInternalRemoved();
GALE_INFO("List of all widget of this context must be equal at 0 ==> otherwise some remove is missing");
m_objectManager.displayListObject();
// Resource is an lower element as objects ...
m_resourceManager.unInit();
// now All must be removed !!!
m_objectManager.unInit();
// release the curent interface :
unLockContext();
GALE_INFO(" == > Gale system Un-Init (END)");
}
void gale::Context::requestUpdateSize() {
gale::eSystemMessage *data = new gale::eSystemMessage();
if (data == nullptr) {
GALE_ERROR("allocationerror of message");
return;
}
data->TypeMessage = eSystemMessage::msgRecalculateSize;
m_msgSystem.post(data);
}
void gale::Context::OS_Resize(const vec2& _size) {
// TODO : Better in the thread ... == > but generate some init error ...
gale::Dimension::setPixelWindowsSize(_size);
gale::eSystemMessage *data = new gale::eSystemMessage();
if (data == nullptr) {
GALE_ERROR("allocationerror of message");
return;
}
data->TypeMessage = eSystemMessage::msgResize;
data->dimention = _size;
m_msgSystem.post(data);
}
void gale::Context::OS_Move(const vec2& _pos) {
/*
gale::eSystemMessage *data = new gale::eSystemMessage();
data->TypeMessage = eSystemMessage::msgResize;
data->resize.w = w;
data->resize.h = h;
m_msgSystem.Post(data);
*/
}
void gale::Context::OS_SetInputMotion(int _pointerID, const vec2& _pos ) {
gale::eSystemMessage *data = new gale::eSystemMessage();
if (data == nullptr) {
GALE_ERROR("allocationerror of message");
return;
}
data->TypeMessage = eSystemMessage::msgInputMotion;
data->inputType = gale::key::typeFinger;
data->inputId = _pointerID;
data->dimention = _pos;
m_msgSystem.post(data);
}
void gale::Context::OS_SetInputState(int _pointerID, bool _isDown, const vec2& _pos ) {
gale::eSystemMessage *data = new gale::eSystemMessage();
if (data == nullptr) {
GALE_ERROR("allocationerror of message");
return;
}
data->TypeMessage = eSystemMessage::msgInputState;
data->inputType = gale::key::typeFinger;
data->inputId = _pointerID;
data->stateIsDown = _isDown;
data->dimention = _pos;
m_msgSystem.post(data);
}
void gale::Context::OS_SetMouseMotion(int _pointerID, const vec2& _pos ) {
gale::eSystemMessage *data = new gale::eSystemMessage();
if (data == nullptr) {
GALE_ERROR("allocationerror of message");
return;
}
data->TypeMessage = eSystemMessage::msgInputMotion;
data->inputType = gale::key::typeMouse;
data->inputId = _pointerID;
data->dimention = _pos;
m_msgSystem.post(data);
}
void gale::Context::OS_SetMouseState(int _pointerID, bool _isDown, const vec2& _pos ) {
gale::eSystemMessage *data = new gale::eSystemMessage();
if (data == nullptr) {
GALE_ERROR("allocationerror of message");
return;
}
data->TypeMessage = eSystemMessage::msgInputState;
data->inputType = gale::key::typeMouse;
data->inputId = _pointerID;
data->stateIsDown = _isDown;
data->dimention = _pos;
m_msgSystem.post(data);
}
void gale::Context::OS_SetKeyboard(gale::key::Special& _special,
char32_t _myChar,
bool _isDown,
bool _isARepeateKey) {
gale::eSystemMessage *data = new gale::eSystemMessage();
if (data == nullptr) {
GALE_ERROR("allocationerror of message");
return;
}
data->TypeMessage = eSystemMessage::msgKeyboardKey;
data->stateIsDown = _isDown;
data->keyboardChar = _myChar;
data->keyboardSpecial = _special;
data->repeateKey = _isARepeateKey;
m_msgSystem.post(data);
}
void gale::Context::OS_SetKeyboardMove(gale::key::Special& _special,
enum gale::key::keyboard _move,
bool _isDown,
bool _isARepeateKey) {
gale::eSystemMessage *data = new gale::eSystemMessage();
if (data == nullptr) {
GALE_ERROR("allocationerror of message");
return;
}
data->TypeMessage = eSystemMessage::msgKeyboardMove;
data->stateIsDown = _isDown;
data->keyboardMove = _move;
data->keyboardSpecial = _special;
data->repeateKey = _isARepeateKey;
m_msgSystem.post(data);
}
void gale::Context::OS_Hide() {
gale::eSystemMessage *data = new gale::eSystemMessage();
if (data == nullptr) {
GALE_ERROR("allocationerror of message");
return;
}
data->TypeMessage = eSystemMessage::msgHide;
m_msgSystem.post(data);
}
void gale::Context::OS_Show() {
gale::eSystemMessage *data = new gale::eSystemMessage();
if (data == nullptr) {
GALE_ERROR("allocationerror of message");
return;
}
data->TypeMessage = eSystemMessage::msgShow;
m_msgSystem.post(data);
}
void gale::Context::OS_ClipBoardArrive(enum gale::context::clipBoard::clipboardListe _clipboardID) {
gale::eSystemMessage *data = new gale::eSystemMessage();
if (data == nullptr) {
GALE_ERROR("allocationerror of message");
return;
}
data->TypeMessage = eSystemMessage::msgClipboardArrive;
data->clipboardID = _clipboardID;
m_msgSystem.post(data);
}
void gale::Context::clipBoardGet(enum gale::context::clipBoard::clipboardListe _clipboardID) {
// just transmit an event , we have the data in the system
OS_ClipBoardArrive(_clipboardID);
}
void gale::Context::clipBoardSet(enum gale::context::clipBoard::clipboardListe _clipboardID) {
// nothing to do, data is already copyed in the GALE clipborad center
}
bool gale::Context::OS_Draw(bool _displayEveryTime) {
int64_t currentTime = gale::getTime();
// this is to prevent the multiple display at the a high frequency ...
#if (!defined(__TARGET_OS__Android) && !defined(__TARGET_OS__Windows))
if(currentTime - m_previousDisplayTime < 1000000/120) {
usleep(1000);
return false;
}
#endif
m_previousDisplayTime = currentTime;
// process the events
if (m_displayFps == true) {
m_FpsSystemEvent.tic();
}
bool needRedraw = false;
//! Event management section ...
{
// set the curent interface :
lockContext();
processEvents();
if (m_initStepId < m_application->getNbStepInit()) {
gale::eSystemMessage *data = new gale::eSystemMessage();
if (data == nullptr) {
GALE_ERROR("allocation error of message");
} else {
data->TypeMessage = eSystemMessage::msgInit;
m_msgSystem.post(data);
}
}
// call all the widget that neded to do something periodicly
m_objectManager.timeCall(currentTime);
// check if the user selected a windows
if (nullptr != m_windowsCurrent) {
// Redraw all needed elements
m_windowsCurrent->onRegenerateDisplay();
}
if (m_displayFps == true) {
m_FpsSystemEvent.incrementCounter();
m_FpsSystemEvent.toc();
}
//! bool needRedraw = gale::widgetManager::isDrawingNeeded();
needRedraw = m_widgetManager.isDrawingNeeded();
// release the curent interface :
unLockContext();
}
bool hasDisplayDone = false;
//! drawing section :
{
// Lock openGl context:
gale::openGL::lock();
if (m_displayFps == true) {
m_FpsSystemContext.tic();
}
if (nullptr != m_windowsCurrent) {
if( true == needRedraw
|| true == _displayEveryTime) {
m_resourceManager.updateContext();
if (m_displayFps == true) {
m_FpsSystemContext.incrementCounter();
}
}
}
if (m_displayFps == true) {
m_FpsSystemContext.toc();
m_FpsSystem.tic();
}
if (nullptr != m_windowsCurrent) {
if( true == needRedraw
|| true == _displayEveryTime) {
m_FpsSystem.incrementCounter();
m_windowsCurrent->sysDraw();
hasDisplayDone = true;
}
}
if (m_displayFps == true) {
m_FpsSystem.toc();
m_FpsFlush.tic();
}
if (hasDisplayDone == true) {
if (m_displayFps == true) {
m_FpsFlush.incrementCounter();
}
gale::openGL::flush();
}
if (m_displayFps == true) {
m_FpsFlush.toc();
}
// release open GL Context
gale::openGL::unLock();
}
if (m_displayFps == true) {
m_FpsSystemEvent.draw();
m_FpsSystemContext.draw();
m_FpsSystem.draw();
m_FpsFlush.draw();
}
{
// set the curent interface :
lockContext();
// release open GL Context
gale::openGL::lock();
// while The Gui is drawing in OpenGl, we do some not realTime things
m_resourceManager.updateContext();
// release open GL Context
gale::openGL::unLock();
m_objectManager.cleanInternalRemoved();
m_resourceManager.cleanInternalRemoved();
// release the curent interface :
unLockContext();
}
return hasDisplayDone;
}
void gale::Context::resetIOEvent() {
m_input.newLayerSet();
}
void gale::Context::OS_OpenGlContextDestroy() {
m_resourceManager.contextHasBeenDestroyed();
}
void gale::Context::setWindows(const std::shared_ptr<gale::widget::Windows>& _windows) {
// remove current focus :
m_widgetManager.focusSetDefault(nullptr);
m_widgetManager.focusRelease();
// set the new pointer as windows system
m_windowsCurrent = _windows;
// set the new default focus :
m_widgetManager.focusSetDefault(_windows);
// request all the widget redrawing
forceRedrawAll();
}
std::shared_ptr<gale::widget::Windows> gale::Context::getWindows() {
return m_windowsCurrent;
};
void gale::Context::forceRedrawAll() {
if (m_windowsCurrent == nullptr) {
return;
}
m_windowsCurrent->calculateSize(vec2(m_windowsSize.x(), m_windowsSize.y()));
}
void gale::Context::OS_Stop() {
// set the curent interface :
lockContext();
GALE_INFO("OS_Stop...");
if (m_windowsCurrent != nullptr) {
m_windowsCurrent->sysOnKill();
}
// release the curent interface :
unLockContext();
}
void gale::Context::OS_Suspend() {
// set the curent interface :
lockContext();
GALE_INFO("OS_Suspend...");
m_previousDisplayTime = -1;
if (m_windowsCurrent != nullptr) {
m_windowsCurrent->onStateSuspend();
}
// release the curent interface :
unLockContext();
}
void gale::Context::OS_Resume() {
// set the curent interface :
lockContext();
GALE_INFO("OS_Resume...");
m_previousDisplayTime = gale::getTime();
m_objectManager.timeCallResume(m_previousDisplayTime);
if (m_windowsCurrent != nullptr) {
m_windowsCurrent->onStateResume();
}
// release the curent interface :
unLockContext();
}
void gale::Context::OS_Foreground() {
// set the curent interface :
lockContext();
GALE_INFO("OS_Foreground...");
if (m_windowsCurrent != nullptr) {
m_windowsCurrent->onStateForeground();
}
// release the curent interface :
unLockContext();
}
void gale::Context::OS_Background() {
// set the curent interface :
lockContext();
GALE_INFO("OS_Background...");
if (m_windowsCurrent != nullptr) {
m_windowsCurrent->onStateBackground();
}
// release the curent interface :
unLockContext();
}
void gale::Context::stop() {
}
void gale::Context::setSize(const vec2& _size) {
GALE_INFO("setSize: NOT implemented ...");
};
void gale::Context::setPos(const vec2& _pos) {
GALE_INFO("setPos: NOT implemented ...");
}
void gale::Context::hide() {
GALE_INFO("hide: NOT implemented ...");
};
void gale::Context::show() {
GALE_INFO("show: NOT implemented ...");
}
void gale::Context::setTitle(const std::string& _title) {
GALE_INFO("setTitle: NOT implemented ...");
}
void gale::Context::keyboardShow() {
GALE_INFO("keyboardShow: NOT implemented ...");
}
void gale::Context::keyboardHide() {
GALE_INFO("keyboardHide: NOT implemented ...");
}
bool gale::Context::systemKeyboradEvent(enum gale::key::keyboardSystem _key, bool _down) {
if (m_windowsCurrent == nullptr) {
return false;
}
lockContext();
bool ret = m_windowsCurrent->onEventHardwareInput(_key, _down);
unLockContext();
return ret;
}

326
gale/context/Context.h Normal file
View File

@ -0,0 +1,326 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#ifndef __GALE_CONTEXT_H__
#define __GALE_CONTEXT_H__
#include <etk/os/Fifo.h>
#include <gale/debug.h>
#include <gale/gale.h>
#include <gale/key/key.h>
#include <gale/resource/Manager.h>
#include <gale/context/Application.h>
#include <gale/context/clipBoard.h>
#include <gale/context/commandLine.h>
#include <gale/context/InputManager.h>
#include <gale/context/Fps.h>
#include <memory>
namespace gale {
/**
* @not-in-doc
*/
class eSystemMessage;
/**
* @not-in-doc
*/
enum orientation{
screenAuto = 0,
screenLandscape,
screenPortrait
};
class Context/* : private gale::object::RemoveEvent */{
private:
std::shared_ptr<gale::context::Application> m_application; //!< Application handle
public:
std::shared_ptr<gale::context::Application> getApplication() {
return m_application;
}
private:
gale::context::CommandLine m_commandLine; //!< Start command line information
public:
gale::context::CommandLine& getCmd() {
return m_commandLine;
};
private:
gale::resource::Manager m_resourceManager; //!< global resources Manager
public:
gale::resource::Manager& getResourcesManager() {
return m_resourceManager;
};
public:
Context(gale::context::Application* _application, int32_t _argc=0, const char* _argv[]=nullptr);
virtual ~Context();
protected:
/**
* @brief set the curent interface.
* @note this lock the main mutex
*/
void lockContext();
/**
* @brief set the curent interface at nullptr.
* @note this un-lock the main mutex
*/
void unLockContext();
private:
int64_t m_previousDisplayTime; // this is to limit framerate ... in case...
gale::context::InputManager m_input;
etk::Fifo<gale::eSystemMessage*> m_msgSystem;
bool m_displayFps;
gale::context::Fps m_FpsSystemEvent;
gale::context::Fps m_FpsSystemContext;
gale::context::Fps m_FpsSystem;
gale::context::Fps m_FpsFlush;
/**
* @brief Processing all the event arrived ... (commoly called in draw function)
*/
void processEvents();
public:
virtual void setArchiveDir(int _mode, const char* _str);
virtual void OS_SetInputMotion(int _pointerID, const vec2& _pos);
virtual void OS_SetInputState(int _pointerID, bool _isDown, const vec2& _pos);
virtual void OS_SetMouseMotion(int _pointerID, const vec2& _pos);
virtual void OS_SetMouseState(int _pointerID, bool _isDown, const vec2& _pos);
virtual void OS_SetKeyboard(gale::key::Special& _special,
char32_t _myChar,
bool _isDown,
bool _isARepeateKey=false);
virtual void OS_SetKeyboardMove(gale::key::Special& _special,
enum gale::key::keyboard _move,
bool _isDown,
bool _isARepeateKey=false);
/**
* @brief The current context is suspended
*/
virtual void OS_Suspend();
/**
* @brief The current context is resumed
*/
virtual void OS_Resume();
/**
* @brief The current context is set in foreground (framerate is maximum speed)
*/
virtual void OS_Foreground();
/**
* @brief The current context is set in background (framerate is slowing down (max fps)/5 # 4fps)
*/
virtual void OS_Background();
void requestUpdateSize();
// return true if a flush is needed
bool OS_Draw(bool _displayEveryTime);
public:
/**
* @brief reset event management for the IO like Input ou Mouse or keyborad
*/
void resetIOEvent();
/**
* @brief The OS inform that the openGL constext has been destroy == > use to automaticly reload the texture and other thinks ...
*/
void OS_OpenGlContextDestroy();
/**
* @brief The OS Inform that the Window has been killed
*/
void OS_Stop();
/**
* @brief The application request that the Window will be killed
*/
virtual void stop();
private:
std::shared_ptr<gale::widget::Windows> m_windowsCurrent; //!< curent displayed windows
public:
/**
* @brief set the current windows to display :
* @param _windows Windows that might be displayed
*/
void setWindows(const std::shared_ptr<gale::widget::Windows>& _windows);
/**
* @brief get the current windows that is displayed
* @return the current handle on the windows (can be null)
*/
std::shared_ptr<gale::widget::Windows> getWindows();
private:
vec2 m_windowsSize; //!< current size of the system
public:
/**
* @brief get the current windows size
* @return the current size ...
*/
const vec2& getSize() {
return m_windowsSize;
};
/**
* @brief The OS inform that the current windows has change his size.
* @param[in] _size new size of the windows.
*/
virtual void OS_Resize(const vec2& _size);
/**
* @brief The application request a change of his curent size.
* @param[in] _size new Requested size of the windows.
*/
virtual void setSize(const vec2& _size);
/**
* @brief The OS inform that the current windows has change his position.
* @param[in] _pos New position of the Windows.
*/
void OS_Move(const vec2& _pos);
/**
* @brief The Application request that the current windows will change his position.
* @param[in] _pos New position of the Windows requested.
*/
virtual void setPos(const vec2& _pos);
/**
* @brief The OS inform that the Windows is now Hidden.
*/
void OS_Hide();
/**
* @brief The Application request that the Windows will be Hidden.
*/
virtual void hide();
/**
* @brief The OS inform that the Windows is now visible.
*/
void OS_Show();
/**
* @brief The Application request that the Windows will be visible.
*/
virtual void show();
/**
* @brief Redraw all the windows
*/
void forceRedrawAll();
// TODO : Later ...
/**
* @brief This is to transfert the event from one widget to another one
* @param source the widget where the event came from
* @param destination the widget where the event mitgh be generated now
*/
void inputEventTransfertWidget(std::shared_ptr<gale::Widget> _source, std::shared_ptr<gale::Widget> _destination);
/**
* @brief This fonction lock the pointer properties to move in relative instead of absolute
* @param[in] widget The widget that lock the pointer events
*/
void inputEventGrabPointer(std::shared_ptr<gale::Widget> _widget);
/**
* @brief This fonction un-lock the pointer properties to move in relative instead of absolute
*/
void inputEventUnGrabPointer();
/**
* @brief display the virtal keyboard (for touch system only)
*/
virtual void keyboardShow();
/**
* @brief Hide the virtal keyboard (for touch system only)
*/
virtual void keyboardHide();
/**
* @brief Inform the Gui that we want to have a copy of the clipboard
* @param[in] _clipboardID ID of the clipboard (STD/SELECTION) only apear here
*/
virtual void clipBoardGet(enum gale::context::clipBoard::clipboardListe _clipboardID);
/**
* @brief Inform the Gui that we are the new owner of the clipboard
* @param[in] _clipboardID ID of the clipboard (STD/SELECTION) only apear here
*/
virtual void clipBoardSet(enum gale::context::clipBoard::clipboardListe _clipboardID);
/**
* @brief Call by the OS when a clipboard arrive to US (previously requested by a widget)
* @param[in] Id of the clipboard
*/
void OS_ClipBoardArrive(enum gale::context::clipBoard::clipboardListe _clipboardID);
/**
* @brief set the new title of the windows
* @param[in] title New desired title
*/
virtual void setTitle(const std::string& _title);
/**
* @brief Open an URL on an eternal brother.
* @param[in] _url URL to open.
*/
virtual void openURL(const std::string& _url) { };
/**
* @brief force the screen orientation (availlable on portable elements ...
* @param[in] _orientation Selected orientation.
*/
virtual void forceOrientation(enum gale::orientation _orientation) { };
/**
* @brief get all the event from the X system
* @param[in] _isGrabbed "true" if all the event will be get, false if we want only ours.
* @param[in] _forcedPosition the position where the mouse might be reset at every events ...
*/
virtual void grabPointerEvents(bool _isGrabbed, const vec2& _forcedPosition) { };
/**
* @brief set the cursor display type.
* @param[in] _newCursor selected new cursor.
*/
virtual void setCursor(enum gale::context::cursorDisplay _newCursor) { };
/**
* @brief set the Icon of the program
* @param[in] _inputFile new filename icon of the curent program.
*/
virtual void setIcon(const std::string& _inputFile) { };
/**
* @brief get the curent time in micro-second
* @note : must be implemented in all system OS implementation
* @return The curent time of the process
*/
static int64_t getTime();
private:
// TODO : set user argument here ....
public:
/**
* @brief This is the only one things the User might done in his main();
* @note : must be implemented in all system OPS implementation
* @note To answare you before you ask the question, this is really simple:
* Due to the fect that the current system is multiple-platform, you "main"
* Does not exist in the android platform, then gale call other start
* and stop function, to permit to have only one code
* @note The main can not be in the gale, due to the fact thet is an librairy
* @param[in] _argc Standard argc
* @param[in] _argv Standard argv
* @return normal error int for the application error management
*/
static int main(int _argc, const char *_argv[]);
private:
size_t m_initStepId;
size_t m_initTotalStep;
public:
/**
* @brief Special for init (main) set the start image when loading data
* @param[in] _fileName Name of the image to load
*/
void setInitImage(const std::string& _fileName);
protected:
/**
* @brief HARDWARE keyboard event from the system
* @param[in] _key event type
* @param[in] _status Up or down status
* @return Keep the event or not
*/
virtual bool systemKeyboradEvent(enum gale::key::keyboardSystem _key, bool _down);
};
/**
* @brief From everyware in the program, we can get the context inteface.
* @return current reference on the instance.
*/
Context& getContext();
};
#endif

141
gale/context/Fps.h Normal file
View File

@ -0,0 +1,141 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#ifndef __GALE_FPS_H__
#define __GALE_FPS_H__
namespace gale {
namespace context {
/**
* @brief This class is designed to count the number of frame per second in the main renderer system
* @not-in-doc
*/
class Fps {
// display every second ...
#define DISPLAY_PERIODE_US (1000000)
private:
int64_t startTime;
int64_t nbCallTime;
int64_t nbDisplayTime;
int64_t min;
int64_t avg;
int64_t max;
int64_t min_idle;
int64_t avg_idle;
int64_t max_idle;
int64_t ticTime;
bool display;
bool drwingDone;
const char * m_displayName;
bool m_displayFPS;
public:
/**
* @brief Constructor
*/
Fps(const char * displayName, bool displayFPS) {
startTime = -1;
nbCallTime = 0;
nbDisplayTime = 0;
min = 99999999999999LL;
avg = 0;
max = 0;
min_idle = 99999999999999LL;
avg_idle = 0;
max_idle = 0;
ticTime = 0;
display = false;
drwingDone = false;
m_displayName = displayName;
m_displayFPS = displayFPS;
}
/**
* @brief Destructor
*/
~Fps() {
}
/**
* @brief this might be call every time a diplay start
*/
void tic() {
int64_t currentTime = gale::getTime();
ticTime = currentTime;
nbCallTime++;
if (startTime<0) {
startTime = currentTime;
}
//GALE_DEBUG("current : " << currentTime << "time diff : " << (currentTime - startTime));
if ( (currentTime - startTime) > DISPLAY_PERIODE_US) {
display = true;
}
}
/**
* @brief this might be call every time a diplay stop, it do the display every second
* @param[in] displayTime display curent time of the frame.
*/
void toc(bool displayTime = false) {
int64_t currentTime = gale::getTime();
int64_t processTimeLocal = (currentTime - ticTime);
if (displayTime == true) {
GALE_PRINT(m_displayName << " : processTime : " << (float)((float)processTimeLocal / 1000.0) << "ms ");
}
if (drwingDone) {
min = std::min(min, processTimeLocal);
max = std::max(max, processTimeLocal);
avg += processTimeLocal;
drwingDone = false;
} else {
min_idle = std::min(min_idle, processTimeLocal);
max_idle = std::max(max_idle, processTimeLocal);
avg_idle += processTimeLocal;
}
}
/**
* @brief this might be call when a display is really done
*/
void incrementCounter() {
nbDisplayTime++;
drwingDone = true;
}
/**
* @brief draw debug display ...
*/
void draw() {
if (true == display) {
if (nbDisplayTime>0) {
GALE_PRINT(m_displayName << " : Active : "
<< (float)((float)min / 1000.0) << "ms "
<< (float)((float)avg / (float)nbDisplayTime / 1000.0) << "ms "
<< (float)((float)max / 1000.0) << "ms ");
}
if (nbCallTime-nbDisplayTime>0) {
GALE_PRINT(m_displayName << " : idle : "
<< (float)((float)min_idle / 1000.0) << "ms "
<< (float)((float)avg_idle / (float)(nbCallTime-nbDisplayTime) / 1000.0) << "ms "
<< (float)((float)max_idle / 1000.0) << "ms ");
}
if (true == m_displayFPS) {
GALE_PRINT("FPS : " << nbDisplayTime << "/" << nbCallTime << "fps");
}
max = 0;
min = 99999999999999LL;
avg = 0;
max_idle = 0;
min_idle = 99999999999999LL;
avg_idle = 0;
nbCallTime = 0;
nbDisplayTime = 0;
startTime = -1;
display = false;
}
}
};
};
};
#endif

View File

@ -0,0 +1,20 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#import <UIKit/UIKit.h>
@class OpenglView;
@interface AppDelegate : UIResponder <UIApplicationDelegate> {
UIWindow *window;
OpenglView *glView;
}
@property (nonatomic, retain) IBOutlet UIWindow *window;
@property (nonatomic, retain) IBOutlet OpenglView *glView;
@end

View File

@ -0,0 +1,97 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#import <UIKit/UIKit.h>
#include "ewol/context/IOs/Interface.h"
#import <ewol/context/IOs/OpenglView.h>
#import <ewol/context/IOs/AppDelegate.h>
#include <ewol/context/IOs/Context.h>
#include <ewol/debug.h>
@implementation AppDelegate
@synthesize window;
@synthesize glView;
- (void)applicationDidFinishLaunching:(UIApplication *)application {
CGRect screenBounds = [[UIScreen mainScreen] bounds];
CGFloat screenScale = [[UIScreen mainScreen] scale];
NSLog(@"Start with screeen bounds : %fx%f\n", screenBounds.size.width, screenBounds.size.height);
CGSize currentSize = CGSizeMake(screenBounds.size.width * screenScale, screenBounds.size.height * screenScale);
//screenBounds.size.width *= screenScale;
//screenBounds.size.height *= screenScale;
NSLog(@"Start with screeen bounds : %fx%f\n", screenBounds.size.width, screenBounds.size.height);
window = [[UIWindow alloc] initWithFrame:screenBounds];
window.contentMode = UIViewContentModeRedraw;
glView = [[OpenglView alloc] initWithFrame:window.bounds];
glView.contentMode = UIViewContentModeRedraw;
[window addSubview:glView];
[window makeKeyAndVisible];
// Create interface of ewol here ....
NSLog(@"CREATE EWOL interface creation\n");
IOs::createInterface();
IOs::resize(currentSize.width, currentSize.height);
IOs::start();
}
/*
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
return YES;
}
*/
- (void)applicationWillResignActive:(UIApplication *)application {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
EWOL_INFO("move windows in applicationWillResignActive");
[glView speedSlow];
IOs::background();
}
- (void)applicationDidEnterBackground:(UIApplication *)application {
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
EWOL_INFO("move windows in applicationDidEnterBackground");
[glView stopDisplayLink];
IOs::suspend();
}
- (void)applicationWillEnterForeground:(UIApplication *)application {
// Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
EWOL_INFO("move windows in applicationWillEnterForeground");
IOs::resume();
[glView startDisplayLink];
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
EWOL_INFO("move windows in applicationDidBecomeActive");
[glView speedNormal];
IOs::foreground();
}
- (void)applicationWillTerminate:(UIApplication *)application {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
// Create interface of ewol here ....
EWOL_INFO("move windows in applicationWillTerminate");
IOs::stop();
IOs::releaseInterface();
}
/*
- (void)dealloc {
[window release];
[glView release];
[super dealloc];
}
*/
@end

View File

@ -0,0 +1,273 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#include <gale/debug.h>
#include <gale/gale.h>
#include <gale/key/key.h>
#include <gale/context/commandLine.h>
#include <etk/types.h>
#include <etk/os/FSNode.h>
#include <gale/widget/Manager.h>
#include <gale/resource/Manager.h>
#include <gale/context/Context.h>
#include <gale/context/IOs/Interface.h>
#include <gale/context/IOs/Context.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/times.h>
#include <mach/clock.h>
#include <mach/mach.h>
#include <etk/etk.h>
int64_t gale::getTime() {
struct timespec now;
clock_serv_t cclock;
mach_timespec_t mts;
host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &cclock);
clock_get_time(cclock, &mts);
mach_port_deallocate(mach_task_self(), cclock);
now.tv_sec = mts.tv_sec;
now.tv_nsec = mts.tv_nsec;
//GALE_VERBOSE("current time : " << now.tv_sec << "s " << now.tv_usec << "us");
return (int64_t)((int64_t)now.tv_sec*(int64_t)1000000 + (int64_t)now.tv_nsec/(int64_t)1000);
}
#undef __class__
#define __class__ "MacOSInterface"
class MacOSInterface : public gale::Context {
private:
gale::key::Special m_guiKeyBoardMode;
public:
MacOSInterface(gale::context::Application* _application, int32_t _argc, const char* _argv[]) :
gale::Context(_application, _argc, _argv) {
// nothing to do ...
}
int32_t Run() {
return 0;
}
virtual void stop() {
mm_exit();
}
public:
//interface MacOS :
bool MAC_Draw(bool _displayEveryTime) {
return OS_Draw(_displayEveryTime);
}
void MAC_Resize(float _x, float _y) {
OS_Resize(vec2(_x,_y));
}
void MAC_SetMouseState(int32_t _id, bool _isDown, float _x, float _y) {
OS_SetMouseState(_id, _isDown, vec2(_x, _y));
}
void MAC_SetMouseMotion(int32_t _id, float _x, float _y) {
OS_SetMouseMotion(_id, vec2(_x, _y));
}
void MAC_SetInputState(int32_t _id, bool _isDown, float _x, float _y) {
OS_SetInputState(_id, _isDown, vec2(_x, _y));
}
void MAC_SetInputMotion(int32_t _id, float _x, float _y) {
OS_SetInputMotion(_id, vec2(_x, _y));
}
void MAC_SetKeyboard(gale::key::Special _keyboardMode, int32_t _unichar, bool _isDown, bool _isAReapeateKey) {
if (_unichar == u32char::Delete) {
_unichar = u32char::Suppress;
} else if (_unichar == u32char::Suppress) {
_unichar = u32char::Delete;
}
if (_unichar == u32char::CarrierReturn) {
_unichar = u32char::Return;
}
//GALE_DEBUG("key: " << _unichar << " up=" << !_isDown);
if (_unichar <= 4) {
enum gale::key::keyboard move;
switch(_unichar) {
case 0:
move = gale::key::keyboardUp;
break;
case 1:
move = gale::key::keyboardDown;
break;
case 2:
move = gale::key::keyboardLeft;
break;
case 3:
move = gale::key::keyboardRight;
break;
}
OS_SetKeyboardMove(_keyboardMode, move, !_isDown, _isAReapeateKey);
} else {
OS_SetKeyboard(_keyboardMode, _unichar, !_isDown, _isAReapeateKey);
}
}
void MAC_SetKeyboardMove(gale::key::Special& _special,
enum gale::key::keyboard _move,
bool _isDown) {
OS_SetKeyboardMove(_special, _move, _isDown);
}
void openURL(const std::string& _url) {
mm_openURL(_url.c_str());
}
};
MacOSInterface* interface = nullptr;
bool IOs::draw(bool _displayEveryTime) {
if (interface == nullptr) {
return false;
}
return interface->MAC_Draw(_displayEveryTime);
}
void IOs::resize(float _x, float _y) {
if (interface == nullptr) {
return;
}
interface->MAC_Resize(_x, _y);
}
void IOs::setMouseState(int32_t _id, bool _isDown, float _x, float _y) {
if (interface == nullptr) {
return;
}
interface->MAC_SetMouseState(_id, _isDown, _x, _y);
}
void IOs::setMouseMotion(int32_t _id, float _x, float _y) {
if (interface == nullptr) {
return;
}
interface->MAC_SetMouseMotion(_id, _x, _y);
}
void IOs::setInputState(int32_t _id, bool _isDown, float _x, float _y) {
if (interface == nullptr) {
return;
}
interface->MAC_SetInputState(_id, _isDown, _x, _y);
}
void IOs::setInputMotion(int32_t _id, float _x, float _y) {
if (interface == nullptr) {
return;
}
interface->MAC_SetInputMotion(_id, _x, _y);
}
void IOs::setKeyboard(gale::key::Special _keyboardMode, int32_t _unichar, bool _isDown, bool _isAReapeateKey) {
if (interface == nullptr) {
return;
}
interface->MAC_SetKeyboard(_keyboardMode, _unichar, _isDown, _isAReapeateKey);
}
void IOs::setKeyboardMove(gale::key::Special& _keyboardMode, enum gale::key::keyboard _move, bool _isDown) {
if (interface == nullptr) {
return;
}
interface->MAC_SetKeyboardMove(_keyboardMode, _move, _isDown);
}
void IOs::start() {
if (interface == nullptr) {
return;
}
//interface->OS_Start();
}
void IOs::resume() {
if (interface == nullptr) {
return;
}
interface->OS_Resume();
}
void IOs::suspend() {
if (interface == nullptr) {
return;
}
interface->OS_Suspend();
}
void IOs::stop() {
if (interface == nullptr) {
return;
}
interface->OS_Stop();
}
void IOs::background() {
if (interface == nullptr) {
return;
}
interface->OS_Background();
}
void IOs::foreground() {
if (interface == nullptr) {
return;
}
interface->OS_Foreground();
}
static int l_argc = 0;
static const char **l_argv = nullptr;
static gale::context::Application* l_application;
/**
* @brief Main of the program
* @param std IO
* @return std IO
*/
int gale::run(gale::context::Application* _application, int _argc, const char *_argv[]) {
l_argc = _argc;
l_argv = _argv;
l_application = _application;
return mm_main(_argc, _argv);
}
// Creat and relaese gale::Context interface:
void IOs::createInterface() {
etk::init(l_argc, l_argv);
GALE_INFO("Create new interface");
interface = new MacOSInterface(l_application, l_argc, l_argv);
l_application = nullptr;
if (nullptr == interface) {
GALE_CRITICAL("Can not create the X11 interface ... MEMORY allocation error");
return;
}
}
void IOs::releaseInterface() {
if (interface != nullptr) {
GALE_INFO("Remove interface");
}
delete(interface);
interface = nullptr;
}

View File

@ -0,0 +1,40 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#ifndef __MAC_OS_CONTEXT_H__
#define __MAC_OS_CONTEXT_H__
#include <gale/key/key.h>
namespace IOs {
// Create and relaese gale::Context interface:
void createInterface();
void releaseInterface();
// return true if a flush is needed
bool draw(bool _displayEveryTime);
/**
* @brief The OS inform that the current windows has change his size.
* @param[in] _size new size of the windows.
*/
void resize(float _x, float _y);
void setMouseState(int32_t _id, bool _isDown, float _x, float _y);
void setMouseMotion(int32_t _id, float _x, float _y);
void setInputState(int32_t _id, bool _isDown, float _x, float _y);
void setInputMotion(int32_t _id, float _x, float _y);
void setKeyboard(gale::key::Special _keyboardMode, int32_t _unichar, bool _isDown, bool _isAReapeateKey);
void setKeyboardMove(gale::key::Special& _keyboardMode, enum gale::key::keyboard _move, bool _isDown);
void start();
void stop();
void foreground();
void background();
void resume();
void suspend();
};
#endif

View File

@ -0,0 +1,24 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#ifndef __GALE_MM_INTERFACE_H__
#define __GALE_MM_INTERFACE_H__
#ifdef __cplusplus
extern "C" {
#endif
int mm_main(int _argc, const char *_argv[]);
void mm_exit();
void mm_openURL(const char *_url);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,31 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#import <UIKit/UIKit.h>
#import <ewol/context/IOs/AppDelegate.h>
//#import "AppDelegate.h"
int mm_main(int argc, const char *argv[]) {
@autoreleasepool {
return UIApplicationMain(argc, (char**)argv, nil, NSStringFromClass([AppDelegate class]));
}
// return no error
return 0;
}
void mm_exit(void) {
[[NSThread mainThread] cancel];
}
void mm_openURL(const char *_url) {
NSString* url = [[NSString alloc] initWithUTF8String:_url];
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:url]];
}

View File

@ -0,0 +1,41 @@
//
// EAGLView.h
// OpenGLBasics
//
// Created by Charlie Key on 6/24/09.
//
#import <UIKit/UIKit.h>
#import <OpenGLES/EAGL.h>
#include <OpenGLES/ES2/gl.h>
#include <OpenGLES/ES2/glext.h>
/*
This class wraps the CAEAGLLayer from CoreAnimation into a convenient UIView subclass.
The view content is basically an EAGL surface you render your OpenGL scene into.
Note that setting the view non-opaque will only work if the EAGL surface has an alpha channel.
*/
@interface OpenglView : UIView {
@private
CAEAGLLayer* _eaglLayer;
EAGLContext *_context;
GLuint _colorRenderBuffer;
GLuint _depthRenderBuffer;
/* OpenGL names for the renderbuffer and framebuffers used to render to this view */
GLuint viewRenderbuffer, viewFramebuffer;
/* OpenGL name for the depth buffer that is attached to viewFramebuffer, if it exists (0 if it does not exist) */
GLuint depthRenderbuffer;
CGSize m_currentSize;
CADisplayLink* displayLink; //!< link to start and stop display of the view...
int deltaDisplay;
int displayCounter;
}
- (void)stopDisplayLink;
- (void)startDisplayLink;
- (void)speedSlow;
- (void)speedNormal;
@end

View File

@ -0,0 +1,281 @@
//
// EAGLView.m
// OpenGLBasics
//
// Created by Charlie Key on 6/24/09.
//
#import <QuartzCore/QuartzCore.h>
#import <OpenGLES/EAGLDrawable.h>
#include <ewol/context/IOs/Context.h>
#include <ewol/Dimension.h>
#include <sys/types.h>
#include <sys/sysctl.h>
#import "OpenglView.h"
#include <ewol/debug.h>
@interface OpenglView ()
@end
@implementation OpenglView
// You must implement this method (it does not work without it)
+ (Class)layerClass {
return [CAEAGLLayer class];
}
- (NSString *) platform {
size_t size;
sysctlbyname("hw.machine", NULL, &size, NULL, 0);
char *machine = (char*)malloc(size);
sysctlbyname("hw.machine", machine, &size, NULL, 0);
NSString *platform = [NSString stringWithUTF8String:machine];
free(machine);
return platform;
}
- (NSString *) platformString {
NSString *platform = [self platform];
if ([platform isEqualToString:@"iPhone1,1"]) return @"iPhone 1G";
if ([platform isEqualToString:@"iPhone1,2"]) return @"iPhone 3G";
if ([platform isEqualToString:@"iPhone2,1"]) return @"iPhone 3GS";
if ([platform isEqualToString:@"iPhone3,1"]) return @"iPhone 4";
if ([platform isEqualToString:@"iPhone3,3"]) return @"Verizon iPhone 4";
if ([platform isEqualToString:@"iPhone4,1"]) return @"iPhone 4S";
if ([platform isEqualToString:@"iPhone5,1"]) return @"iPhone 5 (GSM)";
if ([platform isEqualToString:@"iPhone5,2"]) return @"iPhone 5 (GSM+CDMA)";
if ([platform isEqualToString:@"iPhone5,3"]) return @"iPhone 5c (GSM)";
if ([platform isEqualToString:@"iPhone5,4"]) return @"iPhone 5c (GSM+CDMA)";
if ([platform isEqualToString:@"iPhone6,1"]) return @"iPhone 5s (GSM)";
if ([platform isEqualToString:@"iPhone6,2"]) return @"iPhone 5s (GSM+CDMA)";
if ([platform isEqualToString:@"iPod1,1"]) return @"iPod Touch 1G";
if ([platform isEqualToString:@"iPod2,1"]) return @"iPod Touch 2G";
if ([platform isEqualToString:@"iPod3,1"]) return @"iPod Touch 3G";
if ([platform isEqualToString:@"iPod4,1"]) return @"iPod Touch 4G";
if ([platform isEqualToString:@"iPod5,1"]) return @"iPod Touch 5G";
if ([platform isEqualToString:@"iPad1,1"]) return @"iPad";
if ([platform isEqualToString:@"iPad2,1"]) return @"iPad 2 (WiFi)";
if ([platform isEqualToString:@"iPad2,2"]) return @"iPad 2 (GSM)";
if ([platform isEqualToString:@"iPad2,3"]) return @"iPad 2 (CDMA)";
if ([platform isEqualToString:@"iPad2,4"]) return @"iPad 2 (WiFi)";
if ([platform isEqualToString:@"iPad2,5"]) return @"iPad Mini (WiFi)";
if ([platform isEqualToString:@"iPad2,6"]) return @"iPad Mini (GSM)";
if ([platform isEqualToString:@"iPad2,7"]) return @"iPad Mini (GSM+CDMA)";
if ([platform isEqualToString:@"iPad3,1"]) return @"iPad 3 (WiFi)";
if ([platform isEqualToString:@"iPad3,2"]) return @"iPad 3 (GSM+CDMA)";
if ([platform isEqualToString:@"iPad3,3"]) return @"iPad 3 (GSM)";
if ([platform isEqualToString:@"iPad3,4"]) return @"iPad 4 (WiFi)";
if ([platform isEqualToString:@"iPad3,5"]) return @"iPad 4 (GSM)";
if ([platform isEqualToString:@"iPad3,6"]) return @"iPad 4 (GSM+CDMA)";
if ([platform isEqualToString:@"iPad4,1"]) return @"iPad Air (WiFi)";
if ([platform isEqualToString:@"iPad4,2"]) return @"iPad Air (Cellular)";
if ([platform isEqualToString:@"iPad4,4"]) return @"iPad mini 2G (WiFi)";
if ([platform isEqualToString:@"iPad4,5"]) return @"iPad mini 2G (Cellular)";
if ([platform isEqualToString:@"i386"]) return @"Simulator";
if ([platform isEqualToString:@"x86_64"]) return @"Simulator";
return platform;
}
- (float)getScreenPPP {
NSString *platform = [self platform];
if ([platform isEqualToString:@"iPhone1,1"]) return 326.0f; //@"iPhone 1G";
if ([platform isEqualToString:@"iPhone1,2"]) return 326.0f; //@"iPhone 3G";
if ([platform isEqualToString:@"iPhone2,1"]) return 326.0f; //@"iPhone 3GS";
if ([platform isEqualToString:@"iPhone3,1"]) return 326.0f; //@"iPhone 4";
if ([platform isEqualToString:@"iPhone3,3"]) return 326.0f; //@"Verizon iPhone 4";
if ([platform isEqualToString:@"iPhone4,1"]) return 326.0f; //@"iPhone 4S";
if ([platform isEqualToString:@"iPhone5,1"]) return 326.0f; //@"iPhone 5 (GSM)";
if ([platform isEqualToString:@"iPhone5,2"]) return 326.0f; //@"iPhone 5 (GSM+CDMA)";
if ([platform isEqualToString:@"iPhone5,3"]) return 326.0f; //@"iPhone 5c (GSM)";
if ([platform isEqualToString:@"iPhone5,4"]) return 326.0f; //@"iPhone 5c (GSM+CDMA)";
if ([platform isEqualToString:@"iPhone6,1"]) return 326.0f; //@"iPhone 5s (GSM)";
if ([platform isEqualToString:@"iPhone6,2"]) return 326.0f; //@"iPhone 5s (GSM+CDMA)";
if ([platform isEqualToString:@"iPod1,1"]) return 326.0f; //@"iPod Touch 1G";
if ([platform isEqualToString:@"iPod2,1"]) return 326.0f; //@"iPod Touch 2G";
if ([platform isEqualToString:@"iPod3,1"]) return 326.0f; //@"iPod Touch 3G";
if ([platform isEqualToString:@"iPod4,1"]) return 326.0f; //@"iPod Touch 4G";
if ([platform isEqualToString:@"iPod5,1"]) return 326.0f; //@"iPod Touch 5G";
if ([platform isEqualToString:@"iPad1,1"]) return 264.0f; //@"iPad";
if ([platform isEqualToString:@"iPad2,1"]) return 264.0f; //@"iPad 2 (WiFi)";
if ([platform isEqualToString:@"iPad2,2"]) return 264.0f; //@"iPad 2 (GSM)";
if ([platform isEqualToString:@"iPad2,3"]) return 264.0f; //@"iPad 2 (CDMA)";
if ([platform isEqualToString:@"iPad2,4"]) return 264.0f; //@"iPad 2 (WiFi)";
if ([platform isEqualToString:@"iPad2,5"]) return 163.0f; //@"iPad Mini (WiFi)";
if ([platform isEqualToString:@"iPad2,6"]) return 163.0f; //@"iPad Mini (GSM)";
if ([platform isEqualToString:@"iPad2,7"]) return 163.0f; //@"iPad Mini (GSM+CDMA)";
if ([platform isEqualToString:@"iPad3,1"]) return 264.0f; //@"iPad 3 (WiFi)";
if ([platform isEqualToString:@"iPad3,2"]) return 264.0f; //@"iPad 3 (GSM+CDMA)";
if ([platform isEqualToString:@"iPad3,3"]) return 264.0f; //@"iPad 3 (GSM)";
if ([platform isEqualToString:@"iPad3,4"]) return 264.0f; //@"iPad 4 (WiFi)";
if ([platform isEqualToString:@"iPad3,5"]) return 264.0f; //@"iPad 4 (GSM)";
if ([platform isEqualToString:@"iPad3,6"]) return 264.0f; //@"iPad 4 (GSM+CDMA)";
if ([platform isEqualToString:@"iPad4,1"]) return 264.0f; //@"iPad Air (WiFi)";
if ([platform isEqualToString:@"iPad4,2"]) return 264.0f; //@"iPad Air (Cellular)";
if ([platform isEqualToString:@"iPad4,4"]) return 326.0f; //@"iPad mini 2G (WiFi)";
if ([platform isEqualToString:@"iPad4,5"]) return 326.0f; //@"iPad mini 2G (Cellular)";
if ([platform isEqualToString:@"i386"]) return 200.0f; //@"Simulator";
if ([platform isEqualToString:@"x86_64"]) return 326.0f; //@"Simulator";
return 326.0f;
}
- (void)setNeedsDisplay {
EWOL_INFO("**** setNeedsDisplay:" << vec2(self.frame.size.width, self.frame.size.height));
// TODO : SIZE change ...
}
- (void)configureAspectRatio {
CGRect screenBounds = [[UIScreen mainScreen] bounds];
CGFloat screenScale = [[UIScreen mainScreen] scale];
m_currentSize = CGSizeMake(screenBounds.size.width * screenScale, screenBounds.size.height * screenScale);
//self.frame.size = m_currentSize;
EWOL_INFO("**** screen size:" << vec2(m_currentSize.width, m_currentSize.height));
float ratio = [self getScreenPPP];
EWOL_INFO("**** pixel ratio: " << ratio);
ewol::Dimension::setPixelRatio(vec2(1.0f/ratio, 1.0f/ratio), ewol::Dimension::Inch);
IOs::resize(m_currentSize.width, m_currentSize.height);
CGRect localBounds = [self bounds];
EWOL_INFO("**** localBounds:" << vec2(localBounds.size.width, localBounds.size.height));
}
- (void)setupLayer {
_eaglLayer = (CAEAGLLayer*) self.layer;
CGFloat screenScale = [[UIScreen mainScreen] scale];
_eaglLayer.contentsScale = screenScale;
_eaglLayer.opaque = YES;
}
- (void)setupContext {
EAGLRenderingAPI api = kEAGLRenderingAPIOpenGLES2;
_context = [[EAGLContext alloc] initWithAPI:api];
if (!_context) {
NSLog(@"Failed to initialize OpenGLES 2.0 context");
exit(1);
}
if (![EAGLContext setCurrentContext:_context]) {
NSLog(@"Failed to set current OpenGL context");
exit(1);
}
}
- (void)setupRenderBuffer {
glGenRenderbuffers(1, &_colorRenderBuffer);
glBindRenderbuffer(GL_RENDERBUFFER, _colorRenderBuffer);
[_context renderbufferStorage:GL_RENDERBUFFER fromDrawable:_eaglLayer];
}
- (void)setupDepthBuffer {
glGenRenderbuffers(1, &_depthRenderBuffer);
glBindRenderbuffer(GL_RENDERBUFFER, _depthRenderBuffer);
CGFloat screenScale = [[UIScreen mainScreen] scale];
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, self.frame.size.width*screenScale, self.frame.size.height*screenScale);
}
- (void)setupFrameBuffer {
GLuint framebuffer;
glGenFramebuffers(1, &framebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, _colorRenderBuffer);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, _depthRenderBuffer);
}
- (void)render:(CADisplayLink*)displayLink {
displayCounter++;
if (displayCounter >= deltaDisplay) {
displayCounter = 0;
IOs::draw(true);
[_context presentRenderbuffer:GL_RENDERBUFFER];
}
}
- (void)speedSlow {
deltaDisplay = 5;
}
- (void)speedNormal {
deltaDisplay = 1;
}
- (void)startDisplayLink {
if (displayLink != NULL) {
return;
}
displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(render:)];
[displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
}
- (void)stopDisplayLink {
if (displayLink == NULL) {
return;
}
[displayLink removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
displayLink = NULL;
}
- (id)initWithFrame:(CGRect)frame {
deltaDisplay = 1;
displayCounter = 0;
NSLog(@"INIT with size : %fx%f, %fx%f", frame.origin.x, frame.origin.y, frame.size.width, frame.size.height);
self = [super initWithFrame:frame];
self.contentScaleFactor = 1.0f;
// TODO : Enable multi touch ==> but this generate many sub errors ... 3 touch can be appear in 1 event ...
//self.multipleTouchEnabled = YES;
if (self) {
[self configureAspectRatio];
[self setupLayer];
[self setupContext];
[self setupDepthBuffer];
[self setupRenderBuffer];
[self setupFrameBuffer];
[self startDisplayLink];
}
return self;
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
CGPoint touchLocation = [touch locationInView:self];
CGRect localBounds = [self bounds];
CGFloat screenScale = [[UIScreen mainScreen] scale];
vec2 positionEvent(touchLocation.x*screenScale, (localBounds.size.height - touchLocation.y)*screenScale);
EWOL_DEBUG(touches.count << " touchesBegan: " << positionEvent);
IOs::setInputState(1, true, positionEvent.x(), positionEvent.y());
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
CGPoint touchLocation = [touch locationInView:self];
CGRect localBounds = [self bounds];
CGFloat screenScale = [[UIScreen mainScreen] scale];
vec2 positionEvent(touchLocation.x*screenScale, (localBounds.size.height - touchLocation.y)*screenScale);
EWOL_DEBUG(touches.count << " touchesEnded: " << positionEvent);
IOs::setInputState(1, false, positionEvent.x(), positionEvent.y());
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
CGPoint touchLocation = [touch locationInView:self];
CGRect localBounds = [self bounds];
CGFloat screenScale = [[UIScreen mainScreen] scale];
vec2 positionEvent(touchLocation.x*screenScale, (localBounds.size.height - touchLocation.y)*screenScale);
EWOL_DEBUG(touches.count << " touchesMoved: " << positionEvent);
IOs::setInputMotion(1, positionEvent.x(), positionEvent.y());
}
- (void)layoutSubviews {
[EAGLContext setCurrentContext:_context];
}
- (void)dealloc {
if ([EAGLContext currentContext] == _context) {
[EAGLContext setCurrentContext:nil];
}
}
@end

View File

@ -0,0 +1,429 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#include <etk/types.h>
#include <etk/types.h>
#include <gale/debug.h>
#include <gale/gale.h>
#include <gale/context/Context.h>
#include <gale/context/InputManager.h>
#include <gale/Application.h>
#define EVENT_DEBUG GALE_VERBOSE
//#define EVENT_DEBUG GALE_DEBUG
void gale::context::InputManager::calculateLimit() {
m_eventInputLimit.sepatateTime = 300000; // µs
m_eventInputLimit.DpiOffset = m_dpi*100;
m_eventMouseLimit.sepatateTime = 300000; // µs
m_eventMouseLimit.DpiOffset = (float)m_dpi*(float)0.1;
}
void gale::context::InputManager::setDpi(int32_t newDPI) {
m_dpi = newDPI;
// recalculate the DPI system ...
calculateLimit();
}
bool gale::context::InputManager::localEventInput(enum gale::key::type _type,
std::shared_ptr<gale::Application> _destApplication,
int32_t _IdInput,
enum gale::key::status _status,
vec2 _pos) {
if (nullptr != _destApplication) {
if (_type == gale::key::typeMouse || _type == gale::key::typeFinger) {
// create the system Event :
gale::event::InputSystem tmpEventSystem(_type, _status, _IdInput, _pos, _destApplication, 0, m_specialKey); // TODO : set the real ID ...
// generate the event :
return _destApplication->systemEventInput(tmpEventSystem);
} else {
return false;
}
}
return false;
}
void gale::context::InputManager::abortElement(InputPoperty *_eventTable,
int32_t _idInput,
enum gale::key::type _type) {
if (nullptr == _eventTable) {
return;
}
if (_eventTable[_idInput].isUsed == true) {
localEventInput(_type,
_eventTable[_idInput].curentApplicationEvent.lock(),
_eventTable[_idInput].destinationInputId,
gale::key::statusAbort,
_eventTable[_idInput].posEvent);
}
}
void gale::context::InputManager::cleanElement(InputPoperty *_eventTable,
int32_t _idInput) {
if (nullptr == _eventTable) {
return;
}
//GALE_INFO("CleanElement[" << idInput << "] = @" << (int64_t)eventTable);
_eventTable[_idInput].isUsed = false;
_eventTable[_idInput].destinationInputId = 0;
_eventTable[_idInput].lastTimeEvent = 0;
_eventTable[_idInput].curentApplicationEvent.reset();
_eventTable[_idInput].origin.setValue(0,0);
_eventTable[_idInput].size.setValue(99999999,99999999);
_eventTable[_idInput].downStart.setValue(0,0);
_eventTable[_idInput].isDown = false;
_eventTable[_idInput].isInside = false;
_eventTable[_idInput].nbClickEvent = 0;
_eventTable[_idInput].posEvent.setValue(0,0);
}
gale::context::InputManager::InputManager(gale::Context& _context) :
m_grabApplication(),
m_context(_context) {
setDpi(200);
GALE_INFO("Init (start)");
for(int32_t iii=0; iii<MAX_MANAGE_INPUT; iii++) {
// remove the property of this input ...
cleanElement(m_eventInputSaved, iii);
cleanElement(m_eventMouseSaved, iii);
}
GALE_INFO("Init (end)");
}
gale::context::InputManager::~InputManager() {
GALE_INFO("Un-Init (start)");
GALE_INFO("Un-Init (end)");
}
int32_t gale::context::InputManager::localGetDestinationId(enum gale::key::type _type,
std::shared_ptr<gale::Application> _destApplication,
int32_t _realInputId) {
if (_type == gale::key::typeFinger) {
int32_t lastMinimum = 0;
for(int32_t iii=0; iii<MAX_MANAGE_INPUT; iii++) {
if (true == m_eventInputSaved[iii].isUsed) {
std::shared_ptr<gale::Application> tmpApplication = m_eventInputSaved[iii].curentApplicationEvent.lock();
if (tmpApplication == _destApplication) {
if (iii != _realInputId) {
lastMinimum = std::max(lastMinimum, m_eventInputSaved[iii].destinationInputId);
}
}
}
}
return lastMinimum+1;
}
return _realInputId;
}
// note if id<0 == > the it was finger event ...
void gale::context::InputManager::motion(enum gale::key::type _type,
int _pointerID,
vec2 _pos) {
EVENT_DEBUG("motion event : " << _type << " " << _pointerID << " " << _pos);
if (MAX_MANAGE_INPUT <= _pointerID) {
// reject pointer == > out of IDs...
return;
}
InputPoperty *eventTable = nullptr;
if (_type == gale::key::typeMouse) {
eventTable = m_eventMouseSaved;
} else if (_type == gale::key::typeFinger) {
eventTable = m_eventInputSaved;
} else {
GALE_ERROR("Unknown type of event");
return;
}
if( _pointerID > MAX_MANAGE_INPUT
|| _pointerID < 0) {
// not manage input
return;
}
std::shared_ptr<gale::Application::Windows> tmpWindows = m_context.getWindows();
// special case for the mouse event 0 that represent the hover event of the system :
if (_type == gale::key::typeMouse && _pointerID == 0) {
// this event is all time on the good Application ... and manage the enter and leave ...
// NOTE : the "layer Application" force us to get the Application at the specific position all the time :
std::shared_ptr<gale::Application> tmpApplication;
if (m_grabApplication.lock() != nullptr) {
// grab all events ...
tmpApplication = m_grabApplication.lock();
} else {
if (nullptr != tmpWindows) {
tmpApplication = tmpWindows->getApplicationAtPos(_pos);
}
}
if( tmpApplication != eventTable[_pointerID].curentApplicationEvent.lock()
|| ( true == eventTable[_pointerID].isInside
&& ( eventTable[_pointerID].origin.x() > _pos.x()
|| eventTable[_pointerID].origin.y() > _pos.y()
|| (eventTable[_pointerID].origin.x() + eventTable[_pointerID].size.x()) < _pos.x()
|| (eventTable[_pointerID].origin.y() + eventTable[_pointerID].size.y()) < _pos.y()) ) ) {
eventTable[_pointerID].isInside = false;
EVENT_DEBUG("GUI : Input ID=" << _pointerID << " == >" << eventTable[_pointerID].destinationInputId << " [LEAVE] " << _pos);
eventTable[_pointerID].posEvent = _pos;
localEventInput(_type,
eventTable[_pointerID].curentApplicationEvent.lock(),
eventTable[_pointerID].destinationInputId,
gale::key::statusLeave,
_pos);
}
if (eventTable[_pointerID].isInside == false) {
// set the element inside ...
eventTable[_pointerID].isInside = true;
// get destination Application :
eventTable[_pointerID].curentApplicationEvent = tmpApplication;
if (tmpApplication == nullptr) {
eventTable[_pointerID].isInside = false;
} else {
eventTable[_pointerID].origin = tmpApplication->getOrigin();
eventTable[_pointerID].size = tmpApplication->getSize();
}
eventTable[_pointerID].destinationInputId = 0;
EVENT_DEBUG("GUI : Input ID=" << _pointerID
<< " == >" << eventTable[_pointerID].destinationInputId
<< " [ENTER] " << _pos);
eventTable[_pointerID].posEvent = _pos;
localEventInput(_type,
tmpApplication,
eventTable[_pointerID].destinationInputId,
gale::key::statusEnter,
_pos);
}
EVENT_DEBUG("GUI : Input ID=" << _pointerID
<< " == >" << eventTable[_pointerID].destinationInputId
<< " [MOVE] " << _pos);
eventTable[_pointerID].posEvent = _pos;
localEventInput(_type,
tmpApplication,
eventTable[_pointerID].destinationInputId,
gale::key::statusMove,
_pos);
} else if (true == eventTable[_pointerID].isUsed) {
if (true == eventTable[_pointerID].isInside) {
if( eventTable[_pointerID].origin.x() > _pos.x()
|| eventTable[_pointerID].origin.y() > _pos.y()
|| (eventTable[_pointerID].origin.x() + eventTable[_pointerID].size.x()) < _pos.x()
|| (eventTable[_pointerID].origin.y() + eventTable[_pointerID].size.y()) < _pos.y()) {
eventTable[_pointerID].isInside = false;
EVENT_DEBUG("GUI : Input ID=" << _pointerID
<< " == >" << eventTable[_pointerID].destinationInputId
<< " [LEAVE] " << _pos);
eventTable[_pointerID].posEvent = _pos;
localEventInput(_type,
eventTable[_pointerID].curentApplicationEvent.lock(),
eventTable[_pointerID].destinationInputId,
gale::key::statusLeave,
_pos);
}
} else {
if( ( eventTable[_pointerID].origin.x() <= _pos.x()
&& (eventTable[_pointerID].origin.x() + eventTable[_pointerID].size.x()) >= _pos.x() )
&& ( eventTable[_pointerID].origin.y() <= _pos.y()
&& (eventTable[_pointerID].origin.y() + eventTable[_pointerID].size.y()) >= _pos.y() ) ) {
eventTable[_pointerID].isInside = true;
EVENT_DEBUG("GUI : Input ID=" << _pointerID
<< " == >" << eventTable[_pointerID].destinationInputId
<< " [ENTER] " << _pos);
eventTable[_pointerID].posEvent = _pos;
localEventInput(_type,
eventTable[_pointerID].curentApplicationEvent.lock(),
eventTable[_pointerID].destinationInputId,
gale::key::statusEnter,
_pos);
}
}
EVENT_DEBUG("GUI : Input ID=" << _pointerID
<< " == >" << eventTable[_pointerID].destinationInputId
<< " [MOVE] " << _pos);
eventTable[_pointerID].posEvent = _pos;
localEventInput(_type,
eventTable[_pointerID].curentApplicationEvent.lock(),
eventTable[_pointerID].destinationInputId,
gale::key::statusMove,
_pos);
}
}
void gale::context::InputManager::state(enum gale::key::type _type,
int _pointerID,
bool _isDown,
vec2 _pos)
{
if (MAX_MANAGE_INPUT <= _pointerID) {
// reject pointer == > out of IDs...
return;
}
EVENT_DEBUG("event pointerId=" << _pointerID);
// convert position in open-GL coordonates ...
InputPoperty *eventTable = nullptr;
InputLimit localLimit;
if (_type == gale::key::typeMouse) {
eventTable = m_eventMouseSaved;
localLimit = m_eventMouseLimit;
} else if (_type == gale::key::typeFinger) {
eventTable = m_eventInputSaved;
localLimit = m_eventInputLimit;
} else {
GALE_ERROR("Unknown type of event");
return;
}
if( _pointerID > MAX_MANAGE_INPUT
|| _pointerID <= 0) {
// not manage input
return;
}
// get the curent time ...
int64_t currentTime = gale::getTime();
std::shared_ptr<gale::Application::Windows> tmpWindows = m_context.getWindows();
if (true == _isDown) {
EVENT_DEBUG("GUI : Input ID=" << _pointerID
<< " == >" << eventTable[_pointerID].destinationInputId
<< " [DOWN] " << _pos);
if(true == eventTable[_pointerID].isUsed) {
// we have an event previously ... check delay between click and offset position
if (currentTime - eventTable[_pointerID].lastTimeEvent > localLimit.sepatateTime) {
cleanElement(eventTable, _pointerID);
} else if( abs(eventTable[_pointerID].downStart.x() - _pos.x()) >= localLimit.DpiOffset
|| abs(eventTable[_pointerID].downStart.y() - _pos.y()) >= localLimit.DpiOffset ){
cleanElement(eventTable, _pointerID);
}
}
if(true == eventTable[_pointerID].isUsed) {
// save start time
eventTable[_pointerID].lastTimeEvent = currentTime;
// generate DOWN Event
EVENT_DEBUG("GUI : Input ID=" << _pointerID
<< " == >" << eventTable[_pointerID].destinationInputId
<< " [DOWN] " << _pos);
eventTable[_pointerID].posEvent = _pos;
localEventInput(_type,
eventTable[_pointerID].curentApplicationEvent.lock(),
eventTable[_pointerID].destinationInputId,
gale::key::statusDown,
_pos);
} else {
// Mark it used :
eventTable[_pointerID].isUsed = true;
// Save current position :
eventTable[_pointerID].downStart = _pos;
// save start time
eventTable[_pointerID].lastTimeEvent = currentTime;
// set the element inside ...
eventTable[_pointerID].isInside = true;
std::shared_ptr<gale::Application> tmpApplication = m_grabApplication.lock();
// get destination Application :
if(nullptr != tmpWindows) {
if ( tmpApplication != nullptr
&& _type == gale::key::typeMouse) {
eventTable[_pointerID].curentApplicationEvent = tmpApplication;
} else {
eventTable[_pointerID].curentApplicationEvent = tmpWindows->getApplicationAtPos(_pos);
}
} else {
eventTable[_pointerID].curentApplicationEvent.reset();
}
tmpApplication = eventTable[_pointerID].curentApplicationEvent.lock();
if (tmpApplication != nullptr) {
eventTable[_pointerID].origin = tmpApplication->getOrigin();
eventTable[_pointerID].size = tmpApplication->getSize();
eventTable[_pointerID].destinationInputId = localGetDestinationId(_type, tmpApplication, _pointerID);
} else {
eventTable[_pointerID].destinationInputId = -1;
}
// generate DOWN Event
EVENT_DEBUG("GUI : Input ID=" << _pointerID
<< " == >" << eventTable[_pointerID].destinationInputId
<< " [DOWN] " << _pos);
eventTable[_pointerID].posEvent = _pos;
localEventInput(_type,
tmpApplication,
eventTable[_pointerID].destinationInputId,
gale::key::statusDown,
_pos);
}
} else {
EVENT_DEBUG("GUI : Input ID=" << _pointerID
<< " == >" << eventTable[_pointerID].destinationInputId
<< " [UP] " << _pos);
if(false == eventTable[_pointerID].isUsed) {
// bad case ... ???
GALE_DEBUG("Up event without previous down ... ");
// Mark it un-used :
eventTable[_pointerID].isUsed = false;
// revove the Application ...
eventTable[_pointerID].curentApplicationEvent.reset();
} else {
std::shared_ptr<gale::Application> tmpApplication = eventTable[_pointerID].curentApplicationEvent.lock();
// generate UP Event
EVENT_DEBUG("GUI : Input ID=" << _pointerID
<< " == >" << eventTable[_pointerID].destinationInputId
<< " [UP] " << _pos);
eventTable[_pointerID].posEvent = _pos;
// send up event after the single event to prevent multiple Application getting elements
localEventInput(_type,
tmpApplication,
_pointerID,
gale::key::statusUp,
_pos);
// generate event (single)
if( abs(eventTable[_pointerID].downStart.x() - _pos.x()) < localLimit.DpiOffset
&& abs(eventTable[_pointerID].downStart.y() - _pos.y()) < localLimit.DpiOffset ){
// Save current position :
eventTable[_pointerID].downStart = _pos;
// save start time
eventTable[_pointerID].lastTimeEvent = currentTime;
int32_t nbClickMax = 0;
if(tmpApplication != nullptr) {
nbClickMax = tmpApplication->getMouseLimit();
if (nbClickMax>5) {
nbClickMax = 5;
}
}
// in grab mode the single to quinte event are not generated ....
if( ( m_grabApplication.lock() == nullptr
|| _type != gale::key::typeMouse )
&& eventTable[_pointerID].nbClickEvent < nbClickMax) {
// generate event SINGLE :
eventTable[_pointerID].nbClickEvent++;
EVENT_DEBUG("GUI : Input ID=" << _pointerID
<< " == >" << eventTable[_pointerID].destinationInputId
<< " [" << eventTable[_pointerID].nbClickEvent << "] " << _pos);
eventTable[_pointerID].posEvent = _pos;
localEventInput(_type,
tmpApplication,
eventTable[_pointerID].destinationInputId,
(enum gale::key::status)(gale::key::statusSingle + eventTable[_pointerID].nbClickEvent-1),
_pos);
if( eventTable[_pointerID].nbClickEvent >= nbClickMax) {
eventTable[_pointerID].nbClickEvent = 0;
}
} else {
eventTable[_pointerID].nbClickEvent = 0;
}
}
// send up event after the single event to prevent multiple Application getting elements
localEventInput(_type,
tmpApplication,
_pointerID,
gale::key::statusUpAfter,
_pos);
// specific for tuch event
if (_type == gale::key::typeFinger) {
cleanElement(eventTable, _pointerID);
}
}
}
}

107
gale/context/InputManager.h Normal file
View File

@ -0,0 +1,107 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#ifndef __GALE_SYSTEM_INPUT_H__
#define __GALE_SYSTEM_INPUT_H__
#include <gale/Application.h>
#define MAX_MANAGE_INPUT (15)
namespace gale {
namespace context {
/**
* @brief internal structure
* @not-in-doc
*/
class InputPoperty {
public:
bool isUsed;
int32_t destinationInputId;
int64_t lastTimeEvent;
std::weak_ptr<gale::Application> curentApplicationEvent;
vec2 origin;
vec2 size;
vec2 downStart;
vec2 posEvent;
bool isDown;
bool isInside;
int32_t nbClickEvent; // 0 .. 1 .. 2 .. 3
};
/**
* @brief internal structure
* @not-in-doc
*/
class InputLimit {
public:
int32_t sepatateTime;
int32_t DpiOffset;
};
class Context;
class InputManager {
// special grab pointer mode :
private:
std::weak_ptr<gale::Application> m_grabApplication; //!< Application that grab the curent pointer.
private:
int32_t m_dpi;
InputLimit m_eventInputLimit;
InputLimit m_eventMouseLimit;
void calculateLimit();
InputPoperty m_eventInputSaved[MAX_MANAGE_INPUT];
InputPoperty m_eventMouseSaved[MAX_MANAGE_INPUT];
void abortElement(InputPoperty* _eventTable, int32_t _idInput, enum gale::key::type _type);
void cleanElement(InputPoperty* _eventTable, int32_t _idInput);
/**
* @brief generate the event on the destinated Application.
* @param[in] _type Type of the event that might be sended.
* @param[in] _destApplication Pointer on the requested Application that element might be sended
* @param[in] _IdInput Id of the event (PC : [0..9] and touch : [1..9])
* @param[in] _typeEvent type of the eventg generated
* @param[in] _pos position of the event
* @return true if event has been greped
*/
bool localEventInput(enum gale::key::type _type,
std::shared_ptr<gale::Application> _destApplication,
int32_t _IdInput,
enum gale::key::status _typeEvent,
vec2 _pos);
/**
* @brief convert the system event id in the correct GALE id depending of the system management mode
* This function find the next input id unused on the specifiic Application
* == > on PC, the ID does not change (GUI is not the same)
* @param[in] _type Type of the kay event.
* @param[in] _destApplication Pointer of the Application destination
* @param[in] _realInputId system Id
* @return the gale input id
*/
int32_t localGetDestinationId(enum gale::key::type _type,
std::shared_ptr<gale::Application> _destApplication,
int32_t _realInputId);
private:
gale::Context& m_context;
public:
InputManager(gale::Context& _context);
~InputManager();
void setDpi(int32_t _newDPI);
// note if id<0 == > the it was finger event ...
void motion(enum gale::key::type _type, int _pointerID, vec2 _pos );
void state(enum gale::key::type _type, int _pointerID, bool _isDown, vec2 _pos);
private:
gale::key::Special m_specialKey;
public:
void setLastKeyboardSpecial(const gale::key::Special& _specialKey) {
m_specialKey = _specialKey;
}
};
};
};
#endif

View File

@ -0,0 +1,16 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#import <Cocoa/Cocoa.h>
@interface MacOsAppDelegate : NSObject <NSApplicationDelegate>
@property (assign) IBOutlet NSWindow *window;
- (void)sendEvent:(NSEvent *)event;
- (void)applicationWillResignActive:(MacOsAppDelegate *)application;
@end

View File

@ -0,0 +1,76 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#import <ewol/context/MacOs/AppDelegate.h>
#import <ewol/context/MacOs/OpenglView.h>
#include <ewol/debug.h>
@implementation MacOsAppDelegate
@synthesize window=_window;
- (BOOL)application:(MacOsAppDelegate *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
OpenGLView *view=[[OpenGLView alloc]initWithFrame:[[NSScreen mainScreen] frame]];
return YES;
}
- (void)applicationWillResignActive:(MacOsAppDelegate *)application {
/*
Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
*/
EWOL_INFO("move windows in applicationWillResignActive");
}
- (void)applicationDidEnterBackground:(MacOsAppDelegate *)application {
/*
Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
*/
EWOL_INFO("move windows in applicationDidEnterBackground");
}
- (void)applicationWillEnterForeground:(MacOsAppDelegate *)application {
/*
Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
*/
EWOL_INFO("move windows in applicationWillEnterForeground");
}
- (void)applicationDidBecomeActive:(MacOsAppDelegate *)application {
/*
Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
*/
EWOL_INFO("move windows in applicationDidBecomeActive");
}
- (void)applicationWillTerminate:(MacOsAppDelegate *)application {
/*
Called when the application is about to terminate.
Save data if appropriate.
See also applicationDidEnterBackground:.
*/
EWOL_INFO("move windows in applicationWillTerminate");
}
- (void)dealloc {
[_window release];
[super dealloc];
}
- (void)sendEvent:(NSEvent *)event {
EWOL_WARNING(" EVENT ... ");
}
@end

View File

@ -0,0 +1,30 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#ifndef __MAC_OS_CONTEXT_H__
#define __MAC_OS_CONTEXT_H__
#include <gale/key/key.h>
namespace MacOs {
// return true if a flush is needed
bool draw(bool _displayEveryTime);
/**
* @brief The OS inform that the current windows has change his size.
* @param[in] _size new size of the windows.
*/
void resize(float _x, float _y);
void setMouseState(int32_t _id, bool _isDown, float _x, float _y);
void setMouseMotion(int32_t _id, float _x, float _y);
void setKeyboard(gale::key::Special _keyboardMode, int32_t _unichar, bool _isDown, bool _isAReapeateKey);
void setKeyboardMove(gale::key::Special& _keyboardMode, enum gale::key::keyboard _move, bool _isDown, bool _isAReapeateKey);
void stopRequested();
void setRedrawCallback(const std::function<void()>& _func);
};
#endif

View File

@ -0,0 +1,246 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#include <ewol/debug.h>
#include <ewol/ewol.h>
#include <ewol/key/key.h>
#include <ewol/context/commandLine.h>
#include <ewol/context/clipBoard.h>
#include <etk/types.h>
#include <etk/os/FSNode.h>
#include <ewol/widget/Manager.h>
#include <ewol/resource/Manager.h>
#include <ewol/context/Context.h>
#include <ewol/context/MacOs/Interface.h>
#include <ewol/context/MacOs/Context.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/times.h>
#include <mach/clock.h>
#include <mach/mach.h>
#include <etk/etk.h>
#import <Cocoa/Cocoa.h>
int64_t ewol::getTime() {
struct timespec now;
clock_serv_t cclock;
mach_timespec_t mts;
host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &cclock);
clock_get_time(cclock, &mts);
mach_port_deallocate(mach_task_self(), cclock);
now.tv_sec = mts.tv_sec;
now.tv_nsec = mts.tv_nsec;
//EWOL_VERBOSE("current time : " << now.tv_sec << "s " << now.tv_usec << "us");
return (int64_t)((int64_t)now.tv_sec*(int64_t)1000000 + (int64_t)now.tv_nsec/(int64_t)1000);
}
#undef __class__
#define __class__ "MacOSInterface"
class MacOSInterface : public ewol::Context {
private:
ewol::key::Special m_guiKeyBoardMode;
public:
MacOSInterface(ewol::context::Application* _application, int _argc, const char* _argv[]) :
ewol::Context(_application, _argc, _argv) {
mm_main(_argc, _argv);
}
int32_t Run() {
return mm_run();
}
public:
//interface MacOS :
bool MAC_Draw(bool _displayEveryTime) {
return OS_Draw(_displayEveryTime);
}
void MAC_Resize(float _x, float _y) {
OS_Resize(vec2(_x,_y));
}
void MAC_SetMouseState(int32_t _id, bool _isDown, float _x, float _y) {
OS_SetMouseState(_id, _isDown, vec2(_x, _y));
}
void MAC_SetMouseMotion(int32_t _id, float _x, float _y) {
OS_SetMouseMotion(_id, vec2(_x, _y));
}
void MAC_SetKeyboard(ewol::key::Special _keyboardMode, int32_t _unichar, bool _isDown, bool _isAReapeateKey) {
if (char32_t(_unichar) == u32char::Delete) {
_unichar = u32char::Suppress;
} else if (char32_t(_unichar) == u32char::Suppress) {
_unichar = u32char::Delete;
}
if (char32_t(_unichar) == u32char::CarrierReturn) {
_unichar = u32char::Return;
}
//EWOL_DEBUG("key: " << _unichar << " up=" << !_isDown);
if (_unichar <= 4) {
enum ewol::key::keyboard move;
switch(_unichar) {
case 0:
move = ewol::key::keyboardUp;
break;
case 1:
move = ewol::key::keyboardDown;
break;
case 2:
move = ewol::key::keyboardLeft;
break;
case 3:
move = ewol::key::keyboardRight;
break;
}
OS_SetKeyboardMove(_keyboardMode, move, !_isDown, _isAReapeateKey);
} else {
OS_SetKeyboard(_keyboardMode, _unichar, !_isDown, _isAReapeateKey);
}
}
void MAC_SetKeyboardMove(ewol::key::Special& _special,
enum ewol::key::keyboard _move,
bool _isDown,
bool _isAReapeateKey) {
OS_SetKeyboardMove(_special, _move, _isDown, _isAReapeateKey);
}
void openURL(const std::string& _url) {
std::string req = "open " + _url;
system(req.c_str());
}
void MAC_Stop() {
OS_Stop();
}
void stop() {
mm_stopApplication();
}
void clipBoardGet(enum ewol::context::clipBoard::clipboardListe _clipboardID) {
if (_clipboardID == ewol::context::clipBoard::clipboardStd) {
NSPasteboard* myPasteboard = [NSPasteboard generalPasteboard];
NSString* myString = [myPasteboard stringForType:NSPasteboardTypeString];
std::string val([myString UTF8String]);
ewol::context::clipBoard::setSystem(_clipboardID, val);
if (val.size() != 0) {
OS_ClipBoardArrive(_clipboardID);
}
} else {
ewol::Context::clipBoardGet(_clipboardID);
}
}
void clipBoardSet(enum ewol::context::clipBoard::clipboardListe _clipboardID) {
if (_clipboardID == ewol::context::clipBoard::clipboardStd) {
NSPasteboard* myPasteboard = [NSPasteboard generalPasteboard];
[myPasteboard clearContents];
//EWOL_ERROR(" copy: " << ewol::context::clipBoard::get(_clipboardID));
NSString *text = [[NSString alloc] initWithUTF8String:ewol::context::clipBoard::get(_clipboardID).c_str()];
BOOL err = [myPasteboard setString:text forType:NSPasteboardTypeString];
if (err == FALSE) {
EWOL_ERROR("copy to clipboard can not be done ...");
}
} else {
ewol::Context::clipBoardSet(_clipboardID);
}
}
};
MacOSInterface* interface = nullptr;
bool MacOs::draw(bool _displayEveryTime) {
if (interface == nullptr) {
return false;
}
return interface->MAC_Draw(_displayEveryTime);
}
void MacOs::resize(float _x, float _y) {
if (interface == nullptr) {
return;
}
interface->MAC_Resize(_x, _y);
}
void MacOs::setMouseState(int32_t _id, bool _isDown, float _x, float _y) {
if (interface == nullptr) {
return;
}
interface->MAC_SetMouseState(_id, _isDown, _x, _y);
}
void MacOs::setMouseMotion(int32_t _id, float _x, float _y) {
if (interface == nullptr) {
return;
}
interface->MAC_SetMouseMotion(_id, _x, _y);
}
void MacOs::setKeyboard(ewol::key::Special _keyboardMode, int32_t _unichar, bool _isDown, bool _isAReapeateKey) {
if (interface == nullptr) {
return;
}
interface->MAC_SetKeyboard(_keyboardMode, _unichar, _isDown, _isAReapeateKey);
}
void MacOs::setKeyboardMove(ewol::key::Special& _keyboardMode, enum ewol::key::keyboard _move, bool _isDown, bool _isAReapeateKey) {
if (interface == nullptr) {
return;
}
interface->MAC_SetKeyboardMove(_keyboardMode, _move, _isDown, _isAReapeateKey);
}
void MacOs::stopRequested() {
if (interface == nullptr) {
return;
}
interface->MAC_Stop();
}
void MacOs::setRedrawCallback(const std::function<void()>& _func) {
if (interface == nullptr) {
return;
}
interface->getWidgetManager().setCallbackonRedrawNeeded(_func);
}
/**
* @brief Main of the program
* @param std IO
* @return std IO
*/
int ewol::run(ewol::context::Application* _application, int _argc, const char* _argv[]) {
etk::init(_argc, _argv);
interface = new MacOSInterface(_application, _argc, _argv);
if (nullptr == interface) {
EWOL_CRITICAL("Can not create the X11 interface ... MEMORY allocation error");
return -2;
}
int32_t retValue = interface->Run();
EWOL_INFO("Stop running");
delete(interface);
interface = nullptr;
return retValue;
}

View File

@ -0,0 +1,24 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#ifndef __GALE_MM_INTERFACE_H__
#define __GALE_MM_INTERFACE_H__
#ifdef __cplusplus
extern "C" {
#endif
int mm_main(int _argc, const char* _argv[]);
int mm_run();
void mm_stopApplication();
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,104 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#include "Context.h"
#import <Cocoa/Cocoa.h>
#include "ewol/context/MacOs/Interface.h"
#import <ewol/context/MacOs/OpenglView.h>
#import <ewol/context/MacOs/Windows.h>
#import <ewol/context/MacOs/AppDelegate.h>
#import <ewol/debug.h>
id window = nil;
void callbackSomeThingToDo() {
//EWOL_CRITICAL("ksdjlkqjsdlfkjsqdlkfjslqkdjflqksjdf");
[window UpdateScreenRequested];
}
int mm_main(int _argc, const char* _argv[]) {
[NSAutoreleasePool new];
[NSApplication sharedApplication];
// set the quit policy and all stadard for Mac
[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
// ---------------------------------------------------------------
// -- basic menu bar creation :
// ---------------------------------------------------------------
// set the basic menu bar (stadard on Mac OSX)
id menubar = [[NSMenu new] autorelease];
//add an item
id appMenuItem = [[NSMenuItem new] autorelease];
// add the item to the menu bar:
[menubar addItem:appMenuItem];
// set the main menu in the menu bar ...
[NSApp setMainMenu:menubar];
id appMenu = [[NSMenu new] autorelease];
id appName = [[NSProcessInfo processInfo] processName];
// create the label to qui the application :
id quitTitle = [@"Quit " stringByAppendingString:appName];
// create the item to quit the appllication with META+q at shortCut
id quitMenuItem = [ [ [NSMenuItem alloc] initWithTitle:quitTitle
action:@selector(stop:) keyEquivalent:@"q"] autorelease];
// add the item to the menu:
[appMenu addItem:quitMenuItem];
// set the application menu to the main app menu ...
[appMenuItem setSubmenu:appMenu];
// ---------------------------------------------------------------
// -- basic windows creation :
// ---------------------------------------------------------------
// create a windows of size 800/600
window = [ [ [EwolMainWindows alloc] initWithContentRect:NSMakeRect(0, 0, 800, 600)
styleMask:(NSTitledWindowMask|NSMiniaturizableWindowMask|NSClosableWindowMask) backing:NSBackingStoreBuffered defer:NO]
autorelease];
[window setAcceptsMouseMovedEvents:YES];
//id window = [ [MacOsAppDelegate alloc] autorelease];
// set the windows at a specific position :
[window cascadeTopLeftFromPoint:NSMakePoint(50,50)];
// set the windows resizable
[window setStyleMask:[window styleMask] | NSResizableWindowMask];
// oposite : [window setStyleMask:[window styleMask] & ~NSResizableWindowMask];
// set the title
[window setTitle:appName];
[window setAcceptsMouseMovedEvents:YES];
// ???
[window makeKeyAndOrderFront:nil];
[NSApp activateIgnoringOtherApps:YES];
NSRect window_frame = [window frame];
OpenGLView* view=[[OpenGLView alloc]initWithFrame:window_frame]; //NSMakeRect(0, 0, 800, 600)];
NSTrackingArea *track = [[NSTrackingArea alloc] initWithRect:window_frame options: NSTrackingMouseMoved | NSTrackingActiveWhenFirstResponder | NSTrackingActiveInKeyWindow
owner:window userInfo:nil];
[view addTrackingArea:track];
[window setContentView:view];
[view setAutoresizesSubviews:YES];
return 0;
}
int mm_run(void) {
//MacOs::setRedrawCallback(std::bind(callbackSomeThingToDo));
[NSApp run];
EWOL_DEBUG("END of application");
// return no error
return 0;
}
void mm_stopApplication() {
EWOL_DEBUG("NSApp terminate start.");
[window closeRequestEwol];
[NSApp stop:nil];
EWOL_DEBUG("NSApp terminate done");
}

View File

@ -0,0 +1,21 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#import <Cocoa/Cocoa.h>
#import <OpenGL/OpenGL.h>
#import <OpenGL/gl.h>
@interface OpenGLView : NSOpenGLView<NSWindowDelegate> {
NSTimer* _refreshTimer;
bool _redraw;
}
- (void)prepareOpenGL;
- (void)drawRect:(NSRect) bounds;
- (void)UpdateScreenRequested;
@end

View File

@ -0,0 +1,70 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#import <ewol/context/MacOs/OpenglView.h>
#include <OpenGL/gl.h>
#include <ewol/context/MacOS/Context.h>
#include <ewol/debug.h>
#include <ewol/Dimension.h>
@implementation OpenGLView
- (void) prepareOpenGL {
EWOL_INFO("prepare");
GLint swapInt = 1;
[[self openGLContext] setValues:&swapInt forParameter:NSOpenGLCPSwapInterval];
// set system dpi size :
NSScreen *screen = [NSScreen mainScreen];
NSDictionary *description = [screen deviceDescription];
NSSize displayPixelSize = [[description objectForKey:NSDeviceSize] sizeValue];
CGSize displayPhysicalSize = CGDisplayScreenSize([[description objectForKey:@"NSScreenNumber"] unsignedIntValue]);
ewol::Dimension::setPixelRatio(vec2((float)displayPixelSize.width/(float)displayPhysicalSize.width,
(float)displayPixelSize.height/(float)displayPhysicalSize.height),
ewol::Dimension::Millimeter);
_refreshTimer=[ [ NSTimer scheduledTimerWithTimeInterval:0.017 target:self selector:@selector(animationTimerFired:) userInfo:nil repeats:YES ] retain ] ;
_redraw = true;
}
- (void)UpdateScreenRequested {
_redraw = true;
}
-(void) drawRect: (NSRect) bounds {
if ( ! _refreshTimer ) {
_refreshTimer=[ [ NSTimer scheduledTimerWithTimeInterval:0.017 target:self selector:@selector(animationTimerFired:) userInfo:nil repeats:YES ] retain ] ;
EWOL_WARNING("create timer ... ");
}
MacOs::draw(false);
}
/**
* Service the animation timer.
*/
- (void) animationTimerFired: (NSTimer *) timer {
if (_redraw == true) {
//_redraw = false;
[self setNeedsDisplay:YES];
//EWOL_WARNING("view refresh ..." );
}
}
-(void)reshape {
EWOL_INFO("view reshape (" << [self frame].size.width << "," << [self frame].size.height << ")" );
// window resize; width and height are in pixel coordinates
// but they are floats
float width = [self frame].size.width;
float height = [self frame].size.height;
MacOs::resize(width,height);
}
@end

View File

@ -0,0 +1,39 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#import <Cocoa/Cocoa.h>
#import <gale/context/MacOs/OpenglView.h>
@interface GaleMainWindows : NSWindow {
OpenGLView* _view;
}
+ (id)alloc;
- (id)init;
+ (void)dealloc;
+ (void)performClose:(id)sender;
// All mouse events:
- (void)mouseDown:(NSEvent *) event;
- (void)mouseDragged:(NSEvent *) event;
- (void)mouseUp:(NSEvent *)event;
- (void)mouseMoved:(NSEvent *)event;
- (void)mouseEntered:(NSEvent *)event;
- (void)mouseExited:(NSEvent *)event;
- (void)rightMouseDown:(NSEvent *)event;
- (void)rightMouseDragged:(NSEvent *)event;
- (void)rightMouseUp:(NSEvent *)event;
- (void)otherMouseDown:(NSEvent *)event;
- (void)otherMouseDragged:(NSEvent *)event;
- (void)otherMouseUp:(NSEvent *)event;
// keyboard eevnts:
- (void)keyDown:(NSEvent *)theEvent;
- (void)flagsChanged:(NSEvent *)theEvent;
- (void)closeRequestGale;
- (void)UpdateScreenRequested;
@end

View File

@ -0,0 +1,443 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#import <ewol/context/MacOs/Windows.h>
#include <ewol/context/MacOS/Context.h>
#include <ewol/key/key.h>
#include <ewol/debug.h>
@implementation EwolMainWindows
+ (id)alloc {
id windowsID = [super alloc];
EWOL_DEBUG("ALLOCATE ...");
return windowsID;
}
- (id)init {
id windowsID = [super init];
//[NSApp setDelegate: self];
EWOL_DEBUG("INIT ...");
// set the windows at a specific position :
[windowsID cascadeTopLeftFromPoint:NSMakePoint(50,50)];
EWOL_DEBUG("ALLOCATE ...");
// set the windows resizable
[windowsID setStyleMask:[windowsID styleMask] | NSResizableWindowMask];
EWOL_DEBUG("ALLOCATE ...");
// oposite : [window setStyleMask:[window styleMask] & ~NSResizableWindowMask];
// set the title
id appName = [[NSProcessInfo processInfo] processName];
EWOL_DEBUG("ALLOCATE ...");
[windowsID setTitle:appName];
EWOL_DEBUG("ALLOCATE ...");
[windowsID setAcceptsMouseMovedEvents:YES];
EWOL_DEBUG("ALLOCATE ...");
// ???
[windowsID makeKeyAndOrderFront:nil];
EWOL_DEBUG("ALLOCATE ...");
[NSApp activateIgnoringOtherApps:YES];
EWOL_DEBUG("ALLOCATE ...");
NSRect window_frame = [windowsID frame];
EWOL_DEBUG("ALLOCATE ...");
_view=[[OpenGLView alloc]initWithFrame:window_frame]; //NSMakeRect(0, 0, 800, 600)];
EWOL_DEBUG("ALLOCATE ...");
[windowsID setContentView:_view];
EWOL_DEBUG("ALLOCATE ...");
[_view setAutoresizesSubviews:YES];
EWOL_DEBUG("ALLOCATE ...");
// Override point for customization after application launch.
//[window addSubview:view];
//[window addChildWindow:view];
//[window makeKeyAndVisible];
//[windowsID setDelegate:view];
EWOL_DEBUG("ALLOCATE ...");
return windowsID;
}
+ (void)dealloc {
EWOL_ERROR("FREE ...");
//[_window release];
[super dealloc];
}
+ (void)performClose:(id)sender {
EWOL_ERROR("perform close ...");
}
static ewol::key::Special guiKeyBoardMode;
-(void)localKeyEvent:(NSEvent*)theEvent isDown:(bool)_isDown {
bool thisIsAReapeateKey = false;
if ([theEvent isARepeat]) {
thisIsAReapeateKey = true;
}
NSString *str = [theEvent charactersIgnoringModifiers];
// TODO : set if for every char in the string !!!
unichar c = [str characterAtIndex:0];
EWOL_VERBOSE("Key Event " << c << " = '" << char(c) << "' isDown=" << _isDown);
bool find = true;
enum ewol::key::keyboard keyInput;
switch (c) {
case 63232: keyInput = ewol::key::keyboardUp; break;
case 63233: keyInput = ewol::key::keyboardDown; break;
case 63234: keyInput = ewol::key::keyboardLeft; break;
case 63235: keyInput = ewol::key::keyboardRight; break;
case 63276: keyInput = ewol::key::keyboardPageUp; break;
case 63277: keyInput = ewol::key::keyboardPageDown; break;
case 63273: keyInput = ewol::key::keyboardStart; break;
case 63275: keyInput = ewol::key::keyboardEnd; break;
/*
case 78: keyInput = ewol::key::keyboardStopDefil; break;
case 127: keyInput = ewol::key::keyboardWait; break;
*/
case 63302:
find = false;
keyInput = ewol::key::keyboardInsert;
if(_isDown == false) {
if (true == guiKeyBoardMode.getInsert()) {
guiKeyBoardMode.setInsert(false);
} else {
guiKeyBoardMode.setInsert(true);
}
}
EWOL_VERBOSE("Key Event " << c << " = '" << char(c) << "' isDown=" << _isDown);
MacOs::setKeyboardMove(guiKeyBoardMode, keyInput, true, thisIsAReapeateKey);
EWOL_VERBOSE("Key Event " << c << " = '" << char(c) << "' isDown=" << !_isDown);
MacOs::setKeyboardMove(guiKeyBoardMode, keyInput, false, thisIsAReapeateKey);
break;
//case 84: keyInput = ewol::key::keyboardCenter; break; // Keypad
case 63236: keyInput = ewol::key::keyboardF1; break;
case 63237: keyInput = ewol::key::keyboardF2; break;
case 63238: keyInput = ewol::key::keyboardF3; break;
case 63239: keyInput = ewol::key::keyboardF4; break;
case 63240: keyInput = ewol::key::keyboardF5; break;
case 63241: keyInput = ewol::key::keyboardF6; break;
case 63242: keyInput = ewol::key::keyboardF7; break;
case 63243: keyInput = ewol::key::keyboardF8; break;
case 63244: keyInput = ewol::key::keyboardF9; break;
case 63245: keyInput = ewol::key::keyboardF10; break;
case 63246: keyInput = ewol::key::keyboardF11; break;
case 63247: keyInput = ewol::key::keyboardF12; break;
case 63272: // Suppress
find = false;
MacOs::setKeyboard(guiKeyBoardMode, u32char::Delete, _isDown, thisIsAReapeateKey);
if (true == thisIsAReapeateKey) {
MacOs::setKeyboard(guiKeyBoardMode, u32char::Delete, !_isDown, thisIsAReapeateKey);
}
break;
default:
find = false;
{
if (guiKeyBoardMode.getAlt() == true) {
// special keyboard transcription ...
str = [theEvent characters];
c = [str characterAtIndex:0];
}
EWOL_VERBOSE("Key Event " << c << " = '" << char(c) << "' isDown=" << _isDown);
MacOs::setKeyboard(guiKeyBoardMode, c, _isDown, thisIsAReapeateKey);
if (true==thisIsAReapeateKey) {
MacOs::setKeyboard(guiKeyBoardMode, c, !_isDown, thisIsAReapeateKey);
}
}
break;
}
if (find == true) {
EWOL_VERBOSE("eventKey Move type : " << keyInput );
MacOs::setKeyboardMove(guiKeyBoardMode, keyInput, _isDown, thisIsAReapeateKey);
if (true == thisIsAReapeateKey) {
MacOs::setKeyboardMove(guiKeyBoardMode, keyInput, !_isDown, thisIsAReapeateKey);
}
}
}
- (void)keyDown:(NSEvent *)theEvent {
[self localKeyEvent:theEvent isDown:true];
}
- (void)keyUp:(NSEvent *)theEvent {
[self localKeyEvent:theEvent isDown:false];
}
- (void)flagsChanged:(NSEvent *)theEvent {
if (([theEvent modifierFlags] & NSAlphaShiftKeyMask) != 0) {
EWOL_VERBOSE("NSAlphaShiftKeyMask");
if (guiKeyBoardMode.getCapsLock() == false) {
guiKeyBoardMode.setCapsLock(true);
MacOs::setKeyboardMove(guiKeyBoardMode, ewol::key::keyboardCapLock, true, false);
}
} else {
if (guiKeyBoardMode.getCapsLock() == true) {
guiKeyBoardMode.setCapsLock(false);
MacOs::setKeyboardMove(guiKeyBoardMode, ewol::key::keyboardCapLock, false, false);
}
}
if (([theEvent modifierFlags] & NSShiftKeyMask) != 0) {
EWOL_VERBOSE("NSShiftKeyMask");
if (guiKeyBoardMode.getShift() == false) {
guiKeyBoardMode.setShift(true);
MacOs::setKeyboardMove(guiKeyBoardMode, ewol::key::keyboardShiftLeft, true, false);
}
} else {
if (guiKeyBoardMode.getShift() == true) {
guiKeyBoardMode.setShift(false);
MacOs::setKeyboardMove(guiKeyBoardMode, ewol::key::keyboardShiftLeft, false, false);
}
}
if (([theEvent modifierFlags] & NSControlKeyMask) != 0) {
//EWOL_VERBOSE("NSControlKeyMask");
if (guiKeyBoardMode.getCtrl() == false) {
EWOL_VERBOSE("NSControlKeyMask DOWN");
guiKeyBoardMode.setCtrl(true);
MacOs::setKeyboardMove(guiKeyBoardMode, ewol::key::keyboardCtrlLeft, true, false);
}
} else {
if (guiKeyBoardMode.getCtrl() == true) {
EWOL_VERBOSE("NSControlKeyMask UP");
guiKeyBoardMode.setCtrl(false);
MacOs::setKeyboardMove(guiKeyBoardMode, ewol::key::keyboardCtrlLeft, false, false);
}
}
if (([theEvent modifierFlags] & NSAlternateKeyMask) != 0) {
EWOL_VERBOSE("NSAlternateKeyMask");
if (guiKeyBoardMode.getAlt() == false) {
guiKeyBoardMode.setAlt(true);
MacOs::setKeyboardMove(guiKeyBoardMode, ewol::key::keyboardAlt, true, false);
}
} else {
if (guiKeyBoardMode.getAlt() == true) {
guiKeyBoardMode.setAlt(false);
MacOs::setKeyboardMove(guiKeyBoardMode, ewol::key::keyboardAlt, false, false);
}
}
if (([theEvent modifierFlags] & NSCommandKeyMask) != 0) {
EWOL_VERBOSE("NSCommandKeyMask");
if (guiKeyBoardMode.getMeta() == false) {
guiKeyBoardMode.setMeta(true);
MacOs::setKeyboardMove(guiKeyBoardMode, ewol::key::keyboardMetaLeft, true, false);
}
} else {
if (guiKeyBoardMode.getMeta() == true) {
guiKeyBoardMode.setMeta(false);
MacOs::setKeyboardMove(guiKeyBoardMode, ewol::key::keyboardMetaLeft, false, false);
}
}
if (([theEvent modifierFlags] & NSNumericPadKeyMask) != 0) {
EWOL_VERBOSE("NSNumericPadKeyMask");
if (guiKeyBoardMode.getNumLock() == false) {
guiKeyBoardMode.setNumLock(true);
MacOs::setKeyboardMove(guiKeyBoardMode, ewol::key::keyboardNumLock, true, false);
}
} else {
if (guiKeyBoardMode.getNumLock() == true) {
guiKeyBoardMode.setNumLock(false);
MacOs::setKeyboardMove(guiKeyBoardMode, ewol::key::keyboardNumLock, false, false);
}
}
if (([theEvent modifierFlags] & NSHelpKeyMask) != 0) {
EWOL_VERBOSE("NSHelpKeyMask");
}
if (([theEvent modifierFlags] & NSFunctionKeyMask) != 0) {
EWOL_VERBOSE("NSFunctionKeyMask");
MacOs::setKeyboardMove(guiKeyBoardMode, ewol::key::keyboardContextMenu, true, false);
MacOs::setKeyboardMove(guiKeyBoardMode, ewol::key::keyboardContextMenu, false, false);
}
EWOL_VERBOSE("EVENT : " << int32_t([theEvent modifierFlags]));
}
// this generate all the event entry availlable ==> like a big keep focus ...
- (BOOL)acceptsFirstResponder {
return YES;
}
- (BOOL)becomeFirstResponder {
return YES;
}
-(void)mouseMoved:(NSEvent *)event {
NSPoint point = [event locationInWindow];
EWOL_VERBOSE("mouseMoved : " << (float)point.x << " " << (float)point.y);
MacOs::setMouseMotion(0, point.x, point.y);
}
-(void)mouseEntered:(NSEvent *)event {
NSPoint point = [event locationInWindow];
EWOL_INFO("mouseEntered : " << (float)point.x << " " << (float)point.y);
}
-(void)mouseExited:(NSEvent *)event {
NSPoint point = [event locationInWindow];
EWOL_INFO("mouseExited : " << (float)point.x << " " << (float)point.y);
}
-(void)mouseDown:(NSEvent *)event {
NSPoint point = [event locationInWindow];
EWOL_VERBOSE("mouseDown : " << (float)point.x << " " << (float)point.y);
MacOs::setMouseState(1, true, point.x, point.y);
}
-(void)mouseDragged:(NSEvent *)event {
NSPoint point = [event locationInWindow];
EWOL_VERBOSE("mouseDragged : " << (float)point.x << " " << (float)point.y);
MacOs::setMouseMotion(1, point.x, point.y);
}
-(void)mouseUp:(NSEvent *)event {
NSPoint point = [event locationInWindow];
EWOL_VERBOSE("mouseUp : " << (float)point.x << " " << (float)point.y);
MacOs::setMouseState(1, false, point.x, point.y);
}
-(void)rightMouseDown:(NSEvent *)event {
NSPoint point = [event locationInWindow];
EWOL_VERBOSE("rightMouseDown : " << (float)point.x << " " << (float)point.y);
MacOs::setMouseState(3, true, point.x, point.y);
}
-(void)rightMouseDragged:(NSEvent *)event {
NSPoint point = [event locationInWindow];
EWOL_VERBOSE("rightMouseDragged : " << (float)point.x << " " << (float)point.y);
MacOs::setMouseMotion(3, point.x, point.y);
}
-(void)rightMouseUp:(NSEvent *)event {
NSPoint point = [event locationInWindow];
EWOL_VERBOSE("rightMouseUp : " << (float)point.x << " " << (float)point.y);
MacOs::setMouseState(3, false, point.x, point.y);
}
-(void)otherMouseDown:(NSEvent *)event {
NSPoint point = [event locationInWindow];
int32_t btNumber = [event buttonNumber];
switch (btNumber) {
case 2: // 2 : Middle button
btNumber = 2;
break;
case 3: // 3 : border button DOWN
btNumber = 8;
break;
case 4: // 4 : border button UP
btNumber = 9;
break;
case 5: // 5 : horizontal scroll Right to left
btNumber = 11;
break;
case 6: // 6 : horizontal scroll left to Right
btNumber = 10;
break;
case 7: // 7 : Red button
btNumber = 12;
break;
default:
btNumber = 15;
break;
}
EWOL_VERBOSE("otherMouseDown : " << (float)point.x << " " << (float)point.y);
MacOs::setMouseState(btNumber, true, point.x, point.y);
}
-(void)otherMouseDragged:(NSEvent *)event {
NSPoint point = [event locationInWindow];
int32_t btNumber = [event buttonNumber];
switch (btNumber) {
case 2: // 2 : Middle button
btNumber = 2;
break;
case 3: // 3 : border button DOWN
btNumber = 8;
break;
case 4: // 4 : border button UP
btNumber = 9;
break;
case 5: // 5 : horizontal scroll Right to left
btNumber = 11;
break;
case 6: // 6 : horizontal scroll left to Right
btNumber = 10;
break;
case 7: // 7 : Red button
btNumber = 12;
break;
default:
btNumber = 15;
break;
}
EWOL_VERBOSE("otherMouseDragged : " << (float)point.x << " " << (float)point.y);
MacOs::setMouseMotion(btNumber, point.x, point.y);
}
-(void)otherMouseUp:(NSEvent *)event {
NSPoint point = [event locationInWindow];
int32_t btNumber = [event buttonNumber];
EWOL_VERBOSE("otherMouseUp: id=" << btNumber );
switch (btNumber) {
case 2: // 2 : Middle button
btNumber = 2;
break;
case 3: // 3 : border button DOWN
btNumber = 8;
break;
case 4: // 4 : border button UP
btNumber = 9;
break;
case 5: // 5 : horizontal scroll Right to left
btNumber = 11;
break;
case 6: // 6 : horizontal scroll left to Right
btNumber = 10;
break;
case 7: // 7 : Red button
btNumber = 12;
break;
default:
btNumber = 15;
break;
}
EWOL_VERBOSE("otherMouseUp : " << (float)point.x << " " << (float)point.y << " bt id=" << btNumber );
MacOs::setMouseState(btNumber, false, point.x, point.y);
}
- (void)scrollWheel:(NSEvent *)event {
NSPoint point = [event locationInWindow];
EWOL_VERBOSE("scrollWheel : " << (float)point.x << " " << (float)point.y << " delta(" << (float)([event deltaX]) << "," << (float)([event deltaY]) << ")");
float deltaY = [event deltaY];
int32_t idEvent = 4;
if (deltaY < 0) {
idEvent = 5;
}
if (fabs(deltaY) < 0.1f) {
return;
}
for (float iii=fabs(deltaY) ; iii>=0.0f ; iii-=1.0f) {
MacOs::setMouseState(idEvent, true , point.x, point.y);
MacOs::setMouseState(idEvent, false, point.x, point.y);
}
}
- (void)closeRequestEwol {
EWOL_VERBOSE("closeRequestEwol: BEGIN");
[super close];
EWOL_VERBOSE("closeRequestEwol: END");
}
- (void)close {
EWOL_VERBOSE("close:");
MacOs::stopRequested();
}
- (void)UpdateScreenRequested {
[_view UpdateScreenRequested];
}
@end

View File

@ -0,0 +1,503 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#include <gale/debug.h>
#include <gale/gale.h>
#include <etk/types.h>
#include <etk/os/FSNode.h>
#include <etk/math/Vector2D.h>
#include <etk/math/Vector3D.h>
#include <gale/widget/Manager.h>
#include <gale/resource/Texture.h>
#include <gale/resource/Image.h>
#include <gale/context/Context.h>
#include <gale/openGL/openGL.h>
#include <sys/time.h>
#include <windows.h>
#include <windowsx.h>
#include <etk/etk.h>
int64_t gale::getTime() {
struct timeval now;
gettimeofday(&now, nullptr);
//GALE_VERBOSE("current time : " << now.tv_sec << "s " << now.tv_usec << "us");
return (int64_t)((int64_t)now.tv_sec*(int64_t)1000000 + (int64_t)now.tv_usec);
}
#undef __class__
#define __class__ "ContextWindows"
class WindowsContext : public gale::Context {
private:
int32_t m_currentHeight = 0;
bool m_inputIsPressed[MAX_MANAGE_INPUT];
gale::key::Special m_guiKeyBoardMode;
bool m_run = true;
bool m_clipBoardOwnerStd = false;
public:
WindowsContext(gale::context::Application* _application, int32_t _argc, const char* _argv[]) :
gale::Context(_application, _argc, _argv) {
for (int32_t iii=0; iii<MAX_MANAGE_INPUT; ++iii) {
m_inputIsPressed[iii] = false;
}
}
~WindowsContext() {
}
int32_t run() {
HINSTANCE hInstance = 0;
WNDCLASS wc;
HWND hWnd;
HDC hDC;
HGLRC hRC;
MSG msg;
// register window class
wc.style = CS_OWNDC;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon( nullptr, IDI_APPLICATION );
wc.hCursor = LoadCursor( nullptr, IDC_ARROW );
wc.hbrBackground = (HBRUSH)GetStockObject( BLACK_BRUSH );
wc.lpszMenuName = nullptr;
wc.lpszClassName = "GaleMainWindows";
RegisterClass( &wc );
// create main window
hWnd = CreateWindow( "GaleMainWindows", "Gale ... TODO Title",
WS_CAPTION | WS_POPUPWINDOW | WS_VISIBLE | WS_SIZEBOX,
0, 0, 800, 600,
nullptr, nullptr, hInstance, nullptr);
int border_thickness = GetSystemMetrics(SM_CXSIZEFRAME);
int title_size = GetSystemMetrics(SM_CYCAPTION);
m_currentHeight = 600-2*border_thickness -title_size;
OS_Resize(vec2(800-2*border_thickness, m_currentHeight));
// enable openGL for the window
enableOpenGL( hWnd, &hDC, &hRC );
// program main loop
while(true == m_run) {
// check for messages
if ( PeekMessage( &msg, nullptr, 0, 0, PM_REMOVE )) {
// handle or dispatch messages
if ( msg.message == WM_QUIT ) {
m_run = false;
} else {
TranslateMessage( &msg );
DispatchMessage( &msg );
}
} else {
OS_Draw(true);
SwapBuffers( hDC );
}
}
// shutdown openGL
disableOpenGL( hWnd, hDC, hRC );
// destroy the window explicitly
DestroyWindow( hWnd );
return msg.wParam;
}
void Stop() {
m_run = false;
// To exit program ...
PostQuitMessage(0);
}
void setSize(const vec2& _size) {
float border_thickness = GetSystemMetrics(SM_CXSIZEFRAME);
float title_size = GetSystemMetrics(SM_CYCAPTION);
vec2 newSize(_size.x() + border_thickness*2.0f,
_size.y() + border_thickness*2.0f + title_size);
//m_currentHeight = size.y;
// TODO : Later
}
void ClipBoardGet(enum gale::context::clipBoard::clipboardListe _clipboardID) {
// this is to force the local system to think we have the buffer
// TODO : remove this 2 line when code will be writen
m_clipBoardOwnerStd = true;
switch (_clipboardID) {
case gale::context::clipBoard::clipboardSelection:
// NOTE : Windows does not support the middle button the we do it internaly
// just transmit an event , we have the data in the system
OS_ClipBoardArrive(gale::context::clipBoard::clipboardSelection);
break;
case gale::context::clipBoard::clipboardStd:
if (false == m_clipBoardOwnerStd) {
// generate a request TO the OS
// TODO : Send the message to the OS "We disire to receive the copy buffer ...
} else {
// just transmit an event , we have the data in the system
OS_ClipBoardArrive(gale::context::clipBoard::clipboardStd);
}
break;
default:
GALE_ERROR("Request an unknow ClipBoard ...");
break;
}
}
void ClipBoardSet(enum gale::context::clipBoard::clipboardListe _clipboardID) {
switch (_clipboardID) {
case gale::context::clipBoard::clipboardSelection:
// NOTE : nothing to do : Windows deas ot supported Middle button
break;
case gale::context::clipBoard::clipboardStd:
// Request the clipBoard :
if (false == m_clipBoardOwnerStd) {
// TODO : Inform the OS that we have the current buffer of copy ...
m_clipBoardOwnerStd = true;
}
break;
default:
GALE_ERROR("Request an unknow ClipBoard ...");
break;
}
}
// enable openGL
void enableOpenGL(HWND _hWnd, HDC* _hDC, HGLRC* _hRC) {
// get the device context (DC)
*_hDC = GetDC( _hWnd );
PIXELFORMATDESCRIPTOR pfd;
// set the pixel format for the DC
ZeroMemory(&pfd, sizeof( pfd ) );
pfd.nSize = sizeof( pfd );
pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 24;
pfd.cDepthBits = 16;
pfd.iLayerType = PFD_MAIN_PLANE;
int format = ChoosePixelFormat( *_hDC, &pfd );
SetPixelFormat( *_hDC, format, &pfd );
// create and enable the render context(RC)
*_hRC = wglCreateContext( *_hDC );
wglMakeCurrent( *_hDC, *_hRC );
}
// disable openGL
void disableOpenGL(HWND _hWnd, HDC _hDC, HGLRC _hRC) {
wglMakeCurrent( nullptr, NULL );
wglDeleteContext( _hRC );
ReleaseDC( _hWnd, _hDC );
}
// Window Procedure
static LRESULT CALLBACK WndProc(HWND _hWnd, UINT _message, WPARAM _wParam, LPARAM _lParam) {
// TODO : set this function really work...
// TODO : return classPointer->WndProcReal(_hWnd, _message, _wParam, _lParam);
return 0;
}
LRESULT CALLBACK WndProcReal(HWND _hWnd, UINT _message, WPARAM _wParam, LPARAM _lParam) {
bool buttonIsDown = true;
int32_t mouseButtonId = 0;
ivec2 pos;
// to know all _message : http://wiki.winehq.org/List_Of_Windows__messages
switch (_message) {
/* **************************************************************************
* Gui event
* **************************************************************************/
case WM_CREATE:
GALE_DEBUG("WM_CREATE");
return 0;
case WM_CLOSE:
GALE_DEBUG("WM_CLOSE");
PostQuitMessage( 0 );
return 0;
case WM_DESTROY:
GALE_DEBUG("WM_DESTROY");
return 0;
case WM_MOVE:
GALE_DEBUG("WM_MOVE");
return 0;
case WM_SIZE:
GALE_DEBUG("WM_SIZE");
return 0;
/*
case WM_GETMINMAXINFO:
{
MINMAXINFO* tmpVal = (MINMAXINFO*)lParam;
GALE_DEBUG("WM_GETMINMAXINFO : ");
GALE_DEBUG(" ptMaxSize : " << tmpVal->ptMaxSize.x << "," << tmpVal->ptMaxSize.y << ")");
GALE_DEBUG(" ptMaxPosition : " << tmpVal->ptMaxPosition.x << "," << tmpVal->ptMaxPosition.y << ")");
GALE_DEBUG(" ptMinTrackSize : " << tmpVal->ptMinTrackSize.x << "," << tmpVal->ptMinTrackSize.y << ")");
GALE_DEBUG(" ptMaxTrackSize : " << tmpVal->ptMaxTrackSize.x << "," << tmpVal->ptMaxTrackSize.y << ")");
}
return 0;
*/
case WM_WINDOWPOSCHANGING: {
WINDOWPOS* tmpVal = (WINDOWPOS*)_lParam;
if (nullptr != tmpVal) {
//GALE_DEBUG("WM_WINDOWPOSCHANGING : : (" << tmpVal->x << "," << tmpVal->y << ") ( " << tmpVal->cx << "," << tmpVal->cy << ")");
// in windows system, we need to remove the size of the border elements :
int border_thickness = GetSystemMetrics(SM_CXSIZEFRAME);
int title_size = GetSystemMetrics(SM_CYCAPTION);
m_currentHeight = tmpVal->cy - 2*border_thickness - title_size;
OS_Resize(vec2(tmpVal->cx-2*border_thickness, m_currentHeight));
}
return 0;
}
// these message are not parse by us ...
case WM_SETCURSOR: // Call the windows if we want the mouse event :
case WM_NCHITTEST: // inform the application the position of the mouse is moving
return DefWindowProc( _hWnd, _message, _wParam, _lParam );
/* **************************************************************************
* Keyboard management
* **************************************************************************/
case WM_KEYUP:
buttonIsDown = false;
case WM_KEYDOWN: {
char32_t tmpChar = 0;
enum gale::key::keyboard keyInput;
switch (_wParam) {
//case 80: // keypad
case VK_UP: keyInput = gale::key::keyboardUp; break;
//case 83: // keypad
case VK_LEFT: keyInput = gale::key::keyboardLeft; break;
//case 85: // keypad
case VK_RIGHT: keyInput = gale::key::keyboardRight; break;
//case 88: // keypad
case VK_DOWN: keyInput = gale::key::keyboardDown; break;
//case 81: // keypad
case VK_PRIOR: keyInput = gale::key::keyboardPageUp; break;
//case 89: // keypad
case VK_NEXT: keyInput = gale::key::keyboardPageDown; break;
//case 79: // keypad
case VK_HOME: keyInput = gale::key::keyboardStart; break;
//case 87: // keypad
case VK_END: keyInput = gale::key::keyboardEnd; break;
//case VK_: keyInput = gale::key::keyboardStopDefil; break;
case VK_PAUSE: keyInput = gale::key::keyboardWait; break;
//case 90: // keypad
case VK_INSERT:
keyInput = gale::key::keyboardInsert;
m_guiKeyBoardMode.setInsert(buttonIsDown);
break;
case VK_F1: keyInput = gale::key::keyboardF1; break;
case VK_F2: keyInput = gale::key::keyboardF2; break;
case VK_F3: keyInput = gale::key::keyboardF3; break;
case VK_F4: keyInput = gale::key::keyboardF4; break;
case VK_F5: keyInput = gale::key::keyboardF5; break;
case VK_F6: keyInput = gale::key::keyboardF6; break;
case VK_F7: keyInput = gale::key::keyboardF7; break;
case VK_F8: keyInput = gale::key::keyboardF8; break;
case VK_F9: keyInput = gale::key::keyboardF9; break;
case VK_F10: keyInput = gale::key::keyboardF10; break;
case VK_F11: keyInput = gale::key::keyboardF11; break;
case VK_F12:
case VK_F13:
case VK_F14:
case VK_F15:
case VK_F16:
case VK_F17:
case VK_F18:
case VK_F19:
case VK_F20:
case VK_F21:
case VK_F22:
case VK_F23:
case VK_F24: keyInput = gale::key::keyboardF12; break;
case VK_CAPITAL:
keyInput = gale::key::keyboardCapLock;
m_guiKeyBoardMode.setCapsLock(buttonIsDown);
break;
case VK_SHIFT:
case VK_LSHIFT:
keyInput = gale::key::keyboardShiftLeft;
m_guiKeyBoardMode.setShift(buttonIsDown);
break;
case VK_RSHIFT:
keyInput = gale::key::keyboardShiftRight;
m_guiKeyBoardMode.setShift(buttonIsDown);
break;
case VK_CONTROL:
case VK_LCONTROL:
keyInput = gale::key::keyboardCtrlLeft;
m_guiKeyBoardMode.setCtrl(buttonIsDown);
break;
case VK_RCONTROL:
keyInput = gale::key::keyboardCtrlRight;
m_guiKeyBoardMode.setCtrl(buttonIsDown);
break;
case VK_LWIN:
keyInput = gale::key::keyboardMetaLeft;
m_guiKeyBoardMode.setMeta(buttonIsDown);
break;
case VK_RWIN:
keyInput = gale::key::keyboardMetaRight;
m_guiKeyBoardMode.setMeta(buttonIsDown);
break;
case VK_MENU:
case VK_LMENU:
keyInput = gale::key::keyboardAlt;
m_guiKeyBoardMode.setAlt(buttonIsDown);
break;
case VK_RMENU:
keyInput = gale::key::keyboardAltGr;
m_guiKeyBoardMode.setAltGr(buttonIsDown);
break;
//case : keyInput = gale::key::keyboardContextMenu; break;
case VK_NUMLOCK:
keyInput = gale::key::keyboardNumLock;
m_guiKeyBoardMode.setNumLock(buttonIsDown);
break;
case VK_BACK: // DEL
tmpChar = 0x08;
break;
// TODO : Really strang, need to understand why ...
case 46: // Suppr
tmpChar = 0x7F;
break;
case VK_TAB: // special case for TAB
tmpChar = 0x09;
break;
case VK_RETURN: // special case for TAB
tmpChar = '\n';
break;
default:
{
BYTE kbd[256];
GetKeyboardState(kbd);
const int BUFFER_LENGTH = 8; //Length of the buffer
WCHAR chars[BUFFER_LENGTH];
ToUnicode(_wParam, _lParam, kbd, chars,BUFFER_LENGTH,0);
tmpChar = utf8::convertChar32((char*)chars);
}
break;
}
GALE_DEBUG("kjhkjhkjhkjhkj = " << _wParam);
if (tmpChar == 0) {
//GALE_DEBUG("eventKey Move type : " << getCharTypeMoveEvent(keyInput) );
OS_SetKeyboardMove(m_guiKeyBoardMode, keyInput, buttonIsDown);
} else {
OS_SetKeyboard(m_guiKeyBoardMode, tmpChar, buttonIsDown);
}
return 0;
}
/* **************************************************************************
* Mouse management
* **************************************************************************/
case WM_LBUTTONUP:
buttonIsDown = false;
case WM_LBUTTONDOWN:
mouseButtonId = 1;
pos.setValue(GET_X_LPARAM(_lParam),
m_currentHeight-GET_Y_LPARAM(_lParam));
m_inputIsPressed[mouseButtonId] = buttonIsDown;
OS_SetMouseState(mouseButtonId, buttonIsDown, vec2(pos.x(),pos.y()));
return 0;
case WM_MBUTTONUP:
buttonIsDown = false;
case WM_MBUTTONDOWN:
mouseButtonId = 2;
pos.setValue(GET_X_LPARAM(_lParam),
m_currentHeight-GET_Y_LPARAM(_lParam));
m_inputIsPressed[mouseButtonId] = buttonIsDown;
OS_SetMouseState(mouseButtonId, buttonIsDown, vec2(pos.x(),pos.y()));
return 0;
case WM_RBUTTONUP:
buttonIsDown = false;
case WM_RBUTTONDOWN:
mouseButtonId = 3;
pos.setValue(GET_X_LPARAM(_lParam),
m_currentHeight-GET_Y_LPARAM(_lParam));
m_inputIsPressed[mouseButtonId] = buttonIsDown;
OS_SetMouseState(mouseButtonId, buttonIsDown, vec2(pos.x(),pos.y()));
return 0;
case WM_MOUSEWHEEL:
if (_wParam & 0x200000) {
GALE_DEBUG("event SCROOL UP");
mouseButtonId = 4;
} else {
GALE_DEBUG("event SCROOL DOWN");
mouseButtonId = 5;
}
pos.setValue(GET_X_LPARAM(_lParam),
m_currentHeight-GET_Y_LPARAM(_lParam));
OS_SetMouseState(mouseButtonId, true, vec2(pos.x(),pos.y()));
OS_SetMouseState(mouseButtonId, false, vec2(pos.x(),pos.y()));
return 0;
case WM_MOUSEHOVER:
case WM_MOUSEMOVE:
pos.setValue(GET_X_LPARAM(_lParam),
m_currentHeight-GET_Y_LPARAM(_lParam));
for (int32_t iii=0; iii<MAX_MANAGE_INPUT ; iii++) {
if (true == m_inputIsPressed[iii]) {
GALE_VERBOSE("Windows event: bt=" << iii << " " << _message << " = \"WM_MOUSEMOVE\" " << pos );
OS_SetMouseMotion(iii, vec2(pos.x(),pos.y()));
return 0;
}
}
GALE_VERBOSE("Windows event: bt=" << 0 << " " << _message << " = \"WM_MOUSEMOVE\" " << pos );
OS_SetMouseMotion(0, vec2(pos.x(),pos.y()));
return 0;
default:
GALE_DEBUG("event ..." << _message );
return DefWindowProc( _hWnd, _message, _wParam, _lParam );
}
}
};
/**
* @brief Main of the program
* @param std IO
* @return std IO
*/
int gale::run(gale::context::Application* _application, int _argc, const char *_argv[]) {
etk::init(_argc, _argv);
GLenum err = glewInit();
if (GLEW_OK != err) {
// Problem: glewInit failed, something is seriously wrong.
GALE_ERROR("Error:" << glewGetErrorString(err));
}
if (!glewIsSupported("GL_VERSION_2_0")) {
GALE_ERROR("OpenGL 2.0 not available");
//return 1;
}
WindowsContext* localInterface = new WindowsContext(_application, _argc, _argv);
if (localInterface == nullptr) {
GALE_CRITICAL("Can not create the 'Windows' interface ... MEMORY allocation error");
return -2;
}
int32_t retValue = localInterface->run();
delete(localInterface);
localInterface = nullptr;
return retValue;
}

1336
gale/context/X11/Context.cpp Normal file

File diff suppressed because it is too large Load Diff

130
gale/context/clipBoard.cpp Normal file
View File

@ -0,0 +1,130 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#include <etk/types.h>
#include <gale/debug.h>
#include <gale/context/clipBoard.h>
#include <gale/context/Context.h>
#undef __class__
#define __class__ "ClipBoard"
/*
note: copy id data :
0 : copy standard
[1..9] : copy internal
10 : middle button
*/
//!< Local copy of the clipboards
static std::string myCopy[gale::context::clipBoard::clipboardCount];
static const char* clipboardDescriptionString[gale::context::clipBoard::clipboardCount+1] = {
"clipboard0",
"clipboard1",
"clipboard2",
"clipboard3",
"clipboard4",
"clipboard5",
"clipboard6",
"clipboard7",
"clipboard8",
"clipboard9",
"clipboardStd",
"clipboardSelection",
"clipboardCount"
};
std::ostream& gale::operator <<(std::ostream& _os, const enum gale::context::clipBoard::clipboardListe _obj) {
if (_obj >= 0 && _obj <gale::context::clipBoard::clipboardCount) {
_os << clipboardDescriptionString[_obj];
} else {
_os << "[ERROR]";
}
return _os;
}
void gale::context::clipBoard::init() {
GALE_INFO("Initialyse ClipBoards");
for(int32_t i=0; i<gale::context::clipBoard::clipboardCount; i++) {
myCopy[i].clear();
}
}
void gale::context::clipBoard::unInit() {
GALE_INFO("Initialyse ClipBoards");
for(int32_t i=0; i<gale::context::clipBoard::clipboardCount; i++) {
myCopy[i].clear();
}
}
void gale::context::clipBoard::set(enum gale::context::clipBoard::clipboardListe _clipboardID, const std::string& _data) {
// check if ID is correct
if(0 == _data.size()) {
GALE_INFO("request a copy of nothing");
return;
} else
if(_clipboardID >= gale::context::clipBoard::clipboardCount) {
GALE_WARNING("request ClickBoard id error");
return;
}
gale::context::clipBoard::setSystem(_clipboardID, _data);
if( gale::context::clipBoard::clipboardStd == _clipboardID
|| gale::context::clipBoard::clipboardSelection == _clipboardID) {
gale::getContext().clipBoardSet(_clipboardID);
}
}
void gale::context::clipBoard::request(enum gale::context::clipBoard::clipboardListe _clipboardID) {
if(_clipboardID >= gale::context::clipBoard::clipboardCount) {
GALE_WARNING("request ClickBoard id error");
return;
}
if( gale::context::clipBoard::clipboardStd == _clipboardID
|| gale::context::clipBoard::clipboardSelection == _clipboardID) {
gale::getContext().clipBoardGet(_clipboardID);
} else {
// generate an event on the main thread ...
gale::getContext().OS_ClipBoardArrive(_clipboardID);
}
}
void gale::context::clipBoard::setSystem(enum gale::context::clipBoard::clipboardListe _clipboardID, const std::string& _data) {
if(_clipboardID >= gale::context::clipBoard::clipboardCount) {
GALE_WARNING("request ClickBoard id error");
return;
}
// Copy datas ...
myCopy[_clipboardID] = _data;
}
const std::string& gale::context::clipBoard::get(enum gale::context::clipBoard::clipboardListe _clipboardID) {
static const std::string emptyString("");
if(_clipboardID >= gale::context::clipBoard::clipboardCount) {
GALE_WARNING("request ClickBoard id error");
return emptyString;
}
// Copy datas ...
return myCopy[_clipboardID];
}

84
gale/context/clipBoard.h Normal file
View File

@ -0,0 +1,84 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#ifndef __GALE_CLIPBOARD_H__
#define __GALE_CLIPBOARD_H__
#include <gale/debug.h>
// TODO : Remove this ... ==> set it in the context ....
namespace gale {
namespace context {
namespace clipBoard {
enum clipboardListe {
clipboard0, //!< internal clipboard 0
clipboard1, //!< internal clipboard 1
clipboard2, //!< internal clipboard 2
clipboard3, //!< internal clipboard 3
clipboard4, //!< internal clipboard 4
clipboard5, //!< internal clipboard 5
clipboard6, //!< internal clipboard 6
clipboard7, //!< internal clipboard 7
clipboard8, //!< internal clipboard 8
clipboard9, //!< internal clipboard 9
clipboardStd, //!< External clipboard represent the Copy/Cut/Past buffer
clipboardSelection, //!< External or internal clipboard depending on the OS, represent the middle button
clipboardCount, //!< Total number of clipboard
};
/**
* @brief set the string data on a specific clipboard. The Gui system is notify that the clipboard "SELECTION" and "COPY" are change
* @param[in] _clipboardID Select the specific ID of the clipboard
* @param[in] _data The string that might be send to the clipboard
*/
void set(enum gale::context::clipBoard::clipboardListe _clipboardID, const std::string& _data);
/**
* @brief Call system to request the current clipboard.
* @note Due to some system that manage the clipboard request asynchronous (like X11) and gale managing the system with only one thread,
* we need the call the system to send us the buffer, this is really ambigous, but the widget (who has focus) receive the
* notification of the arrival of this buffer id
* @param[in] _clipboardID the needed clipboard ID
*/
void request(enum gale::context::clipBoard::clipboardListe _clipboardID);
/**
* @brief set the gale internal buffer (no notification at the GUI). This fuction might be use by the
* Gui abstraction to set the buffer we receive. The end user must not use it.
* @param[in] _clipboardID selected clipboard ID
* @param[in] _data new buffer data
*/
void setSystem(enum gale::context::clipBoard::clipboardListe _clipboardID,const std::string& _data);
/**
* @brief get the gale internal buffer of the curent clipboard. The end user can use it when he receive the event in
* the widget : @ref onEventClipboard == > we can nothe this function is the only one which permit it.
* @note if we call this fuction withoutcallin @ref gale::context::clipBoard::Request, we only get the previous clipboard
* @param[in] _clipboardID selected clipboard ID
* @return the requested buffer
*/
const std::string& get(enum gale::context::clipBoard::clipboardListe _clipboardID);
// internal section
/**
* @brief initialize the clipboard system (done by gale)
*/
void init();
/**
* @brief Un-Initialize the clipboard system (done by gale)
*/
void unInit();
};
};
/**
* @brief Debug operator To display the curent element in a Human redeable information
*/
std::ostream& operator <<(std::ostream& _os, const enum gale::context::clipBoard::clipboardListe _obj);
};
#endif

View File

@ -0,0 +1,40 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#include <gale/debug.h>
#include <gale/context/commandLine.h>
#include <vector>
void gale::context::CommandLine::parse(int32_t _argc, const char* _argv[]) {
for (int32_t i=1 ; i<_argc; i++) {
GALE_INFO("commandLine : \"" << _argv[i] << "\"" );
m_listArgs.push_back(_argv[i]);
}
}
int32_t gale::context::CommandLine::size() {
return m_listArgs.size();
}
const std::string& gale::context::CommandLine::get(int32_t _id) {
static const std::string errorArg("");
if ( _id < 0
&& _id >= (int64_t)m_listArgs.size()) {
return errorArg;
}
return m_listArgs[_id];
}
void gale::context::CommandLine::add(const std::string& _newElement) {
m_listArgs.push_back(_newElement);
}
void gale::context::CommandLine::remove(int32_t _id) {
m_listArgs.erase(m_listArgs.begin()+_id);
}

View File

@ -0,0 +1,48 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#ifndef __GALE_COMMAND_LINE_H__
#define __GALE_COMMAND_LINE_H__
#include <gale/debug.h>
namespace gale {
namespace context {
class CommandLine {
private:
std::vector<std::string> m_listArgs; //!< list of all argument parsed
public:
/**
* @brief Parse the command line parameters
*/
void parse(int32_t _argc, const char* _argv[]);
/**
* @brief get the number of element in the Command line
* @return the number of element
*/
int32_t size();
/**
* @brief get an element with a specific ID
* @return _id The cmdLine Id element
*/
const std::string& get(int32_t _id);
/**
* @brief add one element at the Command line
* @param[in] _newElement String in the input that might be added.
*/
void add(const std::string& _newElement);
/**
* @brief remove an element
* @param[in] _id Id of the element
*/
void remove(int32_t _id);
};
};
};
#endif

45
gale/context/cursor.cpp Normal file
View File

@ -0,0 +1,45 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#include <gale/context/cursor.h>
static const char* cursorDescriptionString[gale::context::cursorCount+1] = {
"cursorArrow",
"cursorLeftArrow",
"cursorInfo",
"cursorDestroy",
"cursorHelp",
"cursorCycle",
"cursorSpray",
"cursorWait",
"cursorText",
"cursorCrossHair",
"cursorSlideUpDown",
"cursorSlideLeftRight",
"cursorResizeUp",
"cursorResizeDown",
"cursorResizeLeft",
"cursorResizeRight",
"cursorCornerTopLeft",
"cursorCornerTopRight",
"cursorCornerButtomLeft",
"cursorCornerButtomRight",
"cursorNone",
"cursorCount"
};
std::ostream& gale::operator <<(std::ostream& _os, const enum gale::context::cursorDisplay _obj) {
if (_obj >= 0 && _obj <gale::context::cursorCount) {
_os << cursorDescriptionString[_obj];
} else {
_os << "[ERROR]";
}
return _os;
}

50
gale/context/cursor.h Normal file
View File

@ -0,0 +1,50 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#ifndef __GALE_CURSOR_H__
#define __GALE_CURSOR_H__
#include <gale/debug.h>
namespace gale {
namespace context {
enum cursorDisplay {
cursorArrow, // this is the normal arrow ...
cursorLeftArrow,
cursorInfo,
cursorDestroy,
cursorHelp,
cursorCycle,
cursorSpray,
cursorWait,
cursorText,
cursorCrossHair,
cursorSlideUpDown, //!< change the position (slide) vertical
cursorSlideLeftRight, //!< change the position (slide) horizontal
cursorResizeUp,
cursorResizeDown,
cursorResizeLeft,
cursorResizeRight,
cursorCornerTopLeft,
cursorCornerTopRight,
cursorCornerButtomLeft,
cursorCornerButtomRight,
cursorNone,
// just for the count:
cursorCount
};
};
/**
* @brief Debug operator To display the curent element in a Human readable information
*/
std::ostream& operator <<(std::ostream& _os, const enum gale::context::cursorDisplay _obj);
};
#endif

View File

@ -0,0 +1,494 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
/*
notes :
sudo edn /etc/udev/rules.d/framebuffer.rules
KERNEL == "fb0", OWNER="root", MODE="0660"
sudo usermod -a -G video username
sudo usermod -a -G tty username
sudo fbset -i
sudo chmod o+wr /dev/fb0
http://mail.directfb.org/pipermail/directfb-users/2010-February/002115.html
on X11 :
http://stackoverflow.com/questions/521957/how-to-develop-a-directfb-app-without-leaving-x-11-environment
$ sudo apt-get install libdirectfb-extra # for Debian and Ubuntu, anyhow
$ cat ~/.directfbrc
system=x11
force-windowed
*/
#include <gale/debug.h>
#include <gale/gale.h>
#include <gale/key.h>
#include <gale/config.h>
#include <gale/commandLine.h>
#include <etk/types.h>
#include <etk/unicode.h>
#include <gale/widget/Manager.h>
#include <gale/renderer/ResourceManager.h>
#include <gale/renderer/eSystem.h>
#include <gale/openGL/openGL.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <directfb.h>
#include <directfbgl.h>
int64_t guiInterface::getTime() {
struct timespec now;
int ret = clock_gettime(CLOCK_REALTIME, &now);
if (ret != 0) {
// Error to get the time ...
now.tv_sec = time(nullptr);
now.tv_nsec = 0;
}
//GALE_VERBOSE("current time : " << now.tv_sec << "s " << now.tv_usec << "us");
return (int64_t)((int64_t)now.tv_sec*(int64_t)1000000 + (int64_t)now.tv_nsec/(int64_t)1000);
}
#undef __class__
#define __class__ "guiInterface"
static gale::SpecialKey guiKeyBoardMode;
bool inputIsPressed[20];
bool m_run = true;
bool m_grabAllEvent = false;
// the super interface
IDirectFB *dfb = nullptr;
// the primary surface (surface of primary layer)
IDirectFBSurface *primary = nullptr;
// the GL context
IDirectFBGL *primary_gl = nullptr;
// event buffer
IDirectFBEventBuffer *events = nullptr;
static int screen_width =800;
static int screen_height = 600;
/**
* @brief set the new title of the windows
* @param title New desired title
* @return ---
*/
void guiInterface::setTitle(std::string& title) {
// TODO : ...
}
void guiInterface::setIcon(std::string inputFile) {
// TODO : ...
}
void DirectFB_Init(int argc, const char *argv[]) {
GALE_INFO("DirectFB init (START)");
DFBResult err;
DFBSurfaceDescription dsc;
GALE_INFO("call DirectFBInit");
int argc2 = 1;
err = DirectFBInit(&argc2, (char***)&argv);
if (DFB_OK!=err) {
GALE_ERROR("DirectFBInit");
DirectFBErrorFatal("DirectFBInit", err);
exit(-1);
}
GALE_INFO("call DirectFBCreate");
// create the super interface
err = DirectFBCreate(&dfb);
if (DFB_OK!=err) {
GALE_ERROR("DirectFBCreate");
DirectFBErrorFatal("DirectFBCreate", err);
exit(-1);
}
GALE_INFO("call setCooperativeLevel");
// set our cooperative level to DFSCL_FULLSCREEN for exclusive access to the primary layer
dfb->setCooperativeLevel(dfb, DFSCL_FULLSCREEN);
//dfb->setCooperativeLevel(dfb, DFSCL_NORMAL);
// get the primary surface, i.e. the surface of the primary layer we have exclusive access to
dsc.flags = (DFBSurfaceDescriptionFlags)(DSDESC_CAPS);// | DSDESC_PIXELFORMAT);
//dsc.caps = (DFBSurfaceCapabilities)(DSCAPS_PRIMARY | DSCAPS_DOUBLE | DSCAPS_DEPTH); // DSCAPS_SHARED
dsc.caps = (DFBSurfaceCapabilities)(DSCAPS_PRIMARY | DSCAPS_DOUBLE | DSCAPS_GL);// | DSCAPS_FLIPPING);
//dsc.caps = (DFBSurfaceCapabilities) (DSCAPS_SUBSURFACE | DSCAPS_VIDEOONLY | DSCAPS_PREMULTIPLIED | DSCAPS_FLIPPING);
dsc.pixelformat = DSPF_ARGB;
dsc.width = 600;
dsc.height = 400;
GALE_INFO("call CreateSurface");
err = dfb->CreateSurface(dfb, &dsc, &primary);
if (DFB_OK!=err) {
GALE_ERROR("dfb->CreateSurface");
DirectFBErrorFatal("dfb->CreateSurface", err);
exit(-1);
}
primary->setBlittingFlags(primary, DSBLIT_BLEND_ALPHACHANNEL);
primary->setPorterDuff( primary, DSPD_ADD );
primary->setDstBlendFunction(primary, DSBF_SRCALPHA);
primary->setDrawingFlags(primary, DSDRAW_BLEND);
primary->Blit(primary, primary, nullptr, 0, 0);
GALE_INFO("call getSize");
// get the size of the surface and fill it
err = primary->getSize(primary, &screen_width, &screen_height);
if (DFB_OK!=err) {
GALE_ERROR("primary->getSize");
DirectFBErrorFatal("primary->getSize", err);
exit(-1);
}
GALE_INFO("call CreateInputEventBuffer");
// create an event buffer for all devices with these caps
err = dfb->CreateInputEventBuffer(dfb, (DFBInputDeviceCapabilities)(DICAPS_KEYS | DICAPS_AXES), DFB_FALSE, &events);
if (DFB_OK!=err) {
GALE_ERROR("dfb->CreateInputEventBuffer");
DirectFBErrorFatal("CreateInputEventBuffer", err);
exit(-1);
}
GALE_INFO("call Flip");
primary->Flip(primary, nullptr, (DFBSurfaceFlipFlags)0);//DSFLIP_ONSYNC);
// NOTE : we need to force it on X11 display ...
GALE_INFO("call getGL");
// get the GL context
err = primary->getGL(primary, &primary_gl);
if (DFB_OK!=err) {
GALE_ERROR("primary->getGL");
DirectFBErrorFatal("GetGL", err);
exit(-1);
}
GALE_INFO("DirectFB init (STOP)");
}
void DirectFB_UnInit() {
// release our interfaces to shutdown DirectFB
primary_gl->release(primary_gl);
primary->release(primary);
events->release(events);
dfb->release(dfb);
}
void DirectFB_Run() {
GALE_INFO("X11 configure windows size : (" << screen_height << "," << screen_width << ")");
eSystem::Resize(screen_width, screen_height);
DFBResult err;
int32_t position = 0;
while (true == m_run) {
DFBInputEvent evt;
unsigned long t;
/*
primary->setColor (primary, 0x00, 0x00, 0x00, 0xFF);
primary->FillRectangle(primary, 0, 0, screen_width, screen_height);
primary->setColor (primary, 0xFF, (uint8_t)position, 0x00, 0xFF);
primary->FillRectangle(primary, position, position, 300, 300);
primary->Flip(primary, nullptr, (DFBSurfaceFlipFlags)0);//DSFLIP_ONSYNC);
position++;
if (position>600) {
position = 0;
}
*/
if(true == m_run) {
err = primary_gl->Lock(primary_gl);
if (DFB_OK!=err) {
GALE_ERROR("primary_gl->Lock");
DirectFBErrorFatal("primary_gl->Lock", err);
}
// TODO : set at false
bool hasDisplay = eSystem::draw(true);
if (true == hasDisplay) {
glFinish();
}
err = primary_gl->Unlock(primary_gl);
if (DFB_OK!=err) {
GALE_ERROR("primary_gl->Unlock");
DirectFBErrorFatal("primary_gl->Unlock", err);
}
primary->Flip(primary, nullptr, (DFBSurfaceFlipFlags)0);//DSFLIP_ONSYNC);
}
while (events->getEvent(events, DFB_EVENT(&evt)) == DFB_OK) {
switch (evt.type) {
default:
case DIET_UNKNOWN: /* unknown event */
GALE_DEBUG("event unknown type : " << evt.type << " symbole=\"" << (char)evt.key_symbol << "\"=" << ((int32_t)evt.key_symbol) << " ...");
break;
case DIET_KEYPRESS: /* a key is been pressed */
case DIET_KEYRELEASE: /* a key is been released */
{
bool isPressed = (evt.type == DIET_KEYPRESS);
//GALE_DEBUG("event KeyBoard isPressed : " << isPressed << " symbole=\"" << (char)evt.key_symbol << "\"=" << ((int32_t)evt.key_symbol) << " ...");
if( 1 <= evt.key_symbol && evt.key_symbol <= 0x7F ) {
eSystem::setKeyboard(guiKeyBoardMode, evt.key_symbol, isPressed, false);
} else {
GALE_DEBUG("event KeyBoard isPressed : " << isPressed << " symbole=\"" << (char)evt.key_symbol << "\"=" << ((int32_t)evt.key_symbol) << " == > not managed key");
}
}
break;
case DIET_AXISMOTION: /* mouse/joystick movement */
{
/*
if (evt.flags & DIEF_AXISREL) {
switch (evt.axis) {
case DIAI_X:
//view_roty += evt.axisrel / 2.0;
break;
case DIAI_Y:
//view_rotx += evt.axisrel / 2.0;
break;
case DIAI_Z:
//view_rotz += evt.axisrel / 2.0;
break;
default:
;
}
}
*/
GALE_DEBUG("event mouse motion flag" << (char)evt.flags << " axis=" << evt.axis << " value=" << evt.axisrel);
}
break;
case DIET_BUTTONPRESS: /* a (mouse) button is been pressed */
case DIET_BUTTONRELEASE: /* a (mouse) button is been released */
{
bool isPressed = (evt.type == DIET_KEYPRESS);
GALE_DEBUG("event mouse event pressed=" << isPressed << " flag" << (char)evt.flags << " axis=" << evt.axis << " value=" << evt.axisrel);
}
break;
/*
case DIET_KEYPRESS:
switch (evt.key_symbol) {
case DIKS_ESCAPE:
m_run = false;
break;
case DIKS_CURSOR_UP:
//inc_rotx = 5.0;
break;
case DIKS_CURSOR_DOWN:
//inc_rotx = -5.0;
break;
case DIKS_CURSOR_LEFT:
//inc_roty = 5.0;
break;
case DIKS_CURSOR_RIGHT:
//inc_roty = -5.0;
break;
case DIKS_PAGE_UP:
//inc_rotz = 5.0;
break;
case DIKS_PAGE_DOWN:
//inc_rotz = -5.0;
break;
default:
;
}
break;
case DIET_KEYRELEASE:
switch (evt.key_symbol) {
case DIKS_CURSOR_UP:
//inc_rotx = 0;
break;
case DIKS_CURSOR_DOWN:
//inc_rotx = 0;
break;
case DIKS_CURSOR_LEFT:
//inc_roty = 0;
break;
case DIKS_CURSOR_RIGHT:
//inc_roty = 0;
break;
case DIKS_PAGE_UP:
//inc_rotz = 0;
break;
case DIKS_PAGE_DOWN:
//inc_rotz = 0;
break;
default:
;
}
break;
case DIET_AXISMOTION:
if (evt.flags & DIEF_AXISREL) {
switch (evt.axis) {
case DIAI_X:
//view_roty += evt.axisrel / 2.0;
break;
case DIAI_Y:
//view_rotx += evt.axisrel / 2.0;
break;
case DIAI_Z:
//view_rotz += evt.axisrel / 2.0;
break;
default:
;
}
}
break;
default:
;
*/
}
}
}
// Note : if we not stop like this the system break ...
exit(-1);
};
// -------------------------------------------------------------------------
// ClipBoard AREA :
// -------------------------------------------------------------------------
void guiInterface::ClipBoardGet(enum gale::context::clipBoard::clipboardListe _clipboardID) {
// TODO : ...
}
void guiInterface::ClipBoardSet(enum gale::context::clipBoard::clipboardListe _clipboardID) {
// TODO : ...
}
#undef __class__
#define __class__ "guiInterface"
void guiInterface::Stop() {
GALE_INFO("X11-API: Stop");
m_run = false;
}
void guiInterface::KeyboardShow() {
// nothing to do : No keyboard on computer ...
}
void guiInterface::KeyboardHide() {
// nothing to do : No keyboard on computer ...
}
void guiInterface::changeSize(ivec2 _size) {
// TODO : ...
}
void guiInterface::changePos(ivec2 _pos) {
// TODO : ...
}
void guiInterface::getAbsPos(ivec2& _pos) {
// TODO : ...
}
void guiInterface::setCursor(enum gale::cursorDisplay _newCursor) {
// TODO : ...
}
void guiInterface::GrabPointerEvents(bool _isGrabbed, vec2 _forcedPosition) {
// TODO : ...
}
/**
* @brief Main of the program
* @param std IO
* @return std IO
*/
int guiInterface::main(int argc, const char *argv[]) {
GALE_INFO("Main (START)");
for (int32_t iii=0; iii<NB_MAX_INPUT; iii++) {
inputIsPressed[iii] = false;
}
m_grabAllEvent = false;
// start X11 thread ...
DirectFB_Init(argc, argv);
//start the basic thread :
eSystem::init();
// Run ...
DirectFB_Run();
// UnInit:
DirectFB_UnInit();
// close X11 :
guiInterface::Stop();
// uninit ALL :
eSystem::UnInit();
GALE_INFO("Main (STOP)");
return 0;
}
void guiInterface::forceOrientation(enum gale::orientation _orientation) {
// nothing to do ...
}
/*
static void init(int argc, char *argv[]) {
glLightfv(GL_LIGHT0, GL_POSITION, pos);
glEnable(GL_CULL_FACE);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_DEPTH_TEST);
glShadeModel(GL_SMOOTH);
glEnableClientState(GL_NORMAL_ARRAY);
glEnableClientState(GL_VERTEX_ARRAY);
for (i=1; i<argc; i++)
{
if (strcmp(argv[i],"-info") == 0)
{
printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
printf("GL_VERSION = %s\n", (char *) glGetString(GL_VERSION));
printf("GL_VENDOR = %s\n", (char *) glGetString(GL_VENDOR));
printf("GL_EXTENSIONS = %s\n", (char *) glGetString(GL_EXTENSIONS));
}
else if (strcmp(argv[i],"-exit") == 0)
{
autoexit = 30;
printf("Auto Exit after %i seconds.\n", autoexit );
}
}
// make the gears
gear1 = gear(1.0, 4.0, 1.0, 20, 0.7, red);
gear2 = gear(0.5, 2.0, 2.0, 10, 0.7, green);
gear3 = gear(1.3, 2.0, 0.5, 10, 0.7, blue);
}
*/

14
gale/debug.cpp Normal file
View File

@ -0,0 +1,14 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#include <gale/debug.h>
int32_t gale::getLogId() {
static int32_t g_val = etk::log::registerInstance("gale");
return g_val;
}

44
gale/debug.h Normal file
View File

@ -0,0 +1,44 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#ifndef __GALE_DEBUG_H__
#define __GALE_DEBUG_H__
#include <etk/log.h>
namespace gale {
int32_t getLogId();
};
#define GALE_BASE(info,data) TK_LOG_BASE(gale::getLogId(),info,data)
#define GALE_PRINT(data) GALE_BASE(-1, data)
#define GALE_CRITICAL(data) GALE_BASE(1, data)
#define GALE_ERROR(data) GALE_BASE(2, data)
#define GALE_WARNING(data) GALE_BASE(3, data)
#ifdef DEBUG
#define GALE_INFO(data) GALE_BASE(4, data)
#define GALE_DEBUG(data) GALE_BASE(5, data)
#define GALE_VERBOSE(data) GALE_BASE(6, data)
#define GALE_TODO(data) GALE_BASE(4, "TODO : " << data)
#else
#define GALE_INFO(data) do { } while(false)
#define GALE_DEBUG(data) do { } while(false)
#define GALE_VERBOSE(data) do { } while(false)
#define GALE_TODO(data) do { } while(false)
#endif
#define GALE_ASSERT(cond,data) \
do { \
if (!(cond)) { \
GALE_CRITICAL(data); \
assert(!#cond); \
} \
} while (0)
#endif

27
gale/event/Entry.cpp Normal file
View File

@ -0,0 +1,27 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#include <gale/widget/Widget.h>
#undef __class__
#define __class__ "event::Entry"
std::ostream& gale::event::operator <<(std::ostream& _os, const gale::event::Entry& _obj) {
_os << "{type=" << _obj.getType();
_os << " status=" << _obj.getStatus();
if (_obj.getType() == gale::key::keyboardChar) {
_os << " char=" << _obj.getChar();
}
_os << "}";
return _os;
}
std::ostream& gale::event::operator <<(std::ostream& _os, const gale::event::EntrySystem& _obj) {
_os << _obj.m_event;
return _os;
}

77
gale/event/Entry.h Normal file
View File

@ -0,0 +1,77 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#ifndef __GALE_EVENT_ENTRY_H__
#define __GALE_EVENT_ENTRY_H__
#include <etk/types.h>
#include <gale/key/key.h>
namespace gale {
namespace event {
class Entry {
private:
enum gale::key::keyboard m_type; //!< type of hardware event
enum gale::key::status m_status; //!< status of hardware event
gale::key::Special m_specialKey; //!< input key status (prevent change in time..)
char32_t m_unicodeData; //!< Unicode data (in some case)
public:
Entry(enum gale::key::keyboard _type,
enum gale::key::status _status,
gale::key::Special _specialKey,
char32_t _char) :
m_type(_type),
m_status(_status),
m_specialKey(_specialKey),
m_unicodeData(_char) {
};
void setType(enum gale::key::keyboard _type) {
m_type = _type;
};
inline const enum gale::key::keyboard& getType() const {
return m_type;
};
void setStatus(enum gale::key::status _status) {
m_status = _status;
};
inline const enum gale::key::status& getStatus() const {
return m_status;
};
void setSpecialKey(const gale::key::Special& _specialKey) {
m_specialKey = _specialKey;
};
inline const gale::key::Special& getSpecialKey() const {
return m_specialKey;
};
void setChar(char32_t _char) {
m_unicodeData = _char;
};
inline const char32_t& getChar() const {
return m_unicodeData;
};
};
std::ostream& operator <<(std::ostream& _os, const gale::event::Entry& _obj);
class EntrySystem {
public:
EntrySystem(enum gale::key::keyboard _type,
enum gale::key::status _status,
gale::key::Special _specialKey,
char32_t _char) :
m_event(_type, _status, _specialKey, _char) {
};
gale::event::Entry m_event;
};
std::ostream& operator <<(std::ostream& _os, const gale::event::EntrySystem& _obj);
};
};
#endif

26
gale/event/Input.cpp Normal file
View File

@ -0,0 +1,26 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#include <gale/widget/Widget.h>
#undef __class__
#define __class__ "event::Input"
std::ostream& gale::event::operator <<(std::ostream& _os, const gale::event::Input& _obj) {
_os << "{type=" << _obj.getType();
_os << " status=" << _obj.getStatus();
_os << " id=" << etk::to_string(_obj.getId());
_os << " pos=" << _obj.getPos();
_os << "}";
return _os;
}
std::ostream& gale::event::operator <<(std::ostream& _os, const gale::event::InputSystem& _obj) {
_os << _obj.m_event;
return _os;
}

110
gale/event/Input.h Normal file
View File

@ -0,0 +1,110 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#ifndef __GALE_EVENT_INPUT_H__
#define __GALE_EVENT_INPUT_H__
#include <etk/types.h>
namespace gale {
namespace event {
class Input {
private:
enum gale::key::type m_type;
enum gale::key::status m_status;
uint8_t m_inputId;
vec2 m_pos;
gale::key::Special m_specialKey; //!< input key status (prevent change in time..)
public:
Input(enum gale::key::type _type,
enum gale::key::status _status,
uint8_t _id,
const vec2& _pos,
gale::key::Special _specialKey):
m_type(_type),
m_status(_status),
m_inputId(_id),
m_pos(_pos),
m_specialKey(_specialKey) {
};
void setType(enum gale::key::type _type) {
m_type = _type;
};
inline const enum gale::key::type& getType() const {
return m_type;
};
void setStatus(enum gale::key::status _status) {
m_status = _status;
};
inline const enum gale::key::status& getStatus() const {
return m_status;
};
void setId(uint8_t _id) {
m_inputId = _id;
};
inline const uint8_t& getId() const {
return m_inputId;
};
void setPos(const vec2& _pos) {
m_pos = _pos;
};
inline const vec2& getPos() const {
return m_pos;
};
void setSpecialKey(const gale::key::Special& _specialKey) {
m_specialKey = _specialKey;
};
inline const gale::key::Special& getSpecialKey() const {
return m_specialKey;
};
/**
* @brief Reset the input property of the curent event.
*/
void reset() const {
// TODO : Call the entry element ant rest it ...
}
};
std::ostream& operator <<(std::ostream& _os, const gale::event::Input& _obj);
class InputSystem {
public:
InputSystem(enum gale::key::type _type,
enum gale::key::status _status,
uint8_t _id,
const vec2& _pos,
std::shared_ptr<gale::Widget> _dest,
int32_t _realIdEvent,
gale::key::Special _specialKey) :
m_event(_type, _status, _id, _pos, _specialKey),
m_dest(_dest),
m_realIdEvent(_realIdEvent) { };
gale::event::Input m_event;
private:
std::shared_ptr<gale::Widget> m_dest;
int32_t m_realIdEvent;
public:
void setDestWidget(std::shared_ptr<gale::Widget> _dest) {
m_dest = _dest;
};
inline std::shared_ptr<gale::Widget> getDestWidget() const {
return m_dest;
};
void setRealId(int32_t _realIdEvent) {
m_realIdEvent = _realIdEvent;
};
inline int32_t getRealId() const {
return m_realIdEvent;
};
};
std::ostream& operator <<(std::ostream& _os, const gale::event::InputSystem& _obj);
};
};
#endif

34
gale/event/Time.cpp Normal file
View File

@ -0,0 +1,34 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#include <gale/widget/Widget.h>
#undef __class__
#define __class__ "event::Time"
std::ostream& gale::event::operator <<(std::ostream& _os, const gale::event::Time& _obj) {
_os << "{time=" << _obj.getTime();
_os << " uptime=" << _obj.getApplUpTime();
_os << " delta=" << _obj.getDelta();
_os << " deltaCall=" << _obj.getDeltaCall();
_os << "}";
return _os;
}
namespace etk {
template<> std::string to_string<gale::event::Time>(gale::event::Time const& _obj) {
std::string out;
out = "{[gale::event::Time]time=" + etk::to_string(_obj.getTime());
out += ";uptime=" + etk::to_string(_obj.getApplUpTime());
out += ";delta=" + etk::to_string(_obj.getDelta());
out += ";deltaCall=" + etk::to_string(_obj.getDeltaCall());
out += "}";
return out;
}
}

67
gale/event/Time.h Normal file
View File

@ -0,0 +1,67 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#ifndef __GALE_EVENT_CALL_TIME_H__
#define __GALE_EVENT_CALL_TIME_H__
#include <etk/types.h>
namespace gale {
namespace event {
class Time {
private:
int64_t m_timeSystem; //!< Current system time (micro-second)
int64_t m_timeUpAppl; //!< Current application wake up-time (micro-second)
float m_timeDelta; //!< Time from the last cycle call of the system (main appl tick) (second)
float m_timeDeltaCall; //!< Time from the last call (when we can manage periodic call with specifying periode) (second)
public:
Time(int64_t _timeSystem,
int64_t _timeUpAppl,
float _timeDelta,
float _timeDeltaCall) :
m_timeSystem(_timeSystem),
m_timeUpAppl(_timeUpAppl),
m_timeDelta(_timeDelta),
m_timeDeltaCall(_timeDeltaCall){
};
public:
void setTime(int64_t _timeSystem) {
m_timeSystem=_timeSystem;
};
inline int64_t getTime() const {
return m_timeSystem;
};
void setApplWakeUpTime(int64_t _timeUpAppl) {
m_timeUpAppl=_timeUpAppl;
};
inline int64_t getApplWakeUpTime() const {
return m_timeUpAppl;
};
inline int64_t getApplUpTime() const {
return m_timeSystem-m_timeUpAppl;
};
void setDelta(float _timeDelta) {
m_timeDelta=_timeDelta;
};
inline float getDelta() const {
return m_timeDelta;
};
void setDeltaCall(float _timeDeltaCall) {
m_timeDeltaCall=_timeDeltaCall;
};
inline float getDeltaCall() const {
return m_timeDeltaCall;
};
};
std::ostream& operator <<(std::ostream& _os, const gale::event::Time& _obj);
};
};
#endif

51
gale/gale.cpp Normal file
View File

@ -0,0 +1,51 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#include <gale/gale.h>
#include <gale/widget/Manager.h>
#include <gale/context/Context.h>
#include <gale/context/commandLine.h>
#include <etk/os/FSNode.h>
#include <gale/Dimension.h>
#include <date/date.h>
#undef __class__
#define __class__ "gale"
#ifndef GALE_VERSION
#define GALE_VERSION "0.0.0"
#endif
std::string gale::getCompilationMode() {
#ifdef MODE_RELEASE
return "Release";
#else
return "Debug";
#endif
}
std::string gale::getBoardType() {
#ifdef __TARGET_OS__Linux
return "Linux";
#elif defined(__TARGET_OS__Android)
return "Android";
#elif defined(__TARGET_OS__Windows)
return "Windows";
#elif defined(__TARGET_OS__IOs)
return "IOs";
#elif defined(__TARGET_OS__MacOs)
return "MacOs";
#else
return "Unknown";
#endif
}
std::string gale::getVersion() {
return GALE_VERSION;
}

52
gale/gale.h Normal file
View File

@ -0,0 +1,52 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#ifndef __GALE_H__
#define __GALE_H__
#include <etk/types.h>
#include <gale/context/Application.h>
namespace gale {
/**
* @brief This is the only one things the User might done in his main();
* @note To answare you before you ask the question, this is really simple:
* Due to the fect that the current system is multiple-platform, you "main"
* Does not exist in the android platform, then gale call other start
* and stop function, to permit to have only one code
* @note The main can not be in the gale, due to the fact thet is an librairy
* @param[in] _application just created instance of the applicationo
* @param[in] _argc Standard argc
* @param[in] _argv Standard argv
* @return normal error int for the application error management
*/
int32_t run(gale::context::Application* _application, int32_t _argc = 0, const char* _argv[] = NULL);
/**
* @brief get GALE version
* @return The string that describe gale version
*/
std::string getVersion();
/**
* @brief get current time in us...
* @return The current time
* @note is implemented by the OS implementation cf renderer/X11/...
*/
int64_t getTime();
/**
* @brief get compilation mode (release/debug)
* @return the string of the mode of commpilation
*/
std::string getCompilationMode();
/**
* @brief get the board type (Android/Linux/MacOs/...)
* @return the string of the mode of commpilation
*/
std::string getBoardType();
};
#endif

214
gale/key/Special.cpp Normal file
View File

@ -0,0 +1,214 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#include <gale/key/Special.h>
#define GALE_FLAG_KEY_CAPS_LOCK 0x00000001
#define GALE_FLAG_KEY_SHIFT 0x00000002
#define GALE_FLAG_KEY_CTRL 0x00000004
#define GALE_FLAG_KEY_META 0x00000008
#define GALE_FLAG_KEY_ALT 0x00000010
#define GALE_FLAG_KEY_ALTGR 0x00000020
#define GALE_FLAG_KEY_NUM_LOCK 0x00000040
#define GALE_FLAG_KEY_INSERT 0x00000080
// TODO : Update to support the Left and right of some key ...
gale::key::Special::Special() :
m_value(0) {
}
void gale::key::Special::update(enum gale::key::keyboard _move, bool _isDown) {
switch (_move) {
case keyboardInsert:
setInsert(_isDown);
break;
case keyboardCapLock:
setCapsLock(_isDown);
break;
case keyboardShiftLeft:
case keyboardShiftRight:
setShift(_isDown);
break;
case keyboardCtrlLeft:
case keyboardCtrlRight:
setCtrl(_isDown);
break;
case keyboardMetaLeft:
case keyboardMetaRight:
setMeta(_isDown);
break;
case keyboardAlt:
setAlt(_isDown);
break;
case keyboardAltGr:
setAltGr(_isDown);
break;
case keyboardNumLock:
setNumLock(_isDown);
break;
default:
break;
}
}
bool gale::key::Special::getCapsLock() const {
if ((m_value & GALE_FLAG_KEY_CAPS_LOCK) != 0) {
return true;
}
return false;
}
void gale::key::Special::setCapsLock(bool _value) {
if ((m_value & GALE_FLAG_KEY_CAPS_LOCK) != 0) {
if (_value == false) {
m_value -= GALE_FLAG_KEY_CAPS_LOCK;
}
} else {
if (_value == true) {
m_value += GALE_FLAG_KEY_CAPS_LOCK;
}
}
}
bool gale::key::Special::getShift() const {
if ((m_value & GALE_FLAG_KEY_SHIFT) != 0) {
return true;
}
return false;
}
void gale::key::Special::setShift(bool _value) {
if ((m_value & GALE_FLAG_KEY_SHIFT) != 0) {
if (_value == false) {
m_value -= GALE_FLAG_KEY_SHIFT;
}
} else {
if (_value == true) {
m_value += GALE_FLAG_KEY_SHIFT;
}
}
}
bool gale::key::Special::getCtrl() const {
if ((m_value & GALE_FLAG_KEY_CTRL) != 0) {
return true;
}
return false;
}
void gale::key::Special::setCtrl(bool _value) {
if ((m_value & GALE_FLAG_KEY_CTRL) != 0) {
if (_value == false) {
m_value -= GALE_FLAG_KEY_CTRL;
}
} else {
if (_value == true) {
m_value += GALE_FLAG_KEY_CTRL;
}
}
}
bool gale::key::Special::getMeta() const {
if ((m_value & GALE_FLAG_KEY_META) != 0) {
return true;
}
return false;
}
void gale::key::Special::setMeta(bool _value) {
if ((m_value & GALE_FLAG_KEY_META) != 0) {
if (_value == false) {
m_value -= GALE_FLAG_KEY_META;
}
} else {
if (_value == true) {
m_value += GALE_FLAG_KEY_META;
}
}
}
bool gale::key::Special::getAlt() const {
if ((m_value & GALE_FLAG_KEY_ALT) != 0) {
return true;
}
return false;
}
void gale::key::Special::setAlt(bool _value) {
if ((m_value & GALE_FLAG_KEY_ALT) != 0) {
if (_value == false) {
m_value -= GALE_FLAG_KEY_ALT;
}
} else {
if (_value == true) {
m_value += GALE_FLAG_KEY_ALT;
}
}
}
bool gale::key::Special::getAltGr() const {
if ((m_value & GALE_FLAG_KEY_ALTGR) != 0) {
return true;
}
return false;
}
void gale::key::Special::setAltGr(bool _value) {
if ((m_value & GALE_FLAG_KEY_ALTGR) != 0) {
if (_value == false) {
m_value -= GALE_FLAG_KEY_ALTGR;
}
} else {
if (_value == true) {
m_value += GALE_FLAG_KEY_ALTGR;
}
}
}
bool gale::key::Special::getNumLock() const {
if ((m_value & GALE_FLAG_KEY_NUM_LOCK) != 0) {
return true;
}
return false;
}
void gale::key::Special::setNumLock(bool _value) {
if ((m_value & GALE_FLAG_KEY_NUM_LOCK) != 0) {
if (_value == false) {
m_value -= GALE_FLAG_KEY_NUM_LOCK;
}
} else {
if (_value == true) {
m_value += GALE_FLAG_KEY_NUM_LOCK;
}
}
}
bool gale::key::Special::getInsert() const {
if ((m_value & GALE_FLAG_KEY_INSERT) != 0) {
return true;
}
return false;
}
void gale::key::Special::setInsert(bool _value) {
if ((m_value & GALE_FLAG_KEY_INSERT) != 0) {
if (_value == false) {
m_value -= GALE_FLAG_KEY_INSERT;
}
} else {
if (_value == true) {
m_value += GALE_FLAG_KEY_INSERT;
}
}
}
std::ostream& gale::key::operator <<(std::ostream& _os, const gale::key::Special _obj) {
_os << " capLock=" << _obj.getCapsLock();
_os << " shift=" << _obj.getShift();
_os << " ctrl=" << _obj.getCtrl();
_os << " meta=" << _obj.getMeta();
_os << " alt=" << _obj.getAlt();
_os << " altGr=" << _obj.getAltGr();
_os << " verNum=" << _obj.getNumLock();
_os << " insert=" << _obj.getInsert();
return _os;
}

121
gale/key/Special.h Normal file
View File

@ -0,0 +1,121 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#ifndef __GALE_KEY_SPECIAL_H__
#define __GALE_KEY_SPECIAL_H__
#include <gale/debug.h>
#include <gale/key/keyboard.h>
namespace gale {
namespace key {
/**
* @brief This class consider generic special keyborad key (insert, control, shift ...)
*/
class Special {
private:
uint32_t m_value;
public:
/**
* @brief Main constructor
*/
Special();
/**
* @brief get the current CapLock Status
* @return The CapLock value
*/
bool getCapsLock() const;
/**
* @brief set the current CapLock Status
* @param[in] _value The new CapLock value
*/
void setCapsLock(bool _value);
/**
* @brief Get the current Shift key status
* @return The Shift value
*/
bool getShift() const;
/**
* @brief Set the current Shift key status
* @param[in] _value The new Shift value
*/
void setShift(bool _value);
/**
* @brief Get the Current Control key status
* @return The Control value
*/
bool getCtrl() const;
/**
* @brief Set the Current Control key status
* @param[in] _value The new Control value
*/
void setCtrl(bool _value);
/**
* @brief Get the current Meta key status (also named windows or apple key)
* @return The Meta value (name Windows key, apple key, command key ...)
*/
bool getMeta() const;
/**
* @brief Set the current Meta key status (also named windows or apple key)
* @param[in] _value The new Meta value (name Windows key, apple key, command key ...)
*/
void setMeta(bool _value);
/**
* @brief Get the current Alt key status
* @return The Alt value
*/
bool getAlt() const;
/**
* @brief Set the current Alt key status
* @param[in] _value The new Alt value
*/
void setAlt(bool _value);
/**
* @brief Get the current Alt-Gr key status
* @return The Alt-gr value (does not exist on MacOs)
*/
bool getAltGr() const;
/**
* @brief Set the current Alt-Gr key status
* @param[in] _value The new Alt-gr value (does not exist on MacOs)
*/
void setAltGr(bool _value);
/**
* @brief Get the current Ver-num key status
* @return The Numerical Lock value
*/
bool getNumLock() const;
/**
* @brief Set the current Ver-num key status
* @param[in] _value The new Numerical Lock value
*/
void setNumLock(bool _value);
/**
* @brief Get the current Intert key status
* @return The Insert value
*/
bool getInsert() const;
/**
* @brief Set the current Intert key status
* @param[in] _value The new Insert value
*/
void setInsert(bool _value);
/**
* @brief Update the internal value with the input moving key.
* @param[in] _move Moving key.
* @param[in] _isFown The Key is pressed or not.
*/
void update(enum gale::key::keyboard _move, bool _isDown);
};
std::ostream& operator <<(std::ostream& _os, const gale::key::Special _obj);
};
};
#endif

19
gale/key/key.h Normal file
View File

@ -0,0 +1,19 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#ifndef __GALE_KEY_H__
#define __GALE_KEY_H__
#include <gale/key/keyboard.h>
#include <gale/key/Special.h>
#include <gale/key/status.h>
#include <gale/key/type.h>
#endif

80
gale/key/keyboard.cpp Normal file
View File

@ -0,0 +1,80 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#include <gale/key/keyboard.h>
static const char* keyboardDescriptionString[gale::key::keyboardCount+1] = {
"keyboardUnknow",
"keyboardChar",
"keyboardLeft",
"keyboardRight",
"keyboardUp",
"keyboardDown",
"keyboardPageUp",
"keyboardPageDown",
"keyboardStart",
"keyboardEnd",
"keyboardPrint",
"keyboardStopDefil",
"keyboardWait",
"keyboardInsert",
"keyboardF1",
"keyboardF2",
"keyboardF3",
"keyboardF4",
"keyboardF5",
"keyboardF6",
"keyboardF7",
"keyboardF8",
"keyboardF9",
"keyboardF10",
"keyboardF11",
"keyboardF12",
"keyboardCapLock",
"keyboardShiftLeft",
"keyboardShiftRight",
"keyboardCtrlLeft",
"keyboardCtrlRight",
"keyboardMetaLeft",
"keyboardMetaRight",
"keyboardAlt",
"keyboardAltGr",
"keyboardContextMenu",
"keyboardNumLock",
"keyboardCount"
};
std::ostream& gale::key::operator <<(std::ostream& _os, const enum gale::key::keyboard _obj) {
if (_obj >= 0 && _obj <gale::key::keyboardCount) {
_os << keyboardDescriptionString[_obj];
} else {
_os << "[ERROR]";
}
return _os;
}
static const char* keyboardSystemDescriptionString[gale::key::keyboardSystemCount+1] = {
"keyboardSystemUnknow",
"keyboardSystemVolumeUp",
"keyboardSystemVolumeDown",
"keyboardSystemMenu",
"keyboardSystemCamera",
"keyboardSystemHome",
"keyboardSystemPower",
"keyboardSystemBack",
"keyboardSystemCount"
};
std::ostream& gale::key::operator <<(std::ostream& _os, const enum gale::key::keyboardSystem _obj) {
if (_obj >= 0 && _obj <gale::key::keyboardSystemCount) {
_os << keyboardSystemDescriptionString[_obj];
} else {
_os << "[ERROR]";
}
return _os;
}

84
gale/key/keyboard.h Normal file
View File

@ -0,0 +1,84 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#ifndef __GALE_KEY_KEYBOARD_H__
#define __GALE_KEY_KEYBOARD_H__
#include <gale/debug.h>
namespace gale {
namespace key {
/**
* @brief Keybord event or joystick event
* @warning If you modify Id of these element check the java interface file of constant : GaleConstant.java
*/
enum keyboard {
keyboardUnknow = 0, //!< Unknown keyboard key
keyboardChar, //!< Char input is arrived ...
keyboardLeft, //!< Left key <--
keyboardRight, //!< Right key -->
keyboardUp, //!< Up key ^
keyboardDown, //!< Down key \/
keyboardPageUp, //!< Page Up key
keyboardPageDown, //!< page down key
keyboardStart, //!< Start key
keyboardEnd, //!< End key
keyboardPrint, //!< print screen key.
keyboardStopDefil, //!< Stop display key.
keyboardWait, //!< Wait key.
keyboardInsert, //!< insert key.
keyboardF1, //!< F1 key.
keyboardF2, //!< F2 key.
keyboardF3, //!< F3 key.
keyboardF4, //!< F4 key.
keyboardF5, //!< F5 key.
keyboardF6, //!< F6 key.
keyboardF7, //!< F7 key.
keyboardF8, //!< F8 key.
keyboardF9, //!< F9 key.
keyboardF10, //!< F10 key.
keyboardF11, //!< F11 key.
keyboardF12, //!< F12 key.
keyboardCapLock, //!< Capital Letter Lock key.
keyboardShiftLeft, //!< Shift left key.
keyboardShiftRight, //!< Shift right key.
keyboardCtrlLeft, //!< Control left key.
keyboardCtrlRight, //!< Control right key.
keyboardMetaLeft, //!< Meta left key (apple key or windows key).
keyboardMetaRight, //!< Meta right key (apple key or windows key).
keyboardAlt, //!< Alt key.
keyboardAltGr, //!< Alt ground key.
keyboardContextMenu, //!< Contextual menu key.
keyboardNumLock, //!< Numerical Lock key.
keyboardCount //!< number of posible key
};
/**
* @brief Debug operator To display the curent element in a Human redeable information
*/
std::ostream& operator <<(std::ostream& _os, const enum gale::key::keyboard _obj);
enum keyboardSystem {
keyboardSystemUnknow = 0, //!< Unknown keyboard system key
keyboardSystemVolumeUp, //!< Hardware volume UP key
keyboardSystemVolumeDown, //!< Hardware volume DOWN key
keyboardSystemMenu, //!< Hardware Menu key
keyboardSystemCamera, //!< Hardware Camera key
keyboardSystemHome, //!< Hardware Home key
keyboardSystemPower, //!< Hardware Power key
keyboardSystemBack, //!< Hardware Back key
keyboardSystemCount //!< number of posible System key
};
std::ostream& operator <<(std::ostream& _os, const enum gale::key::keyboardSystem _obj);
};
};
#endif

38
gale/key/status.cpp Normal file
View File

@ -0,0 +1,38 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#include <gale/key/status.h>
static const char* statusDescriptionString[gale::key::statusCount+1] = {
"statusUnknow",
"statusDown",
"statusMove",
"statusSingle",
"statusDouble",
"statusTriple",
"statusQuad",
"statusQuinte",
"statusUp",
"statusUpAfter",
"statusEnter",
"statusLeave",
"statusAbort",
"statusTransfert",
"statusCount"
};
std::ostream& gale::key::operator <<(std::ostream& _os, const enum gale::key::status _obj) {
if (_obj >= 0 && _obj <gale::key::statusCount) {
_os << statusDescriptionString[_obj];
} else {
_os << "[ERROR]";
}
return _os;
}

47
gale/key/status.h Normal file
View File

@ -0,0 +1,47 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#ifndef __GALE_KEY_STATUS_H__
#define __GALE_KEY_STATUS_H__
#include <gale/debug.h>
namespace gale {
namespace key {
/**
* @brief Keybord event or joyestick event
*/
enum status {
statusUnknow = 0,
statusDown, // availlable on Keyboard too
statusMove,
statusSingle,
statusDouble,
statusTriple,
statusQuad,
statusQuinte,
statusUp, // availlable on Keyboard too
statusUpAfter, // mouse input & finger input this appear after the single event (depending on some case...)
statusEnter,
statusLeave,
statusAbort, // Appeare when an event is tranfert betwwen widgets (the widget which receive this has lost the events)
statusTransfert, // Appeare when an event is tranfert betwwen widgets (the widget which receive this has receive the transfert of the event)
statusCount, // number max of imput possible
};
/**
* @brief Debug operator To display the curent element in a Human redeable information
*/
std::ostream& operator <<(std::ostream& _os, const enum gale::key::status _obj);
};
};
#endif

28
gale/key/type.cpp Normal file
View File

@ -0,0 +1,28 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#include <gale/key/type.h>
static const char* typeDescriptionString[gale::key::typeCount+1] = {
"typeUnknow",
"typeMouse",
"typeFinger",
"typeStylet",
"typeCount"
};
std::ostream& gale::operator <<(std::ostream& _os, const enum gale::key::type _obj) {
if (_obj >= 0 && _obj < gale::key::typeCount) {
_os << typeDescriptionString[_obj];
} else {
_os << "[ERROR]";
}
return _os;
}

37
gale/key/type.h Normal file
View File

@ -0,0 +1,37 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#ifndef __GALE_KEY_TYPE_H__
#define __GALE_KEY_TYPE_H__
#include <gale/debug.h>
namespace gale {
namespace key {
/**
* @brief type of input : Note that the keyboard is not prevent due to the fact that data is too different
*/
enum type {
typeUnknow = 0, //!< Unknow input Type
typeMouse, //!< Mouse type
typeFinger, //!< Finger type
typeStylet, //!< Stylet type
typeCount //!< number of types
};
};
/**
* @brief Debug operator To display the curent element in a Human redeable information
*/
std::ostream& operator <<(std::ostream& _os, const enum gale::key::type _obj);
};
#endif

View File

0
gale/renderer/Renderer.h Normal file
View File

View File

@ -0,0 +1,496 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#include <vector>
#include <gale/debug.h>
#include <gale/openGL/openGL.h>
#include <etk/stdTools.h>
#include <mutex>
//#define DIRECT_MODE
#define CHECK_ERROR_OPENGL
static void checkGlError(const char* _op, int32_t _localLine) {
#ifdef CHECK_ERROR_OPENGL
bool hasError = false;
for (GLint error = glGetError(); error; error = glGetError()) {
GALE_ERROR("after " << _op << "():" << _localLine << " glError(" << error << ")");
hasError = true;
}
if (hasError == true) {
GALE_CRITICAL("plop");
}
#endif
}
#define OPENGL_ERROR(data) do { } while (false)
//#define OPENGL_ERROR(data) GALE_ERROR(data)
#define OPENGL_WARNING(data) do { } while (false)
//#define OPENGL_WARNING(data) GALE_WARNING(data)
#define OPENGL_INFO(data) do { } while (false)
//#define OPENGL_INFO(data) GALE_INFO(data)
/**
* @brief get the draw mutex (gale render).
* @note due ti the fact that the system can be called for multiple instance, for naw we just limit the acces to one process at a time.
* @return the main inteface Mutex
*/
static std::mutex& mutexOpenGl() {
static std::mutex s_drawMutex;
return s_drawMutex;
}
std::vector<mat4> l_matrixList;
mat4 l_matrixCamera;
static uint32_t l_flagsCurrent = 0;
static uint32_t l_flagsMustBeSet = 0;
static uint32_t l_textureflags = 0;
static int32_t l_programId = 0;
void gale::openGL::lock() {
mutexOpenGl().lock();
l_matrixList.clear();
mat4 tmpMat;
l_matrixList.push_back(tmpMat);
l_matrixCamera.identity();
l_flagsCurrent = 0;
l_flagsMustBeSet = 0;
l_textureflags = 0;
l_programId = -1;
}
void gale::openGL::unLock() {
mutexOpenGl().unlock();
}
void gale::openGL::setBasicMatrix(const mat4& _newOne) {
if (l_matrixList.size()!=1) {
GALE_ERROR("matrix is not corect size in the stack : " << l_matrixList.size());
}
l_matrixList.clear();
l_matrixList.push_back(_newOne);
}
void gale::openGL::setMatrix(const mat4& _newOne) {
if (l_matrixList.size() == 0) {
GALE_ERROR("set matrix list is not corect size in the stack : " << l_matrixList.size());
l_matrixList.push_back(_newOne);
return;
}
l_matrixList[l_matrixList.size()-1] = _newOne;
}
void gale::openGL::push() {
if (l_matrixList.size() == 0) {
GALE_ERROR("set matrix list is not corect size in the stack : " << l_matrixList.size());
mat4 tmp;
l_matrixList.push_back(tmp);
return;
}
mat4 tmp = l_matrixList[l_matrixList.size()-1];
l_matrixList.push_back(tmp);
}
void gale::openGL::pop() {
if (l_matrixList.size() <= 1) {
GALE_ERROR("set matrix list is not corect size in the stack : " << l_matrixList.size());
l_matrixList.clear();
mat4 tmp;
l_matrixList.push_back(tmp);
l_matrixCamera.identity();
return;
}
l_matrixList.pop_back();
l_matrixCamera.identity();
}
const mat4& gale::openGL::getMatrix() {
if (l_matrixList.size() == 0) {
GALE_ERROR("set matrix list is not corect size in the stack : " << l_matrixList.size());
mat4 tmp;
l_matrixList.push_back(tmp);
}
return l_matrixList[l_matrixList.size()-1];
}
const mat4& gale::openGL::getCameraMatrix() {
return l_matrixCamera;
}
void gale::openGL::setCameraMatrix(const mat4& _newOne) {
l_matrixCamera = _newOne;
}
void gale::openGL::finish() {
l_programId = -1;
l_textureflags = 0;
}
void gale::openGL::flush() {
l_programId = -1;
l_textureflags = 0;
glFlush();
OPENGL_INFO("========================" );
OPENGL_INFO("== FLUSH OPEN GL ==" );
OPENGL_INFO("========================");
}
void gale::openGL::swap() {
}
std::ostream& gale::operator <<(std::ostream& _os, const enum openGL::openGlFlags& _obj) {
static std::vector<std::pair<enum openGL::openGlFlags, const char*>> list = {
std::make_pair(openGL::FLAG_BLEND, "FLAG_BLEND"),
std::make_pair(openGL::FLAG_CLIP_DISTANCE_I, "FLAG_CLIP_DISTANCE_I"),
std::make_pair(openGL::FLAG_COLOR_LOGIC_OP, "FLAG_COLOR_LOGIC_OP"),
std::make_pair(openGL::FLAG_CULL_FACE, "FLAG_CULL_FACE"),
std::make_pair(openGL::FLAG_DEBUG_OUTPUT, "FLAG_DEBUG_OUTPUT"),
std::make_pair(openGL::FLAG_DEBUG_OUTPUT_SYNCHRONOUS, "FLAG_DEBUG_OUTPUT_SYNCHRONOUS"),
std::make_pair(openGL::FLAG_DEPTH_CLAMP, "FLAG_DEPTH_CLAMP"),
std::make_pair(openGL::FLAG_DEPTH_TEST, "FLAG_DEPTH_TEST"),
std::make_pair(openGL::FLAG_DITHER, "FLAG_DITHER"),
std::make_pair(openGL::FLAG_FRAMEBUFFER_SRGB, "FLAG_FRAMEBUFFER_SRGB"),
std::make_pair(openGL::FLAG_LINE_SMOOTH, "FLAG_LINE_SMOOTH"),
std::make_pair(openGL::FLAG_MULTISAMPLE, "FLAG_MULTISAMPLE"),
std::make_pair(openGL::FLAG_POLYGON_OFFSET_FILL, "FLAG_POLYGON_OFFSET_FILL"),
std::make_pair(openGL::FLAG_POLYGON_OFFSET_LINE, "FLAG_POLYGON_OFFSET_LINE"),
std::make_pair(openGL::FLAG_POLYGON_OFFSET_POINT, "FLAG_POLYGON_OFFSET_POINT"),
std::make_pair(openGL::FLAG_POLYGON_SMOOTH, "FLAG_POLYGON_SMOOTH"),
std::make_pair(openGL::FLAG_PRIMITIVE_RESTART, "FLAG_PRIMITIVE_RESTART"),
std::make_pair(openGL::FLAG_PRIMITIVE_RESTART_FIXED_INDEX, "FLAG_PRIMITIVE_RESTART_FIXED_INDEX"),
std::make_pair(openGL::FLAG_SAMPLE_ALPHA_TO_COVERAGE, "FLAG_SAMPLE_ALPHA_TO_COVERAGE"),
std::make_pair(openGL::FLAG_SAMPLE_ALPHA_TO_ONE, "FLAG_SAMPLE_ALPHA_TO_ONE"),
std::make_pair(openGL::FLAG_SAMPLE_COVERAGE, "FLAG_SAMPLE_COVERAGE"),
std::make_pair(openGL::FLAG_SAMPLE_SHADING, "FLAG_SAMPLE_SHADING"),
std::make_pair(openGL::FLAG_SAMPLE_MASK, "FLAG_SAMPLE_MASK"),
std::make_pair(openGL::FLAG_SCISSOR_TEST, "FLAG_SCISSOR_TEST"),
std::make_pair(openGL::FLAG_STENCIL_TEST, "FLAG_STENCIL_TEST"),
std::make_pair(openGL::FLAG_PROGRAM_POINT_SIZE, "FLAG_PROGRAM_POINT_SIZE"),
std::make_pair(openGL::FLAG_TEXTURE_2D, "FLAG_TEXTURE_2D"),
std::make_pair(openGL::FLAG_ALPHA_TEST, "FLAG_ALPHA_TEST"),
std::make_pair(openGL::FLAG_FOG, "FLAG_FOG")
};
_os << "{";
bool hasOne = false;
for (auto &it : list) {
if ((_obj & it.first) != 0) {
if (hasOne==true) {
_os << ",";
}
_os << it.second;
hasOne = true;
}
}
_os << "}";
return _os;
}
std::vector<std::pair<enum gale::openGL::renderMode, std::string>>& getListRenderMode() {
static std::vector<std::pair<enum gale::openGL::renderMode, std::string>> list = {
std::make_pair(gale::openGL::renderPoint, "POINTS"),
std::make_pair(gale::openGL::renderLine, "LINES"),
std::make_pair(gale::openGL::renderLineStrip, "LINES_STRIP"),
std::make_pair(gale::openGL::renderLineLoop, "LINE_LOOP"),
std::make_pair(gale::openGL::renderTriangle, "TRIANGLE"),
std::make_pair(gale::openGL::renderTriangleStrip, "TRIANGLE_STRIP"),
std::make_pair(gale::openGL::renderTriangleFan, "TRIANGLE_FAN"),
std::make_pair(gale::openGL::renderQuad, "QUAD"),
std::make_pair(gale::openGL::renderQuadStrip, "QUAD_STRIP"),
std::make_pair(gale::openGL::renderPolygon, "POLYGON"),
};
return list;
}
namespace etk {
template<> std::string to_string<gale::openGL::renderMode>(const gale::openGL::renderMode& _obj) {
for (auto &it : getListRenderMode()) {
if (it.first == _obj) {
return it.second;
}
}
GALE_ERROR("Can not convert : " << static_cast<int32_t>(_obj) << " return UNKNOW");
return "UNKNOW";
}
template<> std::u32string to_u32string<gale::openGL::renderMode>(const gale::openGL::renderMode& _obj) {
return etk::to_u32string(etk::to_string(_obj));
}
template<> bool from_string<gale::openGL::renderMode>(gale::openGL::renderMode& _variableRet, const std::string& _value) {
for (auto &it : getListRenderMode()) {
if (it.second == _value) {
_variableRet = it.first;
return true;
}
}
GALE_WARNING("Can not parse : '" << _value << "' set Triangle default value");
_variableRet = gale::openGL::renderTriangle;
return false;
}
template<> bool from_string<gale::openGL::renderMode>(gale::openGL::renderMode& _variableRet, const std::u32string& _value) {
return from_string(_variableRet, etk::to_string(_value));
}
};
std::ostream& gale::operator <<(std::ostream& _os, const enum openGL::renderMode& _obj) {
_os << etk::to_string(_obj);
return _os;
}
typedef struct {
uint32_t curentFlag;
GLenum OGlFlag;
} correspondenceTable_ts;
static correspondenceTable_ts basicFlag[] = {
{(uint32_t)gale::openGL::FLAG_BLEND, GL_BLEND},
#if 0
!(defined(__TARGET_OS__Android) || defined(__TARGET_OS__MacOs))
{(uint32_t)gale::openGL::FLAG_CLIP_DISTANCE_I, GL_CLIP_DISTANCE0},
{(uint32_t)gale::openGL::FLAG_COLOR_LOGIC_OP, GL_COLOR_LOGIC_OP},
#endif
{(uint32_t)gale::openGL::FLAG_CULL_FACE, GL_CULL_FACE},
#if 0
!(defined(__TARGET_OS__Android) || defined(__TARGET_OS__MacOs))
{(uint32_t)gale::openGL::FLAG_DEBUG_OUTPUT, GL_DEBUG_OUTPUT},
{(uint32_t)gale::openGL::FLAG_DEBUG_OUTPUT_SYNCHRONOUS, GL_DEBUG_OUTPUT_SYNCHRONOUS},
{(uint32_t)gale::openGL::FLAG_DEPTH_CLAMP, GL_DEPTH_CLAMP},
#endif
{(uint32_t)gale::openGL::FLAG_DEPTH_TEST, GL_DEPTH_TEST},
{(uint32_t)gale::openGL::FLAG_DITHER, GL_DITHER},
#if 0
!(defined(__TARGET_OS__Android) || defined(__TARGET_OS__MacOs))
{(uint32_t)gale::openGL::FLAG_FRAMEBUFFER_SRGB, GL_FRAMEBUFFER_SRGB},
{(uint32_t)gale::openGL::FLAG_LINE_SMOOTH, GL_LINE_SMOOTH},
{(uint32_t)gale::openGL::FLAG_MULTISAMPLE, GL_MULTISAMPLE},
#endif
{(uint32_t)gale::openGL::FLAG_POLYGON_OFFSET_FILL, GL_POLYGON_OFFSET_FILL},
#if 0
!(defined(__TARGET_OS__Android) || defined(__TARGET_OS__MacOs))
{(uint32_t)gale::openGL::FLAG_POLYGON_OFFSET_LINE, GL_POLYGON_OFFSET_LINE},
{(uint32_t)gale::openGL::FLAG_POLYGON_OFFSET_POINT, GL_POLYGON_OFFSET_POINT},
{(uint32_t)gale::openGL::FLAG_POLYGON_SMOOTH, GL_POLYGON_SMOOTH},
{(uint32_t)gale::openGL::FLAG_PRIMITIVE_RESTART, GL_PRIMITIVE_RESTART},
{(uint32_t)gale::openGL::FLAG_PRIMITIVE_RESTART_FIXED_INDEX, GL_PRIMITIVE_RESTART_FIXED_INDEX},
#endif
{(uint32_t)gale::openGL::FLAG_SAMPLE_ALPHA_TO_COVERAGE, GL_SAMPLE_ALPHA_TO_COVERAGE},
#if 0
!(defined(__TARGET_OS__Android) || defined(__TARGET_OS__MacOs))
{(uint32_t)gale::openGL::FLAG_SAMPLE_ALPHA_TO_ONE, GL_SAMPLE_ALPHA_TO_ONE},
#endif
{(uint32_t)gale::openGL::FLAG_SAMPLE_COVERAGE, GL_SAMPLE_COVERAGE},
#if 0
!(defined(__TARGET_OS__Android) || defined(__TARGET_OS__MacOs))
{(uint32_t)gale::openGL::FLAG_SAMPLE_SHADING, GL_SAMPLE_SHADING},
{(uint32_t)gale::openGL::FLAG_SAMPLE_MASK, GL_SAMPLE_MASK},
#endif
{(uint32_t)gale::openGL::FLAG_SCISSOR_TEST, GL_SCISSOR_TEST},
{(uint32_t)gale::openGL::FLAG_STENCIL_TEST, GL_STENCIL_TEST},
#if 0
!(defined(__TARGET_OS__Android) || defined(__TARGET_OS__MacOs))
{(uint32_t)gale::openGL::FLAG_PROGRAM_POINT_SIZE, GL_PROGRAM_POINT_SIZE},
#endif
{(uint32_t)gale::openGL::FLAG_TEXTURE_2D, GL_TEXTURE_2D},
#if 0
!(defined(__TARGET_OS__Android) || defined(__TARGET_OS__MacOs))
{(uint32_t)gale::openGL::FLAG_ALPHA_TEST, GL_ALPHA_TEST},
{(uint32_t)gale::openGL::FLAG_FOG, GL_FOG}
#endif
//{(uint32_t)gale::openGL::FLAG_, GL_}
};
static int32_t basicFlagCount = sizeof(basicFlag) / sizeof(correspondenceTable_ts);
void gale::openGL::reset() {
#ifdef DIRECT_MODE
GALE_TODO("...");
#else
l_flagsMustBeSet = 0;
l_programId = -1;
l_textureflags = 0;
updateAllFlags();
#endif
}
void gale::openGL::enable(enum gale::openGL::openGlFlags _flagID) {
//GALE_INFO("Enable : " <GALE_ERROR< _flagID);
#ifdef DIRECT_MODE
for (int32_t iii=0; iii<basicFlagCount ; iii++) {
if ( basicFlag[iii].curentFlag == (uint32_t)_flagID ) {
glEnable(basicFlag[iii].OGlFlag);
}
}
# else
//GALE_DEBUG("Enable FLAGS = " << l_flagsMustBeSet);
l_flagsMustBeSet |= (uint32_t)_flagID;
//GALE_DEBUG(" == >" << l_flagsMustBeSet);
#endif
}
void gale::openGL::disable(enum gale::openGL::openGlFlags _flagID) {
//GALE_INFO("Disable : " << _flagID);
#ifdef DIRECT_MODE
for (int32_t iii=0; iii<basicFlagCount ; iii++) {
if ( basicFlag[iii].curentFlag == (uint32_t)_flagID ) {
glDisable(basicFlag[iii].OGlFlag);
}
}
# else
//GALE_DEBUG("Disable FLAGS = " << l_flagsMustBeSet);
l_flagsMustBeSet &= ~((uint32_t)_flagID);
//GALE_DEBUG(" == >" << l_flagsMustBeSet);
#endif
}
void gale::openGL::updateAllFlags() {
#ifdef DIRECT_MODE
return;
#endif
// check if fhags has change :
if (l_flagsMustBeSet == l_flagsCurrent ) {
OPENGL_INFO("OGL: current flag : " << (enum openGL::openGlFlags)l_flagsMustBeSet);
return;
}
OPENGL_INFO("OGL: set new flag : " << (enum openGL::openGlFlags)l_flagsMustBeSet);
for (int32_t iii=0; iii<basicFlagCount ; iii++) {
uint32_t CurrentFlag = basicFlag[iii].curentFlag;
if ( (l_flagsMustBeSet&CurrentFlag)!=(l_flagsCurrent&CurrentFlag) ) {
if ( (l_flagsMustBeSet&CurrentFlag) != 0) {
glEnable(basicFlag[iii].OGlFlag);
OPENGL_INFO(" enable : " << (enum openGL::openGlFlags)basicFlag[iii].curentFlag);
} else {
glDisable(basicFlag[iii].OGlFlag);
OPENGL_INFO(" disable : " << (enum openGL::openGlFlags)basicFlag[iii].curentFlag);
}
}
}
l_flagsCurrent = l_flagsMustBeSet;
}
void gale::openGL::activeTexture(uint32_t _flagID) {
if (l_programId >= 0) {
glActiveTexture(_flagID);
}
}
void gale::openGL::desActiveTexture(uint32_t _flagID) {
if (l_programId >= 0) {
}
}
void gale::openGL::drawArrays(uint32_t _mode, int32_t _first, int32_t _count) {
if (l_programId >= 0) {
updateAllFlags();
glDrawArrays(_mode, _first, _count);
}
}
void gale::openGL::drawElements(uint32_t _mode, const std::vector<uint32_t>& _indices) {
if (l_programId >= 0) {
updateAllFlags();
//GALE_DEBUG("Request draw of " << indices.size() << "elements");
glDrawElements(_mode, _indices.size(), GL_UNSIGNED_INT, &_indices[0]);
}
}
void gale::openGL::drawElements16(uint32_t _mode, const std::vector<uint16_t>& _indices) {
if (l_programId >= 0) {
updateAllFlags();
glDrawElements(_mode, _indices.size(), GL_UNSIGNED_SHORT, &_indices[0]);
}
}
void gale::openGL::drawElements8(uint32_t _mode, const std::vector<uint8_t>& _indices) {
if (l_programId >= 0) {
updateAllFlags();
glDrawElements(_mode, _indices.size(), GL_UNSIGNED_BYTE, &_indices[0]);
}
}
void gale::openGL::useProgram(int32_t _id) {
//GALE_DEBUG("USE prog : " << id);
#if 1
// note : In normal openGL case, the system might call with the program ID and at the end with 0,
// here, we wrap this use to prevent over call of glUseProgram == > then we set -1 when the
// user no more use this program, and just stop grnerating. (chen 0 == > this is an errored program ...
if (-1 == _id) {
// not used == > because it is unneded
return;
}
if (l_programId != _id) {
l_programId = _id;
glUseProgram(l_programId);
}
#else
if (-1 == _id) {
glUseProgram(0);
} else {
l_programId = _id;
glUseProgram(_id);
}
#endif
}
bool gale::openGL::genBuffers(std::vector<GLuint>& _buffers) {
if (_buffers.size() == 0) {
GALE_WARNING("try to generate vector buffer with size 0");
return true;
}
OPENGL_INFO("Create N=" << _buffers.size() << " Buffer");
glGenBuffers(_buffers.size(), &_buffers[0]);
checkGlError("glGenBuffers", __LINE__);
bool hasError = false;
for (size_t iii=0; iii<_buffers.size(); iii++) {
if (_buffers[iii] == 0) {
GALE_ERROR("[" << iii << "] error to create a buffer id=" << _buffers[iii]);
hasError = true;
}
}
return hasError;
}
bool gale::openGL::deleteBuffers(std::vector<GLuint>& _buffers) {
if (_buffers.size() == 0) {
GALE_WARNING("try to delete vector buffer with size 0");
return true;
}
glDeleteBuffers(_buffers.size(), &_buffers[0]);
checkGlError("glDeleteBuffers", __LINE__);
for (auto &it : _buffers) {
it = 0;
}
return true;
}
bool gale::openGL::bindBuffer(GLuint _bufferId) {
glBindBuffer(GL_ARRAY_BUFFER, _bufferId);
checkGlError("glBindBuffer", __LINE__);
return true;
}
bool gale::openGL::bufferData(size_t _size, const void* _data, GLenum _usage) {
glBufferData(GL_ARRAY_BUFFER, _size, _data, _usage);
checkGlError("glBufferData", __LINE__);
return true;
}
bool gale::openGL::unbindBuffer() {
glBindBuffer(GL_ARRAY_BUFFER, 0);
checkGlError("glBindBuffer(0)", __LINE__);
return true;
}

View File

@ -0,0 +1,213 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#ifndef __OPEN_GL_H__
#define __OPEN_GL_H__
#include <etk/types.h>
#include <vector>
#include <etk/math/Matrix4.h>
#ifdef __cplusplus
extern "C" {
#endif
#if defined(__TARGET_OS__Linux)
// TO ENABLE THE SHADER api ...
#define GL_GLEXT_PROTOTYPES
#include <GL/gl.h>
// TODO : Check it it work
// This is to prevent the use of these element that is not allowed in the openGL ES
#undef glVertexPointer
#undef glTexCoordPointer
#undef glColorPointer
#undef glPopMatrix
#undef glPushMatrix
#undef glMatrixMode
#undef glLoadIdentity
#undef glTranslatef
#elif defined(__TARGET_OS__Android)
// Include openGL ES 2
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
#elif defined(__TARGET_OS__Windows)
// TO ENABLE THE SHADER api ...
//#define GL_GLEXT_PROTOTYPES
#define GLEW_STATIC
#include <GL/glew.h>
#elif defined(__TARGET_OS__MacOs)
#include <OpenGL/gl.h>
#include <OpenGL/glu.h>
#elif defined(__TARGET_OS__IOs)
#include <OpenGLES/ES2/gl.h>
#else
#error you need to specify a __TAGET_OS__ ...
#endif
#ifdef __cplusplus
}
#endif
namespace gale {
namespace openGL {
/**
* @brief Lock the openGL context for one user only == > better to keep flags and other things ...
*/
void lock();
/**
* @brief Un-lock the openGL context for an other user...
*/
void unLock();
/**
* @brief When you will done an opengl rendering, you might call this reset matrix first. It remove all the stach of the matrix pushed.
* @param[in] _newOne the default matrix that might be set for the graphic card for renderer. if too more pop will be done, this is the last that mmight survived
*/
void setBasicMatrix(const mat4& _newOne);
/**
* @brief this funtion configure the current use matrix for the renderer (call @ref Push before, and @ref Pop when no more needed).
* @param[in] _newOne The new current matrix use for the render.
* @note We did not use opengl standard system, due to the fact that is not supported in opengl ES-2
*/
void setMatrix(const mat4& _newOne);
/**
* @brief store current matrix in the matrix stack.
*/
void push();
/**
* @brief remove the current matrix and get the last one from the matrix stack.
*/
void pop();
/**
* @brief get a reference on the current matrix destinate to opengl renderer.
* @return The requested matrix.
*/
const mat4& getMatrix();
/**
* @brief get a reference on the current matrix camera destinate to opengl renderer.
* @return The requested matrix.
*/
const mat4& getCameraMatrix();
/**
* @brief set a reference on the current camera to opengl renderer.
* @param[in] _newOne The requested matrix.
*/
void setCameraMatrix(const mat4& _newOne);
/**
* @brief
*/
void finish();
/**
* @brief
*/
void flush();
/**
* @brief
*/
void swap();
enum openGlFlags {
FLAG_BLEND = 1<<0, //!< If enabled, blend the computed fragment color values with the values in the color buffers. See glBlendFunc.
FLAG_CLIP_DISTANCE_I = 1<<1, //!< If enabled, clip geometry against user-defined half space i.
FLAG_COLOR_LOGIC_OP = 1<<2, //!< If enabled, apply the currently selected logical operation to the computed fragment color and color buffer values. See glLogicOp.
FLAG_CULL_FACE = 1<<3, //!< If enabled, cull polygons based on their winding in window coordinates. See glCullFace.
FLAG_DEBUG_OUTPUT = 1<<4, //!< If enabled, debug messages are produced by a debug context. When disabled, the debug message log is silenced. Note that in a non-debug context, very few, if any messages might be produced, even when GL_DEBUG_OUTPUT is enabled.
FLAG_DEBUG_OUTPUT_SYNCHRONOUS = 1<<5, //!< If enabled, debug messages are produced synchronously by a debug context. If disabled, debug messages may be produced asynchronously. In particular, they may be delayed relative to the execution of GL commands, and the debug callback function may be called from a thread other than that in which the commands are executed. See glDebugMessageCallback.
FLAG_DEPTH_CLAMP = 1<<6, //!< If enabled, the -wc≤zc≤wc plane equation is ignored by view volume clipping (effectively, there is no near or far plane clipping). See glDepthRange.
FLAG_DEPTH_TEST = 1<<7, //!< If enabled, do depth comparisons and update the depth buffer. Note that even if the depth buffer exists and the depth mask is non-zero, the depth buffer is not updated if the depth test is disabled. See glDepthFunc and glDepthRange.
FLAG_DITHER = 1<<8, //!< If enabled, dither color components or indices before they are written to the color buffer.
FLAG_FRAMEBUFFER_SRGB = 1<<9, //!< If enabled and the value of GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING for the framebuffer attachment corresponding to the destination buffer is GL_SRGB, the R, G, and B destination color values (after conversion from fixed-point to floating-point) are considered to be encoded for the sRGB color space and hence are linearized prior to their use in blending.
FLAG_LINE_SMOOTH = 1<<10, //!< If enabled, draw lines with correct filtering. Otherwise, draw aliased lines. See glLineWidth.
FLAG_MULTISAMPLE = 1<<11, //!< If enabled, use multiple fragment samples in computing the final color of a pixel. See glSampleCoverage.
FLAG_POLYGON_OFFSET_FILL = 1<<12, //!< If enabled, and if the polygon is rendered in GL_FILL mode, an offset is added to depth values of a polygon's fragments before the depth comparison is performed. See glPolygonOffset.
FLAG_POLYGON_OFFSET_LINE = 1<<13, //!< If enabled, and if the polygon is rendered in GL_LINE mode, an offset is added to depth values of a polygon's fragments before the depth comparison is performed. See glPolygonOffset.
FLAG_POLYGON_OFFSET_POINT = 1<<14, //!< If enabled, an offset is added to depth values of a polygon's fragments before the depth comparison is performed, if the polygon is rendered in GL_POINT mode. See glPolygonOffset.
FLAG_POLYGON_SMOOTH = 1<<15, //!< If enabled, draw polygons with proper filtering. Otherwise, draw aliased polygons. For correct antialiased polygons, an alpha buffer is needed and the polygons must be sorted front to back.
FLAG_PRIMITIVE_RESTART = 1<<16, //!< enables primitive restarting. If enabled, any one of the draw commands which transfers a set of generic attribute array elements to the GL will restart the primitive when the index of the vertex is equal to the primitive restart index. See glPrimitiveRestartIndex.
FLAG_PRIMITIVE_RESTART_FIXED_INDEX = 1<<17, //!< enables primitive restarting with a fixed index. If enabled, any one of the draw commands which transfers a set of generic attribute array elements to the GL will restart the primitive when the index of the vertex is equal to the fixed primitive index for the specified index type. The fixed index is equal to 2n1 where n is equal to 8 for GL_UNSIGNED_BYTE, 16 for GL_UNSIGNED_SHORT and 32 for GL_UNSIGNED_INT.
FLAG_SAMPLE_ALPHA_TO_COVERAGE = 1<<18, //!< If enabled, compute a temporary coverage value where each bit is determined by the alpha value at the corresponding sample location. The temporary coverage value is then ANDed with the fragment coverage value.
FLAG_SAMPLE_ALPHA_TO_ONE = 1<<19, //!< If enabled, each sample alpha value is replaced by the maximum representable alpha value.
FLAG_SAMPLE_COVERAGE = 1<<20, //!< If enabled, the fragment's coverage is ANDed with the temporary coverage value. If GL_SAMPLE_COVERAGE_INVERT is set to GL_TRUE, invert the coverage value. See glSampleCoverage.
FLAG_SAMPLE_SHADING = 1<<21, //!< If enabled, the active fragment shader is run once for each covered sample, or at fraction of this rate as determined by the current value of GL_MIN_SAMPLE_SHADING_VALUE. See glMinSampleShading.
FLAG_SAMPLE_MASK = 1<<22, //!< If enabled, the sample coverage mask generated for a fragment during rasterization will be ANDed with the value of GL_SAMPLE_MASK_VALUE before shading occurs. See glSampleMaski.
FLAG_SCISSOR_TEST = 1<<23, //!< If enabled, discard fragments that are outside the scissor rectangle. See glScissor.
FLAG_STENCIL_TEST = 1<<24, //!< If enabled, do stencil testing and update the stencil buffer. See glStencilFunc and glStencilOp. GL_TEXTURE_CUBE_MAP_SEAMLESS = 1<<0, //!< If enabled, cubemap textures are sampled such that when linearly sampling from the border between two adjacent faces, texels from both faces are used to generate the final sample value. When disabled, texels from only a single face are used to construct the final sample value.
FLAG_PROGRAM_POINT_SIZE = 1<<25, //!< If enabled and a vertex or geometry shader is active, then the derived point size is taken from the (potentially clipped) shader builtin gl_PointSize and clamped to the implementation-dependent point size range.
FLAG_TEXTURE_2D = 1<<26, //!<
FLAG_ALPHA_TEST = 1<<27, //!<
FLAG_FOG = 1<<28, //!<
};
enum renderMode {
renderPoint = GL_POINTS,
renderLine = GL_LINES,
renderLineStrip = GL_LINE_STRIP, //!< Not supported in GALE (TODO : Later)
renderLineLoop = GL_LINE_LOOP,
renderTriangle = GL_TRIANGLES,
renderTriangleStrip = GL_TRIANGLE_STRIP, //!< Not supported in GALE (TODO : Later)
renderTriangleFan = GL_TRIANGLE_FAN, //!< Not supported in GALE (TODO : Later)
#if (!defined(__TARGET_OS__IOs) && !defined(__TARGET_OS__Android))
renderQuad = GL_QUADS, //!< Not supported in OpenGL-ES2
renderQuadStrip = GL_QUAD_STRIP, //!< Not supported in OpenGL-ES2
renderPolygon = GL_POLYGON //!< Not supported in OpenGL-ES2
#else
renderQuad, //!< Not supported in OpenGL-ES2
renderQuadStrip, //!< Not supported in OpenGL-ES2
renderPolygon //!< Not supported in OpenGL-ES2
#endif
};
/**
* @brief enable a flag on the system
* @param[in] flagID The flag requested
*/
void enable(enum openGlFlags _flagID);
/**
* @brief disable a flag on the system
* @param[in] flagID The flag requested
*/
void disable(enum openGlFlags _flagID);
/**
* @brieg update all the internal flag needed to be set from tre previous element set ...
*/
void updateAllFlags();
/**
* @brief enable Texture on the system
* @param[in] flagID The flag requested
*/
void activeTexture(uint32_t _flagID);
/**
* @brief disable Texture on the system
* @param[in] flagID The flag requested
*/
void desActiveTexture(uint32_t _flagID);
/**
* @brief draw a specific array == > this enable mode difference ...
*/
void drawArrays(uint32_t _mode, int32_t _first, int32_t _count);
void drawElements (uint32_t _mode, const std::vector<uint32_t>& _indices);
void drawElements16(uint32_t _mode, const std::vector<uint16_t>& _indices);
void drawElements8 (uint32_t _mode, const std::vector<uint8_t>& _indices);
/**
* @brief Use openGL program
* @param[in] id Id of the program that might be used
*/
void useProgram(int32_t _id);
void reset();
bool genBuffers(std::vector<GLuint>& _buffers);
bool deleteBuffers(std::vector<GLuint>& _buffers);
bool bindBuffer(GLuint _bufferId);
bool bufferData(size_t _size, const void* _data, GLenum _usage);
bool unbindBuffer();
};
std::ostream& operator <<(std::ostream& _os, const enum openGL::openGlFlags& _obj);
std::ostream& operator <<(std::ostream& _os, const enum openGL::renderMode& _obj);
};
#endif

193
gale/resource/Manager.cpp Normal file
View File

@ -0,0 +1,193 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#include <etk/types.h>
#include <gale/debug.h>
#include <gale/resource/Manager.h>
#include <gale/resource/FontFreeType.h>
#include <gale/gale.h>
#include <gale/openGL/openGL.h>
#include <gale/context/Context.h>
gale::resource::Manager::Manager() :
m_contextHasBeenRemoved(true) {
// nothing to do ...
}
gale::resource::Manager::~Manager() {
bool hasError = false;
if (m_resourceListToUpdate.size()!=0) {
GALE_ERROR("Must not have anymore resources to update !!!");
hasError = true;
}
// TODO : Remove unneeded elements
if (m_resourceList.size()!=0) {
GALE_ERROR("Must not have anymore resources !!!");
hasError = true;
}
if (true == hasError) {
GALE_ERROR("Check if the function UnInit has been called !!!");
}
}
void gale::resource::Manager::unInit() {
display();
m_resourceListToUpdate.clear();
// remove all resources ...
auto it(m_resourceList.begin());
while(it != m_resourceList.end()) {
std::shared_ptr<gale::Resource> tmpRessource = (*it).lock();
if (tmpRessource != nullptr) {
GALE_WARNING("Find a resource that is not removed : [" << tmpRessource->getId() << "]"
<< "=\"" << tmpRessource->getName() << "\" "
<< tmpRessource.use_count() << " elements");
}
m_resourceList.erase(it);
it = m_resourceList.begin();
}
m_resourceList.clear();
}
void gale::resource::Manager::display() {
GALE_INFO("Resources loaded : ");
// remove all resources ...
for (auto &it : m_resourceList) {
std::shared_ptr<gale::Resource> tmpRessource = it.lock();
if (tmpRessource != nullptr) {
GALE_INFO(" [" << tmpRessource->getId() << "]"
<< tmpRessource->getObjectType()
<< "=\"" << tmpRessource->getName() << "\" "
<< tmpRessource.use_count() << " elements");
}
}
GALE_INFO("Resources ---");
}
void gale::resource::Manager::reLoadResources() {
GALE_INFO("------------- Resources re-loaded -------------");
// remove all resources ...
if (m_resourceList.size() != 0) {
for (size_t jjj=0; jjj<MAX_RESOURCE_LEVEL; jjj++) {
GALE_INFO(" Reload level : " << jjj << "/" << (MAX_RESOURCE_LEVEL-1));
for (auto &it : m_resourceList) {
std::shared_ptr<gale::Resource> tmpRessource = it.lock();
if(tmpRessource != nullptr) {
if (jjj == tmpRessource->getResourceLevel()) {
tmpRessource->reload();
GALE_INFO(" [" << tmpRessource->getId() << "]="<< tmpRessource->getObjectType());
}
}
}
}
}
// TODO : UNderstand why it is set here ...
//gale::requestUpdateSize();
GALE_INFO("------------- Resources -------------");
}
void gale::resource::Manager::update(const std::shared_ptr<gale::Resource>& _object) {
// chek if not added before
for (auto &it : m_resourceListToUpdate) {
if ( it != nullptr
&& it == _object) {
// just prevent some double add ...
return;
}
}
// add it ...
m_resourceListToUpdate.push_back(_object);
}
// Specific to load or update the data in the openGl context == > system use only
void gale::resource::Manager::updateContext() {
if (m_contextHasBeenRemoved == true) {
// need to update all ...
m_contextHasBeenRemoved = false;
if (m_resourceList.size() != 0) {
for (size_t jjj=0; jjj<MAX_RESOURCE_LEVEL; jjj++) {
GALE_INFO(" updateContext level (D) : " << jjj << "/" << (MAX_RESOURCE_LEVEL-1));
for (auto &it : m_resourceList) {
std::shared_ptr<gale::Resource> tmpRessource = it.lock();
if( tmpRessource != nullptr
&& jjj == tmpRessource->getResourceLevel()) {
//GALE_DEBUG("Update context named : " << l_resourceList[iii]->getName());
tmpRessource->updateContext();
}
}
}
}
} else {
if (m_resourceListToUpdate.size() != 0) {
for (size_t jjj=0; jjj<MAX_RESOURCE_LEVEL; jjj++) {
GALE_INFO(" updateContext level (U) : " << jjj << "/" << (MAX_RESOURCE_LEVEL-1));
for (auto &it : m_resourceListToUpdate) {
if ( it != nullptr
&& jjj == it->getResourceLevel()) {
it->updateContext();
}
}
}
}
}
// Clean the update list
m_resourceListToUpdate.clear();
}
// in this case, it is really too late ...
void gale::resource::Manager::contextHasBeenDestroyed() {
for (auto &it : m_resourceList) {
std::shared_ptr<gale::Resource> tmpRessource = it.lock();
if (tmpRessource != nullptr) {
tmpRessource->removeContextToLate();
}
}
// no context preent ...
m_contextHasBeenRemoved = true;
}
// internal generic keeper ...
std::shared_ptr<gale::Resource> gale::resource::Manager::localKeep(const std::string& _filename) {
GALE_VERBOSE("KEEP (DEFAULT) : file : '" << _filename << "' in " << m_resourceList.size() << " resources");
for (auto &it : m_resourceList) {
std::shared_ptr<gale::Resource> tmpRessource = it.lock();
if (tmpRessource != nullptr) {
if (tmpRessource->getName() == _filename) {
return tmpRessource;
}
}
}
return nullptr;
}
// internal generic keeper ...
void gale::resource::Manager::localAdd(const std::shared_ptr<gale::Resource>& _object) {
//Add ... find empty slot
for (auto &it : m_resourceList) {
std::shared_ptr<gale::Resource> tmpRessource = it.lock();
if (tmpRessource == nullptr) {
it = _object;
return;
}
}
// add at the end if no slot is free
m_resourceList.push_back(_object);
}
// in case of error ...
void gale::resource::Manager::cleanInternalRemoved() {
//GALE_INFO("remove object in Manager");
updateContext();
for (auto it(m_resourceList.begin()); it!=m_resourceList.end(); ++it) {
if ((*it).expired() == true) {
m_resourceList.erase(it);
it = m_resourceList.begin();
}
}
}

72
gale/resource/Manager.h Normal file
View File

@ -0,0 +1,72 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#ifndef __RESOURCES_MANAGER_H__
#define __RESOURCES_MANAGER_H__
#include <list>
#include <vector>
#include <etk/types.h>
#include <gale/debug.h>
#include <gale/resource/Resource.h>
namespace gale {
namespace resource {
class Manager{
private:
std::list<std::weak_ptr<gale::Resource>> m_resourceList;
std::vector<std::shared_ptr<gale::Resource>> m_resourceListToUpdate;
bool m_contextHasBeenRemoved;
public:
/**
* @brief initialize the internal variable
*/
Manager();
/**
* @brief Uninitiamize the resource manager, free all resources previously requested
* @note when not free == > generate warning, because the segfault can appear after...
*/
virtual ~Manager();
/**
* @brief remove all resources (un-init) out of the destructor (due to the system implementation)
*/
void unInit();
/**
* @brief display in the log all the resources loaded ...
*/
void display();
/**
* @brief Reload all resources from files, and send there in openGL card if needed.
* @note If file is reference at THEME:XXX:filename if the Theme change the file will reload the newOne
*/
void reLoadResources();
/**
* @brief Call by the system to send all the needed data on the graphic card chen they change ...
* @param[in] _object The resources that might be updated
*/
void update(const std::shared_ptr<gale::Resource>& _object);
/**
* @brief Call by the system chen the openGL Context has been unexpectially removed == > This reload all the texture, VBO and other ....
*/
void updateContext();
/**
* @brief This is to inform the resources manager that we have no more openGl context ...
*/
void contextHasBeenDestroyed();
public:
// internal API to extent eResources in extern Soft
std::shared_ptr<gale::Resource> localKeep(const std::string& _filename);
void localAdd(const std::shared_ptr<gale::Resource>& _object);
virtual void cleanInternalRemoved();
};
};
};
#endif

842
gale/resource/Program.cpp Normal file
View File

@ -0,0 +1,842 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#include <etk/types.h>
#include <gale/debug.h>
#include <gale/resource/Program.h>
#include <gale/resource/Manager.h>
#include <etk/os/FSNode.h>
#include <gale/gale.h>
//#define LOCAL_DEBUG GALE_VERBOSE
#define LOCAL_DEBUG GALE_DEBUG
#undef __class__
#define __class__ "resource::Program"
gale::resource::Program::Program() :
gale::Resource(),
m_exist(false),
m_program(0),
m_hasTexture(false),
m_hasTexture1(false) {
addResourceType("gale::resource::Program");
m_resourceLevel = 1;
}
void gale::resource::Program::init(const std::string& _filename) {
gale::Resource::init(_filename);
GALE_DEBUG("OGL : load PROGRAM '" << m_name << "'");
// load data from file "all the time ..."
etk::FSNode file(m_name);
if (false == file.exist()) {
GALE_INFO("File does not Exist : \"" << file << "\" == > automatic load of framment and shader with same names... ");
std::string tmpFilename = m_name;
// remove extention ...
tmpFilename.erase(tmpFilename.size()-4, 4);
std::shared_ptr<gale::resource::Shader> tmpShader = gale::resource::Shader::create(tmpFilename+"vert");
if (nullptr == tmpShader) {
GALE_ERROR("Error while getting a specific shader filename : " << tmpFilename);
return;
} else {
GALE_DEBUG("Add shader on program : "<< tmpFilename << "vert");
m_shaderList.push_back(tmpShader);
}
tmpShader = gale::resource::Shader::create(tmpFilename+"frag");
if (nullptr == tmpShader) {
GALE_ERROR("Error while getting a specific shader filename : " << tmpFilename);
return;
} else {
GALE_DEBUG("Add shader on program : "<< tmpFilename << "frag");
m_shaderList.push_back(tmpShader);
}
} else {
std::string fileExtention = file.fileGetExtention();
if (fileExtention != "prog") {
GALE_ERROR("File does not have extention \".prog\" for program but : \"" << fileExtention << "\"");
return;
}
if (false == file.fileOpenRead()) {
GALE_ERROR("Can not open the file : \"" << file << "\"");
return;
}
#define MAX_LINE_SIZE (2048)
char tmpData[MAX_LINE_SIZE];
while (file.fileGets(tmpData, MAX_LINE_SIZE) != nullptr) {
int32_t len = strlen(tmpData);
if( tmpData[len-1] == '\n'
|| tmpData[len-1] == '\r') {
tmpData[len-1] = '\0';
len--;
}
GALE_DEBUG(" Read data : \"" << tmpData << "\"");
if (len == 0) {
continue;
}
if (tmpData[0] == '#') {
continue;
}
// get it with relative position :
std::string tmpFilename = file.getRelativeFolder() + tmpData;
std::shared_ptr<gale::resource::Shader> tmpShader = gale::resource::Shader::create(tmpFilename);
if (nullptr == tmpShader) {
GALE_ERROR("Error while getting a specific shader filename : " << tmpFilename);
} else {
GALE_DEBUG("Add shader on program : "<< tmpFilename);
m_shaderList.push_back(tmpShader);
}
}
// close the file:
file.fileClose();
}
updateContext();
}
gale::resource::Program::~Program() {
m_shaderList.clear();
removeContext();
m_elementList.clear();
m_hasTexture = false;
m_hasTexture1 = false;
}
std::ostream& gale::resource::operator <<(std::ostream& _os, const gale::resource::progAttributeElement& _obj) {
_os << "{";
_os << "[" << _obj.m_name << "] ";
_os << _obj.m_elementId << " ";
_os << _obj.m_isLinked;
_os << "}";
return _os;
}
std::ostream& gale::resource::operator <<(std::ostream& _os, const std::vector<gale::resource::progAttributeElement>& _obj){
_os << "{";
for (auto &it : _obj) {
_os << it;
}
_os << "}";
return _os;
}
void gale::resource::Program::checkGlError(const char* _op, int32_t _localLine, int32_t _idElem) {
#ifdef DEBUG
bool isPresent = false;
for (GLint error = glGetError(); error; error = glGetError()) {
GALE_ERROR("after " << _op << "() line=" << _localLine << " glError(" << error << ")");
isPresent = true;
}
if (isPresent == true) {
GALE_ERROR(" in program name : " << m_name);
GALE_ERROR(" program OpenGL ID =" << m_program);
GALE_ERROR(" List IO :");
int32_t id = 0;
for (auto &it : m_elementList) {
if (id == _idElem) {
GALE_ERROR(" * name :" << it.m_name << " OpenGL ID=" << it.m_elementId << " attribute=" << it.m_isAttribute << " is linked=" << it.m_isLinked);
} else {
GALE_ERROR(" name :" << it.m_name << " OpenGL ID=" << it.m_elementId << " attribute=" << it.m_isAttribute << " is linked=" << it.m_isLinked);
}
id++;
}
GALE_CRITICAL("Stop on openGL ERROR");
}
#endif
}
#define LOG_OGL_INTERNAL_BUFFER_LEN (8192)
static char l_bufferDisplayError[LOG_OGL_INTERNAL_BUFFER_LEN] = "";
bool gale::resource::Program::checkIdValidity(int32_t _idElem) {
if ( _idElem < 0
|| (size_t)_idElem > m_elementList.size()) {
return false;
}
return m_elementList[_idElem].m_isLinked;
}
int32_t gale::resource::Program::getAttribute(std::string _elementName) {
// check if it exist previously :
for(size_t iii=0; iii<m_elementList.size(); iii++) {
if (m_elementList[iii].m_name == _elementName) {
return iii;
}
}
progAttributeElement tmp;
tmp.m_name = _elementName;
tmp.m_isAttribute = true;
tmp.m_elementId = glGetAttribLocation(m_program, tmp.m_name.c_str());
tmp.m_isLinked = true;
if (tmp.m_elementId<0) {
GALE_WARNING(" [" << m_elementList.size() << "] glGetAttribLocation(\"" << tmp.m_name << "\") = " << tmp.m_elementId);
tmp.m_isLinked = false;
checkGlError("glGetAttribLocation", __LINE__, tmp.m_elementId);
} else {
GALE_INFO(" [" << m_elementList.size() << "] glGetAttribLocation(\"" << tmp.m_name << "\") = " << tmp.m_elementId);
}
m_elementList.push_back(tmp);
return m_elementList.size()-1;
}
int32_t gale::resource::Program::getUniform(std::string _elementName) {
// check if it exist previously :
for(size_t iii=0; iii<m_elementList.size(); iii++) {
if (m_elementList[iii].m_name == _elementName) {
return iii;
}
}
progAttributeElement tmp;
tmp.m_name = _elementName;
tmp.m_isAttribute = false;
tmp.m_elementId = glGetUniformLocation(m_program, tmp.m_name.c_str());
tmp.m_isLinked = true;
if (tmp.m_elementId<0) {
GALE_WARNING(" [" << m_elementList.size() << "] glGetUniformLocation(\"" << tmp.m_name << "\") = " << tmp.m_elementId);
tmp.m_isLinked = false;
checkGlError("glGetUniformLocation", __LINE__, tmp.m_elementId);
} else {
GALE_INFO(" [" << m_elementList.size() << "] glGetUniformLocation(\"" << tmp.m_name << "\") = " << tmp.m_elementId);
}
m_elementList.push_back(tmp);
return m_elementList.size()-1;
}
void gale::resource::Program::updateContext() {
if (true == m_exist) {
// Do nothing == > too dangerous ...
} else {
// create the Shader
GALE_INFO("Create the Program ... \"" << m_name << "\"");
m_program = glCreateProgram();
if (0 == m_program) {
GALE_ERROR("program creation return error ...");
checkGlError("glCreateProgram", __LINE__);
return;
}
GALE_DEBUG("Create program with oglID=" << m_program);
// first attach vertex shader, and after fragment shader
for (size_t iii=0; iii<m_shaderList.size(); iii++) {
if (nullptr != m_shaderList[iii]) {
if (m_shaderList[iii]->getShaderType() == GL_VERTEX_SHADER) {
glAttachShader(m_program, m_shaderList[iii]->getGL_ID());
checkGlError("glAttachShader", __LINE__);
}
}
}
for (size_t iii=0; iii<m_shaderList.size(); iii++) {
if (nullptr != m_shaderList[iii]) {
if (m_shaderList[iii]->getShaderType() == GL_FRAGMENT_SHADER) {
glAttachShader(m_program, m_shaderList[iii]->getGL_ID());
checkGlError("glAttachShader", __LINE__);
}
}
}
glLinkProgram(m_program);
checkGlError("glLinkProgram", __LINE__);
GLint linkStatus = GL_FALSE;
glGetProgramiv(m_program, GL_LINK_STATUS, &linkStatus);
checkGlError("glGetProgramiv", __LINE__);
if (linkStatus != GL_TRUE) {
GLint bufLength = 0;
l_bufferDisplayError[0] = '\0';
glGetProgramInfoLog(m_program, LOG_OGL_INTERNAL_BUFFER_LEN, &bufLength, l_bufferDisplayError);
char tmpLog[256];
int32_t idOut=0;
GALE_ERROR("Could not compile \"PROGRAM\": \"" << m_name << "\"");
for (size_t iii=0; iii<LOG_OGL_INTERNAL_BUFFER_LEN ; iii++) {
tmpLog[idOut] = l_bufferDisplayError[iii];
if (tmpLog[idOut] == '\n' || tmpLog[idOut] == '\0' || idOut >= 256) {
tmpLog[idOut] = '\0';
GALE_ERROR(" == > " << tmpLog);
idOut=0;
} else {
idOut++;
}
if (l_bufferDisplayError[iii] == '\0') {
break;
}
}
if (idOut != 0) {
tmpLog[idOut] = '\0';
GALE_ERROR(" == > " << tmpLog);
}
glDeleteProgram(m_program);
checkGlError("glDeleteProgram", __LINE__);
m_program = 0;
return;
}
m_exist = true;
// now get the old attribute requested priviously ...
for(size_t iii=0; iii<m_elementList.size(); iii++) {
if (true == m_elementList[iii].m_isAttribute) {
m_elementList[iii].m_elementId = glGetAttribLocation(m_program, m_elementList[iii].m_name.c_str());
m_elementList[iii].m_isLinked = true;
if (m_elementList[iii].m_elementId<0) {
m_elementList[iii].m_isLinked = false;
checkGlError("glGetAttribLocation", __LINE__);
GALE_WARNING("glGetAttribLocation(\"" << m_elementList[iii].m_name << "\") = " << m_elementList[iii].m_elementId);
}
} else {
m_elementList[iii].m_elementId = glGetUniformLocation(m_program, m_elementList[iii].m_name.c_str());
m_elementList[iii].m_isLinked = true;
if (m_elementList[iii].m_elementId<0) {
m_elementList[iii].m_isLinked = false;
checkGlError("glGetUniformLocation", __LINE__);
GALE_WARNING("glGetUniformLocation(\"" << m_elementList[iii].m_name << "\") = " << m_elementList[iii].m_elementId);
}
}
}
}
}
void gale::resource::Program::removeContext() {
if (true == m_exist) {
glDeleteProgram(m_program);
m_program = 0;
m_exist = false;
for(size_t iii=0; iii<m_elementList.size(); iii++) {
m_elementList[iii].m_elementId=0;
}
}
}
void gale::resource::Program::removeContextToLate() {
m_exist = false;
m_program = 0;
}
void gale::resource::Program::reload() {
/* TODO : ...
etk::file file(m_name, etk::FILE_TYPE_DATA);
if (false == file.Exist()) {
GALE_ERROR("File does not Exist : \"" << file << "\"");
return;
}
int32_t fileSize = file.size();
if (0 == fileSize) {
GALE_ERROR("This file is empty : " << file);
return;
}
if (false == file.fOpenRead()) {
GALE_ERROR("Can not open the file : " << file);
return;
}
// remove previous data ...
if (nullptr != m_fileData) {
delete[] m_fileData;
m_fileData = 0;
}
// allocate data
m_fileData = new char[fileSize+5];
if (nullptr == m_fileData) {
GALE_ERROR("Error Memory allocation size=" << fileSize);
return;
}
memset(m_fileData, 0, (fileSize+5)*sizeof(char));
// load data from the file :
file.fRead(m_fileData, 1, fileSize);
// close the file:
file.fClose();
*/
// now change the OGL context ...
removeContext();
updateContext();
}
//////////////////////////////////////////////////////////////////////////////////////////////
void gale::resource::Program::sendAttribute(int32_t _idElem,
int32_t _nbElement,
const void* _pointer,
int32_t _jumpBetweenSample) {
if (0 == m_program) {
return;
}
if ( _idElem < 0
|| (size_t)_idElem > m_elementList.size()) {
GALE_ERROR("idElem = " << _idElem << " not in [0.." << (m_elementList.size()-1) << "]");
return;
}
if (m_elementList[_idElem].m_isLinked == false) {
return;
}
//GALE_ERROR("[" << m_elementList[_idElem].m_name << "] send " << _nbElement << " element");
glVertexAttribPointer(m_elementList[_idElem].m_elementId, // attribute ID of openGL
_nbElement, // number of elements per vertex, here (r,g,b,a)
GL_FLOAT, // the type of each element
GL_FALSE, // take our values as-is
_jumpBetweenSample, // no extra data between each position
_pointer); // Pointer on the buffer
checkGlError("glVertexAttribPointer", __LINE__, _idElem);
glEnableVertexAttribArray(m_elementList[_idElem].m_elementId);
checkGlError("glEnableVertexAttribArray", __LINE__, _idElem);
}
void gale::resource::Program::sendAttributePointer(int32_t _idElem,
const std::shared_ptr<gale::resource::VirtualBufferObject>& _vbo,
int32_t _index,
int32_t _jumpBetweenSample,
int32_t _offset) {
if (0 == m_program) {
return;
}
if (_idElem<0 || (size_t)_idElem>m_elementList.size()) {
GALE_ERROR("idElem = " << _idElem << " not in [0.." << (m_elementList.size()-1) << "]");
return;
}
if (false == m_elementList[_idElem].m_isLinked) {
return;
}
// check error of the VBO goog enought ...
if (_vbo->getElementSize(_index) <= 0) {
GALE_ERROR("Can not bind a VBO Buffer with an element size of : " << _vbo->getElementSize(_index) << " named=" << _vbo->getName());
return;
}
GALE_VERBOSE("[" << m_elementList[_idElem].m_name << "] send " << _vbo->getElementSize(_index) << " element on oglID=" << _vbo->getGL_ID(_index) << " VBOindex=" << _index);
glBindBuffer(GL_ARRAY_BUFFER, _vbo->getGL_ID(_index));
checkGlError("glBindBuffer", __LINE__, _idElem);
GALE_VERBOSE(" id=" << m_elementList[_idElem].m_elementId);
GALE_VERBOSE(" eleme size=" << _vbo->getElementSize(_index));
GALE_VERBOSE(" jump sample=" << _jumpBetweenSample);
GALE_VERBOSE(" offset=" << _offset);
glVertexAttribPointer(m_elementList[_idElem].m_elementId, // attribute ID of openGL
_vbo->getElementSize(_index), // number of elements per vertex, here (r,g,b,a)
GL_FLOAT, // the type of each element
GL_FALSE, // take our values as-is
_jumpBetweenSample, // no extra data between each position
(GLvoid *)_offset); // Pointer on the buffer
checkGlError("glVertexAttribPointer", __LINE__, _idElem);
glEnableVertexAttribArray(m_elementList[_idElem].m_elementId);
checkGlError("glEnableVertexAttribArray", __LINE__, _idElem);
}
//////////////////////////////////////////////////////////////////////////////////////////////
void gale::resource::Program::uniformMatrix(int32_t _idElem, const mat4& _matrix, bool _transpose) {
if (0 == m_program) {
return;
}
if (_idElem<0 || (size_t)_idElem>m_elementList.size()) {
GALE_ERROR("idElem = " << _idElem << " not in [0.." << (m_elementList.size()-1) << "]");
return;
}
if (false == m_elementList[_idElem].m_isLinked) {
return;
}
//GALE_ERROR("[" << m_elementList[_idElem].m_name << "] send 1 matrix");
// note : Android des not supported the transposition of the matrix, then we will done it oursef:
if (true == _transpose) {
mat4 tmp = _matrix;
tmp.transpose();
glUniformMatrix4fv(m_elementList[_idElem].m_elementId, 1, GL_FALSE, tmp.m_mat);
} else {
glUniformMatrix4fv(m_elementList[_idElem].m_elementId, 1, GL_FALSE, _matrix.m_mat);
}
checkGlError("glUniformMatrix4fv", __LINE__, _idElem);
}
//////////////////////////////////////////////////////////////////////////////////////////////
void gale::resource::Program::uniform1f(int32_t _idElem, float _value1) {
if (0 == m_program) {
return;
}
if (_idElem<0 || (size_t)_idElem>m_elementList.size()) {
GALE_ERROR("idElem = " << _idElem << " not in [0.." << (m_elementList.size()-1) << "]");
return;
}
if (false == m_elementList[_idElem].m_isLinked) {
return;
}
glUniform1f(m_elementList[_idElem].m_elementId, _value1);
checkGlError("glUniform1f", __LINE__, _idElem);
}
void gale::resource::Program::uniform2f(int32_t _idElem, float _value1, float _value2) {
if (0 == m_program) {
return;
}
if (_idElem<0 || (size_t)_idElem>m_elementList.size()) {
GALE_ERROR("idElem = " << _idElem << " not in [0.." << (m_elementList.size()-1) << "]");
return;
}
if (false == m_elementList[_idElem].m_isLinked) {
return;
}
glUniform2f(m_elementList[_idElem].m_elementId, _value1, _value2);
checkGlError("glUniform2f", __LINE__, _idElem);
}
void gale::resource::Program::uniform3f(int32_t _idElem, float _value1, float _value2, float _value3) {
if (0 == m_program) {
return;
}
if (_idElem<0 || (size_t)_idElem>m_elementList.size()) {
GALE_ERROR("idElem = " << _idElem << " not in [0.." << (m_elementList.size()-1) << "]");
return;
}
if (false == m_elementList[_idElem].m_isLinked) {
return;
}
glUniform3f(m_elementList[_idElem].m_elementId, _value1, _value2, _value3);
checkGlError("glUniform3f", __LINE__, _idElem);
}
void gale::resource::Program::uniform4f(int32_t _idElem, float _value1, float _value2, float _value3, float _value4) {
if (0 == m_program) {
return;
}
if (_idElem<0 || (size_t)_idElem>m_elementList.size()) {
GALE_ERROR("idElem = " << _idElem << " not in [0.." << (m_elementList.size()-1) << "]");
return;
}
if (false == m_elementList[_idElem].m_isLinked) {
return;
}
glUniform4f(m_elementList[_idElem].m_elementId, _value1, _value2, _value3, _value4);
checkGlError("glUniform4f", __LINE__, _idElem);
}
//////////////////////////////////////////////////////////////////////////////////////////////
void gale::resource::Program::uniform1i(int32_t _idElem, int32_t _value1) {
if (0 == m_program) {
return;
}
if (_idElem<0 || (size_t)_idElem>m_elementList.size()) {
GALE_ERROR("idElem = " << _idElem << " not in [0.." << (m_elementList.size()-1) << "]");
return;
}
if (false == m_elementList[_idElem].m_isLinked) {
return;
}
glUniform1i(m_elementList[_idElem].m_elementId, _value1);
checkGlError("glUniform1i", __LINE__, _idElem);
}
void gale::resource::Program::uniform2i(int32_t _idElem, int32_t _value1, int32_t _value2) {
if (0 == m_program) {
return;
}
if (_idElem<0 || (size_t)_idElem>m_elementList.size()) {
GALE_ERROR("idElem = " << _idElem << " not in [0.." << (m_elementList.size()-1) << "]");
return;
}
if (false == m_elementList[_idElem].m_isLinked) {
return;
}
glUniform2i(m_elementList[_idElem].m_elementId, _value1, _value2);
checkGlError("glUniform2i", __LINE__, _idElem);
}
void gale::resource::Program::uniform3i(int32_t _idElem, int32_t _value1, int32_t _value2, int32_t _value3) {
if (0 == m_program) {
return;
}
if (_idElem<0 || (size_t)_idElem>m_elementList.size()) {
GALE_ERROR("idElem = " << _idElem << " not in [0.." << (m_elementList.size()-1) << "]");
return;
}
if (false == m_elementList[_idElem].m_isLinked) {
return;
}
glUniform3i(m_elementList[_idElem].m_elementId, _value1, _value2, _value3);
checkGlError("glUniform3i", __LINE__, _idElem);
}
void gale::resource::Program::uniform4i(int32_t _idElem, int32_t _value1, int32_t _value2, int32_t _value3, int32_t _value4) {
if (0 == m_program) {
return;
}
if (_idElem<0 || (size_t)_idElem>m_elementList.size()) {
GALE_ERROR("idElem = " << _idElem << " not in [0.." << (m_elementList.size()-1) << "]");
return;
}
if (false == m_elementList[_idElem].m_isLinked) {
return;
}
glUniform4i(m_elementList[_idElem].m_elementId, _value1, _value2, _value3, _value4);
checkGlError("glUniform4i", __LINE__, _idElem);
}
//////////////////////////////////////////////////////////////////////////////////////////////
void gale::resource::Program::uniform1fv(int32_t _idElem, int32_t _nbElement, const float *_value) {
if (0 == m_program) {
return;
}
if (_idElem<0 || (size_t)_idElem>m_elementList.size()) {
GALE_ERROR("idElem = " << _idElem << " not in [0.." << (m_elementList.size()-1) << "]");
return;
}
if (false == m_elementList[_idElem].m_isLinked) {
return;
}
if (0 == _nbElement) {
GALE_ERROR("No element to send at open GL ...");
return;
}
if (nullptr == _value) {
GALE_ERROR("nullptr Input pointer to send at open GL ...");
return;
}
glUniform1fv(m_elementList[_idElem].m_elementId, _nbElement, _value);
checkGlError("glUniform1fv", __LINE__, _idElem);
}
void gale::resource::Program::uniform2fv(int32_t _idElem, int32_t _nbElement, const float *_value) {
if (0 == m_program) {
return;
}
if (_idElem<0 || (size_t)_idElem>m_elementList.size()) {
GALE_ERROR("idElem = " << _idElem << " not in [0.." << (m_elementList.size()-1) << "]");
return;
}
if (false == m_elementList[_idElem].m_isLinked) {
return;
}
if (0 == _nbElement) {
GALE_ERROR("No element to send at open GL ...");
return;
}
if (nullptr == _value) {
GALE_ERROR("nullptr Input pointer to send at open GL ...");
return;
}
glUniform2fv(m_elementList[_idElem].m_elementId, _nbElement, _value);
checkGlError("glUniform2fv", __LINE__, _idElem);
}
void gale::resource::Program::uniform3fv(int32_t _idElem, int32_t _nbElement, const float *_value) {
if (0 == m_program) {
return;
}
if (_idElem<0 || (size_t)_idElem>m_elementList.size()) {
GALE_ERROR("idElem = " << _idElem << " not in [0.." << (m_elementList.size()-1) << "]");
return;
}
if (false == m_elementList[_idElem].m_isLinked) {
return;
}
if (0 == _nbElement) {
GALE_ERROR("No element to send at open GL ...");
return;
}
if (nullptr == _value) {
GALE_ERROR("nullptr Input pointer to send at open GL ...");
return;
}
GALE_VERBOSE("[" << m_elementList[_idElem].m_name << "] send " << _nbElement << " vec3");
glUniform3fv(m_elementList[_idElem].m_elementId, _nbElement, _value);
checkGlError("glUniform3fv", __LINE__, _idElem);
}
void gale::resource::Program::uniform4fv(int32_t _idElem, int32_t _nbElement, const float *_value) {
if (0 == m_program) {
return;
}
if (_idElem<0 || (size_t)_idElem>m_elementList.size()) {
GALE_ERROR("idElem = " << _idElem << " not in [0.." << (m_elementList.size()-1) << "]");
return;
}
if (false == m_elementList[_idElem].m_isLinked) {
return;
}
if (0 == _nbElement) {
GALE_ERROR("No element to send at open GL ...");
return;
}
if (nullptr == _value) {
GALE_ERROR("nullptr Input pointer to send at open GL ...");
return;
}
GALE_VERBOSE("[" << m_elementList[_idElem].m_name << "] send " << _nbElement << " vec4");
glUniform4fv(m_elementList[_idElem].m_elementId, _nbElement, _value);
checkGlError("glUniform4fv", __LINE__, _idElem);
}
//////////////////////////////////////////////////////////////////////////////////////////////
void gale::resource::Program::uniform1iv(int32_t _idElem, int32_t _nbElement, const int32_t *_value) {
if (0 == m_program) {
return;
}
if (_idElem<0 || (size_t)_idElem>m_elementList.size()) {
GALE_ERROR("idElem = " << _idElem << " not in [0.." << (m_elementList.size()-1) << "]");
return;
}
if (false == m_elementList[_idElem].m_isLinked) {
return;
}
if (0 == _nbElement) {
GALE_ERROR("No element to send at open GL ...");
return;
}
if (nullptr == _value) {
GALE_ERROR("nullptr Input pointer to send at open GL ...");
return;
}
glUniform1iv(m_elementList[_idElem].m_elementId, _nbElement, _value);
checkGlError("glUniform1iv", __LINE__, _idElem);
}
void gale::resource::Program::uniform2iv(int32_t _idElem, int32_t _nbElement, const int32_t *_value) {
if (0 == m_program) {
return;
}
if (_idElem<0 || (size_t)_idElem>m_elementList.size()) {
GALE_ERROR("idElem = " << _idElem << " not in [0.." << (m_elementList.size()-1) << "]");
return;
}
if (false == m_elementList[_idElem].m_isLinked) {
return;
}
if (0 == _nbElement) {
GALE_ERROR("No element to send at open GL ...");
return;
}
if (nullptr == _value) {
GALE_ERROR("nullptr Input pointer to send at open GL ...");
return;
}
glUniform2iv(m_elementList[_idElem].m_elementId, _nbElement, _value);
checkGlError("glUniform2iv", __LINE__, _idElem);
}
void gale::resource::Program::uniform3iv(int32_t _idElem, int32_t _nbElement, const int32_t *_value) {
if (0 == m_program) {
return;
}
if (_idElem<0 || (size_t)_idElem>m_elementList.size()) {
GALE_ERROR("idElem = " << _idElem << " not in [0.." << (m_elementList.size()-1) << "]");
return;
}
if (false == m_elementList[_idElem].m_isLinked) {
return;
}
if (0 == _nbElement) {
GALE_ERROR("No element to send at open GL ...");
return;
}
if (nullptr == _value) {
GALE_ERROR("nullptr Input pointer to send at open GL ...");
return;
}
glUniform3iv(m_elementList[_idElem].m_elementId, _nbElement, _value);
checkGlError("glUniform3iv", __LINE__, _idElem);
}
void gale::resource::Program::uniform4iv(int32_t _idElem, int32_t _nbElement, const int32_t *_value) {
if (0 == m_program) {
return;
}
if (_idElem<0 || (size_t)_idElem>m_elementList.size()) {
GALE_ERROR("idElem = " << _idElem << " not in [0.." << (m_elementList.size()-1) << "]");
return;
}
if (false == m_elementList[_idElem].m_isLinked) {
return;
}
if (0 == _nbElement) {
GALE_ERROR("No element to send at open GL ...");
return;
}
if (nullptr == _value) {
GALE_ERROR("nullptr Input pointer to send at open GL ...");
return;
}
glUniform4iv(m_elementList[_idElem].m_elementId, _nbElement, _value);
checkGlError("glUniform4iv", __LINE__, _idElem);
}
//#define PROGRAM_DISPLAY_SPEED
//////////////////////////////////////////////////////////////////////////////////////////////
#ifdef PROGRAM_DISPLAY_SPEED
int64_t g_startTime = 0;
#endif
void gale::resource::Program::use() {
#ifdef PROGRAM_DISPLAY_SPEED
g_startTime = gale::getTime();
#endif
// event if it was 0 == > set it to prevent other use of the previous shader display ...
gale::openGL::useProgram(m_program);
checkGlError("glUseProgram", __LINE__);
}
void gale::resource::Program::setTexture0(int32_t _idElem, GLint _textureOpenGlID) {
if (0 == m_program) {
return;
}
if (_idElem<0 || (size_t)_idElem>m_elementList.size()) {
return;
}
if (false == m_elementList[_idElem].m_isLinked) {
return;
}
#if 0
gale::openGL::enable(GL_TEXTURE_2D);
checkGlError("glEnable", __LINE__);
#endif
gale::openGL::activeTexture(GL_TEXTURE0);
checkGlError("glActiveTexture", __LINE__, _idElem);
// set the textureID
glBindTexture(GL_TEXTURE_2D, _textureOpenGlID);
checkGlError("glBindTexture", __LINE__, _idElem);
// set the texture on the uniform attribute
glUniform1i(m_elementList[_idElem].m_elementId, /*GL_TEXTURE*/0);
checkGlError("glUniform1i", __LINE__, _idElem);
m_hasTexture = true;
}
void gale::resource::Program::setTexture1(int32_t _idElem, GLint _textureOpenGlID) {
if (0 == m_program) {
return;
}
if (_idElem<0 || (size_t)_idElem>m_elementList.size()) {
return;
}
if (false == m_elementList[_idElem].m_isLinked) {
return;
}
#if 0
gale::openGL::enable(GL_TEXTURE_2D);
checkGlError("glEnable", __LINE__);
#endif
gale::openGL::activeTexture(GL_TEXTURE1);
checkGlError("glActiveTexture", __LINE__, _idElem);
// set the textureID
glBindTexture(GL_TEXTURE_2D, _textureOpenGlID);
checkGlError("glBindTexture", __LINE__, _idElem);
// set the texture on the uniform attribute
glUniform1i(m_elementList[_idElem].m_elementId, /*GL_TEXTURE*/1);
checkGlError("glUniform1i", __LINE__, _idElem);
m_hasTexture1 = true;
}
void gale::resource::Program::unUse() {
//GALE_WARNING("Will use program : " << m_program);
if (0 == m_program) {
return;
}
#if 0
if (true == m_hasTexture) {
gale::openGL::disable(GL_TEXTURE_2D);
//checkGlError("glDisable", __LINE__);
m_hasTexture = false;
}
#endif
// no need to disable program == > this only generate perturbation on speed ...
gale::openGL::useProgram(-1);
#ifdef PROGRAM_DISPLAY_SPEED
float localTime = (float)(gale::getTime() - g_startTime) / 1000.0f;
if (localTime>1) {
GALE_ERROR(" prog : " << localTime << "ms resource=\"" << m_name << "\"");
} else {
GALE_DEBUG(" prog : " << localTime << "ms resource=\"" << m_name << "\"");
}
#endif
checkGlError("glUseProgram", __LINE__);
}

313
gale/resource/Program.h Normal file
View File

@ -0,0 +1,313 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#ifndef __OPEN_GL__PROGRAM_H__
#define __OPEN_GL__PROGRAM_H__
#include <etk/types.h>
#include <etk/math/Vector4D.h>
#include <gale/debug.h>
#include <gale/openGL/openGL.h>
#include <gale/resource/Resource.h>
#include <gale/resource/Shader.h>
#include <gale/resource/VirtualBufferObject.h>
#include <etk/Color.h>
namespace gale {
namespace resource {
/**
* @brief In a openGL program we need some data to communicate with them, we register all the name requested by the user in this structure:
* @note Register all requested element permit to abstract the fact that some element does not exist and remove control of existance from upper code.
* This is important to note when the Program is reloaded the elements availlable can change.
* @not-in-doc
*/
class progAttributeElement {
public :
std::string m_name; //!< Name of the element
GLint m_elementId; //!< openGl Id if this element == > can not exist ==> @ref m_isLinked
bool m_isAttribute; //!< true if it was an attribute element, otherwite it was an uniform
bool m_isLinked; //!< if this element does not exist this is false
};
//! @not-in-doc
std::ostream& operator <<(std::ostream& _os, const gale::resource::progAttributeElement& _obj);
//! @not-in-doc
std::ostream& operator <<(std::ostream& _os, const std::vector<gale::resource::progAttributeElement>& _obj);
/**
* @brief Program is a compilation of some fragment Shader and vertex Shader. This construct automaticly this assiciation
* The input file must have the form : "myFile.prog"
* The data is simple :
* <pre>
* # Comment line ... paid attention at the space at the end of lines, they are considered like a part of the file ...
* # The folder is automaticly get from the program file basic folder
* filename1.vert
* filename2.frag
* filename3.vert
* filename4.frag
* </pre>
*/
class Program : public gale::Resource {
private :
bool m_exist; //!< the file existed
GLuint m_program; //!< openGL id of the current program
std::vector<std::shared_ptr<gale::resource::Shader>> m_shaderList; //!< List of all the shader loaded
std::vector<gale::resource::progAttributeElement> m_elementList; //!< List of all the attribute requested by the user
bool m_hasTexture; //!< A texture has been set to the current shader
bool m_hasTexture1; //!< A texture has been set to the current shader
protected:
/**
* @brief Contructor of an opengl Program.
* @param[in] filename Standard file name format. see @ref etk::FSNode
*/
Program();
void init(const std::string& _filename);
public:
DECLARE_RESOURCE_NAMED_FACTORY(Program);
/**
* @brief Destructor, remove the current Program.
*/
virtual ~Program();
public:
/**
* @brief Check If an Id is valid in the shader or not (sometime the shader have not some attribute, then we need to display some error)
* @return _idElem Id of the Attribute that might be sended.
* @return true The id is valid, false otherwise
*/
bool checkIdValidity(int32_t _idElem);
/**
* @brief User request an attribute on this program.
* @note The attribute is send to the fragment shaders
* @param[in] _elementName Name of the requested attribute.
* @return An abstract ID of the current attribute (this value is all time availlable, even if the program will be reloaded)
*/
int32_t getAttribute(std::string _elementName);
/**
* @brief Send attribute table to the spefified ID attribure (not send if does not really exist in the openGL program).
* @param[in] _idElem Id of the Attribute that might be sended.
* @param[in] _nbElement Specifies the number of elements that are to be modified.
* @param[in] _pointer Pointer on the data that might be sended.
* @param[in] _jumpBetweenSample Number of byte to jump between 2 vertex (this permit to enterlace informations)
*/
void sendAttribute(int32_t _idElem,
int32_t _nbElement,
const void* _pointer,
int32_t _jumpBetweenSample=0);
void sendAttributePointer(int32_t _idElem,
const std::shared_ptr<gale::resource::VirtualBufferObject>& _vbo,
int32_t _index,
int32_t _jumpBetweenSample=0,
int32_t _offset=0);
inline void sendAttribute(int32_t _idElem, const std::vector<vec2>& _data) {
sendAttribute(_idElem, 2/*u,v / x,y*/, &_data[0]);
}
inline void sendAttribute(int32_t _idElem, const std::vector<vec3>& _data) {
sendAttribute(_idElem, 3/*x,y,z,unused*/, &_data[0], 4*sizeof(btScalar));
}
inline void sendAttribute(int32_t _idElem, const std::vector<etk::Color<float>>& _data) {
sendAttribute(_idElem, 4/*r,g,b,a*/, &_data[0]);
}
inline void sendAttribute(int32_t _idElem, const std::vector<float>& _data) {
sendAttribute(_idElem, 1, &_data[0]);
}
/**
* @brief User request an Uniform on this program.
* @note uniform value is availlable for all the fragment shader in the program (only one value for all)
* @param[in] _elementName Name of the requested uniform.
* @return An abstract ID of the current uniform (this value is all time availlable, even if the program will be reloaded)
*/
int32_t getUniform(std::string _elementName);
/**
* @brief Send a uniform element to the spefified ID (not send if does not really exist in the openGL program)
* @param[in] _idElem Id of the uniform that might be sended.
* @param[in] _matrix Matrix that might be sended.
* @param[in] _transpose Transpose the matrix (needed all the taime in the normal openGl access (only not done in the openGL-ES2 due to the fact we must done it ourself)
*/
void uniformMatrix(int32_t _idElem, const mat4& _matrix, bool _transpose=true);
inline void uniform(int32_t _idElem, const etk::Color<float>& _value) {
uniform4f(_idElem, _value.r(), _value.g(), _value.b(), _value.a());
}
/**
* @brief Send 1 float uniform element to the spefified ID (not send if does not really exist in the openGL program)
* @param[in] _idElem Id of the uniform that might be sended.
* @param[in] _value1 Value to send at the Uniform
*/
void uniform1f(int32_t _idElem, float _value1);
/**
* @brief Send 2 float uniform element to the spefified ID (not send if does not really exist in the openGL program)
* @param[in] _idElem Id of the uniform that might be sended.
* @param[in] _value1 Value to send at the Uniform
* @param[in] _value2 Value to send at the Uniform
*/
void uniform2f(int32_t _idElem, float _value1, float _value2);
/**
* @brief Send 3 float uniform element to the spefified ID (not send if does not really exist in the openGL program)
* @param[in] _idElem Id of the uniform that might be sended.
* @param[in] _value1 Value to send at the Uniform
* @param[in] _value2 Value to send at the Uniform
* @param[in] _value3 Value to send at the Uniform
*/
void uniform3f(int32_t _idElem, float _value1, float _value2, float _value3);
/**
* @brief Send 4 float uniform element to the spefified ID (not send if does not really exist in the openGL program)
* @param[in] _idElem Id of the uniform that might be sended.
* @param[in] _value1 Value to send at the Uniform
* @param[in] _value2 Value to send at the Uniform
* @param[in] _value3 Value to send at the Uniform
* @param[in] _value4 Value to send at the Uniform
*/
void uniform4f(int32_t _idElem, float _value1, float _value2, float _value3, float _value4);
/**
* @brief Send 1 signed integer uniform element to the spefified ID (not send if does not really exist in the openGL program)
* @param[in] _idElem Id of the uniform that might be sended.
* @param[in] _value1 Value to send at the Uniform
*/
void uniform1i(int32_t _idElem, int32_t _value1);
/**
* @brief Send 2 signed integer uniform element to the spefified ID (not send if does not really exist in the openGL program)
* @param[in] _idElem Id of the uniform that might be sended.
* @param[in] _value1 Value to send at the Uniform
* @param[in] _value2 Value to send at the Uniform
*/
void uniform2i(int32_t _idElem, int32_t _value1, int32_t _value2);
/**
* @brief Send 3 signed integer uniform element to the spefified ID (not send if does not really exist in the openGL program)
* @param[in] _idElem Id of the uniform that might be sended.
* @param[in] _value1 Value to send at the Uniform
* @param[in] _value2 Value to send at the Uniform
* @param[in] _value3 Value to send at the Uniform
*/
void uniform3i(int32_t _idElem, int32_t _value1, int32_t _value2, int32_t _value3);
/**
* @brief Send 4 signed integer uniform element to the spefified ID (not send if does not really exist in the openGL program)
* @param[in] _idElem Id of the uniform that might be sended.
* @param[in] _value1 Value to send at the Uniform
* @param[in] _value2 Value to send at the Uniform
* @param[in] _value3 Value to send at the Uniform
* @param[in] _value4 Value to send at the Uniform
*/
void uniform4i(int32_t _idElem, int32_t _value1, int32_t _value2, int32_t _value3, int32_t _value4);
/**
* @brief Send "vec1" uniform element to the spefified ID (not send if does not really exist in the openGL program)
* @param[in] _idElem Id of the uniform that might be sended.
* @param[in] _nbElement Number of element sended
* @param[in] _value Pointer on the data
*/
void uniform1fv(int32_t _idElem, int32_t _nbElement, const float *_value);
/**
* @brief Send "vec2" uniform element to the spefified ID (not send if does not really exist in the openGL program)
* @param[in] _idElem Id of the uniform that might be sended.
* @param[in] _nbElement Number of element sended
* @param[in] _value Pointer on the data
*/
void uniform2fv(int32_t _idElem, int32_t _nbElement, const float *_value);
/**
* @brief Send "vec3" uniform element to the spefified ID (not send if does not really exist in the openGL program)
* @param[in] _idElem Id of the uniform that might be sended.
* @param[in] _nbElement Number of element sended
* @param[in] _value Pointer on the data
*/
void uniform3fv(int32_t _idElem, int32_t _nbElement, const float *_value);
/**
* @brief Send "vec4" uniform element to the spefified ID (not send if does not really exist in the openGL program)
* @param[in] _idElem Id of the uniform that might be sended.
* @param[in] _nbElement Number of element sended
* @param[in] _value Pointer on the data
*/
void uniform4fv(int32_t _idElem, int32_t _nbElement, const float *_value);
/**
* @brief Send "ivec1" uniform element to the spefified ID (not send if does not really exist in the openGL program)
* @param[in] _idElem Id of the uniform that might be sended.
* @param[in] _nbElement Number of element sended
* @param[in] _value Pointer on the data
*/
void uniform1iv(int32_t _idElem, int32_t _nbElement, const int32_t *_value);
/**
* @brief Send "ivec2" uniform element to the spefified ID (not send if does not really exist in the openGL program)
* @param[in] _idElem Id of the Attribute that might be sended.
* @param[in] _nbElement Number of element sended
* @param[in] _value Pointer on the data
*/
void uniform2iv(int32_t _idElem, int32_t _nbElement, const int32_t *_value);
/**
* @brief Send "ivec3" uniform element to the spefified ID (not send if does not really exist in the openGL program)
* @param[in] _idElem Id of the uniform that might be sended.
* @param[in] _nbElement Number of element sended
* @param[in] _value Pointer on the data
*/
void uniform3iv(int32_t _idElem, int32_t _nbElement, const int32_t *_value);
/**
* @brief Send "ivec4" uniform element to the spefified ID (not send if does not really exist in the openGL program)
* @param[in] _idElem Id of the uniform that might be sended.
* @param[in] _nbElement Number of element sended
* @param[in] _value Pointer on the data
*/
void uniform4iv(int32_t _idElem, int32_t _nbElement, const int32_t *_value);
inline void uniform2(int32_t _idElem, const vec2& _value) {
uniform2fv(_idElem, 1, &_value.m_floats[0]);
};
inline void uniform3(int32_t _idElem, const vec3& _value) {
uniform3fv(_idElem, 1, &_value.m_floats[0]);
};
inline void uniform4(int32_t _idElem, const vec4& _value) {
uniform4fv(_idElem, 1, &_value.m_floats[0]);
};
inline void uniform2(int32_t _idElem, const ivec2& _value) {
uniform2iv(_idElem, 1, &_value.m_floats[0]);
};
inline void uniform3(int32_t _idElem, const ivec3& _value) {
uniform3iv(_idElem, 1, &_value.m_floats[0]);
};
inline void uniform4(int32_t _idElem, const ivec4& _value) {
uniform4iv(_idElem, 1, &_value.m_floats[0]);
};
/**
* @brief Request the processing of this program
*/
void use();
/**
* @brief set the testure Id on the specify uniform element.
* @param[in] _idElem Id of the uniform that might be sended.
* @param[in] _textureOpenGlID Real openGL texture ID
*/
void setTexture0(int32_t _idElem, GLint _textureOpenGlID);
void setTexture1(int32_t _idElem, GLint _textureOpenGlID);
/**
* @brief Stop the processing of this program
*/
void unUse();
/**
* @brief This load/reload the data in the opengl context, needed when removed previously.
*/
void updateContext();
/**
* @brief remove the data from the opengl context.
*/
void removeContext();
/**
* @brief Special android spec! It inform us that all context is removed and after notify us...
*/
void removeContextToLate();
/**
* @brief Relode the shader from the file. used when a request of resouces reload is done.
* @note this is really usefull when we tested the new themes or shader developpements.
*/
void reload();
private:
void checkGlError(const char* _op, int32_t _localLine, int32_t _idElem=-2);
};
};
};
#endif

View File

@ -0,0 +1,54 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#include <etk/types.h>
#include <gale/debug.h>
#include <gale/resource/Resource.h>
#include <gale/resource/Manager.h>
#include <gale/gale.h>
#include <gale/context/Context.h>
Resource() :
m_id(0),
m_resourceHasBeenInit(false),
m_resourceLevel(MAX_RESOURCE_LEVEL-1) {
static size_t id = 0;
m_id = id++;
addResourceType("gale::Resource");
setStatusResource(true);
};
void gale::Resource::init() {
m_resourceHasBeenInit=true;
}
void gale::Resource::init(const std::string& _name) {
m_resourceHasBeenInit=true;
m_name = _name;
}
void gale::Resource::updateContext() {
GALE_DEBUG("Not set for : [" << getId() << "]" << getName() << " loaded " << shared_from_this().use_count() << " time(s)");
}
void gale::Resource::removeContext() {
GALE_DEBUG("Not set for : [" << getId() << "]" << getName() << " loaded " << shared_from_this().use_count() << " time(s)");
}
void gale::Resource::removeContextToLate() {
GALE_DEBUG("Not set for : [" << getId() << "]" << getName() << " loaded " << shared_from_this().use_count() << " time(s)");
}
void gale::Resource::reload() {
GALE_DEBUG("Not set for : [" << getId() << "]" << getName() << " loaded " << shared_from_this().use_count() << " time(s)");
}
gale::resource::Manager& gale::Resource::getManager() {
return gale::getContext().getResourcesManager();
}

185
gale/resource/Resource.h Normal file
View File

@ -0,0 +1,185 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#ifndef __RESOURCES_H__
#define __RESOURCES_H__
#include <mutex>
#include <memory>
#include <etk/types.h>
#include <gale/debug.h>
#define MAX_RESOURCE_LEVEL (5)
#define DECLARE_RESOURCE_FACTORY(className) \
template<typename ... T> static std::shared_ptr<className> create( T&& ... all ) { \
std::shared_ptr<className> object(new className()); \
if (resource == nullptr) { \
GALE_ERROR("Factory resource error"); \
return nullptr; \
} \
resource->init(std::forward<T>(all)... ); \
if (resource->resourceHasBeenCorectlyInit() == false) { \
GALE_CRITICAL("resource Is not correctly init : " << #className ); \
} \
getManager().localAdd(resource); \
return resource; \
}
#define DECLARE_RESOURCE_NAMED_FACTORY(className) \
template<typename ... T> static std::shared_ptr<className> create(const std::string& _name, T&& ... all ) { \
std::shared_ptr<className> resource; \
std::shared_ptr<gale::Resource> resource2; \
if (_name != "" && _name != "---") { \
resource2 = getManager().localKeep(_name); \
} \
if (resource2 != nullptr) { \
resource = std::dynamic_pointer_cast<className>(resource2); \
if (resource == nullptr) { \
GALE_CRITICAL("Request resource file : '" << _name << "' With the wrong type (dynamic cast error)"); \
return nullptr; \
} \
} \
if (resource != nullptr) { \
return resource; \
} \
resource = std::shared_ptr<className>(new className()); \
if (resource == nullptr) { \
GALE_ERROR("allocation error of a resource : " << _name); \
return nullptr; \
} \
resource->init(_name, std::forward<T>(all)... ); \
if (resource->resourceHasBeenCorectlyInit() == false) { \
GALE_CRITICAL("resource Is not correctly init : " << #className ); \
} \
getManager().localAdd(resource); \
return resource; \
}
#define DECLARE_RESOURCE_SINGLE_FACTORY(className,uniqueName) \
template<typename ... T> static std::shared_ptr<className> create(T&& ... all ) { \
std::shared_ptr<className> resource; \
std::shared_ptr<gale::Resource> resource2 = getManager().localKeep(uniqueName); \
if (resource2 != nullptr) { \
resource = std::dynamic_pointer_cast<className>(resource2); \
if (resource == nullptr) { \
GALE_CRITICAL("Request resource file : '" << uniqueName << "' With the wrong type (dynamic cast error)"); \
return nullptr; \
} \
} \
if (resource != nullptr) { \
return resource; \
} \
resource = std::shared_ptr<className>(new className()); \
if (resource == nullptr) { \
GALE_ERROR("allocation error of a resource : " << uniqueName); \
return nullptr; \
} \
resource->init(uniqueName, std::forward<T>(all)... ); \
if (resource->resourceHasBeenCorectlyInit() == false) { \
GALE_CRITICAL("resource Is not correctly init : " << #className ); \
} \
getManager().localAdd(resource); \
return resource; \
}
namespace gale {
namespace resource {
class Manager;
};
/**
* @brief A Resource is a generic interface to have an instance that have things that can be used by many people, ad have some hardware dependency.
* For example of resources :
* :** Shaders: openGL display interface.
* :** Texture: openGL imega interface.
* :** Font: Single file interface to store many glyphe ==> reduce the number of parallele loaded files.
* :** ConfigFile: simple widget configuration files
* :** ...
*/
class Resource : public std::enable_shared_from_this<gale::Resource> {
private:
size_t m_id; //!< unique ID definition
bool m_resourceHasBeenInit; //!< Know if the init function has bben called
protected:
/**
* @brief generic protected contructor (use factory to create this class)
*/
Resource();
/**
* @brief Initialisation of the class and previous classes.
* @param[in] _name Name of the resource.
*/
void init();
//! @previous
void init(const std::string& _name);
public:
//! geenric destructor
virtual ~Resource() {
};
bool resourceHasBeenCorectlyInit() {
return m_resourceHasBeenInit;
}
protected:
std::string m_name; //!< name of the resource ...
public:
/**
* @brief get the resource name
* @return The requested name
*/
const std::string& getName() const {
return m_name;
};
/**
* @brief get the resource name
* @param[in] _name The new name
*/
void setName(const std::string& _name) {
m_name = _name;
};
protected:
uint8_t m_resourceLevel; //!< Level of the resource ==> for update priority [0..5] 0 must be update first.
public:
/**
* @brief Get the current resource level;
* @return value in [0..5]
*/
uint8_t getResourceLevel() {
return m_resourceLevel;
};
/**
* @brief Call when need to send data on the harware (openGL)
* @note This is done asynchronously with the create of the Resource.
*/
virtual void updateContext();
/**
* @brief The current OpenGl context is removing ==> remove yout own system data
*/
virtual void removeContext();
/**
* @brief The notification of the Context removing is too late, we have no more acces on the OpenGl context (thank you Android).
* Juste update your internal state
*/
virtual void removeContextToLate();
/**
* @brief User request the reload of all resources (usefull when the file depend on DATA:GUI:xxx ...
*/
virtual void reload();
protected:
/**
* @brief Get the current resource Manager
*/
static gale::resource::Manager& getManager();
};
};
#include <gale/resource/Manager.h>
#endif

158
gale/resource/Shader.cpp Normal file
View File

@ -0,0 +1,158 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#include <etk/types.h>
#include <etk/os/FSNode.h>
#include <gale/debug.h>
#include <gale/resource/Shader.h>
#include <gale/resource/Manager.h>
#undef __class__
#define __class__ "resource::Shader"
gale::resource::Shader::Shader() :
gale::Resource(),
m_exist(false),
m_fileData(nullptr),
m_shader(0),
m_type(0) {
addResourceType("gale::Shader");
m_resourceLevel = 0;
}
void gale::resource::Shader::init(const std::string& _filename) {
gale::Resource::init(_filename);
GALE_DEBUG("OGL : load SHADER \"" << _filename << "\"");
// load data from file "all the time ..."
if (etk::end_with(m_name, ".frag") == true) {
m_type = GL_FRAGMENT_SHADER;
} else if (etk::end_with(m_name, ".vert") == true) {
m_type = GL_VERTEX_SHADER;
} else {
GALE_ERROR("File does not have extention \".vert\" for Vertex Shader or \".frag\" for Fragment Shader. but : \"" << m_name << "\"");
return;
}
reload();
}
gale::resource::Shader::~Shader() {
if (nullptr != m_fileData) {
delete [] m_fileData;
m_fileData = nullptr;
}
if (0!=m_shader) {
glDeleteShader(m_shader);
m_shader = 0;
}
m_exist = false;
}
static void checkGlError(const char* _op) {
for (GLint error = glGetError(); error; error = glGetError()) {
GALE_ERROR("after " << _op << "() glError (" << error << ")");
}
}
#define LOG_OGL_INTERNAL_BUFFER_LEN (8192)
static char l_bufferDisplayError[LOG_OGL_INTERNAL_BUFFER_LEN] = "";
void gale::resource::Shader::updateContext() {
if (true == m_exist) {
// Do nothing == > too dangerous ...
} else {
// create the Shader
if (nullptr == m_fileData) {
m_shader = 0;
return;
}
GALE_INFO("Create Shader : '" << m_name << "'");
m_shader = glCreateShader(m_type);
if (!m_shader) {
GALE_ERROR("glCreateShader return error ...");
checkGlError("glCreateShader");
GALE_CRITICAL(" can not load shader");
return;
} else {
GALE_INFO("Compile shader with GLID=" << m_shader);
glShaderSource(m_shader, 1, (const char**)&m_fileData, nullptr);
glCompileShader(m_shader);
GLint compiled = 0;
glGetShaderiv(m_shader, GL_COMPILE_STATUS, &compiled);
if (!compiled) {
GLint infoLen = 0;
l_bufferDisplayError[0] = '\0';
glGetShaderInfoLog(m_shader, LOG_OGL_INTERNAL_BUFFER_LEN, &infoLen, l_bufferDisplayError);
const char * tmpShaderType = "GL_FRAGMENT_SHADER";
if (m_type == GL_VERTEX_SHADER){
tmpShaderType = "GL_VERTEX_SHADER";
}
GALE_ERROR("Could not compile \"" << tmpShaderType << "\" name='" << m_name << "'");
GALE_ERROR("Error " << l_bufferDisplayError);
std::vector<std::string> lines = etk::split(m_fileData, '\n');
for (size_t iii=0 ; iii<lines.size() ; iii++) {
GALE_ERROR("file " << (iii+1) << "|" << lines[iii]);
}
GALE_CRITICAL(" can not load shader");
return;
}
}
m_exist = true;
}
}
void gale::resource::Shader::removeContext() {
if (true == m_exist) {
glDeleteShader(m_shader);
m_exist = false;
m_shader = 0;
}
}
void gale::resource::Shader::removeContextToLate() {
m_exist = false;
m_shader = 0;
}
void gale::resource::Shader::reload() {
etk::FSNode file(m_name);
if (false == file.exist()) {
GALE_CRITICAL("File does not Exist : '" << file << "' : '" << file.getFileSystemName() << "'");
return;
}
int64_t fileSize = file.fileSize();
if (0 == fileSize) {
GALE_CRITICAL("This file is empty : " << file);
return;
}
if (false == file.fileOpenRead()) {
GALE_CRITICAL("Can not open the file : " << file);
return;
}
// remove previous data ...
if (nullptr != m_fileData) {
delete[] m_fileData;
m_fileData = 0;
}
// allocate data
m_fileData = new char[fileSize+5];
if (nullptr == m_fileData) {
GALE_CRITICAL("Error Memory allocation size=" << fileSize);
return;
}
memset(m_fileData, 0, (fileSize+5)*sizeof(char));
// load data from the file :
file.fileRead(m_fileData, 1, fileSize);
// close the file:
file.fileClose();
// now change the OGL context ...
removeContext();
updateContext();
}

78
gale/resource/Shader.h Normal file
View File

@ -0,0 +1,78 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#ifndef __OPEN_GL__SHADER_H__
#define __OPEN_GL__SHADER_H__
#include <etk/types.h>
#include <gale/debug.h>
#include <gale/openGL/openGL.h>
#include <gale/resource/Resource.h>
namespace gale {
namespace resource {
/**
* @brief Shader is a specific resources for opengl, used only in @ref Program. This are components of the renderer pipe-line
*/
class Shader : public gale::Resource {
private :
bool m_exist; //!< The shader file existed and has been loaded
char* m_fileData; //!< A copy of the data loaded from the file (usefull only when opengl context is removed)
GLuint m_shader; //!< opengl id of this element
GLenum m_type; //!< Type of the current shader(vertex/fragment)
protected:
/**
* @brief Contructor of an opengl Shader
* @param[in] filename Standard file name format. see @ref etk::FSNode
*/
Shader();
public:
void init(const std::string& _filename);
DECLARE_RESOURCE_NAMED_FACTORY(Shader);
/**
* @brief Destructor, remove the current Shader
*/
virtual ~Shader();
public:
/**
* @brief get the opengl reference id of this shader.
* @return The opengl id.
*/
GLuint getGL_ID() {
return m_shader;
};
/**
* @brief get the opengl type of this shader.
* @return The type of this loaded shader.
*/
GLenum getShaderType() {
return m_type;
};
/**
* @brief This load/reload the data in the opengl context, needed when removed previously.
*/
void updateContext();
/**
* @brief remove the data from the opengl context.
*/
void removeContext();
/**
* @brief Special android spec! It inform us that all context is removed and after notify us...
*/
void removeContextToLate();
/**
* @brief Relode the shader from the file. used when a request of resouces reload is done.
* @note this is really usefull when we tested the new themes or shader developpements.
*/
void reload();
};
};
};
#endif

107
gale/resource/Texture.cpp Normal file
View File

@ -0,0 +1,107 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#include <etk/types.h>
#include <gale/gale.h>
#include <gale/openGL/openGL.h>
#include <gale/resource/Manager.h>
#include <gale/resource/Texture.h>
#undef __class__
#define __class__ "resource::Texture"
/**
* @brief get the next power 2 if the input
* @param[in] value Value that we want the next power of 2
* @return result value
*/
static int32_t nextP2(int32_t _value) {
int32_t val=1;
for (int32_t iii=1; iii<31; iii++) {
if (_value <= val) {
return val;
}
val *=2;
}
GALE_CRITICAL("impossible CASE....");
return val;
}
void gale::resource::Texture::init(const std::string& _filename) {
gale::Resource::init(_filename);
}
void gale::resource::Texture::init() {
gale::Resource::init();
}
gale::resource::Texture::Texture() {
addResourceType("gale::compositing::Texture");
m_loaded = false;
m_texId = 0;
m_endPointSize.setValue(1.0,1.0);
}
gale::resource::Texture::~Texture() {
removeContext();
}
void gale::resource::Texture::updateContext() {
if (false == m_loaded) {
// Request a new texture at openGl :
glGenTextures(1, &m_texId);
}
// in all case we set the texture properties :
// TODO : check error ???
glBindTexture(GL_TEXTURE_2D, m_texId);
// TODO : Check error ???
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
//--- mode nearest
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
//--- Mode linear
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
GALE_INFO("TEXTURE: add [" << getId() << "]=" << m_data.getSize() << " OGl_Id=" <<m_texId);
glTexImage2D(GL_TEXTURE_2D, // Target
0, // Level
GL_RGBA, // Format internal
m_data.getWidth(),
m_data.getHeight(),
0, // Border
GL_RGBA, // format
GL_UNSIGNED_BYTE, // type
m_data.getTextureDataPointer() );
// now the data is loaded
m_loaded = true;
}
void gale::resource::Texture::removeContext() {
if (true == m_loaded) {
// Request remove texture ...
GALE_INFO("TEXTURE: Rm [" << getId() << "] texId=" << m_texId);
glDeleteTextures(1, &m_texId);
m_loaded = false;
}
}
void gale::resource::Texture::removeContextToLate() {
m_loaded = false;
m_texId=0;
}
void gale::resource::Texture::flush() {
// request to the manager to be call at the next update ...
getManager().update(std::dynamic_pointer_cast<gale::Resource>(shared_from_this()));
}
void gale::resource::Texture::setImageSize(ivec2 _newSize) {
_newSize.setValue( nextP2(_newSize.x()), nextP2(_newSize.y()) );
m_data.resize(_newSize);
}

68
gale/resource/Texture.h Normal file
View File

@ -0,0 +1,68 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#ifndef __GALE_TEXTURE_H__
#define __GALE_TEXTURE_H__
#include <etk/types.h>
#include <gale/debug.h>
#include <egami/Image.h>
#include <gale/openGL/openGL.h>
#include <gale/resource/Resource.h>
namespace gale {
namespace resource {
class Texture : public gale::Resource {
protected:
// openGl Context propoerties :
egami::Image m_data;
// openGl textureID :
GLuint m_texId;
// some image are not square == > we need to sqared it to prevent some openGl api error the the displayable size is not all the time 0.0 -> 1.0
vec2 m_endPointSize;
// internal state of the openGl system :
bool m_loaded;
// Gale internal API:
public:
void updateContext();
void removeContext();
void removeContextToLate();
// middleware interface:
public:
GLuint getId() const {
return m_texId;
};
const vec2& getUsableSize() const {
return m_endPointSize;
};
const ivec2& getOpenGlSize() const {
return m_data.getSize();
};
// Public API:
protected:
void init(const std::string& _filename);
void init();
Texture();
public:
DECLARE_RESOURCE_FACTORY(Texture);
virtual ~Texture();
public:
// you must set the size here, because it will be set in multiple of pow(2)
void setImageSize(ivec2 newSize);
// get the reference on this image to draw nomething on it ...
inline egami::Image& get() {
return m_data;
};
// flush the data to send it at the openGl system
void flush();
};
};
};
#endif

View File

@ -0,0 +1,183 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#include <etk/types.h>
#include <gale/debug.h>
#include <gale/resource/Manager.h>
#include <gale/resource/VirtualBufferObject.h>
#undef __class__
#define __class__ "resource::VirtualBufferObject"
void gale::resource::VirtualBufferObject::init(int32_t _number) {
gale::Resource::init();
m_vbo.resize(_number, 0);
m_vboUsed.resize(_number, false);
m_buffer.resize(_number);
m_vboSizeDataOffset.resize(_number, -1);
GALE_DEBUG("OGL : load VBO count=\"" << _number << "\"");
}
gale::resource::VirtualBufferObject::VirtualBufferObject() :
m_exist(false) {
addResourceType("gale::VirtualBufferObject");
m_resourceLevel = 3;
}
gale::resource::VirtualBufferObject::~VirtualBufferObject() {
removeContext();
}
void gale::resource::VirtualBufferObject::retreiveData() {
GALE_ERROR("TODO ... ");
}
void gale::resource::VirtualBufferObject::updateContext() {
if (false == m_exist) {
// Allocate and assign a Vertex Array Object to our handle
gale::openGL::genBuffers(m_vbo);
}
m_exist = true;
for (size_t iii=0; iii<m_vbo.size(); iii++) {
GALE_INFO("VBO : add [" << getId() << "]=" << m_buffer[iii].size() << "*sizeof(float) OGl_Id=" << m_vbo[iii]);
if (true == m_vboUsed[iii]) {
// select the buffer to set data inside it ...
if (m_buffer[iii].size()>0) {
gale::openGL::bindBuffer(m_vbo[iii]);
gale::openGL::bufferData(sizeof(float)*m_buffer[iii].size(), &((m_buffer[iii])[0]), GL_STATIC_DRAW);
}
}
}
// un-bind it to permet to have no erreor in the next display ...
gale::openGL::unbindBuffer();
}
void gale::resource::VirtualBufferObject::removeContext() {
if (true == m_exist) {
gale::openGL::deleteBuffers(m_vbo);
m_exist = false;
}
}
void gale::resource::VirtualBufferObject::removeContextToLate() {
m_exist = false;
for (size_t iii=0; iii<m_vbo.size(); iii++) {
m_vbo[iii] = 0;
}
}
void gale::resource::VirtualBufferObject::reload() {
removeContext();
updateContext();
}
void gale::resource::VirtualBufferObject::flush() {
// request to the manager to be call at the next update ...
getManager().update(std::dynamic_pointer_cast<gale::Resource>(shared_from_this()));
}
void gale::resource::VirtualBufferObject::pushOnBuffer(int32_t _id, const vec3& _data) {
if (m_vboSizeDataOffset[_id] == -1) {
m_vboSizeDataOffset[_id] = 3;
} else if (m_vboSizeDataOffset[_id] != 3) {
GALE_WARNING("set multiType in VBO (Not supported ==> TODO : Maybe update it");
return;
}
m_vboUsed[_id] = true;
m_buffer[_id].push_back(_data.x());
m_buffer[_id].push_back(_data.y());
m_buffer[_id].push_back(_data.z());
}
vec3 gale::resource::VirtualBufferObject::getOnBufferVec3(int32_t _id, int32_t _elementID) {
if ((size_t)_elementID*3 > m_buffer[_id].size()) {
return vec3(0,0,0);
}
return vec3(m_buffer[_id][3*_elementID],
m_buffer[_id][3*_elementID+1],
m_buffer[_id][3*_elementID+2]);
}
int32_t gale::resource::VirtualBufferObject::bufferSize(int32_t _id) {
return m_buffer[_id].size()/m_vboSizeDataOffset[_id];
}
int32_t gale::resource::VirtualBufferObject::getElementSize(int32_t _id) {
return m_vboSizeDataOffset[_id];
}
void gale::resource::VirtualBufferObject::pushOnBuffer(int32_t _id, const vec2& _data) {
if (m_vboSizeDataOffset[_id] == -1) {
m_vboSizeDataOffset[_id] = 2;
} else if (m_vboSizeDataOffset[_id] != 2) {
GALE_WARNING("set multiType in VBO (Not supported ==> TODO : Maybe update it");
return;
}
m_vboUsed[_id] = true;
m_buffer[_id].push_back(_data.x());
m_buffer[_id].push_back(_data.y());
}
vec2 gale::resource::VirtualBufferObject::getOnBufferVec2(int32_t _id, int32_t _elementID) {
if ((size_t)_elementID*2 > m_buffer[_id].size()) {
return vec2(0,0);
}
return vec2(m_buffer[_id][2*_elementID],
m_buffer[_id][2*_elementID+1]);
}
void gale::resource::VirtualBufferObject::pushOnBuffer(int32_t _id, const etk::Color<float,4>& _data) {
if (m_vboSizeDataOffset[_id] == -1) {
m_vboSizeDataOffset[_id] = 4;
} else if (m_vboSizeDataOffset[_id] != 4) {
GALE_WARNING("set multiType in VBO (Not supported ==> TODO : Maybe update it");
return;
}
m_vboUsed[_id] = true;
m_buffer[_id].push_back(_data.r());
m_buffer[_id].push_back(_data.g());
m_buffer[_id].push_back(_data.b());
m_buffer[_id].push_back(_data.a());
}
void gale::resource::VirtualBufferObject::pushOnBuffer(int32_t _id, const etk::Color<float,3>& _data) {
if (m_vboSizeDataOffset[_id] == -1) {
m_vboSizeDataOffset[_id] = 3;
} else if (m_vboSizeDataOffset[_id] != 3) {
GALE_WARNING("set multiType in VBO (Not supported ==> TODO : Maybe update it");
return;
}
m_vboUsed[_id] = true;
m_buffer[_id].push_back(_data.r());
m_buffer[_id].push_back(_data.g());
m_buffer[_id].push_back(_data.b());
}
void gale::resource::VirtualBufferObject::pushOnBuffer(int32_t _id, const etk::Color<float,2>& _data) {
if (m_vboSizeDataOffset[_id] == -1) {
m_vboSizeDataOffset[_id] = 2;
} else if (m_vboSizeDataOffset[_id] != 2) {
GALE_WARNING("set multiType in VBO (Not supported ==> TODO : Maybe update it");
return;
}
m_vboUsed[_id] = true;
m_buffer[_id].push_back(_data.r());
m_buffer[_id].push_back(_data.g());
}
void gale::resource::VirtualBufferObject::pushOnBuffer(int32_t _id, const etk::Color<float,1>& _data) {
if (m_vboSizeDataOffset[_id] == -1) {
m_vboSizeDataOffset[_id] = 1;
} else if (m_vboSizeDataOffset[_id] != 1) {
GALE_WARNING("set multiType in VBO (Not supported ==> TODO : Maybe update it");
return;
}
m_vboUsed[_id] = true;
m_buffer[_id].push_back(_data.r());
}

View File

@ -0,0 +1,128 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#ifndef __OPEN_GL__VIRTUAL_BUFFER_OBJECT_H__
#define __OPEN_GL__VIRTUAL_BUFFER_OBJECT_H__
#include <etk/types.h>
#include <etk/math/Vector2D.h>
#include <gale/debug.h>
#include <gale/resource/Resource.h>
#include <gale/openGL/openGL.h>
#include <etk/Color.h>
namespace gale {
namespace resource {
/**
* @brief VirtualBufferObject is a specific resources for opengl, this load the data directly in the graphic card ad keep these inside
*/
class VirtualBufferObject : public gale::Resource {
private :
bool m_exist; //!< This data is availlable in the Graphic card
std::vector<GLuint> m_vbo; //!< openGl ID of this VBO
std::vector<bool> m_vboUsed; //!< true if the VBO is allocated or used ...
std::vector<std::vector<float>> m_buffer; //!< data that is availlable in the VBO system ...
std::vector<int8_t> m_vboSizeDataOffset; //!< Internal size of the VBO (dynamicly set)
protected:
/**
* @brief Constructor of this VBO.
* @param[in] accesMode Acces mode : ???
*/
VirtualBufferObject();
void init(int32_t _number);
public:
DECLARE_RESOURCE_FACTORY(VirtualBufferObject);
/**
* @brief Destructor of this VBO.
*/
virtual ~VirtualBufferObject();
public:
/**
* @brief get the real openGL ID.
* @return the Ogl id reference of this VBO.
*/
GLuint getGL_ID(int32_t _id) {
return m_vbo[_id];
};
/**
* @brief get a reference on hte buffer data for this VBO.
* @param[in] id Id of the buffer requested
* @return A reference on the data.
*/
std::vector<float>& getRefBuffer(int32_t _id) {
m_vboUsed[_id] = true;
return m_buffer[_id];
};
/**
* @brief Get the buffer Number of element.
* @param[in] _id VBO Element
* @return Number of Float in the buffer.
*/
int32_t bufferSize(int32_t _id);
/**
* @brief Get the offset between element.
* @param[in] _id VBO Element
* @return Number of Float to jump between target.
*/
int32_t getElementSize(int32_t _id);
/**
* @brief push data on a buffer with a custum type :
* @param[in] _id Id of the buffer requested.
* @param[in] _data Direct data that might be set.
*/
void pushOnBuffer(int32_t _id, const vec3& _data);
vec3 getOnBufferVec3(int32_t _id, int32_t _elementID);
/**
* @brief push data on a buffer with a custum type :
* @param[in] _id Id of the buffer requested.
* @param[in] _data Direct data that might be set.
*/
void pushOnBuffer(int32_t _id, const vec2& _data);
vec2 getOnBufferVec2(int32_t _id, int32_t _elementID);
/**
* @brief push data on a buffer with a custum type :
* @param[in] _id Id of the buffer requested.
* @param[in] _data Direct data that might be set (Color).
*/
void pushOnBuffer(int32_t _id, const etk::Color<float,4>& _data);
//! @previous
void pushOnBuffer(int32_t _id, const etk::Color<float,3>& _data);
//! @previous
void pushOnBuffer(int32_t _id, const etk::Color<float,2>& _data);
//! @previous
void pushOnBuffer(int32_t _id, const etk::Color<float,1>& _data);
/**
* @brief get the data from the graphic card.
*/
void retreiveData();
/**
* @brief Send the data to the graphic card.
*/
void flush();
/**
* @brief This load/reload the data in the opengl context, needed when removed previously.
*/
void updateContext();
/**
* @brief remove the data from the opengl context.
*/
void removeContext();
/**
* @brief Special android spec! It inform us that all context is removed and after notify us...
*/
void removeContextToLate();
/**
* @brief Relode the shader from the file. used when a request of resouces reload is done.
* @note this is really usefull when we tested the new themes or shader developpements.
*/
void reload();
};
};
};
#endif

13
license.txt Normal file
View File

@ -0,0 +1,13 @@
Copyright gale Edouard DUPIN
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.

619
lutin_gale.py Normal file
View File

@ -0,0 +1,619 @@
#!/usr/bin/python
import lutin.module as module
import lutin.tools as tools
import lutin.debug as debug
import os
import lutin.multiprocess as lutinMultiprocess
def get_desc():
return "gale is a main library to use widget in the openGl environement and manage all the wraping os"
def get_license():
return "APACHE v2.0"
def create(target):
# module name is 'edn' and type binary.
myModule = module.Module(__file__, 'gale', 'LIBRARY')
# add extra compilation flags :
myModule.add_extra_compile_flags()
# add the file to compile:
myModule.add_src_file([
'gale/gale.cpp',
'gale/debug.cpp',
'gale/Dimension.cpp'
])
# context :
myModule.add_src_file([
'gale/context/clipBoard.cpp',
'gale/context/commandLine.cpp',
'gale/context/Context.cpp',
'gale/context/cursor.cpp',
'gale/context/InputManager.cpp'
])
if target.name=="Linux":
myModule.add_src_file('gale/context/X11/Context.cpp')
elif target.name=="Windows":
myModule.add_src_file('gale/context/Windows/Context.cpp')
elif target.name=="Android":
myModule.add_src_file('gale/context/Android/Context.cpp')
myModule.add_src_file([
'android/src/org/gale/GaleCallback.java',
'android/src/org/gale/GaleConstants.java',
'android/src/org/gale/Gale.java',
'android/src/org/gale/GaleRendererGL.java',
'android/src/org/gale/GaleSurfaceViewGL.java',
'android/src/org/gale/GaleActivity.java',
'android/src/org/gale/GaleWallpaper.java',
'org.gale.GaleConstants.javah'
])
myModule.add_path(tools.get_current_path(__file__) + '/android/src/', type='java')
elif target.name=="MacOs":
myModule.add_src_file([
'gale/context/MacOs/Context.mm',
'gale/context/MacOs/Interface.mm',
'gale/context/MacOs/Windows.mm',
'gale/context/MacOs/OpenglView.mm',
'gale/context/MacOs/AppDelegate.mm'])
elif target.name=="IOs":
myModule.add_src_file([
'gale/context/IOs/Context.cpp',
'gale/context/IOs/Interface.m',
'gale/context/IOs/OpenglView.mm',
'gale/context/IOs/AppDelegate.mm'])
else:
debug.error("unknow mode...")
# event properties :
myModule.add_src_file([
'gale/event/Entry.cpp',
'gale/event/Time.cpp',
'gale/event/Input.cpp'
])
# Key properties :
myModule.add_src_file([
'gale/key/keyboard.cpp',
'gale/key/Special.cpp',
'gale/key/status.cpp',
'gale/key/type.cpp'
])
# OpenGL interface :
myModule.add_src_file([
'gale/renderer/openGL/openGL.cpp'
])
# resources :
myModule.add_src_file([
'gale/resource/Manager.cpp',
'gale/resource/Program.cpp',
'gale/resource/Resource.cpp',
'gale/resource/Shader.cpp',
'gale/resource/Texture.cpp'
])
# name of the dependency
myModule.add_module_depend(['etk', 'date'])
myModule.add_export_path(tools.get_current_path(__file__))
tagFile = tools.get_current_path(__file__) + "/tag"
galeVersionID = tools.file_read_data(tagFile)
myModule.compile_flags('c++', [
"-DGALE_VERSION=\"\\\""+galeVersionID+"\\\"\""
])
if target.name=="Linux":
myModule.add_export_flag('link', '-lGL')
#`pkg-config --cflags directfb` `pkg-config --libs directfb`
#ifeq ("$(CONFIG___GALE_LINUX_GUI_MODE_X11__)","y")
myModule.add_export_flag('link', '-lX11')
#endif
#ifeq ("$(CONFIG___GALE_LINUX_GUI_MODE_DIRECT_FB__)","y")
#myModule.add_export_flag('link', ['-L/usr/local/lib', '-ldirectfb', '-lfusion', '-ldirect'])
#endif
elif target.name=="Android":
myModule.add_module_depend(["SDK", "jvm-basics"])
myModule.add_export_flag('link', "-lGLESv2")
# add tre creator of the basic java class ...
target.add_action("PACKAGE", 50, "gale-auto-wrapper", tool_generate_main_java_class)
# TODO : Add the same for BINARY to create a console interface ?
elif target.name=="Windows":
myModule.add_module_depend("glew")
elif target.name=="MacOs":
myModule.add_export_flag('link', [
"-framework Cocoa",
"-framework OpenGL",
"-framework QuartzCore",
"-framework AppKit"])
elif target.name=="IOs":
myModule.add_export_flag('link', [
"-framework OpenGLES",
"-framework CoreGraphics",
"-framework UIKit",
"-framework GLKit",
"-framework Foundation",
"-framework QuartzCore"])
return myModule
##################################################################
##
## Android specific section
##
##################################################################
def tool_generate_main_java_class(target, module, package_name):
file_list = []
debug.debug("------------------------------------------------------------------------")
debug.debug("Generate android wrapping for '" + package_name + "'")
debug.debug("------------------------------------------------------------------------")
application_name = package_name
if target.config["mode"] == "debug":
application_name += "debug"
target.folder_java_project= target.get_build_folder(package_name) \
+ "/src/" \
+ module.package_prop["COMPAGNY_TYPE"] \
+ "/" + module.package_prop["COMPAGNY_NAME2"] \
+ "/" + application_name + "/"
java_file_wrapper = target.folder_java_project + "/" + application_name + ".java"
android_package_name = module.package_prop["COMPAGNY_TYPE"]+"."+module.package_prop["COMPAGNY_NAME2"]+"." + application_name
debug.print_element("pkg", "absractionFile", "<==", "dynamic file")
# Create folder :
tools.create_directory_of_file(java_file_wrapper)
debug.debug("create file : '" + java_file_wrapper + "'")
# Create file :
tmpFile = open(java_file_wrapper + "_tmp", 'w')
tmpFile.write( "/**\n")
tmpFile.write( " * @author Edouard DUPIN, Kevin BILLONNEAU\n")
tmpFile.write( " * @copyright 2011, Edouard DUPIN, all right reserved\n")
tmpFile.write( " * @license APACHE v2.0 (see license file)\n")
tmpFile.write( " * @note This file is autogenerate ==> see documantation to generate your own\n")
tmpFile.write( " */\n")
tmpFile.write( "package "+ android_package_name + ";\n")
tmpFile.write( "import android.util.Log;\n")
if module.package_prop["ANDROID_APPL_TYPE"]=="APPL":
tmpFile.write( "import org.gale.GaleActivity;\n")
else:
tmpFile.write( "import org.gale.GaleWallpaper;\n")
tmpFile.write( "\n")
if "GENERATE_SECTION__IMPORT" in module.package_prop:
for elem in module.package_prop["GENERATE_SECTION__IMPORT"]:
for line in elem:
tmpFile.write( line + "\n")
if module.package_prop["ANDROID_APPL_TYPE"]=="APPL":
tmpFile.write( "public class " + application_name + " extends GaleActivity {\n")
else:
tmpFile.write( "public class " + application_name + " extends GaleWallpaper {\n")
tmpFile.write( " public static final String SHARED_PREFS_NAME = \"" + application_name + "settings\";\n")
if "GENERATE_SECTION__DECLARE" in module.package_prop:
for elem in module.package_prop["GENERATE_SECTION__DECLARE"]:
for line in elem:
tmpFile.write( " " + line + "\n")
tmpFile.write( " \n")
tmpFile.write( " static {\n")
tmpFile.write( " try {\n")
tmpFile.write( " System.loadLibrary(\"" + package_name + "\");\n")
tmpFile.write( " } catch (UnsatisfiedLinkError e) {\n")
tmpFile.write( " Log.e(\"" + application_name + "\", \"error getting lib(): \" + e);\n")
tmpFile.write( " }\n")
tmpFile.write( " }\n")
tmpFile.write( " \n")
if module.package_prop["ANDROID_APPL_TYPE"]!="APPL":
tmpFile.write( " public Engine onCreateEngine() {\n")
tmpFile.write( " Engine tmpEngine = super.onCreateEngine();\n")
tmpFile.write( " initApkPath(\"" + module.package_prop["COMPAGNY_TYPE"]+"\", \""+module.package_prop["COMPAGNY_NAME2"]+"\", \"" + application_name + "\");\n")
tmpFile.write( " return tmpEngine;\n")
tmpFile.write( " }\n")
if "GENERATE_SECTION__CONSTRUCTOR" in module.package_prop:
tmpFile.write( " public " + application_name + "() {\n")
for elem in module.package_prop["GENERATE_SECTION__CONSTRUCTOR"]:
for line in elem:
tmpFile.write( " " + line + "\n")
tmpFile.write( " }\n")
tmpFile.write( " public void onCreate(android.os.Bundle savedInstanceState) {\n")
tmpFile.write( " super.onCreate(savedInstanceState);\n")
tmpFile.write( " initApkPath(\"" + module.package_prop["COMPAGNY_TYPE"]+"\", \""+module.package_prop["COMPAGNY_NAME2"]+"\", \"" + application_name + "\");\n")
if "GENERATE_SECTION__ON_CREATE" in module.package_prop:
for elem in module.package_prop["GENERATE_SECTION__ON_CREATE"]:
for line in elem:
tmpFile.write( " " + line + "\n")
tmpFile.write( " }\n")
if "GENERATE_SECTION__ON_START" in module.package_prop:
tmpFile.write( " @Override protected void onStart() {\n")
for elem in module.package_prop["GENERATE_SECTION__ON_START"]:
for line in elem:
tmpFile.write( " " + line + "\n")
tmpFile.write( " super.onStart();\n")
tmpFile.write( " }\n")
if "GENERATE_SECTION__ON_RESTART" in module.package_prop:
tmpFile.write( " @Override protected void onRestart() {\n")
for elem in module.package_prop["GENERATE_SECTION__ON_RESTART"]:
for line in elem:
tmpFile.write( " " + line + "\n")
tmpFile.write( " super.onRestart();\n")
tmpFile.write( " }\n")
if "GENERATE_SECTION__ON_RESUME" in module.package_prop:
tmpFile.write( " @Override protected void onResume() {\n")
tmpFile.write( " super.onResume();\n")
for elem in module.package_prop["GENERATE_SECTION__ON_RESUME"]:
for line in elem:
tmpFile.write( " " + line + "\n")
tmpFile.write( " }\n")
if "GENERATE_SECTION__ON_PAUSE" in module.package_prop:
tmpFile.write( " @Override protected void onPause() {\n")
for elem in module.package_prop["GENERATE_SECTION__ON_PAUSE"]:
for line in elem:
tmpFile.write( " " + line + "\n")
tmpFile.write( " super.onPause();\n")
tmpFile.write( " }\n")
if "GENERATE_SECTION__ON_STOP" in module.package_prop:
tmpFile.write( " @Override protected void onStop() {\n")
for elem in module.package_prop["GENERATE_SECTION__ON_STOP"]:
for line in elem:
tmpFile.write( " " + line + "\n")
tmpFile.write( " super.onStop();\n")
tmpFile.write( " }\n")
if "GENERATE_SECTION__ON_DESTROY" in module.package_prop:
tmpFile.write( " @Override protected void onDestroy() {\n")
for elem in module.package_prop["GENERATE_SECTION__ON_DESTROY"]:
for line in elem:
tmpFile.write( " " + line + "\n")
tmpFile.write( " super.onDestroy();\n")
tmpFile.write( " }\n")
tmpFile.write( "}\n")
tmpFile.flush()
tmpFile.close()
tools.move_if_needed(java_file_wrapper + "_tmp", java_file_wrapper);
# add java file to build:
module.add_src_file([java_file_wrapper])
"""
## todo:
tools.create_directory_of_file(target.get_staging_folder(package_name) + "/res/drawable/icon.png");
if "ICON" in module.package_prop.keys() \
and module.package_prop["ICON"] != "":
image.resize(module.package_prop["ICON"], target.get_staging_folder(package_name) + "/res/drawable/icon.png", 256, 256)
else:
# to be sure that we have all time a resource ...
tmpFile = open(target.get_staging_folder(package_name) + "/res/drawable/plop.txt", 'w')
tmpFile.write('plop\n')
tmpFile.flush()
tmpFile.close()
"""
if module.package_prop["ANDROID_MANIFEST"] == "":
# force manifest file:
module.package_prop["ANDROID_MANIFEST"] = target.get_build_folder(package_name) + "/AndroidManifest.xml";
debug.debug(" create file: '" + module.package_prop["ANDROID_MANIFEST"] + "'")
if "VERSION_CODE" not in module.package_prop:
module.package_prop["VERSION_CODE"] = "1"
debug.print_element("pkg", "AndroidManifest.xml", "<==", "package configurations")
tools.create_directory_of_file(module.package_prop["ANDROID_MANIFEST"])
tmpFile = open(module.package_prop["ANDROID_MANIFEST"], 'w')
tmpFile.write( '<?xml version="1.0" encoding="utf-8"?>\n')
tmpFile.write( '<!-- Manifest is autoGenerated with Gale ... do not patch it-->\n')
tmpFile.write( '<manifest xmlns:android="http://schemas.android.com/apk/res/android" \n')
tmpFile.write( ' package="' + android_package_name + '" \n')
tmpFile.write( ' android:versionCode="'+module.package_prop["VERSION_CODE"]+'" \n')
tmpFile.write( ' android:versionName="'+module.package_prop["VERSION"]+'"> \n')
tmpFile.write( ' <uses-feature android:glEsVersion="0x00020000" android:required="true" />\n')
tmpFile.write( ' <uses-sdk android:minSdkVersion="' + str(target.boardId) + '" \n')
tmpFile.write( ' android:targetSdkVersion="' + str(target.boardId) + '" /> \n')
if module.package_prop["ANDROID_APPL_TYPE"]=="APPL":
tmpFile.write( ' <application android:label="' + application_name + '" \n')
if "ICON" in module.package_prop.keys():
tmpFile.write( ' android:icon="@drawable/icon" \n')
if target.config["mode"] == "debug":
tmpFile.write( ' android:debuggable="true" \n')
tmpFile.write( ' >\n')
if "ADMOD_ID" in module.package_prop:
tmpFile.write( ' <meta-data android:name="com.google.android.gms.version" \n')
tmpFile.write( ' android:value="@integer/google_play_services_version"/>\n')
tmpFile.write( ' <activity android:name=".' + application_name + '" \n')
tmpFile.write( ' android:label="' + module.package_prop['NAME'])
if target.config["mode"] == "debug":
tmpFile.write("-debug")
tmpFile.write( '"\n')
if "ICON" in module.package_prop.keys():
tmpFile.write( ' android:icon="@drawable/icon" \n')
tmpFile.write( ' android:hardwareAccelerated="true" \n')
tmpFile.write( ' android:configChanges="keyboard|keyboardHidden|orientation|screenSize"> \n')
tmpFile.write( ' <intent-filter> \n')
tmpFile.write( ' <action android:name="android.intent.action.MAIN" /> \n')
tmpFile.write( ' <category android:name="android.intent.category.LAUNCHER" /> \n')
tmpFile.write( ' </intent-filter> \n')
tmpFile.write( ' </activity> \n')
if "ADMOD_ID" in module.package_prop:
tmpFile.write( ' <activity android:name="com.google.android.gms.ads.AdActivity"\n')
tmpFile.write( ' android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize"/>\n')
tmpFile.write( ' </application>\n')
else:
tmpFile.write( ' <application android:label="' + application_name + '" \n')
tmpFile.write( ' android:permission="android.permission.BIND_WALLPAPER" \n')
if "ICON" in module.package_prop.keys():
tmpFile.write( ' android:icon="@drawable/icon"\n')
tmpFile.write( ' >\n')
tmpFile.write( ' <service android:name=".' + application_name + '" \n')
tmpFile.write( ' android:label="' + module.package_prop['NAME'])
if target.config["mode"] == "debug":
tmpFile.write("-debug")
tmpFile.write( '"\n')
if "ICON" in module.package_prop.keys():
tmpFile.write( ' android:icon="@drawable/icon"\n')
tmpFile.write( ' >\n')
tmpFile.write( ' <intent-filter>\n')
tmpFile.write( ' <action android:name="android.service.wallpaper.WallpaperService" />\n')
tmpFile.write( ' </intent-filter>\n')
tmpFile.write( ' <meta-data android:name="android.service.wallpaper"\n')
tmpFile.write( ' android:resource="@xml/' + application_name + '_resource" />\n')
tmpFile.write( ' </service>\n')
if len(module.package_prop["ANDROID_WALLPAPER_PROPERTIES"])!=0:
tmpFile.write( ' <activity android:label="Setting"\n')
tmpFile.write( ' android:name=".' + application_name + 'Settings"\n')
tmpFile.write( ' android:theme="@android:style/Theme.Light.WallpaperSettings"\n')
tmpFile.write( ' android:exported="true"\n')
if "ICON" in module.package_prop.keys():
tmpFile.write( ' android:icon="@drawable/icon"\n')
tmpFile.write( ' >\n')
tmpFile.write( ' </activity>\n')
tmpFile.write( ' </application>\n')
# write package autorisations :
if True==target.check_right_package(module.package_prop, "WRITE_EXTERNAL_STORAGE"):
tmpFile.write( ' <permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> \n')
tmpFile.write( ' <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> \n')
if True==target.check_right_package(module.package_prop, "CAMERA"):
tmpFile.write( ' <permission android:name="android.permission.CAMERA" /> \n')
tmpFile.write( ' <uses-permission android:name="android.permission.CAMERA" /> \n')
if True==target.check_right_package(module.package_prop, "INTERNET"):
tmpFile.write( ' <permission android:name="android.permission.INTERNET" /> \n')
tmpFile.write( ' <uses-permission android:name="android.permission.INTERNET" /> \n')
if True==target.check_right_package(module.package_prop, "ACCESS_NETWORK_STATE"):
tmpFile.write( ' <permission android:name="android.permission.ACCESS_NETWORK_STATE" /> \n')
tmpFile.write( ' <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> \n')
if True==target.check_right_package(module.package_prop, "MODIFY_AUDIO_SETTINGS"):
tmpFile.write( ' <permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" /> \n')
tmpFile.write( ' <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" /> \n')
if True==target.check_right_package(module.package_prop, "READ_CALENDAR"):
tmpFile.write( ' <permission android:name="android.permission.READ_CALENDAR" /> \n')
tmpFile.write( ' <uses-permission android:name="android.permission.READ_CALENDAR" /> \n')
if True==target.check_right_package(module.package_prop, "READ_CONTACTS"):
tmpFile.write( ' <permission android:name="android.permission.READ_CONTACTS" /> \n')
tmpFile.write( ' <uses-permission android:name="android.permission.READ_CONTACTS" /> \n')
if True==target.check_right_package(module.package_prop, "READ_FRAME_BUFFER"):
tmpFile.write( ' <permission android:name="android.permission.READ_FRAME_BUFFER" /> \n')
tmpFile.write( ' <uses-permission android:name="android.permission.READ_FRAME_BUFFER" /> \n')
if True==target.check_right_package(module.package_prop, "READ_PROFILE"):
tmpFile.write( ' <permission android:name="android.permission.READ_PROFILE" /> \n')
tmpFile.write( ' <uses-permission android:name="android.permission.READ_PROFILE" /> \n')
if True==target.check_right_package(module.package_prop, "RECORD_AUDIO"):
tmpFile.write( ' <permission android:name="android.permission.RECORD_AUDIO" /> \n')
tmpFile.write( ' <uses-permission android:name="android.permission.RECORD_AUDIO" /> \n')
if True==target.check_right_package(module.package_prop, "SET_ORIENTATION"):
tmpFile.write( ' <permission android:name="android.permission.SET_ORIENTATION" /> \n')
tmpFile.write( ' <uses-permission android:name="android.permission.SET_ORIENTATION" /> \n')
if True==target.check_right_package(module.package_prop, "VIBRATE"):
tmpFile.write( ' <permission android:name="android.permission.VIBRATE" /> \n')
tmpFile.write( ' <uses-permission android:name="android.permission.VIBRATE" /> \n')
if True==target.check_right_package(module.package_prop, "ACCESS_COARSE_LOCATION"):
tmpFile.write( ' <permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> \n')
tmpFile.write( ' <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> \n')
if True==target.check_right_package(module.package_prop, "ACCESS_FINE_LOCATION"):
tmpFile.write( ' <permission android:name="android.permission.ACCESS_FINE_LOCATION" /> \n')
tmpFile.write( ' <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> \n')
tmpFile.write( '</manifest>\n\n')
tmpFile.flush()
tmpFile.close()
# end generating android manifest
if module.package_prop["ANDROID_APPL_TYPE"]!="APPL":
#create the Wallpaper sub files : (main element for the application
debug.print_element("pkg", application_name + "_resource.xml", "<==", "package configurations")
tools.create_directory_of_file(target.get_build_folder(package_name) + "/res/xml/" + application_name + "_resource.xml")
tmpFile = open(target.get_build_folder(package_name) + "/res/xml/" + application_name + "_resource.xml", 'w')
tmpFile.write( "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n")
tmpFile.write( "<wallpaper xmlns:android=\"http://schemas.android.com/apk/res/android\"\n")
if len(module.package_prop["ANDROID_WALLPAPER_PROPERTIES"])!=0:
tmpFile.write( " android:settingsActivity=\""+android_package_name + "."+ application_name + "Settings\"\n")
if "ICON" in module.package_prop.keys():
tmpFile.write( " android:thumbnail=\"@drawable/icon\"\n")
tmpFile.write( " />\n")
tmpFile.flush()
tmpFile.close()
# create wallpaper setting if needed (class and config file)
if len(module.package_prop["ANDROID_WALLPAPER_PROPERTIES"])!=0:
tools.create_directory_of_file(target.folder_java_project + application_name + "Settings.java")
debug.print_element("pkg", target.folder_java_project + application_name + "Settings.java", "<==", "package configurations")
tmpFile = open(target.folder_java_project + application_name + "Settings.java", 'w');
tmpFile.write( "package " + android_package_name + ";\n")
tmpFile.write( "\n")
tmpFile.write( "import " + android_package_name + ".R;\n")
tmpFile.write( "\n")
tmpFile.write( "import android.content.SharedPreferences;\n")
tmpFile.write( "import android.os.Bundle;\n")
tmpFile.write( "import android.preference.PreferenceActivity;\n")
tmpFile.write( "\n")
tmpFile.write( "public class " + application_name + "Settings extends PreferenceActivity implements SharedPreferences.OnSharedPreferenceChangeListener\n")
tmpFile.write( "{\n")
tmpFile.write( " @Override protected void onCreate(Bundle icicle) {\n")
tmpFile.write( " super.onCreate(icicle);\n")
tmpFile.write( " getPreferenceManager().setSharedPreferencesName("+ application_name + ".SHARED_PREFS_NAME);\n")
tmpFile.write( " addPreferencesFromResource(R.xml."+ application_name + "_settings);\n")
tmpFile.write( " getPreferenceManager().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);\n")
tmpFile.write( " }\n")
tmpFile.write( " @Override protected void onResume() {\n")
tmpFile.write( " super.onResume();\n")
tmpFile.write( " }\n")
tmpFile.write( " @Override protected void onDestroy() {\n")
tmpFile.write( " getPreferenceManager().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);\n")
tmpFile.write( " super.onDestroy();\n")
tmpFile.write( " }\n")
tmpFile.write( " public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,String key) { }\n")
tmpFile.write( "}\n")
tmpFile.flush()
tmpFile.close()
debug.print_element("pkg", target.get_build_folder(package_name) + "/res/xml/" + application_name + "_settings.xml", "<==", "package configurations")
tools.create_directory_of_file(target.get_build_folder(package_name) + "/res/xml/" + application_name + "_settings.xml")
tmpFile = open(target.get_build_folder(package_name) + "/res/xml/" + application_name + "_settings.xml", 'w');
tmpFile.write( "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n")
tmpFile.write( "<PreferenceScreen xmlns:android=\"http://schemas.android.com/apk/res/android\"\n")
tmpFile.write( " android:title=\"Settings\"\n")
tmpFile.write( " android:key=\"" + application_name + "_settings\">\n")
WALL_haveArray = False
for WALL_type, WALL_key, WALL_title, WALL_summary, WALL_other in module.package_prop["ANDROID_WALLPAPER_PROPERTIES"]:
debug.info("find : '" + WALL_type + "'");
if WALL_type == "list":
debug.info(" create : LIST");
tmpFile.write( " <ListPreference android:key=\"" + application_name + "_" + WALL_key + "\"\n")
tmpFile.write( " android:title=\"" + WALL_title + "\"\n")
tmpFile.write( " android:summary=\"" + WALL_summary + "\"\n")
tmpFile.write( " android:entries=\"@array/" + application_name + "_" + WALL_key + "_names\"\n")
tmpFile.write( " android:entryValues=\"@array/" + application_name + "_" + WALL_key + "_prefix\"/>\n")
WALL_haveArray=True
elif WALL_type == "bool":
debug.info(" create : CHECKBOX");
tmpFile.write( " <CheckBoxPreference android:key=\"" + application_name + "_" + WALL_key + "\"\n")
tmpFile.write( " android:title=\"" + WALL_title + "\"\n")
tmpFile.write( " android:summary=\"" + WALL_summary + "\"\n")
tmpFile.write( " android:summaryOn=\"" + WALL_other[0] + "\"\n")
tmpFile.write( " android:summaryOff=\"" + WALL_other[1] + "\"/>\n")
tmpFile.write( "</PreferenceScreen>\n")
tmpFile.flush()
tmpFile.close()
if WALL_haveArray==True:
for WALL_type, WALL_key, WALL_title, WALL_summary, WALL_other in module.package_prop["ANDROID_WALLPAPER_PROPERTIES"]:
if WALL_type == "list":
debug.print_element("pkg", target.get_build_folder(package_name) + "/res/values/" + WALL_key + ".xml", "<==", "package configurations")
tools.create_directory_of_file(target.get_build_folder(package_name) + "/res/values/" + WALL_key + ".xml")
tmpFile = open(target.get_build_folder(package_name) + "/res/values/" + WALL_key + ".xml", 'w');
tmpFile.write( "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n")
tmpFile.write( "<resources xmlns:xliff=\"urn:oasis:names:tc:xliff:document:1.2\">\n")
tmpFile.write( " <string-array name=\"" + application_name + "_" + WALL_key + "_names\">\n")
for WALL_subKey, WALL_display in WALL_other:
tmpFile.write( " <item>" + WALL_display + "</item>\n")
tmpFile.write( " </string-array>\n")
tmpFile.write( " <string-array name=\"" + application_name + "_" + WALL_key + "_prefix\">\n")
for WALL_subKey, WALL_display in WALL_other:
tmpFile.write( " <item>" + WALL_subKey + "</item>\n")
tmpFile.write( " </string-array>\n")
tmpFile.write( "</resources>\n")
tmpFile.flush()
tmpFile.close()
"""
#add properties on wallpaper :
# myModule.pkg_add("ANDROID_WALLPAPER_PROPERTIES", ["list", key, title, summary, [["key","value display"],["key2","value display 2"]])
# myModule.pkg_add("ANDROID_WALLPAPER_PROPERTIES", ["list", "testpattern", "Select test pattern", "Choose which test pattern to display", [["key","value display"],["key2","value display 2"]]])
# myModule.pkg_add("ANDROID_WALLPAPER_PROPERTIES", ["bool", key, title, summary, ["enable string", "disable String"])
# myModule.pkg_add("ANDROID_WALLPAPER_PROPERTIES", ["bool", "movement", "Motion", "Apply movement to test pattern", ["Moving test pattern", "Still test pattern"]
#copy needed resources :
for res_source, res_dest in module.package_prop["ANDROID_RESOURCES"]:
if res_source == "":
continue
tools.copy_file(res_source , target.get_staging_folder(package_name) + "/res/" + res_dest + "/" + os.path.basename(res_source), force=True)
"""
"""
# Doc :
# http://asantoso.wordpress.com/2009/09/15/how-to-build-android-application-package-apk-from-the-command-line-using-the-sdk-tools-continuously-integrated-using-cruisecontrol/
debug.print_element("pkg", "R.java", "<==", "Resources files")
tools.create_directory_of_file(target.get_staging_folder(package_name) + "/src/noFile")
androidToolPath = target.folder_sdk + "/build-tools/"
# find android tool version
dirnames = tools.get_list_sub_folder(androidToolPath)
if len(dirnames) != 1:
debug.error("an error occured when getting the tools for android")
androidToolPath += dirnames[0] + "/"
adModResouceFolder = ""
if "ADMOD_ID" in module.package_prop:
adModResouceFolder = " -S " + target.folder_sdk + "/extras/google/google_play_services/libproject/google-play-services_lib/res/ "
cmdLine = androidToolPath + "aapt p -f " \
+ "-M " + target.get_staging_folder(package_name) + "/AndroidManifest.xml " \
+ "-F " + target.get_staging_folder(package_name) + "/resources.res " \
+ "-I " + target.folder_sdk + "/platforms/android-" + str(target.boardId) + "/android.jar "\
+ "-S " + target.get_staging_folder(package_name) + "/res/ " \
+ adModResouceFolder \
+ "-J " + target.get_staging_folder(package_name) + "/src/ "
multiprocess.run_command(cmdLine)
#aapt package -f -M ${manifest.file} -F ${packaged.resource.file} -I ${path.to.android-jar.library}
# -S ${android-resource-directory} [-m -J ${folder.to.output.the.R.java}]
tools.create_directory_of_file(target.get_staging_folder(package_name) + "/build/classes/noFile")
debug.print_element("pkg", "*.class", "<==", "*.java")
# more information with : -Xlint
# + java_file_wrapper + " "\ # this generate ex: out/Android/debug/staging/tethys/src/com/edouarddupin/tethys/edn.java
#generate android java files:
filesString=""
for element in module.package_prop["ANDROID_JAVA_FILES"]:
if element=="DEFAULT":
filesString += target.folder_gale + "/android/src/org/gale/GaleAudioTask.java "
filesString += target.folder_gale + "/android/src/org/gale/GaleCallback.java "
filesString += target.folder_gale + "/android/src/org/gale/GaleConstants.java "
filesString += target.folder_gale + "/android/src/org/gale/Gale.java "
filesString += target.folder_gale + "/android/src/org/gale/GaleRendererGL.java "
filesString += target.folder_gale + "/android/src/org/gale/GaleSurfaceViewGL.java "
filesString += target.folder_gale + "/android/src/org/gale/GaleActivity.java "
filesString += target.folder_gale + "/android/src/org/gale/GaleWallpaper.java "
else:
filesString += element + " "
if "ADMOD_ID" in module.package_prop:
filesString += target.folder_sdk + "/extras/google/google_play_services/libproject/google-play-services_lib/src/android/UnusedStub.java "
if len(module.package_prop["ANDROID_WALLPAPER_PROPERTIES"])!=0:
filesString += target.folder_java_project + application_name + "Settings.java "
adModJarFile = ""
if "ADMOD_ID" in module.package_prop:
adModJarFile = ":" + target.folder_sdk + "/extras/google/google_play_services/libproject/google-play-services_lib/libs/google-play-services.jar"
cmdLine = "javac " \
+ "-d " + target.get_staging_folder(package_name) + "/build/classes " \
+ "-classpath " + target.folder_sdk + "/platforms/android-" + str(target.boardId) + "/android.jar" \
+ adModJarFile + " " \
+ filesString \
+ java_file_wrapper + " " \
+ target.get_staging_folder(package_name) + "/src/R.java "
multiprocess.run_command(cmdLine)
debug.print_element("pkg", ".dex", "<==", "*.class")
cmdLine = androidToolPath + "dx " \
+ "--dex --no-strict " \
+ "--output=" + target.get_staging_folder(package_name) + "/build/" + application_name + ".dex " \
+ target.get_staging_folder(package_name) + "/build/classes/ "
if "ADMOD_ID" in module.package_prop:
cmdLine += target.folder_sdk + "/extras/google/google_play_services/libproject/google-play-services_lib/libs/google-play-services.jar "
multiprocess.run_command(cmdLine)
"""
return {"files":file_list}