/*
 * Copyright (c) 2003, 2004, Oracle and/or its affiliates. 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.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package sun.awt;

import java.awt.Color;

import java.io.UnsupportedEncodingException;

import java.util.HashMap;
import java.util.Map;


Per-screen XSETTINGS.
/** * Per-screen XSETTINGS. */
public class XSettings { /** */ private long serial = -1;
Update these settings with data obtained from XSETTINGS manager.
Params:
  • data – settings data obtained from _XSETTINGS_SETTINGS window property of the settings manager.
Returns:a Map of changed settings.
/** * Update these settings with <code>data</code> obtained from * XSETTINGS manager. * * @param data settings data obtained from * <code>_XSETTINGS_SETTINGS</code> window property of the * settings manager. * @return a <code>Map</code> of changed settings. */
public Map update(byte[] data) { return (new Update(data)).update(); }
TBS ...
/** * TBS ... */
class Update { /* byte order mark */ private static final int LITTLE_ENDIAN = 0; private static final int BIG_ENDIAN = 1; /* setting type */ private static final int TYPE_INTEGER = 0; private static final int TYPE_STRING = 1; private static final int TYPE_COLOR = 2; private byte[] data; private int dlen; private int idx; private boolean isLittle; private long serial = -1; private int nsettings = 0; private boolean isValid; private HashMap updatedSettings;
Construct an Update object for the data read from _XSETTINGS_SETTINGS property of the XSETTINGS selection owner.
Params:
  • data – _XSETTINGS_SETTINGS contents.
/** * Construct an Update object for the data read from * <code>_XSETTINGS_SETTINGS</code> property of the XSETTINGS * selection owner. * * @param data <code>_XSETTINGS_SETTINGS</code> contents. */
Update(byte[] data) { this.data = data; dlen = data.length; if (dlen < 12) { // XXX: debug trace? return; } // first byte gives endianness of the data // next 3 bytes are unused (pad to 32 bit) idx = 0; isLittle = (getCARD8() == LITTLE_ENDIAN); idx = 4; serial = getCARD32(); // N_SETTINGS is actually CARD32 (i.e. unsigned), but // since java doesn't have an unsigned int type, and // N_SETTINGS cannot realistically exceed 2^31 (so we // gonna use int anyway), just read it as INT32. idx = 8; nsettings = getINT32(); updatedSettings = new HashMap(); isValid = true; } private void needBytes(int n) throws IndexOutOfBoundsException { if (idx + n <= dlen) { return; } throw new IndexOutOfBoundsException("at " + idx + " need " + n + " length " + dlen); } private int getCARD8() throws IndexOutOfBoundsException { needBytes(1); int val = data[idx] & 0xff; ++idx; return val; } private int getCARD16() throws IndexOutOfBoundsException { needBytes(2); int val; if (isLittle) { val = ((data[idx + 0] & 0xff) ) | ((data[idx + 1] & 0xff) << 8); } else { val = ((data[idx + 0] & 0xff) << 8) | ((data[idx + 1] & 0xff) ); } idx += 2; return val; } private int getINT32() throws IndexOutOfBoundsException { needBytes(4); int val; if (isLittle) { val = ((data[idx + 0] & 0xff) ) | ((data[idx + 1] & 0xff) << 8) | ((data[idx + 2] & 0xff) << 16) | ((data[idx + 3] & 0xff) << 24); } else { val = ((data[idx + 0] & 0xff) << 24) | ((data[idx + 1] & 0xff) << 16) | ((data[idx + 2] & 0xff) << 8) | ((data[idx + 3] & 0xff) << 0); } idx += 4; return val; } private long getCARD32() throws IndexOutOfBoundsException { return getINT32() & 0x00000000ffffffffL; } private String getString(int len) throws IndexOutOfBoundsException { needBytes(len); String str = null; try { str = new String(data, idx, len, "UTF-8"); } catch (UnsupportedEncodingException e) { // XXX: cannot happen, "UTF-8" is always supported } idx = (idx + len + 3) & ~0x3; return str; }
Update settings.
/** * Update settings. */
public Map update() { if (!isValid) { return null; } synchronized (XSettings.this) { long currentSerial = XSettings.this.serial; if (this.serial <= currentSerial) { return null; } for (int i = 0; i < nsettings && idx < dlen; ++i) { updateOne(currentSerial); } XSettings.this.serial = this.serial; } return updatedSettings; }
Parses a particular x setting.
Throws:
  • IndexOutOfBoundsException – if there isn't enough data for a setting.
/** * Parses a particular x setting. * * @exception IndexOutOfBoundsException if there isn't enough * data for a setting. */
private void updateOne(long currentSerial) throws IndexOutOfBoundsException, IllegalArgumentException { int type = getCARD8(); ++idx; // pad to next CARD16 // save position of the property name, skip to serial int nameLen = getCARD16(); int nameIdx = idx; // check if we should bother idx = (idx + nameLen + 3) & ~0x3; // pad to 32 bit long lastChanged = getCARD32(); // Avoid constructing garbage for properties that has not // changed, skip the data for this property. if (lastChanged <= currentSerial) { // skip if (type == TYPE_INTEGER) { idx += 4; } else if (type == TYPE_STRING) { int len = getINT32(); idx = (idx + len + 3) & ~0x3; } else if (type == TYPE_COLOR) { idx += 8; // 4 CARD16 } else { throw new IllegalArgumentException("Unknown type: " + type); } return; } idx = nameIdx; String name = getString(nameLen); idx += 4; // skip serial, parsed above Object value = null; if (type == TYPE_INTEGER) { value = Integer.valueOf(getINT32()); } else if (type == TYPE_STRING) { value = getString(getINT32()); } else if (type == TYPE_COLOR) { int r = getCARD16(); int g = getCARD16(); int b = getCARD16(); int a = getCARD16(); value = new Color(r / 65535.0f, g / 65535.0f, b / 65535.0f, a / 65535.0f); } else { throw new IllegalArgumentException("Unknown type: " + type); } if (name == null) { // dtrace??? return; } updatedSettings.put(name, value); } } // class XSettings.Update }