blob: ba5f3837bd73bfe7a0ce019130dcd74603d5490b [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26package sun.awt.X11;
27
28import java.util.*;
29import sun.misc.Unsafe;
30
31public class WindowPropertyGetter {
32 private static Unsafe unsafe = XlibWrapper.unsafe;
33 private final long actual_type = unsafe.allocateMemory(8);
34 private final long actual_format = unsafe.allocateMemory(4);
35 private final long nitems_ptr = unsafe.allocateMemory(8);
36 private final long bytes_after = unsafe.allocateMemory(8);
37 private final long data = unsafe.allocateMemory(8);
38 private final long window;
39 private final XAtom property;
40 private final long offset;
41 private final long length;
42 private final boolean auto_delete;
43 private final long type;
44 private boolean executed = false;
45 public WindowPropertyGetter(long window, XAtom property, long offset,
46 long length, boolean auto_delete, long type)
47 {
48 if (property.getAtom() == 0) {
49 throw new IllegalArgumentException("Property ATOM should be initialized first:" + property);
50 }
51 // Zero is AnyPropertyType.
52 // if (type == 0) {
53 // throw new IllegalArgumentException("Type ATOM shouldn't be zero");
54 // }
55 if (window == 0) {
56 throw new IllegalArgumentException("Window must not be zero");
57 }
58 this.window = window;
59 this.property = property;
60 this.offset = offset;
61 this.length = length;
62 this.auto_delete = auto_delete;
63 this.type = type;
64
65 Native.putLong(data, 0);
66 sun.java2d.Disposer.addRecord(this, disposer = new UnsafeXDisposerRecord("WindowPropertyGetter", new long[] {actual_type,
67 actual_format, nitems_ptr, bytes_after}, new long[] {data}));
68 }
69 UnsafeXDisposerRecord disposer;
70 public WindowPropertyGetter(long window, XAtom property, long offset,
71 long length, boolean auto_delete, XAtom type)
72 {
73 this(window, property, offset, length, auto_delete, type.getAtom());
74 }
75 public int execute() {
76 return execute(null);
77 }
78 public int execute(XToolkit.XErrorHandler errorHandler) {
79
80 XToolkit.awtLock();
81 try {
82 if (isDisposed()) {
83 throw new IllegalStateException("Disposed");
84 }
85 if (executed) {
86 throw new IllegalStateException("Already executed");
87 }
88 executed = true;
89
90 if (isCachingSupported() && isCached()) {
91 readFromCache();
92 return XlibWrapper.Success;
93 }
94
95 // Fix for performance problem - IgnodeBadWindowHandler is
96 // used too much without reason, just ignore it
97 if (errorHandler == XToolkit.IgnoreBadWindowHandler) {
98 errorHandler = null;
99 }
100
101 if (errorHandler != null) {
102 XToolkit.WITH_XERROR_HANDLER(errorHandler);
103 }
104 Native.putLong(data, 0);
105 int status = XlibWrapper.XGetWindowProperty(XToolkit.getDisplay(), window, property.getAtom(),
106 offset, length, (auto_delete?1:0), type,
107 actual_type, actual_format, nitems_ptr,
108 bytes_after, data);
109 if (isCachingSupported() && status == XlibWrapper.Success && getData() != 0 && isCacheableProperty(property)) {
110 // Property has some data, we cache them
111 cacheProperty();
112 }
113
114 if (errorHandler != null) {
115 XToolkit.RESTORE_XERROR_HANDLER();
116 }
117 return status;
118 } finally {
119 XToolkit.awtUnlock();
120 }
121 }
122
123 public boolean isExecuted() {
124 return executed;
125 }
126
127 public boolean isDisposed() {
128 return disposer.disposed;
129 }
130
131 public int getActualFormat() {
132 if (isDisposed()) {
133 throw new IllegalStateException("Disposed");
134 }
135 if (!executed) {
136 throw new IllegalStateException("Not executed");
137 }
138 return unsafe.getInt(actual_format);
139 }
140 public long getActualType() {
141 if (isDisposed()) {
142 throw new IllegalStateException("Disposed");
143 }
144 if (!executed) {
145 throw new IllegalStateException("Not executed");
146 }
147 return XAtom.getAtom(actual_type);
148 }
149 public int getNumberOfItems() {
150 if (isDisposed()) {
151 throw new IllegalStateException("Disposed");
152 }
153 if (!executed) {
154 throw new IllegalStateException("Not executed");
155 }
156 return (int)Native.getLong(nitems_ptr);
157 }
158 public long getData() {
159 if (isDisposed()) {
160 throw new IllegalStateException("Disposed");
161 }
162 return Native.getLong(data);
163 }
164 public long getBytesAfter() {
165 if (isDisposed()) {
166 throw new IllegalStateException("Disposed");
167 }
168 if (!executed) {
169 throw new IllegalStateException("Not executed");
170 }
171 return Native.getLong(bytes_after);
172 }
173 public void dispose() {
174 XToolkit.awtLock();
175 try {
176 if (isDisposed()) {
177 return;
178 }
179 disposer.dispose();
180 } finally {
181 XToolkit.awtUnlock();
182 }
183 }
184
185 static boolean isCachingSupported() {
186 return XPropertyCache.isCachingSupported();
187 }
188
189 static Set<XAtom> cacheableProperties = new HashSet<XAtom>(Arrays.asList(new XAtom[] {
190 XAtom.get("_NET_WM_STATE"), XAtom.get("WM_STATE"), XAtom.get("_MOTIF_WM_HINTS")}));
191
192 static boolean isCacheableProperty(XAtom property) {
193 return cacheableProperties.contains(property);
194 }
195
196 boolean isCached() {
197 return XPropertyCache.isCached(window, property);
198 }
199
200 int getDataLength() {
201 return getActualFormat() / 8 * getNumberOfItems();
202 }
203
204 void readFromCache() {
205 property.putAtom(actual_type);
206 XPropertyCache.PropertyCacheEntry entry = XPropertyCache.getCacheEntry(window, property);
207 Native.putInt(actual_format, entry.getFormat());
208 Native.putLong(nitems_ptr, entry.getNumberOfItems());
209 Native.putLong(bytes_after, entry.getBytesAfter());
210 Native.putLong(data, unsafe.allocateMemory(getDataLength()));
211 XlibWrapper.memcpy(getData(), entry.getData(), getDataLength());
212 }
213
214 void cacheProperty() {
215 XPropertyCache.storeCache(
216 new XPropertyCache.PropertyCacheEntry(getActualFormat(),
217 getNumberOfItems(),
218 getBytesAfter(),
219 getData(),
220 getDataLength()),
221 window,
222 property);
223 }
224
225}