< prev index next >

modules/javafx.graphics/src/main/native-glass/mac/GlassTouches.m

Print this page

  1 /*
  2  * Copyright (c) 2012, 2018, 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

 25 
 26 #import "common.h"
 27 #import "com_sun_glass_events_TouchEvent.h"
 28 
 29 #import "GlassMacros.h"
 30 #import "GlassTouches.h"
 31 #import "GlassKey.h"
 32 #import "GlassHelper.h"
 33 #import "GlassStatics.h"
 34 
 35 
 36 //#define VERBOSE
 37 #ifndef VERBOSE
 38     #define LOG(MSG, ...)
 39 #else
 40     #define LOG(MSG, ...) GLASS_LOG(MSG, ## __VA_ARGS__);
 41 #endif
 42 
 43 
 44 static GlassTouches* glassTouches = nil;

 45 
 46 
 47 @interface GlassTouches (hidden)
 48 
 49 - (void)releaseTouches;
 50 
 51 - (void)terminateImpl;
 52 
 53 - (void)enableTouchInputEventTap;
 54 
 55 - (void)sendJavaTouchEvent:(NSEvent *)theEvent;
 56 - (void)notifyTouch:(JNIEnv*)env    identity:(const id)identity
 57                                     phase:(NSUInteger)phase
 58                                     pos:(const NSPoint*)pos;
 59 @end
 60 
 61 
 62 static jint getTouchStateFromPhase(NSUInteger phase)
 63 {
 64     switch (phase)

159     if (!glassTouches || glassTouches->curConsumer != delegate)
160     {
161         return;
162     }
163 
164     // Keep updating java touch point counter, just have no view to notify.
165     glassTouches->curConsumer = nil;
166 
167     LOG("TOUCHES: stopTracking: delegate=%p\n", glassTouches->curConsumer);
168 }
169 
170 + (void)terminate
171 {
172     // Should be called right after Application's run loop terminate
173     [glassTouches terminateImpl];
174     glassTouches = nil;
175 }
176 
177 - (id)init
178 {





179     self = [super init];
180     if (self != nil)
181     {
182         self->curConsumer   = nil;
183         self->eventTap      = nil;
184         self->runLoopSource = nil;
185         self->touches       = nil;
186         self->lastTouchId   = 0;
187 
188         //
189         // Notes after fixing RT-23199:
190         //
191         //  Don't use NSMachPort and NSRunLoop to integrate CFMachPortRef
192         //  instance into run loop.
193         //
194         // Ignoring the above "don't"s results into performance degradation
195         // referenced in the bug.
196         //
197 
198         self->eventTap = CGEventTapCreate(kCGHIDEventTap,
199                                           kCGHeadInsertEventTap,
200                                           kCGEventTapOptionListenOnly,
201                                           CGEventMaskBit(NSEventTypeGesture),
202                                           listenTouchEvents, nil);
203 
204         LOG("TOUCHES: eventTap=%p\n", self->eventTap);
205 
206         if (self->eventTap)
207         {   // Create a run loop source.
208             self->runLoopSource = CFMachPortCreateRunLoopSource(
209                                                         kCFAllocatorDefault,
210                                                         self->eventTap, 0);
211 
212             LOG("TOUCHES: runLoopSource=%p\n", self->runLoopSource);
213 
214             // Add to the current run loop.
215             CFRunLoopAddSource(CFRunLoopGetCurrent(), self->runLoopSource,
216                                kCFRunLoopCommonModes);


217         }
218     }
219     return self;
220 }
221 
222 @end
223 
224 
225 @implementation GlassTouches (hidden)
226 - (void)terminateImpl
227 {
228     LOG("TOUCHES: terminateImpl eventTap=%p runLoopSource=%p\n", self->eventTap,
229         self->runLoopSource);

230 
231     if (self->runLoopSource)
232     {
233         CFRunLoopRemoveSource(CFRunLoopGetCurrent(), self->runLoopSource,
234                               kCFRunLoopCommonModes);
235         CFRelease(self->runLoopSource);
236         self->runLoopSource = nil;
237     }
238 
239     if (self->eventTap)
240     {
241         CFRelease(self->eventTap);
242         self->eventTap = nil;

243     }
244 
245     [self releaseTouches];
246 }
247 
248 - (void)enableTouchInputEventTap
249 {
250     CGEventTapEnable(self->eventTap, true);


251 }
252 
253 - (void)sendJavaTouchEvent:(NSEvent *)theEvent
254 {
255     jint modifiers = GetJavaModifiers(theEvent);
256 
257     const NSSet* touchPoints =
258             [theEvent touchesMatchingPhase:NSTouchPhaseAny inView:nil];
259 
260     //
261     // Known issues with OSX touch input:
262     // - multiple 'NSTouchPhaseBegan' for the same touch point;
263     // - missing 'NSTouchPhaseEnded' for released touch points
264     //  (RT-20139, RT-20375);
265     //
266 
267     //
268     // Find just released touch points that are not in the cache already.
269     // Don't send TouchEvent#TOUCH_RELEASED for these touch points.
270     //

  1 /*
  2  * Copyright (c) 2012, 2020, 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

 25 
 26 #import "common.h"
 27 #import "com_sun_glass_events_TouchEvent.h"
 28 
 29 #import "GlassMacros.h"
 30 #import "GlassTouches.h"
 31 #import "GlassKey.h"
 32 #import "GlassHelper.h"
 33 #import "GlassStatics.h"
 34 
 35 
 36 //#define VERBOSE
 37 #ifndef VERBOSE
 38     #define LOG(MSG, ...)
 39 #else
 40     #define LOG(MSG, ...) GLASS_LOG(MSG, ## __VA_ARGS__);
 41 #endif
 42 
 43 
 44 static GlassTouches* glassTouches = nil;
 45 static BOOL useEventTap = NO;
 46 
 47 
 48 @interface GlassTouches (hidden)
 49 
 50 - (void)releaseTouches;
 51 
 52 - (void)terminateImpl;
 53 
 54 - (void)enableTouchInputEventTap;
 55 
 56 - (void)sendJavaTouchEvent:(NSEvent *)theEvent;
 57 - (void)notifyTouch:(JNIEnv*)env    identity:(const id)identity
 58                                     phase:(NSUInteger)phase
 59                                     pos:(const NSPoint*)pos;
 60 @end
 61 
 62 
 63 static jint getTouchStateFromPhase(NSUInteger phase)
 64 {
 65     switch (phase)

160     if (!glassTouches || glassTouches->curConsumer != delegate)
161     {
162         return;
163     }
164 
165     // Keep updating java touch point counter, just have no view to notify.
166     glassTouches->curConsumer = nil;
167 
168     LOG("TOUCHES: stopTracking: delegate=%p\n", glassTouches->curConsumer);
169 }
170 
171 + (void)terminate
172 {
173     // Should be called right after Application's run loop terminate
174     [glassTouches terminateImpl];
175     glassTouches = nil;
176 }
177 
178 - (id)init
179 {
180     useEventTap = YES;
181     if (@available(macOS 10.15, *)) {
182         useEventTap = NO;
183     }
184 
185     self = [super init];
186     if (self != nil)
187     {
188         self->curConsumer   = nil;
189         self->eventTap      = nil;
190         self->runLoopSource = nil;
191         self->touches       = nil;
192         self->lastTouchId   = 0;
193 
194         if (useEventTap) {
195             //
196             // Notes after fixing RT-23199:
197             //
198             //  Don't use NSMachPort and NSRunLoop to integrate CFMachPortRef
199             //  instance into run loop.
200             //
201             // Ignoring the above "don't"s results into performance degradation
202             // referenced in the bug.
203             //
204 
205             self->eventTap = CGEventTapCreate(kCGHIDEventTap,
206                                               kCGHeadInsertEventTap,
207                                               kCGEventTapOptionListenOnly,
208                                               CGEventMaskBit(NSEventTypeGesture),
209                                               listenTouchEvents, nil);
210 
211             LOG("TOUCHES: eventTap=%p\n", self->eventTap);
212 
213             if (self->eventTap)
214             {   // Create a run loop source.
215                 self->runLoopSource = CFMachPortCreateRunLoopSource(
216                                                             kCFAllocatorDefault,
217                                                             self->eventTap, 0);
218 
219                 LOG("TOUCHES: runLoopSource=%p\n", self->runLoopSource);
220 
221                 // Add to the current run loop.
222                 CFRunLoopAddSource(CFRunLoopGetCurrent(), self->runLoopSource,
223                                    kCFRunLoopCommonModes);
224             }
225         }
226     }
227     return self;
228 }
229 
230 @end
231 
232 
233 @implementation GlassTouches (hidden)
234 - (void)terminateImpl
235 {
236     if (useEventTap) {
237         LOG("TOUCHES: terminateImpl eventTap=%p runLoopSource=%p\n", self->eventTap,
238             self->runLoopSource);
239 
240         if (self->runLoopSource)
241         {
242             CFRunLoopRemoveSource(CFRunLoopGetCurrent(), self->runLoopSource,
243                                   kCFRunLoopCommonModes);
244             CFRelease(self->runLoopSource);
245             self->runLoopSource = nil;
246         }
247 
248         if (self->eventTap)
249         {
250             CFRelease(self->eventTap);
251             self->eventTap = nil;
252         }
253     }

254     [self releaseTouches];
255 }
256 
257 - (void)enableTouchInputEventTap
258 {
259     if (useEventTap) {
260         CGEventTapEnable(self->eventTap, true);
261     }
262 }
263 
264 - (void)sendJavaTouchEvent:(NSEvent *)theEvent
265 {
266     jint modifiers = GetJavaModifiers(theEvent);
267 
268     const NSSet* touchPoints =
269             [theEvent touchesMatchingPhase:NSTouchPhaseAny inView:nil];
270 
271     //
272     // Known issues with OSX touch input:
273     // - multiple 'NSTouchPhaseBegan' for the same touch point;
274     // - missing 'NSTouchPhaseEnded' for released touch points
275     //  (RT-20139, RT-20375);
276     //
277 
278     //
279     // Find just released touch points that are not in the cache already.
280     // Don't send TouchEvent#TOUCH_RELEASED for these touch points.
281     //
< prev index next >