mirror of
https://github.com/JetBrains/JetBrainsRuntime.git
synced 2025-12-13 12:59:41 +01:00
Compare commits
3 Commits
ui-touch-t
...
635
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ae41b6933c | ||
|
|
c8ad353f45 | ||
|
|
57162c91c3 |
@@ -50,7 +50,7 @@ BOOL postEventDuringEventSynthesis = NO;
|
|||||||
* Subtypes of NSApplicationDefined, which are used for custom events.
|
* Subtypes of NSApplicationDefined, which are used for custom events.
|
||||||
*/
|
*/
|
||||||
enum {
|
enum {
|
||||||
ExecuteBlockEvent, NativeSyncQueueEvent
|
ExecuteBlockEvent = 777, NativeSyncQueueEvent
|
||||||
};
|
};
|
||||||
|
|
||||||
@implementation NSApplicationAWT
|
@implementation NSApplicationAWT
|
||||||
@@ -366,11 +366,15 @@ untilDate:(NSDate *)expiration inMode:(NSString *)mode dequeue:(BOOL)deqFlag {
|
|||||||
{
|
{
|
||||||
if ([event type] == NSApplicationDefined
|
if ([event type] == NSApplicationDefined
|
||||||
&& TS_EQUAL([event timestamp], dummyEventTimestamp)
|
&& TS_EQUAL([event timestamp], dummyEventTimestamp)
|
||||||
&& [event subtype] == NativeSyncQueueEvent) {
|
&& (short)[event subtype] == NativeSyncQueueEvent
|
||||||
|
&& [event data1] == NativeSyncQueueEvent
|
||||||
|
&& [event data2] == NativeSyncQueueEvent) {
|
||||||
[seenDummyEventLock lockWhenCondition:NO];
|
[seenDummyEventLock lockWhenCondition:NO];
|
||||||
[seenDummyEventLock unlockWithCondition:YES];
|
[seenDummyEventLock unlockWithCondition:YES];
|
||||||
|
|
||||||
} else if ([event type] == NSApplicationDefined && [event subtype] == ExecuteBlockEvent) {
|
} else if ([event type] == NSApplicationDefined
|
||||||
|
&& (short)[event subtype] == ExecuteBlockEvent
|
||||||
|
&& [event data1] != 0 && [event data2] == ExecuteBlockEvent) {
|
||||||
void (^block)() = (void (^)()) [event data1];
|
void (^block)() = (void (^)()) [event data1];
|
||||||
block();
|
block();
|
||||||
[block release];
|
[block release];
|
||||||
@@ -401,7 +405,7 @@ untilDate:(NSDate *)expiration inMode:(NSString *)mode dequeue:(BOOL)deqFlag {
|
|||||||
context: nil
|
context: nil
|
||||||
subtype: ExecuteBlockEvent
|
subtype: ExecuteBlockEvent
|
||||||
data1: encode
|
data1: encode
|
||||||
data2: 0];
|
data2: ExecuteBlockEvent];
|
||||||
|
|
||||||
[NSApp postEvent: event atStart: NO];
|
[NSApp postEvent: event atStart: NO];
|
||||||
[pool drain];
|
[pool drain];
|
||||||
@@ -419,8 +423,8 @@ untilDate:(NSDate *)expiration inMode:(NSString *)mode dequeue:(BOOL)deqFlag {
|
|||||||
windowNumber: 0
|
windowNumber: 0
|
||||||
context: nil
|
context: nil
|
||||||
subtype: NativeSyncQueueEvent
|
subtype: NativeSyncQueueEvent
|
||||||
data1: 0
|
data1: NativeSyncQueueEvent
|
||||||
data2: 0];
|
data2: NativeSyncQueueEvent];
|
||||||
if (useCocoa) {
|
if (useCocoa) {
|
||||||
[NSApp postEvent:event atStart:NO];
|
[NSApp postEvent:event atStart:NO];
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -1651,7 +1651,7 @@ LRESULT AwtComponent::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
|
|||||||
window->AwtSetActiveWindow(TRUE, LOWORD(lParam)/*hittest*/);
|
window->AwtSetActiveWindow(TRUE, LOWORD(lParam)/*hittest*/);
|
||||||
}
|
}
|
||||||
mr = mrConsume;
|
mr = mrConsume;
|
||||||
retValue = MA_NOACTIVATE;
|
retValue = AwtToolkit::GetInstance().IsActiveWindowTrackingEnabled() ? MA_ACTIVATE : MA_NOACTIVATE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case WM_CTLCOLORMSGBOX:
|
case WM_CTLCOLORMSGBOX:
|
||||||
|
|||||||
@@ -700,6 +700,13 @@ BOOL AwtToolkit::Initialize(BOOL localPump) {
|
|||||||
tk.m_touchKbrdAutoShowIsEnabled = env->CallStaticBooleanMethod(
|
tk.m_touchKbrdAutoShowIsEnabled = env->CallStaticBooleanMethod(
|
||||||
sunToolkitCls, isTouchKeyboardAutoShowEnabledMID);
|
sunToolkitCls, isTouchKeyboardAutoShowEnabledMID);
|
||||||
|
|
||||||
|
BOOL tracking = FALSE;
|
||||||
|
int result = 0;
|
||||||
|
result = ::SystemParametersInfo(SPI_GETACTIVEWINDOWTRACKING, 0,
|
||||||
|
&tracking, 0);
|
||||||
|
|
||||||
|
tk.m_active_window_tracking_mode_enabled = (tracking && (result != 0));
|
||||||
|
|
||||||
CATCH_BAD_ALLOC_RET(FALSE);
|
CATCH_BAD_ALLOC_RET(FALSE);
|
||||||
|
|
||||||
if (tk.m_isWin8OrLater && tk.m_touchKbrdAutoShowIsEnabled) {
|
if (tk.m_isWin8OrLater && tk.m_touchKbrdAutoShowIsEnabled) {
|
||||||
@@ -803,6 +810,10 @@ BOOL AwtToolkit::IsDynamicLayoutSet() {
|
|||||||
return m_isDynamicLayoutSet;
|
return m_isDynamicLayoutSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOL AwtToolkit::IsActiveWindowTrackingEnabled() {
|
||||||
|
return m_active_window_tracking_mode_enabled;
|
||||||
|
}
|
||||||
|
|
||||||
BOOL AwtToolkit::IsDynamicLayoutSupported() {
|
BOOL AwtToolkit::IsDynamicLayoutSupported() {
|
||||||
// SPI_GETDRAGFULLWINDOWS is only supported on Win95 if
|
// SPI_GETDRAGFULLWINDOWS is only supported on Win95 if
|
||||||
// Windows Plus! is installed. Otherwise, box frame resize.
|
// Windows Plus! is installed. Otherwise, box frame resize.
|
||||||
|
|||||||
@@ -240,6 +240,7 @@ public:
|
|||||||
void SetDynamicLayout(BOOL dynamic);
|
void SetDynamicLayout(BOOL dynamic);
|
||||||
BOOL IsDynamicLayoutSet();
|
BOOL IsDynamicLayoutSet();
|
||||||
BOOL IsDynamicLayoutSupported();
|
BOOL IsDynamicLayoutSupported();
|
||||||
|
BOOL IsActiveWindowTrackingEnabled();
|
||||||
BOOL IsDynamicLayoutActive();
|
BOOL IsDynamicLayoutActive();
|
||||||
BOOL areExtraMouseButtonsEnabled();
|
BOOL areExtraMouseButtonsEnabled();
|
||||||
void setExtraMouseButtonsEnabled(BOOL enable);
|
void setExtraMouseButtonsEnabled(BOOL enable);
|
||||||
@@ -477,6 +478,7 @@ private:
|
|||||||
BOOL m_isActive; // set to FALSE at beginning of Dispose
|
BOOL m_isActive; // set to FALSE at beginning of Dispose
|
||||||
BOOL m_isDisposed; // set to TRUE at end of Dispose
|
BOOL m_isDisposed; // set to TRUE at end of Dispose
|
||||||
BOOL m_areExtraMouseButtonsEnabled;
|
BOOL m_areExtraMouseButtonsEnabled;
|
||||||
|
BOOL m_active_window_tracking_mode_enabled;
|
||||||
|
|
||||||
typedef BOOL (WINAPI *RegisterTouchWindowFunc)(HWND hWnd, ULONG ulFlags);
|
typedef BOOL (WINAPI *RegisterTouchWindowFunc)(HWND hWnd, ULONG ulFlags);
|
||||||
typedef BOOL (WINAPI *GetTouchInputInfoFunc)(HTOUCHINPUT hTouchInput,
|
typedef BOOL (WINAPI *GetTouchInputInfoFunc)(HTOUCHINPUT hTouchInput,
|
||||||
|
|||||||
62
test/jdk/java/awt/FileDialog/MacOSGoToFolderCrash.java
Normal file
62
test/jdk/java/awt/FileDialog/MacOSGoToFolderCrash.java
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.awt.EventQueue;
|
||||||
|
import java.awt.FileDialog;
|
||||||
|
import java.awt.Frame;
|
||||||
|
import java.awt.Robot;
|
||||||
|
import java.awt.event.KeyEvent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
* @key headful
|
||||||
|
* @bug 8234522
|
||||||
|
* @requires (os.family == "mac")
|
||||||
|
*/
|
||||||
|
public final class MacOSGoToFolderCrash {
|
||||||
|
|
||||||
|
public static void main(final String[] args) throws Exception {
|
||||||
|
EventQueue.invokeLater(() -> {
|
||||||
|
FileDialog fd = new FileDialog((Frame) null);
|
||||||
|
fd.setVisible(true);
|
||||||
|
});
|
||||||
|
Robot robot = new Robot();
|
||||||
|
robot.setAutoDelay(400);
|
||||||
|
robot.waitForIdle();
|
||||||
|
// "⌘+Shift+G" – Open "Go To Folder" window
|
||||||
|
robot.keyPress(KeyEvent.VK_META);
|
||||||
|
robot.keyPress(KeyEvent.VK_SHIFT);
|
||||||
|
robot.keyPress(KeyEvent.VK_G);
|
||||||
|
robot.keyRelease(KeyEvent.VK_G);
|
||||||
|
robot.keyRelease(KeyEvent.VK_SHIFT);
|
||||||
|
robot.keyRelease(KeyEvent.VK_META);
|
||||||
|
// Select something
|
||||||
|
robot.keyPress(KeyEvent.VK_DOWN);
|
||||||
|
robot.keyRelease(KeyEvent.VK_DOWN);
|
||||||
|
robot.keyPress(KeyEvent.VK_ENTER);
|
||||||
|
robot.keyRelease(KeyEvent.VK_ENTER);
|
||||||
|
// Close File dialog
|
||||||
|
robot.keyPress(KeyEvent.VK_ESCAPE);
|
||||||
|
robot.keyRelease(KeyEvent.VK_ESCAPE);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -620,12 +620,13 @@ java/awt/dnd/DisposeFrameOnDragCrash/DisposeFrameOnDragTest.java
|
|||||||
java/awt/dnd/DragInterceptorAppletTest/DragInterceptorAppletTest.html 8215538 windows-all,macosx-all,linux-all (macosx-all,linux-all: commit)
|
java/awt/dnd/DragInterceptorAppletTest/DragInterceptorAppletTest.html 8215538 windows-all,macosx-all,linux-all (macosx-all,linux-all: commit)
|
||||||
java/awt/dnd/DropTargetEnterExitTest/ExtraDragEnterTest.java 8029680 macosx-all,linux-all,windows-all
|
java/awt/dnd/DropTargetEnterExitTest/ExtraDragEnterTest.java 8029680 macosx-all,linux-all,windows-all
|
||||||
java/awt/dnd/DropTargetEnterExitTest/MissedDragExitTest.java 8028998,8159694 macosx-all,windows-all,linux-all
|
java/awt/dnd/DropTargetEnterExitTest/MissedDragExitTest.java 8028998,8159694 macosx-all,windows-all,linux-all
|
||||||
|
java/awt/dnd/FileListBetweenJVMsTest/FileListBetweenJVMsTest.html 7124379,7188825 macosx-all,linux-all,windows-all
|
||||||
java/awt/dnd/ImageTransferTest/ImageTransferTest.java 8176556 generic-all
|
java/awt/dnd/ImageTransferTest/ImageTransferTest.java 8176556 generic-all
|
||||||
java/awt/dnd/InterJVMGetDropSuccessTest/InterJVMGetDropSuccessTest.html
|
java/awt/dnd/InterJVMGetDropSuccessTest/InterJVMGetDropSuccessTest.html 8208555 windows-all
|
||||||
java/awt/dnd/MissingDragExitEventTest/MissingDragExitEventTest.java 8030121 macosx-all,windows-all,linux-all
|
java/awt/dnd/MissingDragExitEventTest/MissingDragExitEventTest.java 8030121 macosx-all,windows-all,linux-all
|
||||||
java/awt/dnd/MissingEventsOnModalDialog/MissingEventsOnModalDialogTest.java 8164464 linux-all,macosx-all,windows-all
|
java/awt/dnd/MissingEventsOnModalDialog/MissingEventsOnModalDialogTest.java 8164464 linux-all,macosx-all,windows-all
|
||||||
java/awt/dnd/NoFormatsCrashTest/NoFormatsCrashTest.html 8214221 windows-all,linux-all,macosx-all
|
java/awt/dnd/NoFormatsCrashTest/NoFormatsCrashTest.html 8214221 windows-all,linux-all,macosx-all
|
||||||
java/awt/dnd/URIListBetweenJVMsTest/URIListBetweenJVMsTest.html 8171510 macosx-all
|
java/awt/dnd/URIListBetweenJVMsTest/URIListBetweenJVMsTest.html 8171510,7124379 macosx-all,linux-all
|
||||||
java/awt/dnd/URIListToFileListBetweenJVMsTest/URIListToFileListBetweenJVMsTest.html 8194947 generic-all
|
java/awt/dnd/URIListToFileListBetweenJVMsTest/URIListToFileListBetweenJVMsTest.html 8194947 generic-all
|
||||||
java/awt/event/ComponentEvent/MovedResizedTardyEventTest/MovedResizedTardyEventTest.html 6511207 generic-all
|
java/awt/event/ComponentEvent/MovedResizedTardyEventTest/MovedResizedTardyEventTest.html 6511207 generic-all
|
||||||
java/awt/event/HierarchyEvent/AncestorResized/AncestorResized.java 6618538 generic-all
|
java/awt/event/HierarchyEvent/AncestorResized/AncestorResized.java 6618538 generic-all
|
||||||
|
|||||||
@@ -112,11 +112,9 @@ java/awt/datatransfer/MissedHtmlAndRtfBug/MissedHtmlAndRtfBug.html
|
|||||||
java/awt/datatransfer/SystemSelection/SystemSelectionSwingTest.java nobug linux-all
|
java/awt/datatransfer/SystemSelection/SystemSelectionSwingTest.java nobug linux-all
|
||||||
java/awt/dnd/AcceptDropMultipleTimes/AcceptDropMultipleTimes.java nobug macosx-all,windows-all,linux-all
|
java/awt/dnd/AcceptDropMultipleTimes/AcceptDropMultipleTimes.java nobug macosx-all,windows-all,linux-all
|
||||||
java/awt/dnd/DnDTestWithHIDPI/DragTestWithHIDPI.java nobug macosx-all,windows-all,linux-all
|
java/awt/dnd/DnDTestWithHIDPI/DragTestWithHIDPI.java nobug macosx-all,windows-all,linux-all
|
||||||
java/awt/dnd/FileListBetweenJVMsTest/FileListBetweenJVMsTest.html nobug macosx-all,linux-all,windows-all
|
|
||||||
java/awt/dnd/InterJVMGetDropSuccessTest/InterJVMGetDropSuccessTest.html nobug macosx-all,windows-all,linux-all
|
java/awt/dnd/InterJVMGetDropSuccessTest/InterJVMGetDropSuccessTest.html nobug macosx-all,windows-all,linux-all
|
||||||
java/awt/dnd/RecognizedActionTest/RecognizedActionTest.java nobug macosx-all,windows-all,linux-all
|
java/awt/dnd/RecognizedActionTest/RecognizedActionTest.java nobug macosx-all,windows-all,linux-all
|
||||||
java/awt/dnd/RemoveDropTargetCrashTest/RemoveDropTargetCrashTest.java nobug macosx-all,windows-all
|
java/awt/dnd/RemoveDropTargetCrashTest/RemoveDropTargetCrashTest.java nobug macosx-all,windows-all
|
||||||
java/awt/dnd/URIListBetweenJVMsTest/URIListBetweenJVMsTest.html nobug macosx-all,linux-all
|
|
||||||
java/awt/event/KeyEvent/AltCharAcceleratorTest/AltCharAcceleratorTest.java nobug macosx-all,windows-all,linux-all
|
java/awt/event/KeyEvent/AltCharAcceleratorTest/AltCharAcceleratorTest.java nobug macosx-all,windows-all,linux-all
|
||||||
java/awt/event/KeyEvent/DeadKey/DeadKeyMacOSXInputText.java nobug macosx-all
|
java/awt/event/KeyEvent/DeadKey/DeadKeyMacOSXInputText.java nobug macosx-all
|
||||||
java/awt/event/KeyEvent/DeadKey/deadKeyMacOSX.java nobug macosx-all
|
java/awt/event/KeyEvent/DeadKey/deadKeyMacOSX.java nobug macosx-all
|
||||||
|
|||||||
@@ -1,38 +0,0 @@
|
|||||||
###Tips for compiling libraries and preparing env for test running
|
|
||||||
|
|
||||||
|
|
||||||
## Linux
|
|
||||||
|
|
||||||
prepare env for work with uinput: [group permissions](https://github.com/tuomasjjrasanen/python-uinput/issues/6#issuecomment-538710069)
|
|
||||||
|
|
||||||
```shell script
|
|
||||||
cd JetBrainsRuntime/test/jdk/jbu/native
|
|
||||||
# complile lib
|
|
||||||
gcc -shared -fPIC -I<path_to_jdk>/JetBrainsRuntime/build/linux-x86_64-normal-server-release/images/jdk/include/linux -I<path_to_jdk>/JetBrainsRuntime/build/linux-x86_64-normal-server-release/images/jdk/include touchscreen_device.c -o libtouchscreen_device.so
|
|
||||||
```
|
|
||||||
|
|
||||||
In IDEA run configurations set envvar to find libtouchscreen_device.so
|
|
||||||
```
|
|
||||||
LD_LIBRARY_PATH=<path_to_jdk>\JetBrainsRuntime\test\jdk\jbu\native
|
|
||||||
```
|
|
||||||
|
|
||||||
## Windows
|
|
||||||
|
|
||||||
prepare windows env: look for vcvarsall.bat [here](https://github.com/JetBrains/JetBrainsRuntime#windows)
|
|
||||||
```
|
|
||||||
cd JetBrainsRuntime\test\jdk\jbu\native
|
|
||||||
cl -I<path_to_jdk>\JetBrainsRuntime\build\windows-x86_64-normal-server-release\jdk\include\win32 -I<path_to_jdk>\JetBrainsRuntime\build\windows-x86_64-normal-server-release\jdk\include -MD -LD windows_touch_robot.c "<path_to_user32lib>\user32.lib" -Fewindows_touch_robot.dll
|
|
||||||
```
|
|
||||||
|
|
||||||
user32.lib is needed for WinUser.h (touch injection stuff)
|
|
||||||
|
|
||||||
In IDEA run configurations set envvar to find windows_touch_robot.dll
|
|
||||||
```
|
|
||||||
PATH="<path_to_jdk>\JetBrainsRuntime\test\jdk\jbu\native"
|
|
||||||
```
|
|
||||||
|
|
||||||
my paths are
|
|
||||||
```
|
|
||||||
user32: "C:\Program Files (x86)\Windows Kits\10\Lib\10.0.18362.0\um\x64\user32.lib"
|
|
||||||
path_to_jdk: "C:\Program_Files\cygwin64\home\Denis.Konoplev"
|
|
||||||
```
|
|
||||||
@@ -1,205 +0,0 @@
|
|||||||
#include <jni.h>
|
|
||||||
|
|
||||||
#include <errno.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <linux/input.h>
|
|
||||||
#include <linux/types.h>
|
|
||||||
#include <linux/uinput.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <sys/ioctl.h>
|
|
||||||
#include <sys/time.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
// TODO sort includes
|
|
||||||
// TODO add casts
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
__u16 type;
|
|
||||||
__u16 code;
|
|
||||||
__s32 value;
|
|
||||||
} TEventData;
|
|
||||||
|
|
||||||
static int set_bit(int fd, unsigned long int request, unsigned long int bit) {
|
|
||||||
return ioctl(fd, request, bit);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int touch_begin(int fd, int tracking_id, int x, int y) {
|
|
||||||
struct input_event ev;
|
|
||||||
|
|
||||||
const int cnt = 7;
|
|
||||||
TEventData eventData[7] = {{EV_ABS, ABS_MT_TRACKING_ID, tracking_id},
|
|
||||||
{EV_ABS, ABS_MT_POSITION_X, x},
|
|
||||||
{EV_ABS, ABS_MT_POSITION_Y, y},
|
|
||||||
{EV_KEY, BTN_TOUCH, 1},
|
|
||||||
{EV_ABS, ABS_X, x},
|
|
||||||
{EV_ABS, ABS_Y, y},
|
|
||||||
{EV_SYN, 0, 0}};
|
|
||||||
|
|
||||||
for (int i = 0; i < cnt; i++) {
|
|
||||||
memset(&ev, 0, sizeof(struct input_event));
|
|
||||||
ev.type = eventData[i].type;
|
|
||||||
ev.code = eventData[i].code;
|
|
||||||
ev.value = eventData[i].value;
|
|
||||||
|
|
||||||
if (write(fd, &ev, sizeof(struct input_event)) < 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int touch_update(int fd, int x, int y) {
|
|
||||||
struct input_event ev;
|
|
||||||
|
|
||||||
const int cnt = 5;
|
|
||||||
TEventData eventData[5] = {{EV_ABS, ABS_MT_POSITION_X, x},
|
|
||||||
{EV_ABS, ABS_MT_POSITION_Y, y},
|
|
||||||
{EV_ABS, ABS_X, x},
|
|
||||||
{EV_ABS, ABS_Y, y},
|
|
||||||
{EV_SYN, 0, 0}};
|
|
||||||
|
|
||||||
for (int i = 0; i < cnt; i++) {
|
|
||||||
memset(&ev, 0, sizeof(struct input_event));
|
|
||||||
ev.type = eventData[i].type;
|
|
||||||
ev.code = eventData[i].code;
|
|
||||||
ev.value = eventData[i].value;
|
|
||||||
|
|
||||||
if (write(fd, &ev, sizeof(struct input_event)) < 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// todo consider different name in case of multitouch
|
|
||||||
static int touch_end(int fd) {
|
|
||||||
struct input_event ev;
|
|
||||||
|
|
||||||
const int cnt = 3;
|
|
||||||
TEventData eventData[3] = {
|
|
||||||
{EV_ABS, ABS_MT_TRACKING_ID, -1}, {EV_KEY, BTN_TOUCH, 0}, {EV_SYN, 0, 0}};
|
|
||||||
|
|
||||||
for (int i = 0; i < cnt; i++) {
|
|
||||||
memset(&ev, 0, sizeof(struct input_event));
|
|
||||||
ev.type = eventData[i].type;
|
|
||||||
ev.code = eventData[i].code;
|
|
||||||
ev.value = eventData[i].value;
|
|
||||||
|
|
||||||
if (write(fd, &ev, sizeof(struct input_event)) < 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Class: quality_util_TouchScreenDevice
|
|
||||||
* Method: create
|
|
||||||
* Signature: ()I
|
|
||||||
*/
|
|
||||||
JNIEXPORT jint JNICALL Java_quality_util_UnixTouchScreenDevice_create(JNIEnv *env,
|
|
||||||
jobject o,
|
|
||||||
jint width,
|
|
||||||
jint height) {
|
|
||||||
int productId = 123;
|
|
||||||
const int FAKE_VENDOR_ID = 0x453;
|
|
||||||
const int MAX_FINGER_COUNT = 9;
|
|
||||||
const int MAX_TRACKING_ID = 65535;
|
|
||||||
|
|
||||||
int fd = open("/dev/uinput", O_WRONLY | O_NONBLOCK);
|
|
||||||
if (fd < 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int ret_code = 0;
|
|
||||||
ret_code = set_bit(fd, UI_SET_EVBIT, EV_SYN);
|
|
||||||
ret_code = set_bit(fd, UI_SET_EVBIT, EV_KEY);
|
|
||||||
ret_code = set_bit(fd, UI_SET_KEYBIT, BTN_TOUCH);
|
|
||||||
ret_code = set_bit(fd, UI_SET_EVBIT, EV_ABS);
|
|
||||||
ret_code = set_bit(fd, UI_SET_ABSBIT, ABS_X);
|
|
||||||
ret_code = set_bit(fd, UI_SET_ABSBIT, ABS_Y);
|
|
||||||
ret_code = set_bit(fd, UI_SET_ABSBIT, ABS_MT_SLOT);
|
|
||||||
ret_code = set_bit(fd, UI_SET_ABSBIT, ABS_MT_POSITION_X);
|
|
||||||
ret_code = set_bit(fd, UI_SET_ABSBIT, ABS_MT_POSITION_Y);
|
|
||||||
ret_code = set_bit(fd, UI_SET_ABSBIT, ABS_MT_TRACKING_ID);
|
|
||||||
ret_code = set_bit(fd, UI_SET_PROPBIT, INPUT_PROP_DIRECT);
|
|
||||||
|
|
||||||
if (ret_code < 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct uinput_user_dev virtual_touch_device;
|
|
||||||
memset(&virtual_touch_device, 0, sizeof(virtual_touch_device));
|
|
||||||
snprintf(virtual_touch_device.name, UINPUT_MAX_NAME_SIZE,
|
|
||||||
"Virtual Touch Device - %#x", productId);
|
|
||||||
virtual_touch_device.id.bustype = BUS_VIRTUAL;
|
|
||||||
virtual_touch_device.id.vendor = FAKE_VENDOR_ID;
|
|
||||||
virtual_touch_device.id.product = productId;
|
|
||||||
virtual_touch_device.id.version = 1;
|
|
||||||
|
|
||||||
virtual_touch_device.absmin[ABS_X] = 0;
|
|
||||||
virtual_touch_device.absmax[ABS_X] = width;
|
|
||||||
virtual_touch_device.absmin[ABS_Y] = 0;
|
|
||||||
virtual_touch_device.absmax[ABS_Y] = height;
|
|
||||||
virtual_touch_device.absmin[ABS_MT_SLOT] = 0;
|
|
||||||
virtual_touch_device.absmax[ABS_MT_SLOT] = MAX_FINGER_COUNT;
|
|
||||||
virtual_touch_device.absmin[ABS_MT_POSITION_X] = 0;
|
|
||||||
virtual_touch_device.absmax[ABS_MT_POSITION_X] = width;
|
|
||||||
virtual_touch_device.absmin[ABS_MT_POSITION_Y] = 0;
|
|
||||||
virtual_touch_device.absmax[ABS_MT_POSITION_Y] = height;
|
|
||||||
virtual_touch_device.absmin[ABS_MT_TRACKING_ID] = 0;
|
|
||||||
virtual_touch_device.absmax[ABS_MT_TRACKING_ID] = MAX_TRACKING_ID;
|
|
||||||
|
|
||||||
ret_code = write(fd, &virtual_touch_device, sizeof(virtual_touch_device));
|
|
||||||
ret_code = ioctl(fd, UI_DEV_CREATE);
|
|
||||||
if (ret_code < 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return fd;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Class: quality_util_TouchScreenDevice
|
|
||||||
* Method: destroy
|
|
||||||
* Signature: (I)V
|
|
||||||
*/
|
|
||||||
JNIEXPORT jint JNICALL Java_quality_util_UnixTouchScreenDevice_destroy(JNIEnv *env,
|
|
||||||
jobject o,
|
|
||||||
jint fd) {
|
|
||||||
if (ioctl(fd, UI_DEV_DESTROY) < 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return close(fd);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Class: quality_util_TouchScreenDevice
|
|
||||||
* Method: clickImpl
|
|
||||||
* Signature: (IIII)V
|
|
||||||
*/
|
|
||||||
// todo return code with checked exception
|
|
||||||
JNIEXPORT jint JNICALL Java_quality_util_UnixTouchScreenDevice_clickImpl(
|
|
||||||
JNIEnv *env, jobject o, jint fd, jint trackingId, jint x, jint y) {
|
|
||||||
touch_begin(fd, trackingId, x, y);
|
|
||||||
touch_end(fd);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Class: quality_util_TouchScreenDevice
|
|
||||||
* Method: moveImpl
|
|
||||||
* Signature: (IIIIII)V
|
|
||||||
*/
|
|
||||||
JNIEXPORT jint JNICALL Java_quality_util_UnixTouchScreenDevice_moveImpl(
|
|
||||||
JNIEnv *env, jobject o, jint fd, jint trackingId, jint fromX, jint fromY,
|
|
||||||
jint toX, jint toY) {
|
|
||||||
touch_begin(fd, trackingId, fromX, fromY);
|
|
||||||
touch_update(fd, toX, toY);
|
|
||||||
touch_end(fd);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -1,84 +0,0 @@
|
|||||||
#include <jni.h>
|
|
||||||
|
|
||||||
#include <windows.h>
|
|
||||||
#include <WinUser.h>
|
|
||||||
|
|
||||||
POINTER_TOUCH_INFO create_touch_info()
|
|
||||||
{
|
|
||||||
POINTER_TOUCH_INFO contact;
|
|
||||||
InitializeTouchInjection(1, TOUCH_FEEDBACK_DEFAULT); // Number of contact point
|
|
||||||
memset(&contact, 0, sizeof(POINTER_TOUCH_INFO));
|
|
||||||
|
|
||||||
contact.touchFlags = TOUCH_FLAG_NONE;
|
|
||||||
contact.touchMask = TOUCH_MASK_CONTACTAREA | TOUCH_MASK_ORIENTATION | TOUCH_MASK_PRESSURE;
|
|
||||||
contact.orientation = 90; // Orientation of 90 means touching perpendicular to screen.
|
|
||||||
contact.pressure = 32000;
|
|
||||||
|
|
||||||
return contact;
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_contact_area(POINTER_TOUCH_INFO *contact)
|
|
||||||
{
|
|
||||||
// 4 x 4 pixel contact area
|
|
||||||
contact->rcContact.top = contact->pointerInfo.ptPixelLocation.y - 2;
|
|
||||||
contact->rcContact.bottom = contact->pointerInfo.ptPixelLocation.y + 2;
|
|
||||||
contact->rcContact.left = contact->pointerInfo.ptPixelLocation.x - 2;
|
|
||||||
contact->rcContact.right = contact->pointerInfo.ptPixelLocation.x + 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
void touchBegin(POINTER_TOUCH_INFO* contact, LONG x, LONG y)
|
|
||||||
{
|
|
||||||
contact->pointerInfo.pointerType = PT_TOUCH;
|
|
||||||
// primary finger pointerId == 0
|
|
||||||
contact->pointerInfo.pointerId = 0;
|
|
||||||
contact->pointerInfo.ptPixelLocation.x = x;
|
|
||||||
contact->pointerInfo.ptPixelLocation.y = y;
|
|
||||||
set_contact_area(contact);
|
|
||||||
|
|
||||||
contact->pointerInfo.pointerFlags = POINTER_FLAG_DOWN | POINTER_FLAG_INRANGE | POINTER_FLAG_INCONTACT;
|
|
||||||
InjectTouchInput(1, contact);
|
|
||||||
}
|
|
||||||
|
|
||||||
void touchUpdate(POINTER_TOUCH_INFO* contact, LONG x, LONG y)
|
|
||||||
{
|
|
||||||
contact->pointerInfo.pointerFlags = POINTER_FLAG_UPDATE | POINTER_FLAG_INRANGE | POINTER_FLAG_INCONTACT;
|
|
||||||
contact->pointerInfo.ptPixelLocation.x = x;
|
|
||||||
contact->pointerInfo.ptPixelLocation.y = y;
|
|
||||||
InjectTouchInput(1, contact);
|
|
||||||
}
|
|
||||||
|
|
||||||
void touchEnd(POINTER_TOUCH_INFO* contact)
|
|
||||||
{
|
|
||||||
contact->pointerInfo.pointerFlags = POINTER_FLAG_UP;
|
|
||||||
InjectTouchInput(1, contact);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Class: quality_util_WindowsTouchRobot
|
|
||||||
* Method: clickImpl
|
|
||||||
* Signature: (II)V
|
|
||||||
*/
|
|
||||||
JNIEXPORT void JNICALL
|
|
||||||
Java_quality_util_WindowsTouchRobot_clickImpl(JNIEnv* env, jobject o,
|
|
||||||
jint x, jint y)
|
|
||||||
{
|
|
||||||
POINTER_TOUCH_INFO contact = create_touch_info();
|
|
||||||
touchBegin(&contact, x, y);
|
|
||||||
touchEnd(&contact);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Class: quality_util_WindowsTouchRobot
|
|
||||||
* Method: moveImpl
|
|
||||||
* Signature: (IIII)V
|
|
||||||
*/
|
|
||||||
JNIEXPORT void JNICALL
|
|
||||||
Java_quality_util_WindowsTouchRobot_moveImpl(JNIEnv* env, jobject o,
|
|
||||||
jint fromX, jint fromY,
|
|
||||||
jint toX, jint toY)
|
|
||||||
{
|
|
||||||
POINTER_TOUCH_INFO contact = create_touch_info();
|
|
||||||
touchBegin(&contact, fromX, fromY);
|
|
||||||
touchUpdate(&contact, toX, toY);
|
|
||||||
touchEnd(&contact);
|
|
||||||
}
|
|
||||||
@@ -1,338 +0,0 @@
|
|||||||
package quality.event;
|
|
||||||
|
|
||||||
import org.apache.commons.lang3.SystemUtils;
|
|
||||||
import org.junit.Test;
|
|
||||||
import quality.util.UnixTouchRobot;
|
|
||||||
import quality.util.TouchRobot;
|
|
||||||
import quality.util.WindowsTouchRobot;
|
|
||||||
|
|
||||||
import javax.swing.*;
|
|
||||||
import java.awt.*;
|
|
||||||
import java.awt.event.*;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.concurrent.CountDownLatch;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
public class TouchScreenEventsTest {
|
|
||||||
static final int TIMEOUT = 2;
|
|
||||||
// TODO make this constants accessible within jdk
|
|
||||||
static final int TOUCH_BEGIN = 2;
|
|
||||||
static final int TOUCH_UPDATE = 3;
|
|
||||||
static final int TOUCH_END = 4;
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testTouchClick() throws Exception {
|
|
||||||
runTest(new TouchClickSuite());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testTouchMove() throws Exception {
|
|
||||||
runTest(new TouchMoveSuite());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testTouchTinyMove() throws Exception {
|
|
||||||
runTest(new TouchTinyMoveSuite());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testTouchHorizontalScroll() throws Exception {
|
|
||||||
runTest(new TouchAxesScrollSuite(TouchAxesScrollSuite.AXIS.X));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testTouchVerticalScroll() throws Exception {
|
|
||||||
runTest(new TouchAxesScrollSuite(TouchAxesScrollSuite.AXIS.Y));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void runTest(TouchTestSuite suite) throws Exception {
|
|
||||||
GUI gui = new GUI();
|
|
||||||
try {
|
|
||||||
TouchRobot robot = getTouchRobot();
|
|
||||||
SwingUtilities.invokeAndWait(gui::createAndShow);
|
|
||||||
suite.addListener(gui.frame);
|
|
||||||
robot.waitForIdle();
|
|
||||||
|
|
||||||
suite.perform(gui, robot);
|
|
||||||
robot.waitForIdle();
|
|
||||||
suite.passed();
|
|
||||||
} finally {
|
|
||||||
SwingUtilities.invokeLater(() -> {
|
|
||||||
if (gui.frame != null) {
|
|
||||||
gui.frame.dispose();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static TouchRobot getTouchRobot() throws IOException, AWTException {
|
|
||||||
if (SystemUtils.IS_OS_UNIX) {
|
|
||||||
return new UnixTouchRobot();
|
|
||||||
} else if (SystemUtils.IS_OS_WINDOWS) {
|
|
||||||
return new WindowsTouchRobot();
|
|
||||||
}
|
|
||||||
throw new RuntimeException("Touch robot for this platform isn't implemented");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class GUI {
|
|
||||||
JFrame frame;
|
|
||||||
Rectangle frameBounds;
|
|
||||||
|
|
||||||
void createAndShow() {
|
|
||||||
frame = new JFrame();
|
|
||||||
frame.setSize(640, 480);
|
|
||||||
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
|
||||||
frame.setVisible(true);
|
|
||||||
frameBounds = frame.getBounds();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
interface TouchTestSuite {
|
|
||||||
void perform(GUI gui, TouchRobot robot) throws IOException;
|
|
||||||
|
|
||||||
void passed() throws InterruptedException;
|
|
||||||
|
|
||||||
void addListener(JFrame frame);
|
|
||||||
}
|
|
||||||
|
|
||||||
class TouchClickSuite implements MouseListener, TouchTestSuite {
|
|
||||||
private volatile boolean pressed;
|
|
||||||
private volatile boolean released;
|
|
||||||
private volatile boolean clicked;
|
|
||||||
private final CountDownLatch latch = new CountDownLatch(3);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void mouseClicked(MouseEvent e) {
|
|
||||||
if (!clicked) {
|
|
||||||
clicked = true;
|
|
||||||
latch.countDown();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void mousePressed(MouseEvent e) {
|
|
||||||
pressed = true;
|
|
||||||
if (!pressed) {
|
|
||||||
pressed = true;
|
|
||||||
latch.countDown();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void mouseReleased(MouseEvent e) {
|
|
||||||
if (!released) {
|
|
||||||
released = true;
|
|
||||||
latch.countDown();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void mouseEntered(MouseEvent e) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void mouseExited(MouseEvent e) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void perform(GUI gui, TouchRobot robot) throws IOException {
|
|
||||||
int x = gui.frameBounds.x + gui.frameBounds.width / 2;
|
|
||||||
int y = gui.frameBounds.y + gui.frameBounds.height / 2;
|
|
||||||
robot.touchClick(42, x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void passed() throws InterruptedException {
|
|
||||||
latch.await(TouchScreenEventsTest.TIMEOUT, TimeUnit.SECONDS);
|
|
||||||
if (!pressed || !released || !clicked) {
|
|
||||||
String error = (pressed ? "" : "pressed: " + pressed) +
|
|
||||||
(released ? "" : ", released: " + released) +
|
|
||||||
(clicked ? "" : ", clicked: " + clicked);
|
|
||||||
throw new RuntimeException("Touch click failed: " + error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void addListener(JFrame frame) {
|
|
||||||
frame.addMouseListener(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class TouchMoveSuite implements MouseWheelListener, TouchTestSuite {
|
|
||||||
private volatile boolean begin;
|
|
||||||
private volatile boolean update;
|
|
||||||
private volatile boolean end;
|
|
||||||
private final CountDownLatch latch = new CountDownLatch(3);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void mouseWheelMoved(MouseWheelEvent e) {
|
|
||||||
if (e.getScrollType() == TouchScreenEventsTest.TOUCH_BEGIN) {
|
|
||||||
if (!begin) {
|
|
||||||
begin = true;
|
|
||||||
latch.countDown();
|
|
||||||
}
|
|
||||||
} else if (e.getScrollType() == TouchScreenEventsTest.TOUCH_UPDATE) {
|
|
||||||
if (!update) {
|
|
||||||
update = true;
|
|
||||||
latch.countDown();
|
|
||||||
}
|
|
||||||
} else if (e.getScrollType() == TouchScreenEventsTest.TOUCH_END) {
|
|
||||||
if (!end) {
|
|
||||||
end = true;
|
|
||||||
latch.countDown();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void perform(GUI gui, TouchRobot robot) throws IOException {
|
|
||||||
int x1 = gui.frameBounds.x + gui.frameBounds.width / 4;
|
|
||||||
int y1 = gui.frameBounds.y + gui.frameBounds.height / 4;
|
|
||||||
int x2 = gui.frameBounds.x + gui.frameBounds.width / 2;
|
|
||||||
int y2 = gui.frameBounds.y + gui.frameBounds.height / 2;
|
|
||||||
robot.touchMove(42, x1, y1, x2, y2);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void passed() throws InterruptedException {
|
|
||||||
latch.await(TouchScreenEventsTest.TIMEOUT, TimeUnit.SECONDS);
|
|
||||||
if (!begin || !update || !end) {
|
|
||||||
String error = (begin ? "" : "begin: " + begin) +
|
|
||||||
(update ? "" : ", update: " + update) +
|
|
||||||
(end ? "" : ", end: " + end);
|
|
||||||
throw new RuntimeException("Touch move failed: " + error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void addListener(JFrame frame) {
|
|
||||||
frame.addMouseWheelListener(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class TouchTinyMoveSuite implements MouseWheelListener, MouseListener, TouchTestSuite {
|
|
||||||
private volatile boolean scroll;
|
|
||||||
private volatile boolean click;
|
|
||||||
private final CountDownLatch latch = new CountDownLatch(1);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void mouseWheelMoved(MouseWheelEvent e) {
|
|
||||||
if (e.getScrollType() == TouchScreenEventsTest.TOUCH_UPDATE) {
|
|
||||||
scroll = true;
|
|
||||||
latch.countDown();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void perform(GUI gui, TouchRobot robot) throws IOException {
|
|
||||||
int x1 = gui.frameBounds.x + gui.frameBounds.width / 4;
|
|
||||||
int y1 = gui.frameBounds.y + gui.frameBounds.height / 4;
|
|
||||||
// move inside tiny area
|
|
||||||
int x2 = x1 + 1;
|
|
||||||
int y2 = y1 + 1;
|
|
||||||
robot.touchMove(42, x1, y1, x2, y2);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void passed() throws InterruptedException {
|
|
||||||
latch.await(TouchScreenEventsTest.TIMEOUT, TimeUnit.SECONDS);
|
|
||||||
if (scroll || !click) {
|
|
||||||
String error = (scroll ? "scroll " + scroll : "") +
|
|
||||||
(click ? "" : ", click: " + click);
|
|
||||||
throw new RuntimeException("Tiny touch move failed: " + error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void addListener(JFrame frame) {
|
|
||||||
frame.addMouseWheelListener(this);
|
|
||||||
frame.addMouseListener(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void mouseClicked(MouseEvent e) {
|
|
||||||
click = true;
|
|
||||||
latch.countDown();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void mousePressed(MouseEvent e) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void mouseReleased(MouseEvent e) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void mouseEntered(MouseEvent e) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void mouseExited(MouseEvent e) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class TouchAxesScrollSuite implements MouseWheelListener, TouchTestSuite {
|
|
||||||
enum AXIS {X, Y}
|
|
||||||
|
|
||||||
private final AXIS axis;
|
|
||||||
private volatile boolean vertical;
|
|
||||||
private volatile boolean horizontal;
|
|
||||||
private final CountDownLatch latch = new CountDownLatch(1);
|
|
||||||
|
|
||||||
TouchAxesScrollSuite(AXIS axis) {
|
|
||||||
this.axis = axis;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void mouseWheelMoved(MouseWheelEvent e) {
|
|
||||||
if (e.getScrollType() == TouchScreenEventsTest.TOUCH_UPDATE) {
|
|
||||||
if (e.isShiftDown()) {
|
|
||||||
horizontal = true;
|
|
||||||
} else {
|
|
||||||
vertical = true;
|
|
||||||
}
|
|
||||||
latch.countDown();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void perform(GUI gui, TouchRobot robot) throws IOException {
|
|
||||||
int x1 = gui.frameBounds.x + gui.frameBounds.width / 4;
|
|
||||||
int y1 = gui.frameBounds.y + gui.frameBounds.height / 4;
|
|
||||||
switch (axis) {
|
|
||||||
case X:
|
|
||||||
int x2 = gui.frameBounds.x + gui.frameBounds.width / 2;
|
|
||||||
robot.touchMove(42, x1, y1, x2, y1);
|
|
||||||
break;
|
|
||||||
case Y:
|
|
||||||
int y2 = gui.frameBounds.y + gui.frameBounds.height / 2;
|
|
||||||
robot.touchMove(42, x1, y1, x1, y2);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void passed() throws InterruptedException {
|
|
||||||
latch.await(TouchScreenEventsTest.TIMEOUT, TimeUnit.SECONDS);
|
|
||||||
String error = "horizontal " + horizontal + ", vertical: " + vertical;
|
|
||||||
switch (axis) {
|
|
||||||
case X:
|
|
||||||
if (!horizontal || vertical) {
|
|
||||||
throw new RuntimeException("Touch axes failed: " + error);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case Y:
|
|
||||||
if (horizontal || !vertical) {
|
|
||||||
throw new RuntimeException("Touch axes failed: " + error);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void addListener(JFrame frame) {
|
|
||||||
frame.addMouseWheelListener(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
package quality.util;
|
|
||||||
|
|
||||||
import java.awt.*;
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
public abstract class TouchRobot extends Robot {
|
|
||||||
public TouchRobot() throws AWTException {
|
|
||||||
}
|
|
||||||
|
|
||||||
public TouchRobot(GraphicsDevice screen) throws AWTException {
|
|
||||||
super(screen);
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract void touchClick(int fingerId, int x, int y) throws IOException;
|
|
||||||
|
|
||||||
public abstract void touchMove(int fingerId, int fromX, int fromY, int toX, int toY) throws IOException;
|
|
||||||
}
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
package quality.util;
|
|
||||||
|
|
||||||
import java.awt.*;
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
public class UnixTouchRobot extends TouchRobot {
|
|
||||||
private UnixTouchScreenDevice device;
|
|
||||||
|
|
||||||
public UnixTouchRobot() throws AWTException, IOException {
|
|
||||||
super();
|
|
||||||
device = new UnixTouchScreenDevice();
|
|
||||||
}
|
|
||||||
|
|
||||||
public UnixTouchRobot(GraphicsDevice screen) throws AWTException, IOException {
|
|
||||||
super(screen);
|
|
||||||
device = new UnixTouchScreenDevice();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void touchClick(int fingerId, int x, int y) throws IOException {
|
|
||||||
device.click(fingerId, x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void touchMove(int fingerId, int fromX, int fromY, int toX, int toY) throws IOException {
|
|
||||||
device.move(fingerId, fromX, fromY, toX, toY);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,68 +0,0 @@
|
|||||||
package quality.util;
|
|
||||||
|
|
||||||
import java.awt.*;
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
public class UnixTouchScreenDevice implements AutoCloseable {
|
|
||||||
// TODO add product id
|
|
||||||
private int width;
|
|
||||||
private int height;
|
|
||||||
private int fileDescriptor;
|
|
||||||
|
|
||||||
static {
|
|
||||||
System.loadLibrary("touchscreen_device");
|
|
||||||
}
|
|
||||||
|
|
||||||
public UnixTouchScreenDevice() throws IOException {
|
|
||||||
this(Toolkit.getDefaultToolkit().getScreenSize().width, Toolkit.getDefaultToolkit().getScreenSize().height);
|
|
||||||
}
|
|
||||||
|
|
||||||
public UnixTouchScreenDevice(int width, int height) throws IOException {
|
|
||||||
this.width = width;
|
|
||||||
this.height = height;
|
|
||||||
fileDescriptor = create(getWidth(), getHeight());
|
|
||||||
checkCompletion(fileDescriptor,
|
|
||||||
"Failed to create virtual touchscreen device");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void close() throws Exception {
|
|
||||||
checkCompletion(destroy(fileDescriptor),
|
|
||||||
"Failed to close touchscreen device");
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getWidth() {
|
|
||||||
return width;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getHeight() {
|
|
||||||
return height;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void click(int trackingId, int x, int y) throws IOException {
|
|
||||||
checkCompletion(clickImpl(fileDescriptor, trackingId, x, y),
|
|
||||||
"Failed to click on touchscreen device");
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void move(int trackingId, int fromX, int fromY, int toX, int toY) throws IOException {
|
|
||||||
checkCompletion(moveImpl(fileDescriptor, trackingId, fromX, fromY, toX, toY),
|
|
||||||
"Failed to move on virtual touchscreen device");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void checkCompletion(int code, String errorMessage) throws IOException {
|
|
||||||
if (code < 0) {
|
|
||||||
throw new IOException(errorMessage);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private native int create(int width, int height);
|
|
||||||
|
|
||||||
private native int destroy(int fd);
|
|
||||||
|
|
||||||
private native int clickImpl(int fd, int trackingId, int x, int y);
|
|
||||||
|
|
||||||
private native int moveImpl(int fd, int trackingId, int fromX, int fromY, int toX, int toY);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
package quality.util;
|
|
||||||
|
|
||||||
import java.awt.*;
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
public class WindowsTouchRobot extends TouchRobot {
|
|
||||||
static {
|
|
||||||
System.loadLibrary("windows_touch_robot");
|
|
||||||
}
|
|
||||||
|
|
||||||
public WindowsTouchRobot() throws AWTException, IOException {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
public WindowsTouchRobot(GraphicsDevice screen) throws AWTException, IOException {
|
|
||||||
super(screen);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void touchClick(int fingerId, int x, int y) throws IOException {
|
|
||||||
// TODO unused finger id cause windows use different finger id model
|
|
||||||
clickImpl(x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void touchMove(int fingerId, int fromX, int fromY, int toX, int toY) throws IOException {
|
|
||||||
// TODO unused finger id cause windows use different finger id model
|
|
||||||
moveImpl(fromX, fromY, toX, toY);
|
|
||||||
}
|
|
||||||
|
|
||||||
private native void clickImpl(int x, int y);
|
|
||||||
|
|
||||||
private native void moveImpl(int fromX, int fromY, int toX, int toY);
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user