Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/solaris/classes/sun/awt/XSettings.java
32287 views
/*1* Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package sun.awt;2627import java.awt.Color;2829import java.io.UnsupportedEncodingException;3031import java.util.HashMap;32import java.util.Map;333435/**36* Per-screen XSETTINGS.37*/38public class XSettings {3940/**41*/42private long serial = -1;434445/**46* Update these settings with <code>data</code> obtained from47* XSETTINGS manager.48*49* @param data settings data obtained from50* <code>_XSETTINGS_SETTINGS</code> window property of the51* settings manager.52* @return a <code>Map</code> of changed settings.53*/54public Map update(byte[] data) {55return (new Update(data)).update();56}575859/**60* TBS ...61*/62class Update {6364/* byte order mark */65private static final int LITTLE_ENDIAN = 0;66private static final int BIG_ENDIAN = 1;6768/* setting type */69private static final int TYPE_INTEGER = 0;70private static final int TYPE_STRING = 1;71private static final int TYPE_COLOR = 2;7273private byte[] data;74private int dlen;75private int idx;76private boolean isLittle;77private long serial = -1;78private int nsettings = 0;79private boolean isValid;8081private HashMap updatedSettings;828384/**85* Construct an Update object for the data read from86* <code>_XSETTINGS_SETTINGS</code> property of the XSETTINGS87* selection owner.88*89* @param data <code>_XSETTINGS_SETTINGS</code> contents.90*/91Update(byte[] data) {92this.data = data;9394dlen = data.length;95if (dlen < 12) {96// XXX: debug trace?97return;98}99100// first byte gives endianness of the data101// next 3 bytes are unused (pad to 32 bit)102idx = 0;103isLittle = (getCARD8() == LITTLE_ENDIAN);104105idx = 4;106serial = getCARD32();107108// N_SETTINGS is actually CARD32 (i.e. unsigned), but109// since java doesn't have an unsigned int type, and110// N_SETTINGS cannot realistically exceed 2^31 (so we111// gonna use int anyway), just read it as INT32.112idx = 8;113nsettings = getINT32();114115updatedSettings = new HashMap();116117isValid = true;118}119120121private void needBytes(int n)122throws IndexOutOfBoundsException123{124if (idx + n <= dlen) {125return;126}127128throw new IndexOutOfBoundsException("at " + idx129+ " need " + n130+ " length " + dlen);131}132133134private int getCARD8()135throws IndexOutOfBoundsException136{137needBytes(1);138139int val = data[idx] & 0xff;140141++idx;142return val;143}144145146private int getCARD16()147throws IndexOutOfBoundsException148{149needBytes(2);150151int val;152if (isLittle) {153val = ((data[idx + 0] & 0xff) )154| ((data[idx + 1] & 0xff) << 8);155} else {156val = ((data[idx + 0] & 0xff) << 8)157| ((data[idx + 1] & 0xff) );158}159160idx += 2;161return val;162}163164165private int getINT32()166throws IndexOutOfBoundsException167{168needBytes(4);169170int val;171if (isLittle) {172val = ((data[idx + 0] & 0xff) )173| ((data[idx + 1] & 0xff) << 8)174| ((data[idx + 2] & 0xff) << 16)175| ((data[idx + 3] & 0xff) << 24);176} else {177val = ((data[idx + 0] & 0xff) << 24)178| ((data[idx + 1] & 0xff) << 16)179| ((data[idx + 2] & 0xff) << 8)180| ((data[idx + 3] & 0xff) << 0);181}182183idx += 4;184return val;185}186187188private long getCARD32()189throws IndexOutOfBoundsException190{191return getINT32() & 0x00000000ffffffffL;192}193194195private String getString(int len)196throws IndexOutOfBoundsException197{198needBytes(len);199200String str = null;201try {202str = new String(data, idx, len, "UTF-8");203} catch (UnsupportedEncodingException e) {204// XXX: cannot happen, "UTF-8" is always supported205}206207idx = (idx + len + 3) & ~0x3;208return str;209}210211212/**213* Update settings.214*/215public Map update() {216if (!isValid) {217return null;218}219220synchronized (XSettings.this) {221long currentSerial = XSettings.this.serial;222223if (this.serial <= currentSerial) {224return null;225}226227for (int i = 0; i < nsettings && idx < dlen; ++i) {228updateOne(currentSerial);229}230231XSettings.this.serial = this.serial;232}233234return updatedSettings;235}236237238/**239* Parses a particular x setting.240*241* @exception IndexOutOfBoundsException if there isn't enough242* data for a setting.243*/244private void updateOne(long currentSerial)245throws IndexOutOfBoundsException,246IllegalArgumentException247{248int type = getCARD8();249++idx; // pad to next CARD16250251// save position of the property name, skip to serial252int nameLen = getCARD16();253int nameIdx = idx;254255// check if we should bother256idx = (idx + nameLen + 3) & ~0x3; // pad to 32 bit257long lastChanged = getCARD32();258259// Avoid constructing garbage for properties that has not260// changed, skip the data for this property.261if (lastChanged <= currentSerial) { // skip262if (type == TYPE_INTEGER) {263idx += 4;264} else if (type == TYPE_STRING) {265int len = getINT32();266idx = (idx + len + 3) & ~0x3;267} else if (type == TYPE_COLOR) {268idx += 8; // 4 CARD16269} else {270throw new IllegalArgumentException("Unknown type: "271+ type);272}273274return;275}276277idx = nameIdx;278String name = getString(nameLen);279idx += 4; // skip serial, parsed above280281Object value = null;282if (type == TYPE_INTEGER) {283value = Integer.valueOf(getINT32());284}285else if (type == TYPE_STRING) {286value = getString(getINT32());287}288else if (type == TYPE_COLOR) {289int r = getCARD16();290int g = getCARD16();291int b = getCARD16();292int a = getCARD16();293294value = new Color(r / 65535.0f,295g / 65535.0f,296b / 65535.0f,297a / 65535.0f);298}299else {300throw new IllegalArgumentException("Unknown type: " + type);301}302303if (name == null) {304// dtrace???305return;306}307308updatedSettings.put(name, value);309}310311} // class XSettings.Update312}313314315