rev 60071 : 8211999: Window positioning bugs due to overlapping GraphicsDevice bounds (Windows/HiDPI)
Reviewed-by: XXX

   1 /*
   2  * Copyright (c) 2003, 2017, 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 #include <windowsx.h>
  27 #include <jni.h>
  28 #include <jni_util.h>
  29 #include "awt.h"
  30 #include "awt_Object.h"
  31 #include "awt_Component.h"
  32 
  33 extern "C" {
  34 
  35 /*
  36  * Class:     sun_awt_windows_WMouseInfoPeer
  37  * Method:    isWindowUnderMouse
  38  * Signature: (Ljava/awt/Window)Z
  39  */
  40 JNIEXPORT jboolean JNICALL
  41 Java_sun_awt_windows_WMouseInfoPeer_isWindowUnderMouse(JNIEnv *env, jclass cls,
  42                                                         jobject window)
  43 {
  44     POINT pt;
  45 
  46     if (env->EnsureLocalCapacity(1) < 0) {
  47         return JNI_FALSE;
  48     }
  49 
  50     jobject winPeer = AwtObject::GetPeerForTarget(env, window);
  51     CHECK_NULL_RETURN(winPeer, JNI_FALSE);
  52     PDATA pData;
  53     pData = JNI_GET_PDATA(winPeer);
  54     env->DeleteLocalRef(winPeer);
  55     if (pData == NULL) {
  56         return JNI_FALSE;
  57     }
  58 
  59     AwtComponent * ourWindow = (AwtComponent *)pData;
  60     HWND hwnd = ourWindow->GetHWnd();
  61     VERIFY(::GetCursorPos(&pt));
  62 
  63     AwtComponent * componentFromPoint = AwtComponent::GetComponent(::WindowFromPoint(pt));
  64 
  65     while (componentFromPoint != NULL
  66         && componentFromPoint->GetHWnd() != hwnd
  67         && !AwtComponent::IsTopLevelHWnd(componentFromPoint->GetHWnd()))
  68     {
  69         componentFromPoint = componentFromPoint->GetParent();
  70     }
  71 
  72     return ((componentFromPoint != NULL) && (componentFromPoint->GetHWnd() == hwnd)) ? JNI_TRUE : JNI_FALSE;
  73 
  74 }
  75 
  76 /*
  77  * Class:     sun_awt_windows_WMouseInfoPeer
  78  * Method:    fillPointWithCoords
  79  * Signature: (Ljava/awt/Point)I
  80  */
  81 JNIEXPORT jint JNICALL
  82 Java_sun_awt_windows_WMouseInfoPeer_fillPointWithCoords(JNIEnv *env, jclass cls, jobject point)
  83 {
  84     static jclass pointClass = NULL;
  85     static jfieldID xID, yID;
  86     POINT pt;
  87 
  88     VERIFY(::GetCursorPos(&pt));
  89     if (pointClass == NULL) {
  90         jclass pointClassLocal = env->FindClass("java/awt/Point");
  91         DASSERT(pointClassLocal != NULL);
  92         if (pointClassLocal == NULL) {
  93             return (jint)0;
  94         }
  95         pointClass = (jclass)env->NewGlobalRef(pointClassLocal);
  96         env->DeleteLocalRef(pointClassLocal);
  97     }
  98 
  99     HMONITOR monitor = MonitorFromPoint(pt, MONITOR_DEFAULTTOPRIMARY);
 100     int screen = AwtWin32GraphicsDevice::GetScreenFromHMONITOR(monitor);
 101     Devices::InstanceAccess devices;
 102     AwtWin32GraphicsDevice *device = devices->GetDevice(screen);
 103 
 104     xID = env->GetFieldID(pointClass, "x", "I");
 105     CHECK_NULL_RETURN(xID, (jint)0);
 106     yID = env->GetFieldID(pointClass, "y", "I");
 107     CHECK_NULL_RETURN(yID, (jint)0);
 108 
 109     int x = (device == NULL) ? pt.x : device->ScaleDownX(pt.x);
 110     int y = (device == NULL) ? pt.y : device->ScaleDownY(pt.y);
 111 
 112     env->SetIntField(point, xID, x);
 113     env->SetIntField(point, yID, y);
 114 
 115     // Always return 0 on Windows: we assume there's always a
 116     // virtual screen device used.
 117     return (jint)0;
 118 }
 119 
 120 } // extern "C"
--- EOF ---