diff options
Diffstat (limited to 'platform')
| -rw-r--r-- | platform/android/java_class_wrapper.cpp | 2 | ||||
| -rw-r--r-- | platform/osx/os_osx.h | 6 | ||||
| -rw-r--r-- | platform/osx/os_osx.mm | 146 | ||||
| -rw-r--r-- | platform/windows/os_windows.cpp | 134 | ||||
| -rw-r--r-- | platform/windows/os_windows.h | 10 |
5 files changed, 239 insertions, 59 deletions
diff --git a/platform/android/java_class_wrapper.cpp b/platform/android/java_class_wrapper.cpp index 52ff9cd56..bd266c76b 100644 --- a/platform/android/java_class_wrapper.cpp +++ b/platform/android/java_class_wrapper.cpp @@ -546,7 +546,7 @@ JavaObject::~JavaObject() { void JavaClassWrapper::_bind_methods() { - ClassDB::bind_method(D_METHOD("wrap:JavaClass", "name"), &JavaClassWrapper::wrap); + ClassDB::bind_method(D_METHOD("wrap", "name"), &JavaClassWrapper::wrap); } bool JavaClassWrapper::_get_type_sig(JNIEnv *env, jobject obj, uint32_t &sig, String &strsig) { diff --git a/platform/osx/os_osx.h b/platform/osx/os_osx.h index 4b5682518..56e6802ee 100644 --- a/platform/osx/os_osx.h +++ b/platform/osx/os_osx.h @@ -104,6 +104,10 @@ public: Size2 window_size; Rect2 restore_rect; + Point2 im_position; + ImeCallback im_callback; + void *im_target; + power_osx *power_manager; float _mouse_scale(float p_scale) { @@ -203,6 +207,8 @@ public: virtual void set_borderless_window(int p_borderless); virtual bool get_borderless_window(); + virtual void set_ime_position(const Point2 &p_pos); + virtual void set_ime_intermediate_text_callback(ImeCallback p_callback, void *p_inp); virtual PowerState get_power_state(); virtual int get_power_seconds_left(); diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm index e88405805..6d8a6eca6 100644 --- a/platform/osx/os_osx.mm +++ b/platform/osx/os_osx.mm @@ -261,10 +261,12 @@ static bool mouse_down_control = false; @end -@interface GodotContentView : NSView { +@interface GodotContentView : NSView <NSTextInputClient> { NSTrackingArea *trackingArea; + NSMutableAttributedString *markedText; + bool imeMode; } - +- (void)cancelComposition; @end @implementation GodotContentView @@ -278,16 +280,128 @@ static bool mouse_down_control = false; - (id)init { self = [super init]; trackingArea = nil; + imeMode = false; [self updateTrackingAreas]; [self registerForDraggedTypes:[NSArray arrayWithObject:NSFilenamesPboardType]]; + markedText = [[NSMutableAttributedString alloc] init]; return self; } - (void)dealloc { [trackingArea release]; + [markedText release]; [super dealloc]; } +static const NSRange kEmptyRange = { NSNotFound, 0 }; + +- (BOOL)hasMarkedText { + return (markedText.length > 0); +} + +- (NSRange)markedRange { + return (markedText.length > 0) ? NSMakeRange(0, markedText.length - 1) : kEmptyRange; +} + +- (NSRange)selectedRange { + return kEmptyRange; +} + +- (void)setMarkedText:(id)aString selectedRange:(NSRange)selectedRange replacementRange:(NSRange)replacementRange { + if ([aString isKindOfClass:[NSAttributedString class]]) { + [markedText initWithAttributedString:aString]; + } else { + [markedText initWithString:aString]; + } + if (OS_OSX::singleton->im_callback) { + 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)); + } +} + +- (void)doCommandBySelector:(SEL)aSelector { + if ([self respondsToSelector:aSelector]) + [self performSelector:aSelector]; +} + +- (void)unmarkText { + imeMode = false; + [[markedText mutableString] setString:@""]; + if (OS_OSX::singleton->im_callback) + OS_OSX::singleton->im_callback(OS_OSX::singleton->im_target, "", Point2()); +} + +- (NSArray *)validAttributesForMarkedText { + return [NSArray array]; +} + +- (NSAttributedString *)attributedSubstringForProposedRange:(NSRange)aRange actualRange:(NSRangePointer)actualRange { + return nil; +} + +- (NSUInteger)characterIndexForPoint:(NSPoint)aPoint { + return 0; +} + +- (NSRect)firstRectForCharacterRange:(NSRange)aRange actualRange:(NSRangePointer)actualRange { + const NSRect contentRect = [OS_OSX::singleton->window_view frame]; + NSRect pointInWindowRect = NSMakeRect(OS_OSX::singleton->im_position.x / OS_OSX::singleton->display_scale, contentRect.size.height - (OS_OSX::singleton->im_position.y / OS_OSX::singleton->display_scale) - 1, 0, 0); + NSPoint pointOnScreen = [[OS_OSX::singleton->window_view window] convertRectToScreen:pointInWindowRect].origin; + + return NSMakeRect(pointOnScreen.x, pointOnScreen.y, 0, 0); +} + +- (void)cancelComposition { + [self unmarkText]; + NSInputManager *currentInputManager = [NSInputManager currentInputManager]; + [currentInputManager markedTextAbandoned:self]; +} + +- (void)insertText:(id)aString { + [self insertText:aString replacementRange:NSMakeRange(0, 0)]; +} + +- (void)insertText:(id)aString replacementRange:(NSRange)replacementRange { + NSEvent *event = [NSApp currentEvent]; + Ref<InputEventKey> k; + k.instance(); + + get_key_modifier_state([event modifierFlags], k); + k->set_pressed(true); + k->set_echo(false); + k->set_scancode(0); + + NSString *characters; + if ([aString isKindOfClass:[NSAttributedString class]]) { + characters = [aString string]; + } else { + characters = (NSString *)aString; + } + + NSUInteger i, length = [characters length]; + + NSCharacterSet *ctrlChars = [NSCharacterSet controlCharacterSet]; + NSCharacterSet *wsnlChars = [NSCharacterSet whitespaceAndNewlineCharacterSet]; + if ([characters rangeOfCharacterFromSet:ctrlChars].length && [characters rangeOfCharacterFromSet:wsnlChars].length == 0) { + NSInputManager *currentInputManager = [NSInputManager currentInputManager]; + [currentInputManager markedTextAbandoned:self]; + [self cancelComposition]; + return; + } + + for (i = 0; i < length; i++) { + const unichar codepoint = [characters characterAtIndex:i]; + if ((codepoint & 0xFF00) == 0xF700) + continue; + + k->set_unicode(codepoint); + OS_OSX::singleton->push_input(k); + } + [self cancelComposition]; +} + - (NSDragOperation)draggingEntered:(id<NSDraggingInfo>)sender { return NSDragOperationCopy; } @@ -634,15 +748,12 @@ static int translateKey(unsigned int key) { NSString *characters = [event characters]; NSUInteger i, length = [characters length]; - if (length > 0 && keycode_has_unicode(k->get_scancode())) { - for (i = 0; i < length; i++) { - k->set_unicode([characters characterAtIndex:i]); - OS_OSX::singleton->push_input(k); - k->set_scancode(0); - } - } else { + //disable raw input in IME mode + if (!imeMode) OS_OSX::singleton->push_input(k); - } + + if ((OS_OSX::singleton->im_position.x != 0) && (OS_OSX::singleton->im_position.y != 0)) + [self interpretKeyEvents:[NSArray arrayWithObject:event]]; } - (void)flagsChanged:(NSEvent *)event { @@ -761,6 +872,18 @@ inline void sendScrollEvent(int button, double factor, 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]; + } +} + +void OS_OSX::set_ime_position(const Point2 &p_pos) { + im_position = p_pos; +} + int OS_OSX::get_video_driver_count() const { return 1; } @@ -1735,6 +1858,9 @@ OS_OSX::OS_OSX() { mouse_mode = OS::MOUSE_MODE_VISIBLE; main_loop = NULL; singleton = this; + im_position = Point2(); + im_callback = NULL; + im_target = NULL; autoreleasePool = [[NSAutoreleasePool alloc] init]; eventSource = CGEventSourceCreate(kCGEventSourceStateHIDSystemState); diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp index f72e5ef59..779f909a1 100644 --- a/platform/windows/os_windows.cpp +++ b/platform/windows/os_windows.cpp @@ -889,23 +889,6 @@ static int QueryDpiForMonitor(HMONITOR hmon, _MonitorDpiType dpiType = MDT_Defau return (dpiX + dpiY) / 2; } -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.position.x = lprcMonitor->left; - minfo.rect.position.y = lprcMonitor->top; - minfo.rect.size.x = lprcMonitor->right - lprcMonitor->left; - minfo.rect.size.y = lprcMonitor->bottom - lprcMonitor->top; - - minfo.dpi = QueryDpiForMonitor(hMonitor); - - self->monitor_info.push_back(minfo); - - return TRUE; -} - void OS_Windows::initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver) { main_loop = NULL; @@ -941,9 +924,6 @@ void OS_Windows::initialize(const VideoMode &p_desired, int p_video_driver, int return; // Return } - EnumDisplayMonitors(NULL, NULL, MonitorEnumProc, 0); - - print_line("DETECTED MONITORS: " + itos(monitor_info.size())); pre_fs_valid = true; if (video_mode.fullscreen) { @@ -1217,8 +1197,6 @@ void OS_Windows::finalize() { physics_2d_server->finish(); memdelete(physics_2d_server); - - monitor_info.clear(); } void OS_Windows::finalize_core() { @@ -1344,51 +1322,131 @@ OS::VideoMode OS_Windows::get_video_mode(int p_screen) const { void OS_Windows::get_fullscreen_mode_list(List<VideoMode> *p_list, int p_screen) const { } +static BOOL CALLBACK _MonitorEnumProcCount(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData) { + + int *data = (int *)dwData; + (*data)++; + return TRUE; +} + int OS_Windows::get_screen_count() const { - return monitor_info.size(); + int data = 0; + EnumDisplayMonitors(NULL, NULL, _MonitorEnumProcCount, (LPARAM)&data); + return data; } -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; +typedef struct { + int count; + int screen; + HMONITOR monitor; +} EnumScreenData; + +static BOOL CALLBACK _MonitorEnumProcScreen(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData) { + + EnumScreenData *data = (EnumScreenData *)dwData; + if (data->monitor == hMonitor) { + data->screen = data->count; } - return 0; + data->count++; + return TRUE; } -void OS_Windows::set_current_screen(int p_screen) { - ERR_FAIL_INDEX(p_screen, monitor_info.size()); +int OS_Windows::get_current_screen() const { + + EnumScreenData data = { 0, 0, MonitorFromWindow(hWnd, MONITOR_DEFAULTTONEAREST) }; + EnumDisplayMonitors(NULL, NULL, _MonitorEnumProcScreen, (LPARAM)&data); + return data.screen; +} + +void OS_Windows::set_current_screen(int p_screen) { Vector2 ofs = get_window_position() - get_screen_position(get_current_screen()); set_window_position(ofs + get_screen_position(p_screen)); } +typedef struct { + int count; + int screen; + Point2 pos; +} EnumPosData; + +static BOOL CALLBACK _MonitorEnumProcPos(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData) { + + EnumPosData *data = (EnumPosData *)dwData; + if (data->count == data->screen) { + data->pos.x = lprcMonitor->left; + data->pos.y = lprcMonitor->top; + } + + data->count++; + return TRUE; +} + 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.position); + EnumPosData data = { 0, p_screen, Point2() }; + EnumDisplayMonitors(NULL, NULL, _MonitorEnumProcPos, (LPARAM)&data); + return data.pos; } + +typedef struct { + int count; + int screen; + Size2 size; +} EnumSizeData; + +static BOOL CALLBACK _MonitorEnumProcSize(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData) { + + EnumSizeData *data = (EnumSizeData *)dwData; + if (data->count == data->screen) { + data->size.x = lprcMonitor->right - lprcMonitor->left; + data->size.y = lprcMonitor->bottom - lprcMonitor->top; + } + + data->count++; + return TRUE; +} + 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); + EnumSizeData data = { 0, p_screen, Size2() }; + EnumDisplayMonitors(NULL, NULL, _MonitorEnumProcSize, (LPARAM)&data); + return data.size; +} + +typedef struct { + int count; + int screen; + int dpi; +} EnumDpiData; + +static BOOL CALLBACK _MonitorEnumProcDpi(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData) { + + EnumDpiData *data = (EnumDpiData *)dwData; + if (data->count == data->screen) { + data->dpi = QueryDpiForMonitor(hMonitor); + } + + data->count++; + return TRUE; } int OS_Windows::get_screen_dpi(int p_screen) const { - ERR_FAIL_INDEX_V(p_screen, monitor_info.size(), 72); - UINT dpix, dpiy; - return monitor_info[p_screen].dpi; + EnumDpiData data = { 0, p_screen, 72 }; + EnumDisplayMonitors(NULL, NULL, _MonitorEnumProcDpi, (LPARAM)&data); + return data.dpi; } + 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) { if (video_mode.fullscreen) return; diff --git a/platform/windows/os_windows.h b/platform/windows/os_windows.h index beaf5d5e3..e9af14f11 100644 --- a/platform/windows/os_windows.h +++ b/platform/windows/os_windows.h @@ -164,22 +164,12 @@ protected: }; Map<ProcessID, ProcessInfo> *process_map; - struct MonitorInfo { - HMONITOR hMonitor; - HDC hdcMonitor; - Rect2 rect; - int dpi; - }; - bool pre_fs_valid; RECT pre_fs_rect; - Vector<MonitorInfo> monitor_info; bool maximized; bool minimized; bool borderless; - static BOOL CALLBACK MonitorEnumProc(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData); - public: LRESULT WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); |
