summaryrefslogtreecommitdiff
path: root/platform/osx/os_osx.mm
diff options
context:
space:
mode:
Diffstat (limited to 'platform/osx/os_osx.mm')
-rw-r--r--platform/osx/os_osx.mm160
1 files changed, 129 insertions, 31 deletions
diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm
index fbefd41bb7..bde0b4e898 100644
--- a/platform/osx/os_osx.mm
+++ b/platform/osx/os_osx.mm
@@ -541,7 +541,9 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
}
- (void)cursorUpdate:(NSEvent *)event {
- //setModeCursor(window, window->cursorMode);
+ OS::CursorShape p_shape = OS_OSX::singleton->cursor_shape;
+ OS_OSX::singleton->cursor_shape = OS::CURSOR_MAX;
+ OS_OSX::singleton->set_cursor_shape(p_shape);
}
static void _mouseDownEvent(NSEvent *event, int index, int mask, bool pressed) {
@@ -656,11 +658,12 @@ static void _mouseDownEvent(NSEvent *event, int index, int mask, bool pressed) {
return;
if (OS_OSX::singleton->main_loop && OS_OSX::singleton->mouse_mode != OS::MOUSE_MODE_CAPTURED)
OS_OSX::singleton->main_loop->notification(MainLoop::NOTIFICATION_WM_MOUSE_ENTER);
- if (OS_OSX::singleton->input) {
+ if (OS_OSX::singleton->input)
OS_OSX::singleton->input->set_mouse_in_window(true);
- OS_OSX::singleton->cursor_shape = OS::CURSOR_MAX;
- OS_OSX::singleton->set_cursor_shape(OS::CURSOR_ARROW);
- }
+
+ OS::CursorShape p_shape = OS_OSX::singleton->cursor_shape;
+ OS_OSX::singleton->cursor_shape = OS::CURSOR_MAX;
+ OS_OSX::singleton->set_cursor_shape(p_shape);
}
- (void)magnifyWithEvent:(NSEvent *)event {
@@ -847,16 +850,16 @@ struct _KeyCodeMap {
static const _KeyCodeMap _keycodes[55] = {
{ '`', KEY_QUOTELEFT },
{ '~', KEY_ASCIITILDE },
- { '0', KEY_KP_0 },
- { '1', KEY_KP_1 },
- { '2', KEY_KP_2 },
- { '3', KEY_KP_3 },
- { '4', KEY_KP_4 },
- { '5', KEY_KP_5 },
- { '6', KEY_KP_6 },
- { '7', KEY_KP_7 },
- { '8', KEY_KP_8 },
- { '9', KEY_KP_9 },
+ { '0', KEY_0 },
+ { '1', KEY_1 },
+ { '2', KEY_2 },
+ { '3', KEY_3 },
+ { '4', KEY_4 },
+ { '5', KEY_5 },
+ { '6', KEY_6 },
+ { '7', KEY_7 },
+ { '8', KEY_8 },
+ { '9', KEY_9 },
{ '-', KEY_MINUS },
{ '_', KEY_UNDERSCORE },
{ '=', KEY_EQUAL },
@@ -1330,6 +1333,9 @@ Error OS_OSX::initialize(const VideoMode &p_desired, int p_video_driver, int p_a
restore_rect = Rect2(get_window_position(), get_window_size());
+ if (p_desired.layered_splash) {
+ set_window_per_pixel_transparency_enabled(true);
+ }
return OK;
}
@@ -1510,39 +1516,78 @@ void OS_OSX::set_cursor_shape(CursorShape p_shape) {
void OS_OSX::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) {
if (p_cursor.is_valid()) {
Ref<Texture> texture = p_cursor;
- Ref<Image> image = texture->get_data();
+ Ref<AtlasTexture> atlas_texture = p_cursor;
+ Ref<Image> image;
+ Size2 texture_size;
+ Rect2 atlas_rect;
- ERR_FAIL_COND(texture->get_width() > 256 || texture->get_height() > 256);
+ if (texture.is_valid()) {
+ image = texture->get_data();
+ }
+
+ if (!image.is_valid() && atlas_texture.is_valid()) {
+ texture = atlas_texture->get_atlas();
+
+ atlas_rect.size.width = texture->get_width();
+ atlas_rect.size.height = texture->get_height();
+ atlas_rect.position.x = atlas_texture->get_region().position.x;
+ atlas_rect.position.y = atlas_texture->get_region().position.y;
+
+ texture_size.width = atlas_texture->get_region().size.x;
+ texture_size.height = atlas_texture->get_region().size.y;
+ } else if (image.is_valid()) {
+ texture_size.width = texture->get_width();
+ texture_size.height = texture->get_height();
+ }
+
+ ERR_FAIL_COND(!texture.is_valid());
+ ERR_FAIL_COND(texture_size.width > 256 || texture_size.height > 256);
+
+ image = texture->get_data();
NSBitmapImageRep *imgrep = [[[NSBitmapImageRep alloc]
initWithBitmapDataPlanes:NULL
- pixelsWide:image->get_width()
- pixelsHigh:image->get_height()
+ pixelsWide:int(texture_size.width)
+ pixelsHigh:int(texture_size.height)
bitsPerSample:8
samplesPerPixel:4
hasAlpha:YES
isPlanar:NO
colorSpaceName:NSDeviceRGBColorSpace
- bytesPerRow:image->get_width() * 4
+ bytesPerRow:int(texture_size.width) * 4
bitsPerPixel:32] autorelease];
ERR_FAIL_COND(imgrep == nil);
uint8_t *pixels = [imgrep bitmapData];
- int len = image->get_width() * image->get_height();
+ int len = int(texture_size.width * texture_size.height);
PoolVector<uint8_t> data = image->get_data();
PoolVector<uint8_t>::Read r = data.read();
+ image->lock();
+
/* Premultiply the alpha channel */
for (int i = 0; i < len; i++) {
- uint8_t alpha = r[i * 4 + 3];
- pixels[i * 4 + 0] = (uint8_t)(((uint16_t)r[i * 4 + 0] * alpha) / 255);
- pixels[i * 4 + 1] = (uint8_t)(((uint16_t)r[i * 4 + 1] * alpha) / 255);
- pixels[i * 4 + 2] = (uint8_t)(((uint16_t)r[i * 4 + 2] * alpha) / 255);
+ int row_index = floor(i / texture_size.width) + atlas_rect.position.y;
+ int column_index = (i % int(texture_size.width)) + atlas_rect.position.x;
+
+ if (atlas_texture.is_valid()) {
+ column_index = MIN(column_index, atlas_rect.size.width - 1);
+ row_index = MIN(row_index, atlas_rect.size.height - 1);
+ }
+
+ uint32_t color = image->get_pixel(column_index, row_index).to_argb32();
+
+ uint8_t alpha = (color >> 24) & 0xFF;
+ pixels[i * 4 + 0] = ((color >> 16) & 0xFF) * alpha / 255;
+ pixels[i * 4 + 1] = ((color >> 8) & 0xFF) * alpha / 255;
+ pixels[i * 4 + 2] = ((color)&0xFF) * alpha / 255;
pixels[i * 4 + 3] = alpha;
}
- NSImage *nsimage = [[[NSImage alloc] initWithSize:NSMakeSize(image->get_width(), image->get_height())] autorelease];
+ image->unlock();
+
+ NSImage *nsimage = [[[NSImage alloc] initWithSize:NSMakeSize(texture_size.width, texture_size.height)] autorelease];
[nsimage addRepresentation:imgrep];
NSCursor *cursor = [[NSCursor alloc] initWithImage:nsimage hotSpot:NSMakePoint(p_hotspot.x, p_hotspot.y)];
@@ -1552,6 +1597,11 @@ void OS_OSX::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, c
if (p_shape == CURSOR_ARROW) {
[cursor set];
}
+ } else {
+ // Reset to default system cursor
+ cursors[p_shape] = NULL;
+ cursor_shape = CURSOR_MAX;
+ set_cursor_shape(p_shape);
}
}
@@ -2042,6 +2092,8 @@ void OS_OSX::set_window_size(const Size2 p_size) {
void OS_OSX::set_window_fullscreen(bool p_enabled) {
if (zoomed != p_enabled) {
+ if (layered_window)
+ set_window_per_pixel_transparency_enabled(false);
[window_object toggleFullScreen:nil];
}
zoomed = p_enabled;
@@ -2123,6 +2175,39 @@ void OS_OSX::request_attention() {
[NSApp requestUserAttention:NSCriticalRequest];
}
+bool OS_OSX::get_window_per_pixel_transparency_enabled() const {
+
+ if (!is_layered_allowed()) return false;
+ return layered_window;
+}
+
+void OS_OSX::set_window_per_pixel_transparency_enabled(bool p_enabled) {
+
+ if (!is_layered_allowed()) return;
+ if (layered_window != p_enabled) {
+ if (p_enabled) {
+ set_borderless_window(true);
+ GLint opacity = 0;
+ [window_object setBackgroundColor:[NSColor clearColor]];
+ [window_object setOpaque:NO];
+ [window_object setHasShadow:NO];
+ [context setValues:&opacity forParameter:NSOpenGLCPSurfaceOpacity];
+ layered_window = true;
+ } else {
+ GLint opacity = 1;
+ [window_object setBackgroundColor:[NSColor colorWithCalibratedWhite:1 alpha:1]];
+ [window_object setOpaque:YES];
+ [window_object setHasShadow:YES];
+ [context setValues:&opacity forParameter:NSOpenGLCPSurfaceOpacity];
+ layered_window = false;
+ }
+ [context update];
+ NSRect frame = [window_object frame];
+ [window_object setFrame:NSMakeRect(frame.origin.x, frame.origin.y, 1, 1) display:YES];
+ [window_object setFrame:frame display:YES];
+ }
+}
+
void OS_OSX::set_borderless_window(bool p_borderless) {
// OrderOut prevents a lose focus bug with the window
@@ -2131,6 +2216,9 @@ void OS_OSX::set_borderless_window(bool p_borderless) {
if (p_borderless) {
[window_object setStyleMask:NSWindowStyleMaskBorderless];
} else {
+ if (layered_window)
+ set_window_per_pixel_transparency_enabled(false);
+
[window_object setStyleMask:NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable | NSWindowStyleMaskResizable];
// Force update of the window styles
@@ -2339,12 +2427,21 @@ void OS_OSX::run() {
//int frames=0;
//uint64_t frame=0;
- while (!force_quit) {
+ bool quit = false;
- process_events(); // get rid of pending events
- joypad_osx->process_joypads();
- if (Main::iteration() == true)
- break;
+ while (!force_quit && !quit) {
+
+ @try {
+
+ process_events(); // get rid of pending events
+ joypad_osx->process_joypads();
+
+ if (Main::iteration() == true) {
+ quit = true;
+ }
+ } @catch (NSException *exception) {
+ ERR_PRINTS("NSException: " + String([exception reason].UTF8String));
+ }
};
main_loop->finish();
@@ -2435,6 +2532,7 @@ OS_OSX::OS_OSX() {
im_position = Point2();
im_callback = NULL;
im_target = NULL;
+ layered_window = false;
autoreleasePool = [[NSAutoreleasePool alloc] init];
eventSource = CGEventSourceCreate(kCGEventSourceStateHIDSystemState);