<AWT Dev> Fwd: Found and solved a bug on Cursor Management on Windows platforms

Morvan Le Mescam morvan.lemescam at gmail.com
Fri Apr 26 08:59:04 PDT 2013


Thanks for this anwer.

I successfully rebuilt the JDK on Windows (see my first mail) so I think I
can patch it but I don't really know how...

Regards


2013/4/26 Anthony Petrov <anthony.petrov at oracle.com>

> Hi Morvan,
>
> The IDC_HAND system cursor was introduced in Windows 2000. Java's
> HAND_CURSOR seems to be introduced way before Win2K has been released.
> Hence the need for a custom cursor back in the days. Clearly, this doesn't
> make any sense today. We should switch to using the system default cursor
> for this cursor type.
>
> Would you like to prepare a patch for this issue, test it, and post on
> this mailing list for a review? I know that building JDK on Windows is not
> an easy task, but it can be accomplished nevertheless, and the new build
> system has made it much simpler than it was before. Please refer to this
> document
>
> http://hg.openjdk.java.net/**jdk8/build/raw-file/tip/**README-builds.html<http://hg.openjdk.java.net/jdk8/build/raw-file/tip/README-builds.html>
>
> for build instructions.
>
> --
> best regards,
> Anthony
>
>
> On 04/22/2013 08:32 PM, Morvan Le Mescam wrote:
>
>> Dear all,
>>
>> When developping a Swing client, I face the following problem :
>> When setting the hand cursor on Windows, I noticed that the default
>> system cursor was not used.
>>
>> I analysed the problem and found the rrot cause.
>> I also made a correction and tested it on Windows 7.
>>
>> This is my analyse :
>>
>> When reading Java source code, it is obvious that on Windows, Java does
>> not use System resources.
>>
>> In the code (from *jdk\src\windows\native\sun\**windows\awt_Cursor.cpp* )
>> bellow :
>>
>> AwtCursor * AwtCursor::***CreateSystemCursor*(jobject jCursor)
>>
>>
>> {
>>
>>      JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
>>
>>      jint type = env->GetIntField(jCursor, AwtCursor::typeID);
>>
>>      DASSERT(type != java_awt_Cursor_CUSTOM_CURSOR)**;
>>
>>      LPCTSTR winCursor;
>>
>>      switch (type) {
>>
>>        case java_awt_Cursor_DEFAULT_**CURSOR:
>>
>>        default:
>>
>>          winCursor = IDC_ARROW;
>>
>>          break;
>>
>>        case java_awt_Cursor_CROSSHAIR_**CURSOR:
>>
>>          winCursor = IDC_CROSS;
>>
>>          break;
>>
>> *[…]*
>>
>> *case java_awt_Cursor_HAND_CURSOR:*
>>
>> *winCursor = TEXT("HAND_CURSOR");*
>>
>> *break;*
>>
>>        case java_awt_Cursor_MOVE_CURSOR:
>>
>>          winCursor = IDC_SIZEALL;
>>
>>          break;
>>
>>      }
>>
>> *    HCURSOR hCursor = ::LoadCursor(NULL, winCursor);*
>>
>>      if (*hCursor == NULL*) {
>>
>>          /* Not a system cursor, check for resource. */
>>
>> *hCursor = ::LoadCursor(AwtToolkit::**GetInstance().GetModuleHandle(**),*
>>
>> *winCursor);*
>>
>>
>>      }
>>
>>      if (hCursor == NULL) {
>>
>>          hCursor = ::LoadCursor(NULL, IDC_ARROW);
>>
>> DASSERT(hCursor != NULL);
>>
>>      }
>>
>>      AwtCursor *awtCursor = new AwtCursor(env, hCursor, jCursor);
>>
>>      setPData(jCursor, ptr_to_jlong(awtCursor));
>>
>>      return awtCursor;
>>
>> }
>>
>> In the case of the HAND_CURSOR (*in red*),  Java will try to load the
>>
>> cursor from the system (*in blue*).
>>
>> If it fails (*hCursor == NULL*) then it will try to load the cursor from
>>
>> its own resource (*in orange*) :
>>
>> *hCursor = ::LoadCursor(AwtToolkit::**GetInstance().GetModuleHandle(**),*
>>
>> *winCursor);*
>>
>>
>> In our case, if we check in the AWTToolkit module resources, in
>> *jdk\src\windows\native\sun\**windows\awr.rc*, we find the following
>> content :
>>
>>
>> #include "windows.h"
>>
>> // Need 2 defines so macro argument to XSTR will get expanded before
>> quoting.
>>
>> #define XSTR(x) STR(x)
>>
>> #define STR(x)  #x
>>
>> LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
>>
>> *HAND_CURSOR  CURSOR DISCARDABLE "hand.cur"*
>>
>> AWT_ICON ICON    DISCARDABLE "awt.ico"
>>
>> CHECK_BITMAP BITMAP  DISCARDABLE "check.bmp"
>>
>> And we find that java.exe embed its own hand cursor, in
>> *jdk\src\windows\native\sun\**windows\hand.cur* : The “famous” hand that
>>
>> it is displayed instead of our system cursor.
>>
>>
>> This is the correction :
>>
>> , I made the correction into the JRE source code :
>>
>>        case java_awt_Cursor_HAND_CURSOR:
>>
>>          /* MLM change winCursor = TEXT("HAND_CURSOR"); */
>>
>>          winCursor = IDC_HAND;
>>
>>          break;
>>
>> I could compile and regenerate a JRE with this change :
>>
>> D:\Work\Current\openjdk\build\**windows-amd64\bin>java -version
>>
>> openjdk version "1.7.0-u6-unofficial"
>>
>> OpenJDK Runtime Environment (build 1.7.0-u6-unofficial-b24)
>>
>> OpenJDK 64-Bit Server VM (build 21.0-b17, mixed mode)
>>
>> And this works !
>>
>> If I change the hand cursor at System level, Java takes it into account.
>>
>> Last but not least question:
>>
>> Why did a Sun developper, one day : winCursor = TEXT("HAND_CURSOR");
>>
>> This seems so not consistent with other part of the code... So there is
>> probably a good reason. Perhaps the hand cursor was not existant on
>> Windows platform when this was done ?
>>
>>
>> Regards
>>
>>
>> Morvan
>>
>>
>>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.openjdk.java.net/pipermail/awt-dev/attachments/20130426/96dc33ba/attachment.html 


More information about the awt-dev mailing list