Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.desktop/macosx/native/libawt_lwawt/awt/CClipboard.m
41152 views
1
/*
2
* Copyright (c) 2011, 2014, 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 "CDataTransferer.h"
27
#import "ThreadUtilities.h"
28
#import "JNIUtilities.h"
29
#import <Cocoa/Cocoa.h>
30
31
@interface CClipboard : NSObject { }
32
@property NSInteger changeCount;
33
@property jobject clipboardOwner;
34
35
+ (CClipboard*)sharedClipboard;
36
- (void)declareTypes:(NSArray *)types withOwner:(jobject)owner jniEnv:(JNIEnv*)env;
37
- (void)checkPasteboard:(id)sender;
38
@end
39
40
@implementation CClipboard
41
@synthesize changeCount = _changeCount;
42
@synthesize clipboardOwner = _clipboardOwner;
43
44
// Clipboard creation is synchronized at the Java level
45
+ (CClipboard*)sharedClipboard {
46
static CClipboard* sClipboard = nil;
47
if (sClipboard == nil) {
48
sClipboard = [[CClipboard alloc] init];
49
[[NSNotificationCenter defaultCenter] addObserver:sClipboard selector: @selector(checkPasteboard:)
50
name: NSApplicationDidBecomeActiveNotification
51
object: nil];
52
}
53
54
return sClipboard;
55
}
56
57
- (id)init {
58
if (self = [super init]) {
59
self.changeCount = [[NSPasteboard generalPasteboard] changeCount];
60
}
61
return self;
62
}
63
64
- (void)declareTypes:(NSArray*)types withOwner:(jobject)owner jniEnv:(JNIEnv*)env {
65
@synchronized(self) {
66
if (owner != NULL) {
67
if (self.clipboardOwner != NULL) {
68
(*env)->DeleteGlobalRef(env, self.clipboardOwner);
69
}
70
self.clipboardOwner = (*env)->NewGlobalRef(env, owner);
71
}
72
}
73
[ThreadUtilities performOnMainThreadWaiting:YES block:^() {
74
self.changeCount = [[NSPasteboard generalPasteboard] declareTypes:types owner:self];
75
}];
76
}
77
78
- (void)checkPasteboard:(id)sender {
79
80
// This is called via NSApplicationDidBecomeActiveNotification.
81
82
// If the change count on the general pasteboard is different than when we set it
83
// someone else put data on the clipboard. That means the current owner lost ownership.
84
85
NSInteger newChangeCount = [[NSPasteboard generalPasteboard] changeCount];
86
87
if (self.changeCount != newChangeCount) {
88
self.changeCount = newChangeCount;
89
90
JNIEnv *env = [ThreadUtilities getJNIEnv];
91
// Notify that the content might be changed
92
DECLARE_CLASS(jc_CClipboard, "sun/lwawt/macosx/CClipboard");
93
DECLARE_STATIC_METHOD(jm_contentChanged, jc_CClipboard, "notifyChanged", "()V");
94
(*env)->CallStaticVoidMethod(env, jc_CClipboard, jm_contentChanged);
95
CHECK_EXCEPTION();
96
97
// If we have a Java pasteboard owner, tell it that it doesn't own the pasteboard anymore.
98
DECLARE_METHOD(jm_lostOwnership, jc_CClipboard, "notifyLostOwnership", "()V");
99
@synchronized(self) {
100
if (self.clipboardOwner) {
101
(*env)->CallVoidMethod(env, self.clipboardOwner, jm_lostOwnership);
102
CHECK_EXCEPTION();
103
(*env)->DeleteGlobalRef(env, self.clipboardOwner);
104
self.clipboardOwner = NULL;
105
}
106
}
107
}
108
}
109
110
- (BOOL) checkPasteboardWithoutNotification:(id)application {
111
AWT_ASSERT_APPKIT_THREAD;
112
113
NSInteger newChangeCount = [[NSPasteboard generalPasteboard] changeCount];
114
115
if (self.changeCount != newChangeCount) {
116
self.changeCount = newChangeCount;
117
return YES;
118
} else {
119
return NO;
120
}
121
}
122
123
@end
124
125
/*
126
* Class: sun_lwawt_macosx_CClipboard
127
* Method: declareTypes
128
* Signature: ([JLsun/awt/datatransfer/SunClipboard;)V
129
*/
130
JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CClipboard_declareTypes
131
(JNIEnv *env, jobject inObject, jlongArray inTypes, jobject inJavaClip)
132
{
133
JNI_COCOA_ENTER(env);
134
135
jint i;
136
jint nElements = (*env)->GetArrayLength(env, inTypes);
137
NSMutableArray *formatArray = [NSMutableArray arrayWithCapacity:nElements];
138
jlong *elements = (*env)->GetPrimitiveArrayCritical(env, inTypes, NULL);
139
140
for (i = 0; i < nElements; i++) {
141
NSString *pbFormat = formatForIndex(elements[i]);
142
if (pbFormat)
143
[formatArray addObject:pbFormat];
144
}
145
146
(*env)->ReleasePrimitiveArrayCritical(env, inTypes, elements, JNI_ABORT);
147
[[CClipboard sharedClipboard] declareTypes:formatArray withOwner:inJavaClip jniEnv:env];
148
JNI_COCOA_EXIT(env);
149
}
150
151
/*
152
* Class: sun_lwawt_macosx_CClipboard
153
* Method: setData
154
* Signature: ([BJ)V
155
*/
156
JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CClipboard_setData
157
(JNIEnv *env, jobject inObject, jbyteArray inBytes, jlong inFormat)
158
{
159
if (inBytes == NULL) {
160
return;
161
}
162
163
JNI_COCOA_ENTER(env);
164
jint nBytes = (*env)->GetArrayLength(env, inBytes);
165
jbyte *rawBytes = (*env)->GetPrimitiveArrayCritical(env, inBytes, NULL);
166
CHECK_NULL(rawBytes);
167
NSData *bytesAsData = [NSData dataWithBytes:rawBytes length:nBytes];
168
(*env)->ReleasePrimitiveArrayCritical(env, inBytes, rawBytes, JNI_ABORT);
169
NSString *format = formatForIndex(inFormat);
170
[ThreadUtilities performOnMainThreadWaiting:YES block:^() {
171
[[NSPasteboard generalPasteboard] setData:bytesAsData forType:format];
172
}];
173
JNI_COCOA_EXIT(env);
174
}
175
176
/*
177
* Class: sun_lwawt_macosx_CClipboard
178
* Method: getClipboardFormats
179
* Signature: (J)[J
180
*/
181
JNIEXPORT jlongArray JNICALL Java_sun_lwawt_macosx_CClipboard_getClipboardFormats
182
(JNIEnv *env, jobject inObject)
183
{
184
jlongArray returnValue = NULL;
185
JNI_COCOA_ENTER(env);
186
187
__block NSArray* dataTypes;
188
[ThreadUtilities performOnMainThreadWaiting:YES block:^() {
189
dataTypes = [[[NSPasteboard generalPasteboard] types] retain];
190
}];
191
[dataTypes autorelease];
192
193
NSUInteger nFormats = [dataTypes count];
194
NSUInteger knownFormats = 0;
195
NSUInteger i;
196
197
// There can be any number of formats on the general pasteboard. Find out which ones
198
// we know about (i.e., live in the flavormap.properties).
199
for (i = 0; i < nFormats; i++) {
200
NSString *format = (NSString *)[dataTypes objectAtIndex:i];
201
if (indexForFormat(format) != -1)
202
knownFormats++;
203
}
204
205
returnValue = (*env)->NewLongArray(env, knownFormats);
206
if (returnValue == NULL) {
207
return NULL;
208
}
209
210
if (knownFormats == 0) {
211
return returnValue;
212
}
213
214
// Now go back and map the formats we found back to Java indexes.
215
jboolean isCopy;
216
jlong *lFormats = (*env)->GetLongArrayElements(env, returnValue, &isCopy);
217
jlong *saveFormats = lFormats;
218
219
for (i = 0; i < nFormats; i++) {
220
NSString *format = (NSString *)[dataTypes objectAtIndex:i];
221
jlong index = indexForFormat(format);
222
223
if (index != -1) {
224
*lFormats = index;
225
lFormats++;
226
}
227
}
228
229
(*env)->ReleaseLongArrayElements(env, returnValue, saveFormats, JNI_COMMIT);
230
JNI_COCOA_EXIT(env);
231
return returnValue;
232
}
233
234
/*
235
* Class: sun_lwawt_macosx_CClipboard
236
* Method: getClipboardData
237
* Signature: (JJ)[B
238
*/
239
JNIEXPORT jbyteArray JNICALL Java_sun_lwawt_macosx_CClipboard_getClipboardData
240
(JNIEnv *env, jobject inObject, jlong format)
241
{
242
jbyteArray returnValue = NULL;
243
244
// Note that this routine makes no attempt to interpret the data, since we're returning
245
// a byte array back to Java. CDataTransferer will do that if necessary.
246
JNI_COCOA_ENTER(env);
247
248
NSString *formatAsString = formatForIndex(format);
249
__block NSData* clipData;
250
[ThreadUtilities performOnMainThreadWaiting:YES block:^() {
251
clipData = [[[NSPasteboard generalPasteboard] dataForType:formatAsString] retain];
252
}];
253
254
if (clipData == NULL) {
255
JNU_ThrowIOException(env, "Font transform has NaN position");
256
return NULL;
257
} else {
258
[clipData autorelease];
259
}
260
261
NSUInteger dataSize = [clipData length];
262
returnValue = (*env)->NewByteArray(env, dataSize);
263
if (returnValue == NULL) {
264
return NULL;
265
}
266
267
if (dataSize != 0) {
268
const void *dataBuffer = [clipData bytes];
269
(*env)->SetByteArrayRegion(env, returnValue, 0, dataSize, (jbyte *)dataBuffer);
270
}
271
272
JNI_COCOA_EXIT(env);
273
return returnValue;
274
}
275
276
/*
277
* Class: sun_lwawt_macosx_CClipboard
278
* Method: checkPasteboard
279
* Signature: ()V
280
*/
281
JNIEXPORT jboolean JNICALL Java_sun_lwawt_macosx_CClipboard_checkPasteboardWithoutNotification
282
(JNIEnv *env, jobject inObject)
283
{
284
__block BOOL ret = NO;
285
JNI_COCOA_ENTER(env);
286
[ThreadUtilities performOnMainThreadWaiting:YES block:^(){
287
ret = [[CClipboard sharedClipboard] checkPasteboardWithoutNotification:nil];
288
}];
289
290
JNI_COCOA_EXIT(env);
291
return ret;
292
}
293
294