1/*
2 * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.  Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26#import "AWTSurfaceLayers.h"
27#import "ThreadUtilities.h"
28#import "LWCToolkit.h"
29
30#import <JavaNativeFoundation/JavaNativeFoundation.h>
31#import <QuartzCore/CATransaction.h>
32
33@implementation AWTSurfaceLayers
34
35@synthesize windowLayer;
36
37- (id) initWithWindowLayer:(CALayer *)aWindowLayer {
38    self = [super init];
39    if (self == nil) return self;
40
41    self.windowLayer = aWindowLayer;
42
43    return self;
44}
45
46- (void) dealloc {
47    self.windowLayer = nil;
48    [super dealloc];
49}
50
51- (CALayer *) layer {
52    return layer;
53}
54
55- (void) setLayer:(CALayer *)newLayer {
56    if (layer != newLayer) {
57        if (layer != nil || newLayer == nil) {
58            [layer removeFromSuperlayer];
59            [layer release];
60        }
61
62        if (newLayer != nil) {
63            layer = [newLayer retain];
64            // REMIND: window layer -> container layer
65            [windowLayer addSublayer: layer];
66        }
67    }
68}
69
70// Updates back buffer size of the layer if it's an OpenGL layer
71// including all OpenGL sublayers
72+ (void) repaintLayersRecursively:(CALayer*)aLayer {
73    if ([aLayer isKindOfClass:[CAOpenGLLayer class]]) {
74        [aLayer setNeedsDisplay];
75    }
76    for(CALayer *child in aLayer.sublayers) {
77        [AWTSurfaceLayers repaintLayersRecursively: child];
78    }
79}
80
81- (void) setBounds:(CGRect)rect {
82    // translates values to the coordinate system of the "root" layer
83    rect.origin.y = windowLayer.bounds.size.height - rect.origin.y - rect.size.height;
84    [CATransaction begin];
85    [CATransaction setDisableActions:YES];
86    layer.frame = rect;
87    [CATransaction commit];
88    [AWTSurfaceLayers repaintLayersRecursively:layer];
89}
90
91@end
92
93/*
94 * Class:     sun_lwawt_macosx_CPlatformComponent
95 * Method:    nativeCreateLayer
96 * Signature: ()J
97 */
98JNIEXPORT jlong JNICALL
99Java_sun_lwawt_macosx_CPlatformComponent_nativeCreateComponent
100(JNIEnv *env, jobject obj, jlong windowLayerPtr)
101{
102  __block AWTSurfaceLayers *surfaceLayers = nil;
103
104JNF_COCOA_ENTER(env);
105
106    [ThreadUtilities performOnMainThreadWaiting:YES block:^(){
107
108        CALayer *windowLayer = jlong_to_ptr(windowLayerPtr);
109        surfaceLayers = [[AWTSurfaceLayers alloc] initWithWindowLayer: windowLayer];
110    }];
111    
112JNF_COCOA_EXIT(env);
113
114  return ptr_to_jlong(surfaceLayers);
115}
116
117/*
118 * Class:     sun_lwawt_macosx_CPlatformComponent
119 * Method:    nativeSetBounds
120 * Signature: (JIIII)V
121 */
122JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformComponent_nativeSetBounds
123(JNIEnv *env, jclass clazz, jlong surfaceLayersPtr, jint x, jint y, jint width, jint height)
124{
125JNF_COCOA_ENTER(env);
126
127  AWTSurfaceLayers *surfaceLayers = OBJC(surfaceLayersPtr);
128    
129  [ThreadUtilities performOnMainThreadWaiting:NO block:^(){
130
131      CGRect rect = CGRectMake(x, y, width, height);
132      [surfaceLayers setBounds: rect];
133  }];
134
135JNF_COCOA_EXIT(env);
136}
137