001: /*
002: * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025:
026: package sun.awt.X11;
027:
028: import java.util.*;
029: import sun.misc.Unsafe;
030:
031: public class WindowPropertyGetter {
032: private static Unsafe unsafe = XlibWrapper.unsafe;
033: private final long actual_type = unsafe.allocateMemory(8);
034: private final long actual_format = unsafe.allocateMemory(4);
035: private final long nitems_ptr = unsafe.allocateMemory(8);
036: private final long bytes_after = unsafe.allocateMemory(8);
037: private final long data = unsafe.allocateMemory(8);
038: private final long window;
039: private final XAtom property;
040: private final long offset;
041: private final long length;
042: private final boolean auto_delete;
043: private final long type;
044: private boolean executed = false;
045:
046: public WindowPropertyGetter(long window, XAtom property,
047: long offset, long length, boolean auto_delete, long type) {
048: if (property.getAtom() == 0) {
049: throw new IllegalArgumentException(
050: "Property ATOM should be initialized first:"
051: + property);
052: }
053: // Zero is AnyPropertyType.
054: // if (type == 0) {
055: // throw new IllegalArgumentException("Type ATOM shouldn't be zero");
056: // }
057: if (window == 0) {
058: throw new IllegalArgumentException(
059: "Window must not be zero");
060: }
061: this .window = window;
062: this .property = property;
063: this .offset = offset;
064: this .length = length;
065: this .auto_delete = auto_delete;
066: this .type = type;
067:
068: Native.putLong(data, 0);
069: sun.java2d.Disposer.addRecord(this ,
070: disposer = new UnsafeXDisposerRecord(
071: "WindowPropertyGetter", new long[] {
072: actual_type, actual_format, nitems_ptr,
073: bytes_after }, new long[] { data }));
074: }
075:
076: UnsafeXDisposerRecord disposer;
077:
078: public WindowPropertyGetter(long window, XAtom property,
079: long offset, long length, boolean auto_delete, XAtom type) {
080: this (window, property, offset, length, auto_delete, type
081: .getAtom());
082: }
083:
084: public int execute() {
085: return execute(null);
086: }
087:
088: public int execute(XToolkit.XErrorHandler errorHandler) {
089:
090: XToolkit.awtLock();
091: try {
092: if (isDisposed()) {
093: throw new IllegalStateException("Disposed");
094: }
095: if (executed) {
096: throw new IllegalStateException("Already executed");
097: }
098: executed = true;
099:
100: if (isCachingSupported() && isCached()) {
101: readFromCache();
102: return XlibWrapper.Success;
103: }
104:
105: // Fix for performance problem - IgnodeBadWindowHandler is
106: // used too much without reason, just ignore it
107: if (errorHandler == XToolkit.IgnoreBadWindowHandler) {
108: errorHandler = null;
109: }
110:
111: if (errorHandler != null) {
112: XToolkit.WITH_XERROR_HANDLER(errorHandler);
113: }
114: Native.putLong(data, 0);
115: int status = XlibWrapper.XGetWindowProperty(XToolkit
116: .getDisplay(), window, property.getAtom(), offset,
117: length, (auto_delete ? 1 : 0), type, actual_type,
118: actual_format, nitems_ptr, bytes_after, data);
119: if (isCachingSupported() && status == XlibWrapper.Success
120: && getData() != 0 && isCacheableProperty(property)) {
121: // Property has some data, we cache them
122: cacheProperty();
123: }
124:
125: if (errorHandler != null) {
126: XToolkit.RESTORE_XERROR_HANDLER();
127: }
128: return status;
129: } finally {
130: XToolkit.awtUnlock();
131: }
132: }
133:
134: public boolean isExecuted() {
135: return executed;
136: }
137:
138: public boolean isDisposed() {
139: return disposer.disposed;
140: }
141:
142: public int getActualFormat() {
143: if (isDisposed()) {
144: throw new IllegalStateException("Disposed");
145: }
146: if (!executed) {
147: throw new IllegalStateException("Not executed");
148: }
149: return unsafe.getInt(actual_format);
150: }
151:
152: public long getActualType() {
153: if (isDisposed()) {
154: throw new IllegalStateException("Disposed");
155: }
156: if (!executed) {
157: throw new IllegalStateException("Not executed");
158: }
159: return XAtom.getAtom(actual_type);
160: }
161:
162: public int getNumberOfItems() {
163: if (isDisposed()) {
164: throw new IllegalStateException("Disposed");
165: }
166: if (!executed) {
167: throw new IllegalStateException("Not executed");
168: }
169: return (int) Native.getLong(nitems_ptr);
170: }
171:
172: public long getData() {
173: if (isDisposed()) {
174: throw new IllegalStateException("Disposed");
175: }
176: return Native.getLong(data);
177: }
178:
179: public long getBytesAfter() {
180: if (isDisposed()) {
181: throw new IllegalStateException("Disposed");
182: }
183: if (!executed) {
184: throw new IllegalStateException("Not executed");
185: }
186: return Native.getLong(bytes_after);
187: }
188:
189: public void dispose() {
190: XToolkit.awtLock();
191: try {
192: if (isDisposed()) {
193: return;
194: }
195: disposer.dispose();
196: } finally {
197: XToolkit.awtUnlock();
198: }
199: }
200:
201: static boolean isCachingSupported() {
202: return XPropertyCache.isCachingSupported();
203: }
204:
205: static Set<XAtom> cacheableProperties = new HashSet<XAtom>(
206: Arrays
207: .asList(new XAtom[] { XAtom.get("_NET_WM_STATE"),
208: XAtom.get("WM_STATE"),
209: XAtom.get("_MOTIF_WM_HINTS") }));
210:
211: static boolean isCacheableProperty(XAtom property) {
212: return cacheableProperties.contains(property);
213: }
214:
215: boolean isCached() {
216: return XPropertyCache.isCached(window, property);
217: }
218:
219: int getDataLength() {
220: return getActualFormat() / 8 * getNumberOfItems();
221: }
222:
223: void readFromCache() {
224: property.putAtom(actual_type);
225: XPropertyCache.PropertyCacheEntry entry = XPropertyCache
226: .getCacheEntry(window, property);
227: Native.putInt(actual_format, entry.getFormat());
228: Native.putLong(nitems_ptr, entry.getNumberOfItems());
229: Native.putLong(bytes_after, entry.getBytesAfter());
230: Native.putLong(data, unsafe.allocateMemory(getDataLength()));
231: XlibWrapper.memcpy(getData(), entry.getData(), getDataLength());
232: }
233:
234: void cacheProperty() {
235: XPropertyCache.storeCache(
236: new XPropertyCache.PropertyCacheEntry(
237: getActualFormat(), getNumberOfItems(),
238: getBytesAfter(), getData(), getDataLength()),
239: window, property);
240: }
241:
242: }
|