diff options
Diffstat (limited to 'platform')
25 files changed, 1218 insertions, 128 deletions
diff --git a/platform/android/detect.py b/platform/android/detect.py index 4cf12538db..5ef405f7b6 100644 --- a/platform/android/detect.py +++ b/platform/android/detect.py @@ -91,7 +91,7 @@ def configure(env): gcc_path=gcc_path+"/darwin-x86_64/bin" #this may be wrong env['SHLINKFLAGS'][1] = '-shared' elif (os.name=="nt"): - gcc_path=gcc_path+"/windows/bin" #this may be wrong + gcc_path=gcc_path+"/windows-x86_64/bin" #this may be wrong diff --git a/platform/android/dir_access_android.cpp b/platform/android/dir_access_android.cpp index 60bde61fc4..80311e5a08 100644 --- a/platform/android/dir_access_android.cpp +++ b/platform/android/dir_access_android.cpp @@ -79,6 +79,9 @@ bool DirAccessAndroid::current_is_dir() const{ return false; } +bool DirAccessAndroid::current_is_hidden() const{ + return current!="." && current!=".." && current.begins_with("."); +} void DirAccessAndroid::list_dir_end(){ if (aad==NULL) diff --git a/platform/android/dir_access_android.h b/platform/android/dir_access_android.h index a6aead6eb3..57683542fa 100644 --- a/platform/android/dir_access_android.h +++ b/platform/android/dir_access_android.h @@ -52,6 +52,7 @@ public: virtual bool list_dir_begin(); ///< This starts dir listing virtual String get_next(); virtual bool current_is_dir() const; + virtual bool current_is_hidden() const; virtual void list_dir_end(); ///< virtual int get_drive_count(); diff --git a/platform/android/dir_access_jandroid.cpp b/platform/android/dir_access_jandroid.cpp index f32e16e7d8..98f20b2636 100644 --- a/platform/android/dir_access_jandroid.cpp +++ b/platform/android/dir_access_jandroid.cpp @@ -105,6 +105,12 @@ bool DirAccessJAndroid::current_is_dir() const{ return true; } + +bool DirAccessJAndroid::current_is_hidden() const { + + return current!="." && current!=".." && current.begins_with("."); +} + void DirAccessJAndroid::list_dir_end(){ if (id==0) diff --git a/platform/android/dir_access_jandroid.h b/platform/android/dir_access_jandroid.h index 958ea34891..0a696506e6 100644 --- a/platform/android/dir_access_jandroid.h +++ b/platform/android/dir_access_jandroid.h @@ -60,6 +60,7 @@ public: virtual bool list_dir_begin(); ///< This starts dir listing virtual String get_next(); virtual bool current_is_dir() const; + virtual bool current_is_hidden() const; virtual void list_dir_end(); ///< virtual int get_drive_count(); diff --git a/platform/android/export/export.cpp b/platform/android/export/export.cpp index 3e4ea8a4e0..8199e7c622 100644 --- a/platform/android/export/export.cpp +++ b/platform/android/export/export.cpp @@ -185,6 +185,7 @@ class EditorExportPlatformAndroid : public EditorExportPlatform { bool _signed; bool apk_expansion; bool remove_prev; + bool use_32_fb; String apk_expansion_salt; String apk_expansion_pkey; int orientation; @@ -279,6 +280,8 @@ bool EditorExportPlatformAndroid::_set(const StringName& p_name, const Variant& icon=p_value; else if (n=="package/signed") _signed=p_value; + else if (n=="screen/use_32_bits_view") + use_32_fb=p_value; else if (n=="screen/orientation") orientation=p_value; else if (n=="screen/support_small") @@ -344,6 +347,8 @@ bool EditorExportPlatformAndroid::_get(const StringName& p_name,Variant &r_ret) r_ret=icon; else if (n=="package/signed") r_ret=_signed; + else if (n=="screen/use_32_bits_view") + r_ret=use_32_fb; else if (n=="screen/orientation") r_ret=orientation; else if (n=="screen/support_small") @@ -393,6 +398,7 @@ void EditorExportPlatformAndroid::_get_property_list( List<PropertyInfo> *p_list p_list->push_back( PropertyInfo( Variant::STRING, "package/name") ); p_list->push_back( PropertyInfo( Variant::STRING, "package/icon",PROPERTY_HINT_FILE,"png") ); p_list->push_back( PropertyInfo( Variant::BOOL, "package/signed") ); + p_list->push_back( PropertyInfo( Variant::BOOL, "screen/use_32_bits_view") ); p_list->push_back( PropertyInfo( Variant::INT, "screen/orientation",PROPERTY_HINT_ENUM,"Landscape,Portrait") ); p_list->push_back( PropertyInfo( Variant::BOOL, "screen/support_small") ); p_list->push_back( PropertyInfo( Variant::BOOL, "screen/support_normal") ); @@ -1158,8 +1164,14 @@ Error EditorExportPlatformAndroid::export_project(const String& p_path, bool p_d err = export_project_files(save_apk_file,&ed,false); } + + } + if (use_32_fb) + cl.push_back("-use_depth_32"); + + if (cl.size()) { //add comandline Vector<uint8_t> clf; @@ -1534,6 +1546,7 @@ EditorExportPlatformAndroid::EditorExportPlatformAndroid() { quit_request=false; orientation=0; remove_prev=true; + use_32_fb=true; device_thread=Thread::create(_device_poll_thread,this); devices_changed=true; diff --git a/platform/android/java/src/com/android/godot/Godot.java b/platform/android/java/src/com/android/godot/Godot.java index 1a7659a473..2abb4cec53 100644 --- a/platform/android/java/src/com/android/godot/Godot.java +++ b/platform/android/java/src/com/android/godot/Godot.java @@ -109,6 +109,7 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC private Button mPauseButton; private Button mWiFiSettingsButton; + private boolean use_32_bits=false; private boolean mStatePaused; private int mState; @@ -255,7 +256,7 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC // ...add to FrameLayout layout.addView(edittext); - mView = new GodotView(getApplication(),io,use_gl2, this); + mView = new GodotView(getApplication(),io,use_gl2,use_32_bits, this); layout.addView(mView,new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT)); mView.setKeepScreenOn(true); @@ -399,7 +400,9 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC for(int i=0;i<command_line.length;i++) { boolean has_extra = i< command_line.length -1; - if (command_line[i].equals("-use_apk_expansion")) { + if (command_line[i].equals("-use_depth_32")) { + use_32_bits=true; + } else if (command_line[i].equals("-use_apk_expansion")) { use_apk_expansion=true; } else if (has_extra && command_line[i].equals("-apk_expansion_md5")) { main_pack_md5=command_line[i+1]; @@ -568,9 +571,24 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC } @Override public void onSensorChanged(SensorEvent event) { - float x = event.values[0]; - float y = event.values[1]; - float z = event.values[2]; + Display display = ((WindowManager) getSystemService(WINDOW_SERVICE)).getDefaultDisplay(); + int displayRotation = display.getRotation(); + + float[] adjustedValues = new float[3]; + final int axisSwap[][] = { + { 1, -1, 0, 1 }, // ROTATION_0 + {-1, -1, 1, 0 }, // ROTATION_90 + {-1, 1, 0, 1 }, // ROTATION_180 + { 1, 1, 1, 0 } }; // ROTATION_270 + + final int[] as = axisSwap[displayRotation]; + adjustedValues[0] = (float)as[0] * event.values[ as[2] ]; + adjustedValues[1] = (float)as[1] * event.values[ as[3] ]; + adjustedValues[2] = event.values[2]; + + float x = adjustedValues[0]; + float y = adjustedValues[1]; + float z = adjustedValues[2]; GodotLib.accelerometer(x,y,z); } diff --git a/platform/android/java/src/com/android/godot/GodotView.java b/platform/android/java/src/com/android/godot/GodotView.java index f62431b94b..bd81b7f9af 100644 --- a/platform/android/java/src/com/android/godot/GodotView.java +++ b/platform/android/java/src/com/android/godot/GodotView.java @@ -71,14 +71,16 @@ public class GodotView extends GLSurfaceView { private static GodotIO io; private static boolean firsttime=true; private static boolean use_gl2=false; + private static boolean use_32=false; private Godot activity; - public GodotView(Context context,GodotIO p_io,boolean p_use_gl2, Godot p_activity) { + public GodotView(Context context,GodotIO p_io,boolean p_use_gl2, boolean p_use_32_bits, Godot p_activity) { super(context); ctx=context; io=p_io; use_gl2=p_use_gl2; + use_32=p_use_32_bits; activity = p_activity; @@ -366,9 +368,17 @@ public class GodotView extends GLSurfaceView { * custom config chooser. See ConfigChooser class definition * below. */ - setEGLConfigChooser( translucent ? - new ConfigChooser(8, 8, 8, 8, depth, stencil) : - new ConfigChooser(5, 6, 5, 0, depth, stencil) ); + + if (use_32) { + setEGLConfigChooser( translucent ? + new ConfigChooser(8, 8, 8, 8, 24, stencil) : + new ConfigChooser(8, 8, 8, 8, 24, stencil) ); + + } else { + setEGLConfigChooser( translucent ? + new ConfigChooser(8, 8, 8, 8, 16, stencil) : + new ConfigChooser(5, 6, 5, 0, 16, stencil) ); + } /* Set the renderer responsible for frame rendering */ setRenderer(new Renderer()); diff --git a/platform/android/libs/downloader_library/gen/com/android/vending/expansion/downloader/BuildConfig.java b/platform/android/libs/downloader_library/gen/com/android/vending/expansion/downloader/BuildConfig.java index 77ebb4b780..da9d06e63c 100644 --- a/platform/android/libs/downloader_library/gen/com/android/vending/expansion/downloader/BuildConfig.java +++ b/platform/android/libs/downloader_library/gen/com/android/vending/expansion/downloader/BuildConfig.java @@ -2,5 +2,5 @@ package com.android.vending.expansion.downloader; public final class BuildConfig { - public final static boolean DEBUG = true; + public final static boolean DEBUG = false; }
\ No newline at end of file diff --git a/platform/android/os_android.cpp b/platform/android/os_android.cpp index 6b91c01dfc..f00e9c2d77 100644 --- a/platform/android/os_android.cpp +++ b/platform/android/os_android.cpp @@ -291,6 +291,11 @@ void OS_Android::get_fullscreen_mode_list(List<VideoMode> *p_list,int p_screen) p_list->push_back(default_videomode); } +Size2 OS_Android::get_window_size() const { + + return Vector2(default_videomode.width,default_videomode.height); +} + String OS_Android::get_name() { return "Android"; diff --git a/platform/android/os_android.h b/platform/android/os_android.h index 26dbf4a509..bea5371bbc 100644 --- a/platform/android/os_android.h +++ b/platform/android/os_android.h @@ -170,6 +170,8 @@ public: virtual VideoMode get_video_mode(int p_screen=0) const; virtual void get_fullscreen_mode_list(List<VideoMode> *p_list,int p_screen=0) const; + virtual Size2 get_window_size() const; + virtual String get_name(); virtual MainLoop *get_main_loop() const; diff --git a/platform/iphone/os_iphone.cpp b/platform/iphone/os_iphone.cpp index aee5f76684..06b48318ec 100644 --- a/platform/iphone/os_iphone.cpp +++ b/platform/iphone/os_iphone.cpp @@ -474,6 +474,11 @@ String OSIPhone::get_name() { return "iOS"; }; +Size2 OSIPhone::get_window_size() const { + + return Vector2(video_mode.width, video_mode.height); +} + bool OSIPhone::has_touchscreen_ui_hint() const { return true; diff --git a/platform/iphone/os_iphone.h b/platform/iphone/os_iphone.h index cb294d07eb..2585a26479 100644 --- a/platform/iphone/os_iphone.h +++ b/platform/iphone/os_iphone.h @@ -167,6 +167,8 @@ public: virtual void hide_virtual_keyboard(); virtual void set_cursor_shape(CursorShape p_shape); + + virtual Size2 get_window_size() const; virtual bool has_touchscreen_ui_hint() const; diff --git a/platform/javascript/os_javascript.cpp b/platform/javascript/os_javascript.cpp index 581df84925..4c8d8a4205 100644 --- a/platform/javascript/os_javascript.cpp +++ b/platform/javascript/os_javascript.cpp @@ -230,6 +230,12 @@ OS::VideoMode OS_JavaScript::get_video_mode(int p_screen) const { return default_videomode; } + +Size2 OS_JavaScript::get_window_size() const { + + return Vector2(default_videomode.width,default_videomode.height); +} + void OS_JavaScript::get_fullscreen_mode_list(List<VideoMode> *p_list,int p_screen) const { p_list->push_back(default_videomode); diff --git a/platform/javascript/os_javascript.h b/platform/javascript/os_javascript.h index dfc93d3ff0..2e9c8e14c2 100644 --- a/platform/javascript/os_javascript.h +++ b/platform/javascript/os_javascript.h @@ -127,6 +127,7 @@ public: virtual VideoMode get_video_mode(int p_screen=0) const; virtual void get_fullscreen_mode_list(List<VideoMode> *p_list,int p_screen=0) const; + virtual Size2 get_window_size() const; virtual String get_name(); virtual MainLoop *get_main_loop() const; diff --git a/platform/osx/os_osx.h b/platform/osx/os_osx.h index 24f7115938..9ffd4fc3f8 100644 --- a/platform/osx/os_osx.h +++ b/platform/osx/os_osx.h @@ -99,6 +99,13 @@ public: CursorShape cursor_shape; MouseMode mouse_mode; + + bool minimized; + bool maximized; + bool zoomed; + Vector<Rect2> screens; + int current_screen; + Rect2 restore_rect; protected: virtual int get_video_driver_count() const; @@ -112,16 +119,13 @@ protected: virtual void set_main_loop( MainLoop * p_main_loop ); virtual void delete_main_loop(); - public: - - - - static OS_OSX* singleton; + void wm_minimized(bool p_minimized); + virtual String get_name(); virtual void set_cursor_shape(CursorShape p_shape); @@ -133,6 +137,8 @@ public: virtual Point2 get_mouse_pos() const; virtual int get_mouse_button_state() const; virtual void set_window_title(const String& p_title); + + virtual Size2 get_window_size() const; virtual void set_icon(const Image& p_icon); @@ -160,6 +166,24 @@ public: virtual void move_window_to_foreground(); + virtual int get_screen_count() const; + virtual int get_current_screen() const; + virtual void set_current_screen(int p_screen); + virtual Point2 get_screen_position(int p_screen=0); + virtual Point2 get_window_position() const; + virtual void set_window_position(const Point2& p_position); + virtual void set_window_size(const Size2 p_size); + virtual void set_window_fullscreen(bool p_enabled); + virtual bool is_window_fullscreen() const; + virtual void set_window_resizable(bool p_enabled); + virtual bool is_window_resizable() const; + virtual void set_window_minimized(bool p_enabled); + virtual bool is_window_minimized() const; + virtual void set_window_maximized(bool p_enabled); + virtual bool is_window_maximized() const; + Size2 get_screen_size(int p_screen); + + void run(); void set_mouse_mode(MouseMode p_mode); diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm index 1c0d1f9991..a20263f9b2 100644 --- a/platform/osx/os_osx.mm +++ b/platform/osx/os_osx.mm @@ -227,19 +227,6 @@ static int button_mask=0; // centerCursor(window); } -- (void)windowDidMiniaturize:(NSNotification *)notification -{ - // _GodotInputWindowIconify(window, GL_TRUE); -} - -- (void)windowDidDeminiaturize:(NSNotification *)notification -{ - //if (window->monitor) -// enterFullscreenMode(window); - - // _GodotInputWindowIconify(window, GL_FALSE); -} - - (void)windowDidBecomeKey:(NSNotification *)notification { // _GodotInputWindowFocus(window, GL_TRUE); @@ -256,6 +243,21 @@ static int button_mask=0; OS_OSX::singleton->get_main_loop()->notification(MainLoop::NOTIFICATION_WM_FOCUS_OUT); } +- (void)windowDidMiniaturize:(NSNotification*)notification +{ + OS_OSX::singleton->wm_minimized(true); + if (OS_OSX::singleton->get_main_loop()) + OS_OSX::singleton->get_main_loop()->notification(MainLoop::NOTIFICATION_WM_FOCUS_OUT); +}; + +- (void)windowDidDeminiaturize:(NSNotification*)notification +{ + + OS_OSX::singleton->wm_minimized(false); + if (OS_OSX::singleton->get_main_loop()) + OS_OSX::singleton->get_main_loop()->notification(MainLoop::NOTIFICATION_WM_FOCUS_IN); +}; + @end @interface GodotContentView : NSView @@ -903,7 +905,7 @@ void OS_OSX::initialize(const VideoMode& p_desired,int p_video_driver,int p_audi unsigned int attributeCount = 0; // OS X needs non-zero color size, so set resonable values - int colorBits = 24; + int colorBits = 32; // Fail if a robustness strategy was requested @@ -1018,7 +1020,15 @@ void OS_OSX::initialize(const VideoMode& p_desired,int p_video_driver,int p_audi _ensure_data_dir(); + NSArray *screenArray = [NSScreen screens]; + printf("nscreen count %i\n", (int)[screenArray count]); + for (int i=0; i<[screenArray count]; i++) { + NSRect nsrect = [[screenArray objectAtIndex: i] visibleFrame]; + screens.push_back(Rect2(nsrect.origin.x, nsrect.origin.y, nsrect.size.width, nsrect.size.height)); + printf("added screen %i\n", screens.size()); + }; + restore_rect = Rect2(get_window_position(), get_window_size()); } void OS_OSX::finalize() { @@ -1231,7 +1241,10 @@ void OS_OSX::swap_buffers() { } +void OS_OSX::wm_minimized(bool p_minimized) { + minimized = p_minimized; +}; void OS_OSX::set_video_mode(const VideoMode& p_video_mode,int p_screen) { @@ -1245,6 +1258,119 @@ void OS_OSX::get_fullscreen_mode_list(List<VideoMode> *p_list,int p_screen) cons } + +int OS_OSX::get_screen_count() const { + + return screens.size(); +}; + +int OS_OSX::get_current_screen() const { + + return current_screen; +}; + +void OS_OSX::set_current_screen(int p_screen) { + + current_screen = p_screen; +}; + +Point2 OS_OSX::get_screen_position(int p_screen) { + + ERR_FAIL_INDEX_V(p_screen, screens.size(), Point2()); + return screens[p_screen].pos; +}; + +Size2 OS_OSX::get_screen_size(int p_screen) { + + ERR_FAIL_INDEX_V(p_screen, screens.size(), Point2()); + return screens[p_screen].size; +}; + +Point2 OS_OSX::get_window_position() const { + + return Size2([window_object frame].origin.x, [window_object frame].origin.y); +}; + + +void OS_OSX::set_window_position(const Point2& p_position) { + + [window_object setFrame:NSMakeRect(p_position.x, p_position.y, [window_object frame].size.width, [window_object frame].size.height) display:YES]; +}; + +Size2 OS_OSX::get_window_size() const { + + return Size2([window_object frame].size.width, [window_object frame].size.height); +}; + +void OS_OSX::set_window_size(const Size2 p_size) { + + NSRect frame = [window_object frame]; + [window_object setFrame:NSMakeRect(frame.origin.x, frame.origin.y, p_size.x, p_size.y) display:YES]; +}; + +void OS_OSX::set_window_fullscreen(bool p_enabled) { + + [window_object performZoom:nil]; + zoomed = p_enabled; +}; + +bool OS_OSX::is_window_fullscreen() const { + + if ( [window_object respondsToSelector:@selector(isZoomed)] ) + return [window_object isZoomed]; + + return zoomed; +}; + +void OS_OSX::set_window_resizable(bool p_enabled) { + + if (p_enabled) + [window_object setStyleMask:[window_object styleMask] | NSResizableWindowMask ]; + else + [window_object setStyleMask:[window_object styleMask] & ~NSResizableWindowMask ]; +}; + +bool OS_OSX::is_window_resizable() const { + + return [window_object styleMask] & NSResizableWindowMask; +}; + +void OS_OSX::set_window_minimized(bool p_enabled) { + + if (p_enabled) + [window_object performMiniaturize:nil]; + else + [window_object deminiaturize:nil]; +}; + +bool OS_OSX::is_window_minimized() const { + + if ( [window_object respondsToSelector:@selector(isMiniaturized)]) + return [window_object isMiniaturized]; + + return minimized; +}; + + +void OS_OSX::set_window_maximized(bool p_enabled) { + + if (p_enabled) { + restore_rect = Rect2(get_window_position(), get_window_size()); + [window_object setFrame:[[[NSScreen screens] objectAtIndex:current_screen] visibleFrame] display:YES]; + } else { + set_window_size(restore_rect.size); + set_window_position(restore_rect.pos); + }; + maximized = p_enabled; +}; + +bool OS_OSX::is_window_maximized() const { + + // don't know + return maximized; +}; + + void OS_OSX::move_window_to_foreground() { [window_object orderFrontRegardless]; @@ -1473,5 +1599,9 @@ OS_OSX::OS_OSX() { last_id=1; cursor_shape=CURSOR_ARROW; + current_screen = 0; + maximized = false; + minimized = false; + zoomed = false; } diff --git a/platform/server/os_server.cpp b/platform/server/os_server.cpp index 7bc8f61744..1aabf5337b 100644 --- a/platform/server/os_server.cpp +++ b/platform/server/os_server.cpp @@ -56,7 +56,6 @@ void OS_Server::initialize(const VideoMode& p_desired,int p_video_driver,int p_a args=OS::get_singleton()->get_cmdline_args(); current_videomode=p_desired; main_loop=NULL; - rasterizer = memnew( RasterizerDummy ); @@ -163,6 +162,12 @@ OS::VideoMode OS_Server::get_video_mode(int p_screen) const { return current_videomode; } + +Size2 OS_Server::get_window_size() const { + + return Vector2(current_videomode.width,current_videomode.height) ; +} + void OS_Server::get_fullscreen_mode_list(List<VideoMode> *p_list,int p_screen) const { diff --git a/platform/server/os_server.h b/platform/server/os_server.h index fcf96253ad..f8d346ce48 100644 --- a/platform/server/os_server.h +++ b/platform/server/os_server.h @@ -109,6 +109,8 @@ public: virtual VideoMode get_video_mode(int p_screen=0) const; virtual void get_fullscreen_mode_list(List<VideoMode> *p_list,int p_screen=0) const; + virtual Size2 get_window_size() const; + virtual void move_window_to_foreground(); void run(); diff --git a/platform/windows/detect.py b/platform/windows/detect.py index 62bab00f7b..9cdf04797c 100644 --- a/platform/windows/detect.py +++ b/platform/windows/detect.py @@ -1,4 +1,90 @@ -
+#
+# tested on | Windows native | Linux cross-compilation
+# ------------------------+-------------------+---------------------------
+# MSVS C++ 2010 Express | WORKS | n/a
+# Mingw-w64 | WORKS | WORKS
+# Mingw-w32 | WORKS | WORKS
+# MinGW | WORKS | untested
+#
+#####
+# Notes about MSVS C++ :
+#
+# - MSVC2010-Express compiles to 32bits only.
+#
+#####
+# Notes about Mingw-w64 and Mingw-w32 under Windows :
+#
+# - both can be installed using the official installer :
+# http://mingw-w64.sourceforge.net/download.php#mingw-builds
+#
+# - if you want to compile both 32bits and 64bits, don't forget to
+# run the installer twice to install them both.
+#
+# - install them into a path that does not contain spaces
+# ( example : "C:/Mingw-w32", "C:/Mingw-w64" )
+#
+# - if you want to compile faster using the "-j" option, don't forget
+# to install the appropriate version of the Pywin32 python extension
+# available from : http://sourceforge.net/projects/pywin32/files/
+#
+# - before running scons, you must add into the environment path
+# the path to the "/bin" directory of the Mingw version you want
+# to use :
+#
+# set PATH=C:/Mingw-w32/bin;%PATH%
+#
+# - then, scons should be able to detect gcc.
+# - Mingw-w32 only compiles 32bits.
+# - Mingw-w64 only compiles 64bits.
+#
+# - it is possible to add them both at the same time into the PATH env,
+# if you also define the MINGW32_PREFIX and MINGW64_PREFIX environment
+# variables.
+# For instance, you could store that set of commands into a .bat script
+# that you would run just before scons :
+#
+# set PATH=C:\mingw-w32\bin;%PATH%
+# set PATH=C:\mingw-w64\bin;%PATH%
+# set MINGW32_PREFIX=C:\mingw-w32\bin\
+# set MINGW64_PREFIX=C:\mingw-w64\bin\
+#
+#####
+# Notes about Mingw, Mingw-w64 and Mingw-w32 under Linux :
+#
+# - default toolchain prefixes are :
+# "i586-mingw32msvc-" for MinGW
+# "i686-w64-mingw32-" for Mingw-w32
+# "x86_64-w64-mingw32-" for Mingw-w64
+#
+# - if both MinGW and Mingw-w32 are installed on your system
+# Mingw-w32 should take the priority over MinGW.
+#
+# - it is possible to manually override prefixes by defining
+# the MINGW32_PREFIX and MINGW64_PREFIX environment variables.
+#
+#####
+# Notes about Mingw under Windows :
+#
+# - this is the MinGW version from http://mingw.org/
+# - install it into a path that does not contain spaces
+# ( example : "C:/MinGW" )
+# - several DirectX headers might be missing. You can copy them into
+# the C:/MinGW/include" directory from this page :
+# https://code.google.com/p/mingw-lib/source/browse/trunk/working/avcodec_to_widget_5/directx_include/
+# - before running scons, add the path to the "/bin" directory :
+# set PATH=C:/MinGW/bin;%PATH%
+# - scons should be able to detect gcc.
+#
+
+#####
+# TODO :
+#
+# - finish to cleanup this script to remove all the remains of previous hacks and workarounds
+# - make it work with the Windows7 SDK that is supposed to enable 64bits compilation for MSVC2010-Express
+# - confirm it works well with other Visual Studio versions.
+# - update the wiki about the pywin32 extension required for the "-j" option under Windows.
+# - update the wiki to document MINGW32_PREFIX and MINGW64_PREFIX
+#
import os
@@ -13,50 +99,70 @@ def get_name(): def can_build():
-
if (os.name=="nt"):
#building natively on windows!
if (os.getenv("VSINSTALLDIR")):
return True
else:
- print("MSVC Not detected, attempting mingw.")
+ print("\nMSVC not detected, attempting Mingw.")
+ mingw32 = ""
+ mingw64 = ""
+ if ( os.getenv("MINGW32_PREFIX") ) :
+ mingw32 = os.getenv("MINGW32_PREFIX")
+ if ( os.getenv("MINGW64_PREFIX") ) :
+ mingw64 = os.getenv("MINGW64_PREFIX")
+
+ test = "gcc --version > NUL 2>&1"
+ if os.system(test)!= 0 and os.system(mingw32+test)!=0 and os.system(mingw64+test)!=0 :
+ print("- could not detect gcc.")
+ print("Please, make sure a path to a Mingw /bin directory is accessible into the environment PATH.\n")
+ return False
+ else:
+ print("- gcc detected.")
+
return True
-
-
if (os.name=="posix"):
mingw = "i586-mingw32msvc-"
- mingw64 = "i686-w64-mingw32-"
+ mingw64 = "x86_64-w64-mingw32-"
+ mingw32 = "i686-w64-mingw32-"
+
if (os.getenv("MINGW32_PREFIX")):
- mingw=os.getenv("MINGW32_PREFIX")
+ mingw32=os.getenv("MINGW32_PREFIX")
+ mingw = mingw32
if (os.getenv("MINGW64_PREFIX")):
mingw64=os.getenv("MINGW64_PREFIX")
-
- if os.system(mingw+"gcc --version >/dev/null") == 0 or os.system(mingw64+"gcc --version >/dev/null") ==0:
+
+ test = "gcc --version >/dev/null"
+ if os.system(mingw+test) == 0 or os.system(mingw64+test) ==0 or os.system(mingw32+test) ==0 :
return True
-
-
return False
def get_opts():
mingw=""
+ mingw32=""
mingw64=""
- if (os.name!="nt"):
+ if ( os.name == "posix" ):
mingw = "i586-mingw32msvc-"
- mingw64 = "i686-w64-mingw32-"
- if (os.getenv("MINGW32_PREFIX")):
- mingw=os.getenv("MINGW32_PREFIX")
- if (os.getenv("MINGW64_PREFIX")):
- mingw64=os.getenv("MINGW64_PREFIX")
+ mingw32 = "i686-w64-mingw32-"
+ mingw64 = "x86_64-w64-mingw32-"
+
+ if os.system(mingw32+"gcc --version >/dev/null") != 0 :
+ mingw32 = mingw
+
+ if (os.getenv("MINGW32_PREFIX")):
+ mingw32=os.getenv("MINGW32_PREFIX")
+ mingw = mingw32
+ if (os.getenv("MINGW64_PREFIX")):
+ mingw64=os.getenv("MINGW64_PREFIX")
return [
- ('mingw_prefix','Mingw Prefix',mingw),
+ ('mingw_prefix','Mingw Prefix',mingw32),
('mingw_prefix_64','Mingw Prefix 64 bits',mingw64),
- ('mingw64_for_32','Use Mingw 64 for 32 Bits Build',"no"),
]
def get_flags():
@@ -140,13 +246,13 @@ def configure(env): # http://www.scons.org/wiki/LongCmdLinesOnWin32
if (os.name=="nt"):
import subprocess
- def mySpawn(sh, escape, cmd, args, env):
- newargs = ' '.join(args[1:])
- cmdline = cmd + " " + newargs
+
+ def mySubProcess(cmdline,env):
+ #print "SPAWNED : " + cmdline
startupinfo = subprocess.STARTUPINFO()
startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
proc = subprocess.Popen(cmdline, stdin=subprocess.PIPE, stdout=subprocess.PIPE,
- stderr=subprocess.PIPE, startupinfo=startupinfo, shell = False, env = env)
+ stderr=subprocess.PIPE, startupinfo=startupinfo, shell = False, env = env)
data, err = proc.communicate()
rv = proc.wait()
if rv:
@@ -154,35 +260,45 @@ def configure(env): print err
print "====="
return rv
+
+ def mySpawn(sh, escape, cmd, args, env):
+
+ newargs = ' '.join(args[1:])
+ cmdline = cmd + " " + newargs
+
+ rv=0
+ if len(cmdline) > 32000 and cmd.endswith("ar") :
+ cmdline = cmd + " " + args[1] + " " + args[2] + " "
+ for i in range(3,len(args)) :
+ rv = mySubProcess( cmdline + args[i], env )
+ if rv :
+ break
+ else:
+ rv = mySubProcess( cmdline, env )
+
+ return rv
+
env['SPAWN'] = mySpawn
#build using mingw
if (os.name=="nt"):
env['ENV']['TMP'] = os.environ['TMP'] #way to go scons, you can be so stupid sometimes
else:
- env["PROGSUFFIX"]=env["PROGSUFFIX"]+".exe"
+ env["PROGSUFFIX"]=env["PROGSUFFIX"]+".exe" # for linux cross-compilation
mingw_prefix=""
if (env["bits"]=="default"):
env["bits"]="32"
- use64=False
if (env["bits"]=="32"):
-
- if (env["mingw64_for_32"]=="yes"):
- env.Append(CCFLAGS=['-m32'])
- env.Append(LINKFLAGS=['-m32'])
- env.Append(LINKFLAGS=['-static-libgcc'])
- env.Append(LINKFLAGS=['-static-libstdc++'])
- mingw_prefix=env["mingw_prefix_64"];
- else:
- mingw_prefix=env["mingw_prefix"];
-
-
+ env.Append(LINKFLAGS=['-static'])
+ env.Append(LINKFLAGS=['-static-libgcc'])
+ env.Append(LINKFLAGS=['-static-libstdc++'])
+ mingw_prefix=env["mingw_prefix"];
else:
- mingw_prefix=env["mingw_prefix_64"];
env.Append(LINKFLAGS=['-static'])
+ mingw_prefix=env["mingw_prefix_64"];
nulstr=""
@@ -193,10 +309,10 @@ def configure(env): - if os.system(mingw_prefix+"gcc --version"+nulstr)!=0:
- #not really super consistent but..
- print("Can't find Windows compiler: "+mingw_prefix)
- sys.exit(255)
+ # if os.system(mingw_prefix+"gcc --version"+nulstr)!=0:
+ # #not really super consistent but..
+ # print("Can't find Windows compiler: "+mingw_prefix)
+ # sys.exit(255)
if (env["target"]=="release"):
@@ -231,11 +347,11 @@ def configure(env): env.Append(CCFLAGS=['-DGLES2_ENABLED','-DGLEW_ENABLED'])
env.Append(LIBS=['mingw32','opengl32', 'dsound', 'ole32', 'd3d9','winmm','gdi32','iphlpapi','shlwapi','wsock32','kernel32'])
- if (env["bits"]=="32" and env["mingw64_for_32"]!="yes"):
-# env.Append(LIBS=['gcc_s'])
- #--with-arch=i686
- env.Append(CPPFLAGS=['-march=i686'])
- env.Append(LINKFLAGS=['-march=i686'])
+ # if (env["bits"]=="32"):
+# # env.Append(LIBS=['gcc_s'])
+ # #--with-arch=i686
+ # env.Append(CPPFLAGS=['-march=i686'])
+ # env.Append(LINKFLAGS=['-march=i686'])
diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp index 50c42448f4..93275b3d54 100644 --- a/platform/windows/os_windows.cpp +++ b/platform/windows/os_windows.cpp @@ -171,6 +171,8 @@ void OS_Windows::initialize_core() { last_button_state=0; //RedirectIOToConsole(); + maximized=false; + minimized=false; ThreadWindows::make_default(); SemaphoreWindows::make_default(); @@ -421,6 +423,7 @@ LRESULT OS_Windows::WndProc(HWND hWnd,UINT uMsg, WPARAM wParam, LPARAM lParam) { case WM_RBUTTONUP: case WM_MOUSEWHEEL: case WM_LBUTTONDBLCLK: + case WM_RBUTTONDBLCLK: /*case WM_XBUTTONDOWN: case WM_XBUTTONUP: */{ @@ -474,6 +477,12 @@ LRESULT OS_Windows::WndProc(HWND hWnd,UINT uMsg, WPARAM wParam, LPARAM lParam) { mb.button_index=1; mb.doubleclick = true; } break; + case WM_RBUTTONDBLCLK: { + + mb.pressed=true; + mb.button_index=2; + mb.doubleclick = true; + } break; case WM_MOUSEWHEEL: { mb.pressed=true; @@ -1007,6 +1016,23 @@ void OS_Windows::process_joysticks() { }; }; + +BOOL CALLBACK OS_Windows::MonitorEnumProc(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData) { + OS_Windows *self=(OS_Windows*)OS::get_singleton(); + MonitorInfo minfo; + minfo.hMonitor=hMonitor; + minfo.hdcMonitor=hdcMonitor; + minfo.rect.pos.x=lprcMonitor->left; + minfo.rect.pos.y=lprcMonitor->top; + minfo.rect.size.x=lprcMonitor->right - lprcMonitor->left; + minfo.rect.size.y=lprcMonitor->bottom - lprcMonitor->top; + + self->monitor_info.push_back(minfo); + + return TRUE; +} + + void OS_Windows::initialize(const VideoMode& p_desired,int p_video_driver,int p_audio_driver) { @@ -1045,6 +1071,10 @@ void OS_Windows::initialize(const VideoMode& p_desired,int p_video_driver,int p_ } + EnumDisplayMonitors(NULL,NULL,MonitorEnumProc,0); + + print_line("DETECTED MONITORS: "+itos(monitor_info.size())); + pre_fs_valid=true; if (video_mode.fullscreen) { DEVMODE current; @@ -1067,6 +1097,7 @@ void OS_Windows::initialize(const VideoMode& p_desired,int p_video_driver,int p_ video_mode.fullscreen=false; }*/ + pre_fs_valid=false; } DWORD dwExStyle; @@ -1475,6 +1506,251 @@ void OS_Windows::get_fullscreen_mode_list(List<VideoMode> *p_list,int p_screen) } +int OS_Windows::get_screen_count() const { + + return monitor_info.size(); +} +int OS_Windows::get_current_screen() const{ + + HMONITOR monitor = MonitorFromWindow(hWnd,MONITOR_DEFAULTTONEAREST); + for(int i=0;i<monitor_info.size();i++) { + if (monitor_info[i].hMonitor==monitor) + return i; + } + + return 0; +} +void OS_Windows::set_current_screen(int p_screen){ + + ERR_FAIL_INDEX(p_screen,monitor_info.size()); + + Vector2 ofs = get_window_position() - get_screen_position(get_current_screen()); + set_window_position(ofs+get_screen_position(p_screen)); + +} + +Point2 OS_Windows::get_screen_position(int p_screen) const{ + + ERR_FAIL_INDEX_V(p_screen,monitor_info.size(),Point2()); + return Vector2( monitor_info[p_screen].rect.pos ); + +} +Size2 OS_Windows::get_screen_size(int p_screen) const{ + + ERR_FAIL_INDEX_V(p_screen,monitor_info.size(),Point2()); + return Vector2( monitor_info[p_screen].rect.size ); + +} +Point2 OS_Windows::get_window_position() const{ + + RECT r; + GetWindowRect(hWnd,&r); + return Point2(r.left,r.top); +} +void OS_Windows::set_window_position(const Point2& p_position){ + + RECT r; + GetWindowRect(hWnd,&r); + MoveWindow(hWnd,p_position.x,p_position.y,r.right-r.left,r.bottom-r.top,TRUE); + +} +Size2 OS_Windows::get_window_size() const{ + + RECT r; + GetClientRect(hWnd,&r); + return Vector2(r.right-r.left,r.bottom-r.top); + +} +void OS_Windows::set_window_size(const Size2 p_size){ + + video_mode.width=p_size.width; + video_mode.height=p_size.height; + + if (video_mode.fullscreen) { + return; + } + + + RECT crect; + GetClientRect(hWnd,&crect); + + RECT rect; + GetWindowRect(hWnd,&rect); + int dx = (rect.right-rect.left)-(crect.right-crect.left); + int dy = (rect.bottom-rect.top)-(crect.bottom-crect.top); + + rect.right=rect.left+p_size.width+dx; + rect.bottom=rect.top+p_size.height+dy; + + + //print_line("PRE: "+itos(rect.left)+","+itos(rect.top)+","+itos(rect.right-rect.left)+","+itos(rect.bottom-rect.top)); + + /*if (video_mode.resizable) { + AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW, FALSE); + } else { + AdjustWindowRect(&rect, WS_CAPTION | WS_POPUPWINDOW, FALSE); + }*/ + + //print_line("POST: "+itos(rect.left)+","+itos(rect.top)+","+itos(rect.right-rect.left)+","+itos(rect.bottom-rect.top)); + + MoveWindow(hWnd,rect.left,rect.top,rect.right-rect.left,rect.bottom-rect.top,TRUE); + +} +void OS_Windows::set_window_fullscreen(bool p_enabled){ + + if (video_mode.fullscreen==p_enabled) + return; + + + + if (p_enabled) { + + + if (pre_fs_valid) { + GetWindowRect(hWnd,&pre_fs_rect); + //print_line("A: "+itos(pre_fs_rect.left)+","+itos(pre_fs_rect.top)+","+itos(pre_fs_rect.right-pre_fs_rect.left)+","+itos(pre_fs_rect.bottom-pre_fs_rect.top)); + //MapWindowPoints(hWnd, GetParent(hWnd), (LPPOINT) &pre_fs_rect, 2); + //print_line("B: "+itos(pre_fs_rect.left)+","+itos(pre_fs_rect.top)+","+itos(pre_fs_rect.right-pre_fs_rect.left)+","+itos(pre_fs_rect.bottom-pre_fs_rect.top)); + } + + + int cs = get_current_screen(); + Point2 pos = get_screen_position(cs); + Size2 size = get_screen_size(cs); + + /* r.left = pos.x; + r.top = pos.y; + r.bottom = pos.y+size.y; + r.right = pos.x+size.x; +*/ + SetWindowLongPtr(hWnd, GWL_STYLE, + WS_SYSMENU | WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_VISIBLE); + MoveWindow(hWnd, pos.x, pos.y, size.width, size.height, TRUE); + + video_mode.fullscreen=true; + + + } else { + + RECT rect; + + if (pre_fs_valid) { + rect=pre_fs_rect; + } else { + rect.left=0; + rect.right=video_mode.width; + rect.top=0; + rect.bottom=video_mode.height; + } + + + + if (video_mode.resizable) { + + SetWindowLongPtr(hWnd, GWL_STYLE, WS_OVERLAPPEDWINDOW | WS_VISIBLE); + //AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW, FALSE); + MoveWindow(hWnd, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top, TRUE); + } else { + + SetWindowLongPtr(hWnd, GWL_STYLE, WS_CAPTION | WS_POPUPWINDOW | WS_VISIBLE); + //AdjustWindowRect(&rect, WS_CAPTION | WS_POPUPWINDOW, FALSE); + MoveWindow(hWnd, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top, TRUE); + } + + video_mode.fullscreen=false; + pre_fs_valid=true; +/* + DWORD dwExStyle=WS_EX_APPWINDOW | WS_EX_WINDOWEDGE; + DWORD dwStyle=WS_OVERLAPPEDWINDOW; + if (!video_mode.resizable) { + dwStyle &= ~WS_THICKFRAME; + dwStyle &= ~WS_MAXIMIZEBOX; + } + AdjustWindowRectEx(&pre_fs_rect, dwStyle, FALSE, dwExStyle); + video_mode.fullscreen=false; + video_mode.width=pre_fs_rect.right-pre_fs_rect.left; + video_mode.height=pre_fs_rect.bottom-pre_fs_rect.top; +*/ + } + +// MoveWindow(hWnd,r.left,r.top,p_size.x,p_size.y,TRUE); + + +} +bool OS_Windows::is_window_fullscreen() const{ + + return video_mode.fullscreen; +} +void OS_Windows::set_window_resizable(bool p_enabled){ + + if (video_mode.resizable==p_enabled) + return; +/* + GetWindowRect(hWnd,&pre_fs_rect); + DWORD dwExStyle=WS_EX_APPWINDOW | WS_EX_WINDOWEDGE; + DWORD dwStyle=WS_OVERLAPPEDWINDOW; + if (!p_enabled) { + dwStyle &= ~WS_THICKFRAME; + dwStyle &= ~WS_MAXIMIZEBOX; + } + AdjustWindowRectEx(&pre_fs_rect, dwStyle, FALSE, dwExStyle); + */ + + if (!video_mode.fullscreen) { + if (p_enabled) { + SetWindowLongPtr(hWnd, GWL_STYLE, WS_OVERLAPPEDWINDOW | WS_VISIBLE); + } else { + SetWindowLongPtr(hWnd, GWL_STYLE, WS_CAPTION | WS_POPUPWINDOW | WS_VISIBLE); + + } + + RECT rect; + GetWindowRect(hWnd,&rect); + MoveWindow(hWnd, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top, TRUE); + } + + video_mode.resizable=p_enabled; + +} +bool OS_Windows::is_window_resizable() const{ + + return video_mode.resizable; +} +void OS_Windows::set_window_minimized(bool p_enabled){ + + if (p_enabled) { + maximized=false; + minimized=true; + ShowWindow(hWnd,SW_MINIMIZE); + } else { + ShowWindow(hWnd,SW_RESTORE); + maximized=false; + minimized=false; + } +} +bool OS_Windows::is_window_minimized() const{ + + return minimized; + +} +void OS_Windows::set_window_maximized(bool p_enabled){ + + if (p_enabled) { + maximized=true; + minimized=false; + ShowWindow(hWnd,SW_MAXIMIZE); + } else { + ShowWindow(hWnd,SW_RESTORE); + maximized=false; + minimized=false; + } +} +bool OS_Windows::is_window_maximized() const{ + + return maximized; +} + + void OS_Windows::print_error(const char* p_function,const char* p_file,int p_line,const char *p_code,const char*p_rationale,ErrorType p_type) { HANDLE hCon=GetStdHandle(STD_OUTPUT_HANDLE); @@ -1776,7 +2052,7 @@ String OS_Windows::get_executable_path() const { wchar_t bufname[4096]; GetModuleFileNameW(NULL,bufname,4096); String s= bufname; - print_line("EXEC PATHPó: "+s); + print_line("EXEC PATHP¨®: "+s); return s; } diff --git a/platform/windows/os_windows.h b/platform/windows/os_windows.h index 210e25d2d6..4995adc874 100644 --- a/platform/windows/os_windows.h +++ b/platform/windows/os_windows.h @@ -86,7 +86,7 @@ class OS_Windows : public OS { uint64_t ticks_start; uint64_t ticks_per_second; - bool minimized; + bool old_invalid; bool outside; int old_x,old_y; @@ -130,6 +130,7 @@ class OS_Windows : public OS { int joystick_count; Joystick joysticks[JOYSTICKS_MAX]; + Size2 window_rect; VideoMode video_mode; MainLoop *main_loop; @@ -196,6 +197,23 @@ protected: }; Map<ProcessID, ProcessInfo>* process_map; + struct MonitorInfo { + HMONITOR hMonitor; + HDC hdcMonitor; + Rect2 rect; + + + }; + + bool pre_fs_valid; + RECT pre_fs_rect; + Vector<MonitorInfo> monitor_info; + bool maximized; + bool minimized; + + static BOOL CALLBACK MonitorEnumProc(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData); + + public: LRESULT WndProc(HWND hWnd,UINT uMsg, WPARAM wParam, LPARAM lParam); @@ -218,6 +236,24 @@ public: virtual VideoMode get_video_mode(int p_screen=0) const; virtual void get_fullscreen_mode_list(List<VideoMode> *p_list,int p_screen=0) const; + virtual int get_screen_count() const; + virtual int get_current_screen() const; + virtual void set_current_screen(int p_screen); + virtual Point2 get_screen_position(int p_screen=0) const; + virtual Size2 get_screen_size(int p_screen=0) const; + virtual Point2 get_window_position() const; + virtual void set_window_position(const Point2& p_position); + virtual Size2 get_window_size() const; + virtual void set_window_size(const Size2 p_size); + virtual void set_window_fullscreen(bool p_enabled); + virtual bool is_window_fullscreen() const; + virtual void set_window_resizable(bool p_enabled); + virtual bool is_window_resizable() const; + virtual void set_window_minimized(bool p_enabled); + virtual bool is_window_minimized() const; + virtual void set_window_maximized(bool p_enabled); + virtual bool is_window_maximized() const; + virtual MainLoop *get_main_loop() const; virtual String get_name(); diff --git a/platform/x11/detect.py b/platform/x11/detect.py index fb5cdb5089..b0876d7fc6 100644 --- a/platform/x11/detect.py +++ b/platform/x11/detect.py @@ -38,6 +38,11 @@ def can_build(): if (x11_error): print("xcursor not found.. x11 disabled.") return False + + x11_error=os.system("pkg-config xinerama --modversion > /dev/null ") + if (x11_error): + print("xinerama not found.. x11 disabled.") + return False return True # X11 enabled @@ -48,6 +53,7 @@ def get_opts(): ('use_llvm','Use llvm compiler','no'), ('use_sanitizer','Use llvm compiler sanitize address','no'), ('pulseaudio','Detect & Use pulseaudio','yes'), + ('new_wm_api', 'Use experimental window management API','no'), ] def get_flags(): @@ -107,6 +113,7 @@ def configure(env): env.Append(CCFLAGS=['-g2', '-Wall','-DDEBUG_ENABLED','-DDEBUG_MEMORY_ENABLED']) env.ParseConfig('pkg-config x11 --cflags --libs') + env.ParseConfig('pkg-config xinerama --cflags --libs') env.ParseConfig('pkg-config xcursor --cflags --libs') env.ParseConfig('pkg-config openssl --cflags --libs') @@ -147,3 +154,7 @@ def configure(env): env.Append( BUILDERS = { 'GLSL120GLES' : env.Builder(action = methods.build_gles2_headers, suffix = 'glsl.h',src_suffix = '.glsl') } ) #env.Append( BUILDERS = { 'HLSL9' : env.Builder(action = methods.build_hlsl_dx9_headers, suffix = 'hlsl.h',src_suffix = '.hlsl') } ) + if(env["new_wm_api"]=="yes"): + env.Append(CPPFLAGS=['-DNEW_WM_API']) + env.ParseConfig('pkg-config xinerama --cflags --libs') + diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp index ac1818d200..92b0abff37 100644 --- a/platform/x11/os_x11.cpp +++ b/platform/x11/os_x11.cpp @@ -36,6 +36,17 @@ #include "servers/physics/physics_server_sw.h" #include "X11/Xutil.h" + +#include "X11/Xatom.h" +#include "X11/extensions/Xinerama.h" +// ICCCM +#define WM_NormalState 1L // window normal state +#define WM_IconicState 3L // window minimized +// EWMH +#define _NET_WM_STATE_REMOVE 0L // remove/unset property +#define _NET_WM_STATE_ADD 1L // add/set property +#define _NET_WM_STATE_TOGGLE 2L // toggle property + #include "main/main.h" @@ -56,7 +67,7 @@ #include <X11/Xatom.h> -#include "os/pc_joystick_map.h" +//#include "os/pc_joystick_map.h" #undef CursorShape @@ -117,10 +128,10 @@ void OS_X11::initialize(const VideoMode& p_desired,int p_video_driver,int p_audi if (xim == NULL) { WARN_PRINT("XOpenIM failed"); - xim_style=NULL; + xim_style=0L; } else { ::XIMStyles *xim_styles=NULL; - xim_style=0; + xim_style=0L; char *imvalret=NULL; imvalret = XGetIMValues(xim, XNQueryInputStyle, &xim_styles, NULL); if (imvalret != NULL || xim_styles == NULL) { @@ -128,7 +139,7 @@ void OS_X11::initialize(const VideoMode& p_desired,int p_video_driver,int p_audi } if (xim_styles) { - xim_style = 0; + xim_style = 0L; for (int i=0;i<xim_styles->count_styles;i++) { if (xim_styles->supported_styles[i] == @@ -162,14 +173,11 @@ void OS_X11::initialize(const VideoMode& p_desired,int p_video_driver,int p_audi // maybe contextgl wants to be in charge of creating the window //print_line("def videomode "+itos(current_videomode.width)+","+itos(current_videomode.height)); #if defined(OPENGL_ENABLED) || defined(LEGACYGL_ENABLED) + context_gl = memnew( ContextGL_X11( x11_display, x11_window,current_videomode, false ) ); context_gl->initialize(); - if (true) { - rasterizer = memnew( RasterizerGLES2 ); - } else { - //rasterizer = memnew( RasterizerGLES1 ); - }; + rasterizer = memnew( RasterizerGLES2 ); #endif visual_server = memnew( VisualServerRaster(rasterizer) ); @@ -179,9 +187,11 @@ void OS_X11::initialize(const VideoMode& p_desired,int p_video_driver,int p_audi visual_server =memnew(VisualServerWrapMT(visual_server,get_render_thread_mode()==RENDER_SEPARATE_THREAD)); } +#if 1 + // NEW_WM_API // borderless fullscreen window mode if (current_videomode.fullscreen) { - // needed for lxde/openbox, possibly others + // needed for lxde/openbox, possibly others Hints hints; Atom property; hints.flags = 2; @@ -210,7 +220,7 @@ void OS_X11::initialize(const VideoMode& p_desired,int p_video_driver,int p_audi XSendEvent(x11_display, DefaultRootWindow(x11_display), False, SubstructureNotifyMask, &xev); } - // disable resizeable window + // disable resizable window if (!current_videomode.resizable) { XSizeHints *xsh; xsh = XAllocSizeHints(); @@ -226,7 +236,25 @@ void OS_X11::initialize(const VideoMode& p_desired,int p_video_driver,int p_audi xsh->min_height = xwa.height; xsh->max_height = xwa.height; XSetWMNormalHints(x11_display, x11_window, xsh); + XFree(xsh); + } +#else + capture_idle = 0; + minimized = false; + maximized = false; + + if (current_videomode.fullscreen) { + //set_wm_border(false); + set_wm_fullscreen(true); + } + if (!current_videomode.resizable) { + int screen = get_current_screen(); + Size2i screen_size = get_screen_size(screen); + set_window_size(screen_size); + set_window_resizable(false); } +#endif + AudioDriverManagerSW::get_driver(p_audio_driver)->set_singleton(); @@ -264,19 +292,19 @@ void OS_X11::initialize(const VideoMode& p_desired,int p_video_driver,int p_audi XChangeWindowAttributes(x11_display, x11_window,CWEventMask,&new_attr); - XClassHint* classHint; + XClassHint* classHint; - /* set the titlebar name */ - XStoreName(x11_display, x11_window, "Godot"); + /* set the titlebar name */ + XStoreName(x11_display, x11_window, "Godot"); - /* set the name and class hints for the window manager to use */ - classHint = XAllocClassHint(); - if (classHint) { - classHint->res_name = "Godot"; - classHint->res_class = "Godot"; - } - XSetClassHint(x11_display, x11_window, classHint); - XFree(classHint); + /* set the name and class hints for the window manager to use */ + classHint = XAllocClassHint(); + if (classHint) { + classHint->res_name = "Godot"; + classHint->res_class = "Godot"; + } + XSetClassHint(x11_display, x11_window, classHint); + XFree(classHint); wm_delete = XInternAtom(x11_display, "WM_DELETE_WINDOW", true); XSetWMProtocols(x11_display, x11_window, &wm_delete, 1); @@ -468,8 +496,9 @@ void OS_X11::set_mouse_mode(MouseMode p_mode) { center.y = current_videomode.height/2; XWarpPointer(x11_display, None, x11_window, 0,0,0,0, (int)center.x, (int)center.y); - } + input->set_mouse_pos(center); + } } void OS_X11::warp_mouse_pos(const Point2& p_to) { @@ -497,7 +526,6 @@ OS::MouseMode OS_X11::get_mouse_mode() const { int OS_X11::get_mouse_button_state() const { - return last_button_state; } @@ -524,6 +552,344 @@ void OS_X11::get_fullscreen_mode_list(List<VideoMode> *p_list,int p_screen) cons } +//#ifdef NEW_WM_API +#if 0 +// Just now not needed. Can be used for a possible OS.set_border(bool) method +void OS_X11::set_wm_border(bool p_enabled) { + // needed for lxde/openbox, possibly others + Hints hints; + Atom property; + hints.flags = 2; + hints.decorations = p_enabled ? 1L : 0L; + property = XInternAtom(x11_display, "_MOTIF_WM_HINTS", True); + XChangeProperty(x11_display, x11_window, property, property, 32, PropModeReplace, (unsigned char *)&hints, 5); + XMapRaised(x11_display, x11_window); + //XMoveResizeWindow(x11_display, x11_window, 0, 0, 800, 800); +} +#endif + +void OS_X11::set_wm_fullscreen(bool p_enabled) { + // Using EWMH -- Extened Window Manager Hints + XEvent xev; + Atom wm_state = XInternAtom(x11_display, "_NET_WM_STATE", False); + Atom wm_fullscreen = XInternAtom(x11_display, "_NET_WM_STATE_FULLSCREEN", False); + + memset(&xev, 0, sizeof(xev)); + xev.type = ClientMessage; + xev.xclient.window = x11_window; + xev.xclient.message_type = wm_state; + xev.xclient.format = 32; + xev.xclient.data.l[0] = p_enabled ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE; + xev.xclient.data.l[1] = wm_fullscreen; + xev.xclient.data.l[2] = 0; + + XSendEvent(x11_display, DefaultRootWindow(x11_display), False, SubstructureRedirectMask | SubstructureNotifyMask, &xev); +} + +int OS_X11::get_screen_count() const { + // Using Xinerama Extension + int event_base, error_base; + const Bool ext_okay = XineramaQueryExtension(x11_display, &event_base, &error_base); + if( !ext_okay ) return 0; + + int count; + XineramaScreenInfo* xsi = XineramaQueryScreens(x11_display, &count); + XFree(xsi); + return count; +} + +int OS_X11::get_current_screen() const { + int x,y; + Window child; + XTranslateCoordinates( x11_display, x11_window, DefaultRootWindow(x11_display), 0, 0, &x, &y, &child); + + int count = get_screen_count(); + for(int i=0; i<count; i++) { + Point2i pos = get_screen_position(i); + Size2i size = get_screen_size(i); + if( (x >= pos.x && x <pos.x + size.width) && (y >= pos.y && y < pos.y + size.height) ) + return i; + } + return 0; +} + +void OS_X11::set_current_screen(int p_screen) { + int count = get_screen_count(); + if(p_screen >= count) return; + + if( current_videomode.fullscreen ) { + Point2i position = get_screen_position(p_screen); + Size2i size = get_screen_size(p_screen); + + XMoveResizeWindow(x11_display, x11_window, position.x, position.y, size.x, size.y); + } + else { + if( p_screen != get_current_screen() ) { + Point2i position = get_screen_position(p_screen); + XMoveWindow(x11_display, x11_window, position.x, position.y); + } + } +} + +Point2 OS_X11::get_screen_position(int p_screen) const { + // Using Xinerama Extension + int event_base, error_base; + const Bool ext_okay = XineramaQueryExtension(x11_display, &event_base, &error_base); + if( !ext_okay ) return Point2i(0,0); + + int count; + XineramaScreenInfo* xsi = XineramaQueryScreens(x11_display, &count); + if( p_screen >= count ) return Point2i(0,0); + + Point2i position = Point2i(xsi[p_screen].x_org, xsi[p_screen].y_org); + XFree(xsi); + return position; +} + +Size2 OS_X11::get_screen_size(int p_screen) const { + // Using Xinerama Extension + int event_base, error_base; + const Bool ext_okay = XineramaQueryExtension(x11_display, &event_base, &error_base); + if( !ext_okay ) return Size2i(0,0); + + int count; + XineramaScreenInfo* xsi = XineramaQueryScreens(x11_display, &count); + if( p_screen >= count ) return Size2i(0,0); + + Size2i size = Point2i(xsi[p_screen].width, xsi[p_screen].height); + XFree(xsi); + return size; +} + + +Point2 OS_X11::get_window_position() const { + int x,y; + Window child; + XTranslateCoordinates( x11_display, x11_window, DefaultRootWindow(x11_display), 0, 0, &x, &y, &child); + + int screen = get_current_screen(); + Point2i screen_position = get_screen_position(screen); + + return Point2i(x-screen_position.x, y-screen_position.y); +} + +void OS_X11::set_window_position(const Point2& p_position) { + // Using EWMH -- Extended Window Manager Hints + // to get the size of the decoration + Atom property = XInternAtom(x11_display,"_NET_FRAME_EXTENTS", True); + Atom type; + int format; + unsigned long len; + unsigned long remaining; + unsigned char *data = NULL; + int result; + + result = XGetWindowProperty( + x11_display, + x11_window, + property, + 0, + 32, + False, + AnyPropertyType, + &type, + &format, + &len, + &remaining, + &data + ); + + long left = 0L; + long top = 0L; + + if( result == Success ) { + long *extends = (long *) data; + + left = extends[0]; + top = extends[2]; + + XFree(data); + } + + int screen = get_current_screen(); + Point2i screen_position = get_screen_position(screen); + + left -= screen_position.x; + top -= screen_position.y; + + XMoveWindow(x11_display,x11_window,p_position.x - left,p_position.y - top); +} + +Size2 OS_X11::get_window_size() const { + XWindowAttributes xwa; + XGetWindowAttributes(x11_display, x11_window, &xwa); + return Size2i(xwa.width, xwa.height); +} + +void OS_X11::set_window_size(const Size2 p_size) { + XResizeWindow(x11_display, x11_window, p_size.x, p_size.y); +} + +void OS_X11::set_window_fullscreen(bool p_enabled) { + set_wm_fullscreen(p_enabled); + current_videomode.fullscreen = p_enabled; + + visual_server->init(); +} + +bool OS_X11::is_window_fullscreen() const { + return current_videomode.fullscreen; +} + +void OS_X11::set_window_resizable(bool p_enabled) { + XSizeHints *xsh; + xsh = XAllocSizeHints(); + xsh->flags = p_enabled ? 0L : PMinSize | PMaxSize; + if(!p_enabled) { + XWindowAttributes xwa; + XGetWindowAttributes(x11_display,x11_window,&xwa); + xsh->min_width = xwa.width; + xsh->max_width = xwa.width; + xsh->min_height = xwa.height; + xsh->max_height = xwa.height; + } + XSetWMNormalHints(x11_display, x11_window, xsh); + XFree(xsh); + current_videomode.resizable = p_enabled; +} + +bool OS_X11::is_window_resizable() const { + return current_videomode.resizable; +} + +void OS_X11::set_window_minimized(bool p_enabled) { + // Using ICCCM -- Inter-Client Communication Conventions Manual + XEvent xev; + Atom wm_change = XInternAtom(x11_display, "WM_CHANGE_STATE", False); + + memset(&xev, 0, sizeof(xev)); + xev.type = ClientMessage; + xev.xclient.window = x11_window; + xev.xclient.message_type = wm_change; + xev.xclient.format = 32; + xev.xclient.data.l[0] = p_enabled ? WM_IconicState : WM_NormalState; + + XSendEvent(x11_display, DefaultRootWindow(x11_display), False, SubstructureRedirectMask | SubstructureNotifyMask, &xev); + + //XEvent xev; + Atom wm_state = XInternAtom(x11_display, "_NET_WM_STATE", False); + Atom wm_hidden = XInternAtom(x11_display, "_NET_WM_STATE_HIDDEN", False); + + memset(&xev, 0, sizeof(xev)); + xev.type = ClientMessage; + xev.xclient.window = x11_window; + xev.xclient.message_type = wm_state; + xev.xclient.format = 32; + xev.xclient.data.l[0] = _NET_WM_STATE_ADD; + xev.xclient.data.l[1] = wm_hidden; + + XSendEvent(x11_display, DefaultRootWindow(x11_display), False, SubstructureRedirectMask | SubstructureNotifyMask, &xev); +} + +bool OS_X11::is_window_minimized() const { + // Using ICCCM -- Inter-Client Communication Conventions Manual + Atom property = XInternAtom(x11_display,"WM_STATE", True); + Atom type; + int format; + unsigned long len; + unsigned long remaining; + unsigned char *data = NULL; + + int result = XGetWindowProperty( + x11_display, + x11_window, + property, + 0, + 32, + False, + AnyPropertyType, + &type, + &format, + &len, + &remaining, + &data + ); + + if( result == Success ) { + long *state = (long *) data; + if( state[0] == WM_IconicState ) + return true; + } + return false; +} + +void OS_X11::set_window_maximized(bool p_enabled) { + // Using EWMH -- Extended Window Manager Hints + XEvent xev; + Atom wm_state = XInternAtom(x11_display, "_NET_WM_STATE", False); + Atom wm_max_horz = XInternAtom(x11_display, "_NET_WM_STATE_MAXIMIZED_HORZ", False); + Atom wm_max_vert = XInternAtom(x11_display, "_NET_WM_STATE_MAXIMIZED_VERT", False); + + memset(&xev, 0, sizeof(xev)); + xev.type = ClientMessage; + xev.xclient.window = x11_window; + xev.xclient.message_type = wm_state; + xev.xclient.format = 32; + xev.xclient.data.l[0] = p_enabled ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE; + xev.xclient.data.l[1] = wm_max_horz; + xev.xclient.data.l[2] = wm_max_vert; + + XSendEvent(x11_display, DefaultRootWindow(x11_display), False, SubstructureRedirectMask | SubstructureNotifyMask, &xev); + + maximized = p_enabled; +} + +bool OS_X11::is_window_maximized() const { + // Using EWMH -- Extended Window Manager Hints + Atom property = XInternAtom(x11_display,"_NET_WM_STATE",False ); + Atom type; + int format; + unsigned long len; + unsigned long remaining; + unsigned char *data = NULL; + + int result = XGetWindowProperty( + x11_display, + x11_window, + property, + 0, + 1024, + False, + XA_ATOM, + &type, + &format, + &len, + &remaining, + &data + ); + + if(result == Success) { + Atom *atoms = (Atom*) data; + Atom wm_max_horz = XInternAtom(x11_display, "_NET_WM_STATE_MAXIMIZED_HORZ", False); + Atom wm_max_vert = XInternAtom(x11_display, "_NET_WM_STATE_MAXIMIZED_VERT", False); + bool found_wm_max_horz = false; + bool found_wm_max_vert = false; + + for( unsigned int i=0; i < len; i++ ) { + if( atoms[i] == wm_max_horz ) + found_wm_max_horz = true; + if( atoms[i] == wm_max_vert ) + found_wm_max_vert = true; + + if( found_wm_max_horz && found_wm_max_vert ) + return true; + } + XFree(atoms); + } + + return false; +} + InputModifierState OS_X11::get_key_modifier_state(unsigned int p_x11_state) { @@ -598,11 +964,9 @@ void OS_X11::handle_key_event(XKeyEvent *p_event, bool p_echo) { KeySym keysym_keycode=0; // keysym used to find a keycode KeySym keysym_unicode=0; // keysym used to find unicode - int nbytes=0; // bytes the string takes - // XLookupString returns keysyms usable as nice scancodes/ char str[256+1]; - nbytes=XLookupString(xkeyevent, str, 256, &keysym_keycode, NULL); + XLookupString(xkeyevent, str, 256, &keysym_keycode, NULL); // Meanwhile, XLookupString returns keysyms useful for unicode. @@ -699,7 +1063,7 @@ void OS_X11::handle_key_event(XKeyEvent *p_event, bool p_echo) { ::Time tresh=ABS(peek_event.xkey.time-xkeyevent->time); if (peek_event.type == KeyPress && tresh<5 ) { KeySym rk; - nbytes=XLookupString((XKeyEvent*)&peek_event, str, 256, &rk, NULL); + XLookupString((XKeyEvent*)&peek_event, str, 256, &rk, NULL); if (rk==keysym_keycode) { XEvent event; XNextEvent(x11_display, &event); //erase next event @@ -763,13 +1127,18 @@ void OS_X11::process_xevents() { break; case VisibilityNotify: { - XVisibilityEvent * visibility = (XVisibilityEvent *)&event; minimized = (visibility->state == VisibilityFullyObscured); - } break; - case FocusIn: + case FocusIn: + minimized = false; +#ifdef NEW_WM_API + if(current_videomode.fullscreen) { + set_wm_fullscreen(true); + visual_server->init(); + } +#endif main_loop->notification(MainLoop::NOTIFICATION_WM_FOCUS_IN); if (mouse_mode==MOUSE_MODE_CAPTURED) { XGrabPointer(x11_display, x11_window, True, @@ -780,6 +1149,13 @@ void OS_X11::process_xevents() { break; case FocusOut: +#ifdef NEW_WM_API + if(current_videomode.fullscreen) { + set_wm_fullscreen(false); + set_window_minimized(true); + visual_server->init(); + } +#endif main_loop->notification(MainLoop::NOTIFICATION_WM_FOCUS_OUT); if (mouse_mode==MOUSE_MODE_CAPTURED) { //dear X11, I try, I really try, but you never work, you do whathever you want. @@ -806,7 +1182,7 @@ void OS_X11::process_xevents() { event.xbutton.x=last_mouse_pos.x; event.xbutton.y=last_mouse_pos.y; } - + InputEvent mouse_event; mouse_event.ID=++event_id; mouse_event.type = InputEvent::MOUSE_BUTTON; @@ -841,7 +1217,7 @@ void OS_X11::process_xevents() { last_click_ms+=diff; last_click_pos = Point2(event.xbutton.x,event.xbutton.y); } - } + } input->parse_input_event( mouse_event); @@ -851,16 +1227,15 @@ void OS_X11::process_xevents() { last_timestamp=event.xmotion.time; - + // Motion is also simple. // A little hack is in order // to be able to send relative motion events. - Point2i pos( event.xmotion.x, event.xmotion.y ); if (mouse_mode==MOUSE_MODE_CAPTURED) { #if 1 - Vector2 c = Point2i(current_videomode.width/2,current_videomode.height/2); + //Vector2 c = Point2i(current_videomode.width/2,current_videomode.height/2); if (pos==Point2i(current_videomode.width/2,current_videomode.height/2)) { //this sucks, it's a hack, etc and is a little inaccurate, etc. //but nothing I can do, X11 sucks. @@ -869,9 +1244,9 @@ void OS_X11::process_xevents() { break; } - Point2i ncenter = pos; - pos = last_mouse_pos + ( pos-center ); - center=ncenter; + Point2i new_center = pos; + pos = last_mouse_pos + ( pos - center ); + center=new_center; do_mouse_warp=true; #else //Dear X11, thanks for making my life miserable @@ -884,9 +1259,7 @@ void OS_X11::process_xevents() { XWarpPointer(x11_display, None, x11_window, 0,0,0,0, (int)center.x, (int)center.y); #endif - } - if (!last_mouse_pos_valid) { @@ -895,7 +1268,14 @@ void OS_X11::process_xevents() { } Point2i rel = pos - last_mouse_pos; - + +#ifdef NEW_WM_API + if (mouse_mode==MOUSE_MODE_CAPTURED) { + pos.x = current_videomode.width / 2; + pos.y = current_videomode.height / 2; + } +#endif + InputEvent motion_event; motion_event.ID=++event_id; motion_event.type=InputEvent::MOUSE_MOTION; @@ -915,6 +1295,8 @@ void OS_X11::process_xevents() { motion_event.mouse_motion.relative_y=rel.y; last_mouse_pos=pos; + + // printf("rel: %d,%d\n", rel.x, rel.y ); input->parse_input_event( motion_event); @@ -989,8 +1371,18 @@ void OS_X11::process_xevents() { if (do_mouse_warp) { XWarpPointer(x11_display, None, x11_window, - 0,0,0,0, (int)current_videomode.width/2, (int)current_videomode.height/2); - + 0,0,0,0, (int)current_videomode.width/2, (int)current_videomode.height/2); + + /* + Window root, child; + int root_x, root_y; + int win_x, win_y; + unsigned int mask; + XQueryPointer( x11_display, x11_window, &root, &child, &root_x, &root_y, &win_x, &win_y, &mask ); + + printf("Root: %d,%d\n", root_x, root_y); + printf("Win: %d,%d\n", win_x, win_y); + */ } } @@ -1358,6 +1750,7 @@ void OS_X11::process_joysticks() { #endif }; + void OS_X11::set_cursor_shape(CursorShape p_shape) { ERR_FAIL_INDEX(p_shape,CURSOR_MAX); @@ -1470,8 +1863,6 @@ OS_X11::OS_X11() { #endif minimized = false; - xim_style=NULL; + xim_style=0L; mouse_mode=MOUSE_MODE_VISIBLE; - - }; diff --git a/platform/x11/os_x11.h b/platform/x11/os_x11.h index dd2476ec1b..ebcb0dc2fc 100644 --- a/platform/x11/os_x11.h +++ b/platform/x11/os_x11.h @@ -160,14 +160,20 @@ class OS_X11 : public OS_Unix { Joystick joysticks[JOYSTICKS_MAX]; + unsigned int capture_idle; + bool maximized; + //void set_wm_border(bool p_enabled); + void set_wm_fullscreen(bool p_enabled); + + protected: virtual int get_video_driver_count() const; virtual const char * get_video_driver_name(int p_driver) const; virtual VideoMode get_default_video_mode() const; - virtual int get_audio_driver_count() const; - virtual const char * get_audio_driver_name(int p_driver) const; + virtual int get_audio_driver_count() const; + virtual const char * get_audio_driver_name(int p_driver) const; virtual void initialize(const VideoMode& p_desired,int p_video_driver,int p_audio_driver); virtual void finalize(); @@ -178,6 +184,7 @@ protected: void process_joysticks(); void close_joystick(int p_id = -1); + public: virtual String get_name(); @@ -213,6 +220,25 @@ public: virtual VideoMode get_video_mode(int p_screen=0) const; virtual void get_fullscreen_mode_list(List<VideoMode> *p_list,int p_screen=0) const; + + virtual int get_screen_count() const; + virtual int get_current_screen() const; + virtual void set_current_screen(int p_screen); + virtual Point2 get_screen_position(int p_screen=0) const; + virtual Size2 get_screen_size(int p_screen=0) const; + virtual Point2 get_window_position() const; + virtual void set_window_position(const Point2& p_position); + virtual Size2 get_window_size() const; + virtual void set_window_size(const Size2 p_size); + virtual void set_window_fullscreen(bool p_enabled); + virtual bool is_window_fullscreen() const; + virtual void set_window_resizable(bool p_enabled); + virtual bool is_window_resizable() const; + virtual void set_window_minimized(bool p_enabled); + virtual bool is_window_minimized() const; + virtual void set_window_maximized(bool p_enabled); + virtual bool is_window_maximized() const; + virtual void move_window_to_foreground(); void run(); |