jdk/src/solaris/native/sun/xawt/XToolkit.c
changeset 2810 fa49c6a06baf
parent 2802 d05a9dcc8296
child 2811 8828b8313cab
equal deleted inserted replaced
2809:b373581f6507 2810:fa49c6a06baf
    43 #include "awt_Font.h"
    43 #include "awt_Font.h"
    44 
    44 
    45 #include "sun_awt_X11_XToolkit.h"
    45 #include "sun_awt_X11_XToolkit.h"
    46 #include "java_awt_SystemColor.h"
    46 #include "java_awt_SystemColor.h"
    47 #include "java_awt_TrayIcon.h"
    47 #include "java_awt_TrayIcon.h"
       
    48 #include <X11/extensions/XTest.h>
    48 
    49 
    49 uint32_t awt_NumLockMask = 0;
    50 uint32_t awt_NumLockMask = 0;
    50 Boolean  awt_ModLockIsShiftLock = False;
    51 Boolean  awt_ModLockIsShiftLock = False;
       
    52 
       
    53 static int32_t num_buttons = 0;
       
    54 int32_t getNumButtons();
    51 
    55 
    52 extern JavaVM *jvm;
    56 extern JavaVM *jvm;
    53 
    57 
    54 // Tracing level
    58 // Tracing level
    55 static int tracing = 0;
    59 static int tracing = 0;
   906         AWT_LOCK();
   910         AWT_LOCK();
   907         XFreeCursor(awt_display, xcursor);
   911         XFreeCursor(awt_display, xcursor);
   908         AWT_UNLOCK();
   912         AWT_UNLOCK();
   909     }
   913     }
   910 }
   914 }
       
   915 
       
   916 
       
   917 /*
       
   918  * Class:     sun_awt_X11_XToolkit
       
   919  * Method:    getNumberOfButtonsImpl
       
   920  * Signature: ()I
       
   921  */
       
   922 JNIEXPORT jint JNICALL Java_sun_awt_X11_XToolkit_getNumberOfButtonsImpl
       
   923 (JNIEnv * env, jobject cls){
       
   924     if (num_buttons == 0) {
       
   925         num_buttons = getNumButtons();
       
   926     }
       
   927     return num_buttons;
       
   928 }
       
   929 
       
   930 int32_t getNumButtons() {
       
   931     int32_t major_opcode, first_event, first_error;
       
   932     int32_t xinputAvailable;
       
   933     int32_t numDevices, devIdx, clsIdx;
       
   934     XDeviceInfo* devices;
       
   935     XDeviceInfo* aDevice;
       
   936     XButtonInfo* bInfo;
       
   937     int32_t local_num_buttons = 0;
       
   938 
       
   939     /* 4700242:
       
   940      * If XTest is asked to press a non-existant mouse button
       
   941      * (i.e. press Button3 on a system configured with a 2-button mouse),
       
   942      * then a crash may happen.  To avoid this, we use the XInput
       
   943      * extension to query for the number of buttons on the XPointer, and check
       
   944      * before calling XTestFakeButtonEvent().
       
   945      */
       
   946     xinputAvailable = XQueryExtension(awt_display, INAME, &major_opcode, &first_event, &first_error);
       
   947     DTRACE_PRINTLN3("RobotPeer: XQueryExtension(XINPUT) returns major_opcode = %d, first_event = %d, first_error = %d",
       
   948                     major_opcode, first_event, first_error);
       
   949     if (xinputAvailable) {
       
   950         devices = XListInputDevices(awt_display, &numDevices);
       
   951         for (devIdx = 0; devIdx < numDevices; devIdx++) {
       
   952             aDevice = &(devices[devIdx]);
       
   953             if (aDevice->use == IsXExtensionPointer) {
       
   954                 for (clsIdx = 0; clsIdx < aDevice->num_classes; clsIdx++) {
       
   955                     if (aDevice->inputclassinfo[clsIdx].class == ButtonClass) {
       
   956                         bInfo = (XButtonInfo*)(&(aDevice->inputclassinfo[clsIdx]));
       
   957                         local_num_buttons = bInfo->num_buttons;
       
   958                         DTRACE_PRINTLN1("RobotPeer: XPointer has %d buttons", num_buttons);
       
   959                         break;
       
   960                     }
       
   961                 }
       
   962                 break;
       
   963             }
       
   964             if (local_num_buttons <= 0 ) {
       
   965                 if (aDevice->use == IsXPointer) {
       
   966                     for (clsIdx = 0; clsIdx < aDevice->num_classes; clsIdx++) {
       
   967                         if (aDevice->inputclassinfo[clsIdx].class == ButtonClass) {
       
   968                             bInfo = (XButtonInfo*)(&(aDevice->inputclassinfo[clsIdx]));
       
   969                             local_num_buttons = bInfo->num_buttons;
       
   970                             DTRACE_PRINTLN1("RobotPeer: XPointer has %d buttons", num_buttons);
       
   971                             break;
       
   972                         }
       
   973                     }
       
   974                     break;
       
   975                 }
       
   976             }
       
   977         }
       
   978 
       
   979         XFreeDeviceList(devices);
       
   980     }
       
   981     else {
       
   982         DTRACE_PRINTLN1("RobotPeer: XINPUT extension is unavailable, assuming %d mouse buttons", num_buttons);
       
   983     }
       
   984     if (local_num_buttons == 0 ) {
       
   985         local_num_buttons = 3;
       
   986     }
       
   987 
       
   988     return local_num_buttons;
       
   989 }