diff options
Diffstat (limited to 'platform')
| -rw-r--r-- | platform/iphone/export/export.cpp | 70 | ||||
| -rw-r--r-- | platform/iphone/gl_view.mm | 3 | ||||
| -rw-r--r-- | platform/osx/export/export.cpp | 166 | ||||
| -rw-r--r-- | platform/osx/os_osx.h | 7 | ||||
| -rw-r--r-- | platform/osx/os_osx.mm | 39 | ||||
| -rw-r--r-- | platform/windows/detect.py | 4 | ||||
| -rw-r--r-- | platform/windows/os_windows.cpp | 38 | ||||
| -rw-r--r-- | platform/windows/os_windows.h | 1 | ||||
| -rw-r--r-- | platform/x11/os_x11.cpp | 10 |
9 files changed, 284 insertions, 54 deletions
diff --git a/platform/iphone/export/export.cpp b/platform/iphone/export/export.cpp index 7fb3afe9a9..8a9b254cdc 100644 --- a/platform/iphone/export/export.cpp +++ b/platform/iphone/export/export.cpp @@ -99,6 +99,70 @@ class EditorExportPlatformIOS : public EditorExportPlatform { Error _export_additional_assets(const String &p_out_dir, const Vector<String> &p_assets, bool p_is_framework, Vector<IOSExportAsset> &r_exported_assets); Error _export_additional_assets(const String &p_out_dir, const Vector<SharedObject> &p_libraries, Vector<IOSExportAsset> &r_exported_assets); + bool is_package_name_valid(const String &p_package, String *r_error = NULL) const { + + String pname = p_package; + + if (pname.length() == 0) { + if (r_error) { + *r_error = "Identifier is missing."; + } + return false; + } + + int segments = 0; + bool first = true; + for (int i = 0; i < pname.length(); i++) { + CharType c = pname[i]; + if (first && c == '.') { + if (r_error) { + *r_error = "Identifier segments must be of non-zero length."; + } + return false; + } + if (c == '.') { + segments++; + first = true; + continue; + } + if (!((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '_')) { + if (r_error) { + *r_error = "The character '" + String::chr(c) + "' is not allowed in Identifier."; + } + return false; + } + if (first && (c >= '0' && c <= '9')) { + if (r_error) { + *r_error = "A digit cannot be the first character in a Identifier segment."; + } + return false; + } + if (first && c == '_') { + if (r_error) { + *r_error = "The character '" + String::chr(c) + "' cannot be the first character in a Identifier segment."; + } + return false; + } + first = false; + } + + if (segments == 0) { + if (r_error) { + *r_error = "The Identifier must have at least one '.' separator."; + } + return false; + } + + if (first) { + if (r_error) { + *r_error = "Identifier segments must be of non-zero length."; + } + return false; + } + + return true; + } + protected: virtual void get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features); virtual void get_export_options(List<ExportOption> *r_options); @@ -987,6 +1051,12 @@ bool EditorExportPlatformIOS::can_export(const Ref<EditorExportPreset> &p_preset err += "App Store Team ID not specified - cannot configure the project.\n"; } + String identifier = p_preset->get("application/identifier"); + String pn_err; + if (!is_package_name_valid(identifier, &pn_err)) { + err += "Invalid Identifier - " + pn_err + "\n"; + } + for (unsigned int i = 0; i < (sizeof(icon_infos) / sizeof(icon_infos[0])); ++i) { IconInfo info = icon_infos[i]; String icon_path = p_preset->get(info.preset_key); diff --git a/platform/iphone/gl_view.mm b/platform/iphone/gl_view.mm index 2925b46007..5b4d1f8226 100644 --- a/platform/iphone/gl_view.mm +++ b/platform/iphone/gl_view.mm @@ -84,7 +84,8 @@ Rect2 _get_ios_window_safe_area(float p_window_width, float p_window_height) { } ERR_FAIL_COND_V(insets.left < 0 || insets.top < 0 || insets.right < 0 || insets.bottom < 0, Rect2(0, 0, p_window_width, p_window_height)); - return Rect2(insets.left, insets.top, p_window_width - insets.right - insets.left, p_window_height - insets.bottom - insets.top); + UIEdgeInsets window_insets = UIEdgeInsetsMake(_points_to_pixels(insets.top), _points_to_pixels(insets.left), _points_to_pixels(insets.bottom), _points_to_pixels(insets.right)); + return Rect2(window_insets.left, window_insets.top, p_window_width - window_insets.right - window_insets.left, p_window_height - window_insets.bottom - window_insets.top); } bool _play_video(String p_path, float p_volume, String p_audio_track, String p_subtitle_track) { diff --git a/platform/osx/export/export.cpp b/platform/osx/export/export.cpp index f27c042637..12a0193521 100644 --- a/platform/osx/export/export.cpp +++ b/platform/osx/export/export.cpp @@ -139,10 +139,76 @@ void EditorExportPlatformOSX::get_export_options(List<ExportOption> *r_options) r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "texture_format/etc2"), false)); } +void _rgba8_to_packbits_encode(int p_ch, int p_size, PoolVector<uint8_t> &p_source, Vector<uint8_t> &p_dest) { + + int src_len = p_size * p_size; + + Vector<uint8_t> result; + result.resize(src_len * 1.25); //temp vector for rle encoded data, make it 25% larger for worst case scenario + int res_size = 0; + + uint8_t buf[128]; + int buf_size = 0; + + int i = 0; + while (i < src_len) { + uint8_t cur = p_source.read()[i * 4 + p_ch]; + + if (i < src_len - 2) { + + if ((p_source.read()[(i + 1) * 4 + p_ch] == cur) && (p_source.read()[(i + 2) * 4 + p_ch] == cur)) { + if (buf_size > 0) { + result.write[res_size++] = (uint8_t)(buf_size - 1); + copymem(&result.write[res_size], &buf, buf_size); + res_size += buf_size; + buf_size = 0; + } + + uint8_t lim = i + 130 >= src_len ? src_len - i - 1 : 130; + bool hit_lim = true; + + for (int j = 3; j <= lim; j++) { + if (p_source.read()[(i + j) * 4 + p_ch] != cur) { + hit_lim = false; + i = i + j - 1; + result.write[res_size++] = (uint8_t)(j - 3 + 0x80); + result.write[res_size++] = cur; + break; + } + } + if (hit_lim) { + result.write[res_size++] = (uint8_t)(lim - 3 + 0x80); + result.write[res_size++] = cur; + i = i + lim; + } + } else { + buf[buf_size++] = cur; + if (buf_size == 128) { + result.write[res_size++] = (uint8_t)(buf_size - 1); + copymem(&result.write[res_size], &buf, buf_size); + res_size += buf_size; + buf_size = 0; + } + } + } else { + buf[buf_size++] = cur; + result.write[res_size++] = (uint8_t)(buf_size - 1); + copymem(&result.write[res_size], &buf, buf_size); + res_size += buf_size; + buf_size = 0; + } + + i++; + } + + int ofs = p_dest.size(); + p_dest.resize(p_dest.size() + res_size); + copymem(&p_dest.write[ofs], result.ptr(), res_size); +} + void EditorExportPlatformOSX::_make_icon(const Ref<Image> &p_icon, Vector<uint8_t> &p_data) { Ref<ImageTexture> it = memnew(ImageTexture); - int size = 512; Vector<uint8_t> data; @@ -152,32 +218,82 @@ void EditorExportPlatformOSX::_make_icon(const Ref<Image> &p_icon, Vector<uint8_ data.write[2] = 'n'; data.write[3] = 's'; - const char *name[] = { "ic09", "ic08", "ic07", "icp6", "icp5", "icp4" }; - int index = 0; - - while (size >= 16) { - + struct MacOSIconInfo { + const char *name; + const char *mask_name; + bool is_png; + int size; + }; + + static const MacOSIconInfo icon_infos[] = { + { "ic10", "", true, 1024 }, //1024x1024 32-bit PNG and 512x512@2x 32-bit "retina" PNG + { "ic09", "", true, 512 }, //512×512 32-bit PNG + { "ic14", "", true, 512 }, //256x256@2x 32-bit "retina" PNG + { "ic08", "", true, 256 }, //256×256 32-bit PNG + { "ic13", "", true, 256 }, //128x128@2x 32-bit "retina" PNG + { "ic07", "", true, 128 }, //128x128 32-bit PNG + { "ic12", "", true, 64 }, //32x32@2x 32-bit "retina" PNG + { "ic11", "", true, 32 }, //16x16@2x 32-bit "retina" PNG + { "il32", "l8mk", false, 32 }, //32x32 24-bit RLE + 8-bit uncompressed mask + { "is32", "s8mk", false, 16 } //16x16 24-bit RLE + 8-bit uncompressed mask + }; + + for (unsigned int i = 0; i < (sizeof(icon_infos) / sizeof(icon_infos[0])); ++i) { Ref<Image> copy = p_icon; // does this make sense? doesn't this just increase the reference count instead of making a copy? Do we even need a copy? copy->convert(Image::FORMAT_RGBA8); - copy->resize(size, size); - it->create_from_image(copy); - String path = EditorSettings::get_singleton()->get_cache_dir().plus_file("icon.png"); - ResourceSaver::save(path, it); - - FileAccess *f = FileAccess::open(path, FileAccess::READ); - ERR_FAIL_COND(!f); - - int ofs = data.size(); - uint32_t len = f->get_len(); - data.resize(data.size() + len + 8); - f->get_buffer(&data.write[ofs + 8], len); - memdelete(f); - len += 8; - len = BSWAP32(len); - copymem(&data.write[ofs], name[index], 4); - encode_uint32(len, &data.write[ofs + 4]); - index++; - size /= 2; + copy->resize(icon_infos[i].size, icon_infos[i].size); + + if (icon_infos[i].is_png) { + //encode png icon + it->create_from_image(copy); + String path = EditorSettings::get_singleton()->get_cache_dir().plus_file("icon.png"); + ResourceSaver::save(path, it); + + FileAccess *f = FileAccess::open(path, FileAccess::READ); + ERR_FAIL_COND(!f); + + int ofs = data.size(); + uint32_t len = f->get_len(); + data.resize(data.size() + len + 8); + f->get_buffer(&data.write[ofs + 8], len); + memdelete(f); + len += 8; + len = BSWAP32(len); + copymem(&data.write[ofs], icon_infos[i].name, 4); + encode_uint32(len, &data.write[ofs + 4]); + } else { + PoolVector<uint8_t> src_data = copy->get_data(); + + //encode 24bit RGB RLE icon + { + int ofs = data.size(); + data.resize(data.size() + 8); + + _rgba8_to_packbits_encode(0, icon_infos[i].size, src_data, data); // encode R + _rgba8_to_packbits_encode(1, icon_infos[i].size, src_data, data); // encode G + _rgba8_to_packbits_encode(2, icon_infos[i].size, src_data, data); // encode B + + int len = data.size() - ofs; + len = BSWAP32(len); + copymem(&data.write[ofs], icon_infos[i].name, 4); + encode_uint32(len, &data.write[ofs + 4]); + } + + //encode 8bit mask uncompressed icon + { + int ofs = data.size(); + int len = copy->get_width() * copy->get_height(); + data.resize(data.size() + len + 8); + + for (int j = 0; j < len; j++) { + data.write[ofs + 8 + j] = src_data.read()[j * 4 + 3]; + } + len += 8; + len = BSWAP32(len); + copymem(&data.write[ofs], icon_infos[i].mask_name, 4); + encode_uint32(len, &data.write[ofs + 4]); + } + } } uint32_t total_len = data.size(); diff --git a/platform/osx/os_osx.h b/platform/osx/os_osx.h index 546c88e74a..ae2eb6288c 100644 --- a/platform/osx/os_osx.h +++ b/platform/osx/os_osx.h @@ -124,8 +124,8 @@ public: Point2 im_position; bool im_active; - ImeCallback im_callback; - void *im_target; + String im_text; + Point2 im_selection; power_osx *power_manager; @@ -245,7 +245,8 @@ public: virtual void set_ime_active(const bool p_active); virtual void set_ime_position(const Point2 &p_pos); - virtual void set_ime_intermediate_text_callback(ImeCallback p_callback, void *p_inp); + virtual Point2 get_ime_selection() const; + virtual String get_ime_text() const; virtual String get_unique_id() const; diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm index e7b3e35381..f8dec3ec7a 100644 --- a/platform/osx/os_osx.mm +++ b/platform/osx/os_osx.mm @@ -427,11 +427,13 @@ static const NSRange kEmptyRange = { NSNotFound, 0 }; } else { [markedText initWithString:aString]; } - if (OS_OSX::singleton->im_callback) { + if (OS_OSX::singleton->im_active) { imeMode = true; - String ret; - ret.parse_utf8([[markedText mutableString] UTF8String]); - OS_OSX::singleton->im_callback(OS_OSX::singleton->im_target, ret, Point2(selectedRange.location, selectedRange.length)); + OS_OSX::singleton->im_text.parse_utf8([[markedText mutableString] UTF8String]); + OS_OSX::singleton->im_selection = Point2(selectedRange.location, selectedRange.length); + + if (OS_OSX::singleton->get_main_loop()) + OS_OSX::singleton->get_main_loop()->notification(MainLoop::NOTIFICATION_OS_IME_UPDATE); } } @@ -443,8 +445,13 @@ static const NSRange kEmptyRange = { NSNotFound, 0 }; - (void)unmarkText { imeMode = false; [[markedText mutableString] setString:@""]; - if (OS_OSX::singleton->im_callback) - OS_OSX::singleton->im_callback(OS_OSX::singleton->im_target, "", Point2()); + if (OS_OSX::singleton->im_active) { + OS_OSX::singleton->im_text = String(); + OS_OSX::singleton->im_selection = Point2(); + + if (OS_OSX::singleton->get_main_loop()) + OS_OSX::singleton->get_main_loop()->notification(MainLoop::NOTIFICATION_OS_IME_UPDATE); + } } - (NSArray *)validAttributesForMarkedText { @@ -1136,12 +1143,14 @@ inline void sendPanEvent(double dx, double dy, int modifierFlags) { @end -void OS_OSX::set_ime_intermediate_text_callback(ImeCallback p_callback, void *p_inp) { - im_callback = p_callback; - im_target = p_inp; - if (!im_callback) { - [window_view cancelComposition]; - } +Point2 OS_OSX::get_ime_selection() const { + + return im_selection; +} + +String OS_OSX::get_ime_text() const { + + return im_text; } String OS_OSX::get_unique_id() const { @@ -1169,10 +1178,14 @@ String OS_OSX::get_unique_id() const { } void OS_OSX::set_ime_active(const bool p_active) { + im_active = p_active; + if (!im_active) + [window_view cancelComposition]; } void OS_OSX::set_ime_position(const Point2 &p_pos) { + im_position = p_pos; } @@ -2637,8 +2650,6 @@ OS_OSX::OS_OSX() { singleton = this; im_active = false; im_position = Point2(); - im_callback = NULL; - im_target = NULL; layered_window = false; autoreleasePool = [[NSAutoreleasePool alloc] init]; diff --git a/platform/windows/detect.py b/platform/windows/detect.py index dd0042668f..e14db9a201 100644 --- a/platform/windows/detect.py +++ b/platform/windows/detect.py @@ -147,9 +147,9 @@ def setup_msvc_auto(env): # Note: actual compiler version can be found in env['MSVC_VERSION'], e.g. "14.1" for VS2015 # Get actual target arch into bits (it may be "default" at this point): if env['TARGET_ARCH'] in ('amd64', 'x86_64'): - env['bits'] = 64 + env['bits'] = '64' else: - env['bits'] = 32 + env['bits'] = '32' print(" Found MSVC version %s, arch %s, bits=%s" % (env['MSVC_VERSION'], env['TARGET_ARCH'], env['bits'])) if env['TARGET_ARCH'] in ('amd64', 'x86_64'): env["x86_libtheora_opt_vc"] = False diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp index bdf459fd83..55d2bb2153 100644 --- a/platform/windows/os_windows.cpp +++ b/platform/windows/os_windows.cpp @@ -727,16 +727,28 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) } } break; + case WM_MOVE: { + if (!IsIconic(hWnd)) { + int x = LOWORD(lParam); + int y = HIWORD(lParam); + last_pos = Point2(x, y); + } + } break; + case WM_SIZE: { - int window_w = LOWORD(lParam); - int window_h = HIWORD(lParam); - if (window_w > 0 && window_h > 0 && !preserve_window_size) { - video_mode.width = window_w; - video_mode.height = window_h; - } else { - preserve_window_size = false; - set_window_size(Size2(video_mode.width, video_mode.height)); + // Ignore size when a SIZE_MINIMIZED event is triggered + if (wParam != SIZE_MINIMIZED) { + int window_w = LOWORD(lParam); + int window_h = HIWORD(lParam); + if (window_w > 0 && window_h > 0 && !preserve_window_size) { + video_mode.width = window_w; + video_mode.height = window_h; + } else { + preserve_window_size = false; + set_window_size(Size2(video_mode.width, video_mode.height)); + } } + if (wParam == SIZE_MAXIMIZED) { maximized = true; minimized = false; @@ -1685,6 +1697,10 @@ int OS_Windows::get_screen_dpi(int p_screen) const { Point2 OS_Windows::get_window_position() const { + if (minimized) { + return last_pos; + } + RECT r; GetWindowRect(hWnd, &r); return Point2(r.left, r.top); @@ -1705,9 +1721,15 @@ void OS_Windows::set_window_position(const Point2 &p_position) { ClientToScreen(hWnd, (POINT *)&rect.right); ClipCursor(&rect); } + + last_pos = p_position; } Size2 OS_Windows::get_window_size() const { + if (minimized) { + return Size2(video_mode.width, video_mode.height); + } + RECT r; if (GetClientRect(hWnd, &r)) { // Only area inside of window border return Size2(r.right - r.left, r.bottom - r.top); diff --git a/platform/windows/os_windows.h b/platform/windows/os_windows.h index 6aadd6994c..d09ade4daa 100644 --- a/platform/windows/os_windows.h +++ b/platform/windows/os_windows.h @@ -93,6 +93,7 @@ class OS_Windows : public OS { HDC hDC; // Private GDI Device Context HINSTANCE hInstance; // Holds The Instance Of The Application HWND hWnd; + Point2 last_pos; HBITMAP hBitmap; //DIB section for layered window uint8_t *dib_data; diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp index 04854e93b6..0c02e47b5e 100644 --- a/platform/x11/os_x11.cpp +++ b/platform/x11/os_x11.cpp @@ -2853,11 +2853,19 @@ void OS_X11::set_context(int p_context) { XClassHint *classHint = XAllocClassHint(); if (classHint) { + char *wm_class = (char *)"Godot"; if (p_context == CONTEXT_EDITOR) classHint->res_name = (char *)"Godot_Editor"; if (p_context == CONTEXT_PROJECTMAN) classHint->res_name = (char *)"Godot_ProjectList"; - classHint->res_class = (char *)"Godot"; + + if (p_context == CONTEXT_ENGINE) { + classHint->res_name = (char *)"Godot_Engine"; + wm_class = (char *)((String)GLOBAL_GET("application/config/name")).utf8().ptrw(); + } + + classHint->res_class = wm_class; + XSetClassHint(x11_display, x11_window, classHint); XFree(classHint); } |