5100701: Toolkit.getLockingKeyState() does not work on XToolkit, but works on Motif
Summary: Does not work on Motif but works on XToolkit now; implemented using XQueryPointer.
Reviewed-by: anthony
/*
* Copyright 2003-2008 Sun Microsystems, Inc. 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. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/*
* This code is ported to XAWT from MAWT based on awt_mgrsel.c
* and XSettings.java code written originally by Valeriy Ushakov
* Author : Bino George
*/
package sun.awt.X11;
import java.util.*;
import java.awt.*;
import sun.awt.XSettings;
import java.util.logging.*;
class XAWTXSettings extends XSettings implements XMSelectionListener {
private final XAtom xSettingsPropertyAtom = XAtom.get("_XSETTINGS_SETTINGS");
private static Logger log = Logger.getLogger("sun.awt.X11.XAWTXSettings");
/* The maximal length of the property data. */
public static final long MAX_LENGTH = 1000000;
XMSelection settings;
public XAWTXSettings() {
initXSettings();
}
void initXSettings() {
if (log.isLoggable(Level.FINE)) log.fine("Initializing XAWT XSettings");
settings = new XMSelection("_XSETTINGS");
settings.addSelectionListener(this);
initPerScreenXSettings();
}
void dispose() {
settings.removeSelectionListener(this);
}
public void ownerDeath(int screen, XMSelection sel, long deadOwner) {
if (log.isLoggable(Level.FINE)) log.fine("Owner " + deadOwner + " died for selection " + sel + " screen "+ screen);
}
public void ownerChanged(int screen, XMSelection sel, long newOwner, long data, long timestamp) {
if (log.isLoggable(Level.FINE)) log.fine("New Owner "+ newOwner + " for selection = " + sel + " screen " +screen );
}
public void selectionChanged(int screen, XMSelection sel, long owner , XPropertyEvent event) {
log.fine("Selection changed on sel " + sel + " screen = " + screen + " owner = " + owner + " event = " + event);
updateXSettings(screen,owner);
}
void initPerScreenXSettings() {
if (log.isLoggable(Level.FINE)) log.fine("Updating Per XSettings changes");
/*
* As toolkit cannot yet cope with per-screen desktop properties,
* only report XSETTINGS changes on the default screen. This
* should be "good enough" for most cases.
*/
Map updatedSettings = null;
XToolkit.awtLock();
try {
long display = XToolkit.getDisplay();
int screen = (int) XlibWrapper.DefaultScreen(display);
updatedSettings = getUpdatedSettings(settings.getOwner(screen));
} finally {
XToolkit.awtUnlock();
}
// we must not invoke this under Awt Lock
((XToolkit)Toolkit.getDefaultToolkit()).parseXSettings(0,updatedSettings);
}
private void updateXSettings(int screen, long owner) {
final Map updatedSettings = getUpdatedSettings(owner);
// this method is called under awt lock and usually on toolkit thread
// but parseXSettings() causes public code execution, so we need to transfer
// this to EDT
EventQueue.invokeLater( new Runnable() {
public void run() {
((XToolkit) Toolkit.getDefaultToolkit()).parseXSettings( 0, updatedSettings);
}
});
}
private Map getUpdatedSettings(final long owner) {
if (log.isLoggable(Level.FINE)) log.fine("owner =" + owner);
if (0 == owner) {
return null;
}
Map settings = null;
try {
WindowPropertyGetter getter =
new WindowPropertyGetter(owner, xSettingsPropertyAtom, 0, MAX_LENGTH,
false, xSettingsPropertyAtom.getAtom() );
try {
int status = getter.execute(XToolkit.IgnoreBadWindowHandler);
if (status != XConstants.Success || getter.getData() == 0) {
if (log.isLoggable(Level.FINE)) log.fine("OH OH : getter failed status = " + status );
settings = null;
}
long ptr = getter.getData();
if (log.isLoggable(Level.FINE)) log.fine("noItems = " + getter.getNumberOfItems());
byte array[] = Native.toBytes(ptr,getter.getNumberOfItems());
if (array != null) {
settings = update(array);
}
} finally {
getter.dispose();
}
}
catch (Exception e) {
e.printStackTrace();
}
return settings;
}
}