blob: b98fc9b8ee968a3d592f29e730f6ca4aabd176c4 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 2002-2006 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
28/**
29 * XAtom is a class that allows you to create and modify X Window properties.
30 * An X Atom is an identifier for a property that you can set on any X Window.
31 * Standard X Atom are defined by X11 and these atoms are defined in this class
32 * for convenience. Common X Atoms like <code>XA_WM_NAME</code> are used to communicate with the
33 * Window manager to let it know the Window name. The use and protocol for these
34 * atoms are defined in the Inter client communications converntions manual.
35 * User specified XAtoms are defined by specifying a name that gets Interned
36 * by the XServer and an <code>XAtom</code> object is returned. An <code>XAtom</code> can also be created
37 * by using a pre-exisiting atom like <code>XA_WM_CLASS</code>. A <code>display</code> has to be specified
38 * in order to create an <code>XAtom</code>. <p> <p>
39 *
40 * Once an <code>XAtom</code> instance is created, you can call get and set property methods to
41 * set the values for a particular window. <p> <p>
42 *
43 *
44 * Example usage : To set the window name for a top level: <p>
45 * <code>
46 * XAtom xa = new XAtom(display,XAtom.XA_WM_NAME); <p>
47 * xa.setProperty(window,"Hello World");<p></code>
48 *<p>
49 *<p>
50 * To get the cut buffer :<p>
51 * <p><code>
52 * XAtom xa = new XAtom(display,XAtom.XA_CUT_BUFFER0);<p>
53 * String selection = xa.getProperty(root_window);<p></code>
54 * @author Bino George
55 * @since JDK1.5
56 */
57
58import sun.misc.Unsafe;
59import java.util.HashMap;
60
61public class XAtom {
62
63 // Order of lock: XAWTLock -> XAtom.class
64
65 /* Predefined Atoms - automatically extracted from XAtom.h */
66 private static Unsafe unsafe = XlibWrapper.unsafe;
67 private static XAtom[] emptyList = new XAtom[0];
68
69 public static final long XA_PRIMARY=1;
70 public static final long XA_SECONDARY=2;
71 public static final long XA_ARC=3;
72 public static final long XA_ATOM=4;
73 public static final long XA_BITMAP=5;
74 public static final long XA_CARDINAL=6;
75 public static final long XA_COLORMAP=7;
76 public static final long XA_CURSOR=8;
77 public static final long XA_CUT_BUFFER0=9;
78 public static final long XA_CUT_BUFFER1=10;
79 public static final long XA_CUT_BUFFER2=11;
80 public static final long XA_CUT_BUFFER3=12;
81 public static final long XA_CUT_BUFFER4=13;
82 public static final long XA_CUT_BUFFER5=14;
83 public static final long XA_CUT_BUFFER6=15;
84 public static final long XA_CUT_BUFFER7=16;
85 public static final long XA_DRAWABLE=17;
86 public static final long XA_FONT=18;
87 public static final long XA_INTEGER=19;
88 public static final long XA_PIXMAP=20;
89 public static final long XA_POINT=21;
90 public static final long XA_RECTANGLE=22;
91 public static final long XA_RESOURCE_MANAGER=23;
92 public static final long XA_RGB_COLOR_MAP=24;
93 public static final long XA_RGB_BEST_MAP=25;
94 public static final long XA_RGB_BLUE_MAP=26;
95 public static final long XA_RGB_DEFAULT_MAP=27;
96 public static final long XA_RGB_GRAY_MAP=28;
97 public static final long XA_RGB_GREEN_MAP=29;
98 public static final long XA_RGB_RED_MAP=30;
99 public static final long XA_STRING=31;
100 public static final long XA_VISUALID=32;
101 public static final long XA_WINDOW=33;
102 public static final long XA_WM_COMMAND=34;
103 public static final long XA_WM_HINTS=35;
104 public static final long XA_WM_CLIENT_MACHINE=36;
105 public static final long XA_WM_ICON_NAME=37;
106 public static final long XA_WM_ICON_SIZE=38;
107 public static final long XA_WM_NAME=39;
108 public static final long XA_WM_NORMAL_HINTS=40;
109 public static final long XA_WM_SIZE_HINTS=41;
110 public static final long XA_WM_ZOOM_HINTS=42;
111 public static final long XA_MIN_SPACE=43;
112 public static final long XA_NORM_SPACE=44;
113 public static final long XA_MAX_SPACE=45;
114 public static final long XA_END_SPACE=46;
115 public static final long XA_SUPERSCRIPT_X=47;
116 public static final long XA_SUPERSCRIPT_Y=48;
117 public static final long XA_SUBSCRIPT_X=49;
118 public static final long XA_SUBSCRIPT_Y=50;
119 public static final long XA_UNDERLINE_POSITION=51;
120 public static final long XA_UNDERLINE_THICKNESS=52 ;
121 public static final long XA_STRIKEOUT_ASCENT=53;
122 public static final long XA_STRIKEOUT_DESCENT=54;
123 public static final long XA_ITALIC_ANGLE=55;
124 public static final long XA_X_HEIGHT=56;
125 public static final long XA_QUAD_WIDTH=57;
126 public static final long XA_WEIGHT=58;
127 public static final long XA_POINT_SIZE=59;
128 public static final long XA_RESOLUTION=60;
129 public static final long XA_COPYRIGHT=61;
130 public static final long XA_NOTICE=62;
131 public static final long XA_FONT_NAME=63;
132 public static final long XA_FAMILY_NAME=64;
133 public static final long XA_FULL_NAME=65;
134 public static final long XA_CAP_HEIGHT=66;
135 public static final long XA_WM_CLASS=67;
136 public static final long XA_WM_TRANSIENT_FOR=68;
137 public static final long XA_LAST_PREDEFINED=68;
138 static HashMap<Long, XAtom> atomToAtom = new HashMap<Long, XAtom>();
139 static HashMap<String, XAtom> nameToAtom = new HashMap<String, XAtom>();
140 static void register(XAtom at) {
141 if (at == null) {
142 return;
143 }
144 synchronized (XAtom.class) {
145 if (at.atom != 0) {
146 atomToAtom.put(Long.valueOf(at.atom), at);
147 }
148 if (at.name != null) {
149 nameToAtom.put(at.name, at);
150 }
151 }
152 }
153 static XAtom lookup(long atom) {
154 synchronized (XAtom.class) {
155 return atomToAtom.get(Long.valueOf(atom));
156 }
157 }
158 static XAtom lookup(String name) {
159 synchronized (XAtom.class) {
160 return nameToAtom.get(name);
161 }
162 }
163 /*
164 * [das]Suggestion:
165 * 1.Make XAtom immutable.
166 * 2.Replace public ctors with factory methods (e.g. get() below).
167 */
168 static XAtom get(long atom) {
169 XAtom xatom = lookup(atom);
170 if (xatom == null) {
171 xatom = new XAtom(XToolkit.getDisplay(), atom);
172 }
173 return xatom;
174 }
175 public static XAtom get(String name) {
176 XAtom xatom = lookup(name);
177 if (xatom == null) {
178 xatom = new XAtom(name);
179 }
180 return xatom;
181 }
182 public final String getName() {
183 if (name == null) {
184 XToolkit.awtLock();
185 try {
186 this.name = XlibWrapper.XGetAtomName(display, atom);
187 } finally {
188 XToolkit.awtUnlock();
189 }
190 register();
191 }
192 return name;
193 }
194 static String asString(long atom) {
195 XAtom at = lookup(atom);
196 if (at == null) {
197 return Long.toString(atom);
198 } else {
199 return at.toString();
200 }
201 }
202 void register() {
203 register(this);
204 }
205 public String toString() {
206 if (name != null) {
207 return name + ":" + atom;
208 } else {
209 return Long.toString(atom);
210 }
211 }
212
213 /* interned value of Atom */
214 long atom = 0;
215
216 /* name of atom */
217 String name;
218
219 /* display for X connection */
220 long display;
221
222
223 /** This constructor will create and intern a new XAtom that is specified
224 * by the supplied name.
225 *
226 * @param display X display to use
227 * @param name name of the XAtom to create.
228 * @since 1.5
229 */
230
231 private XAtom(long display, String name) {
232 this(display, name, true);
233 }
234
235 private XAtom(String name) {
236 this(XToolkit.getDisplay(), name, true);
237 }
238
239 public XAtom(String name, boolean autoIntern) {
240 this(XToolkit.getDisplay(), name, autoIntern);
241 }
242
243 /** This constructor will create an instance of XAtom that is specified
244 * by the predefined XAtom specified by u <code> latom </code>
245 *
246 * @param display X display to use.
247 * @param atom a predefined XAtom.
248 * @since 1.5
249 */
250 public XAtom(long display, long atom) {
251 this.atom = atom;
252 this.display = display;
253 register();
254 }
255
256 /** This constructor will create the instance,
257 * and if <code>autoIntern</code> is true intern a new XAtom that is specified
258 * by the supplied name.
259 *
260 * @param display X display to use
261 * @param name name of the XAtom to create.
262 * @since 1.5
263 */
264
265 public XAtom(long display, String name, boolean autoIntern) {
266 this.name = name;
267 this.display = display;
268 if (autoIntern) {
269 XToolkit.awtLock();
270 try {
271 atom = XlibWrapper.InternAtom(display,name,0);
272 } finally {
273 XToolkit.awtUnlock();
274 }
275 }
276 register();
277 }
278
279 /**
280 * Creates uninitialized instance of
281 */
282 public XAtom() {
283 }
284
285 /** Sets the window property for the specified window
286 * @param window window id to use
287 * @param str value to set to.
288 * @since 1.5
289 */
290 public void setProperty(long window, String str) {
291 if (atom == 0) {
292 throw new IllegalStateException("Atom should be initialized");
293 }
294 checkWindow(window);
295 XToolkit.awtLock();
296 try {
297 XlibWrapper.SetProperty(display,window,atom,str);
298 } finally {
299 XToolkit.awtUnlock();
300 }
301 }
302
303 /**
304 * Sets UTF8_STRING type property. Explicitly converts str to UTF-8 byte sequence.
305 */
306 public void setPropertyUTF8(long window, String str) {
307 XAtom XA_UTF8_STRING = XAtom.get("UTF8_STRING"); /* like STRING but encoding is UTF-8 */
308 if (atom == 0) {
309 throw new IllegalStateException("Atom should be initialized");
310 }
311 checkWindow(window);
312 byte[] bdata = null;
313 try {
314 bdata = str.getBytes("UTF-8");
315 } catch (java.io.UnsupportedEncodingException uee) {
316 uee.printStackTrace();
317 }
318 if (bdata != null) {
319 setAtomData(window, XA_UTF8_STRING.atom, bdata);
320 }
321 }
322
323 /**
324 * Sets STRING/8 type property. Explicitly converts str to Latin-1 byte sequence.
325 */
326 public void setProperty8(long window, String str) {
327 if (atom == 0) {
328 throw new IllegalStateException("Atom should be initialized");
329 }
330 checkWindow(window);
331 byte[] bdata = null;
332 try {
333 bdata = str.getBytes("ISO-8859-1");
334 } catch (java.io.UnsupportedEncodingException uee) {
335 uee.printStackTrace();
336 }
337 if (bdata != null) {
338 setAtomData(window, XA_STRING, bdata);
339 }
340 }
341
342
343 /** Gets the window property for the specified window
344 * @param window window id to use
345 * @param str value to set to.
346 * @return string with the property.
347 * @since 1.5
348 */
349 public String getProperty(long window) {
350 if (atom == 0) {
351 throw new IllegalStateException("Atom should be initialized");
352 }
353 checkWindow(window);
354 XToolkit.awtLock();
355 try {
356 return XlibWrapper.GetProperty(display,window,atom);
357 } finally {
358 XToolkit.awtUnlock();
359 }
360 }
361
362
363 /*
364 * Auxiliary function that returns the value of 'property' of type
365 * 'property_type' on window 'window'. Format of the property must be 32.
366 */
367 public long get32Property(long window, long property_type) {
368 if (atom == 0) {
369 throw new IllegalStateException("Atom should be initialized");
370 }
371 checkWindow(window);
372 WindowPropertyGetter getter =
373 new WindowPropertyGetter(window, this, 0, 1,
374 false, property_type);
375 try {
376 int status = getter.execute();
377 if (status != XlibWrapper.Success || getter.getData() == 0) {
378 return 0;
379 }
380 if (getter.getActualType() != property_type || getter.getActualFormat() != 32) {
381 return 0;
382 }
383 return Native.getCard32(getter.getData());
384 } finally {
385 getter.dispose();
386 }
387 }
388
389 /**
390 * Returns value of property of type CARDINAL/32 of this window
391 */
392 public long getCard32Property(XBaseWindow window) {
393 return get32Property(window.getWindow(), XA_CARDINAL);
394 }
395
396 /**
397 * Sets property of type CARDINAL on the window
398 */
399 public void setCard32Property(long window, long value) {
400 if (atom == 0) {
401 throw new IllegalStateException("Atom should be initialized");
402 }
403 checkWindow(window);
404 XToolkit.awtLock();
405 try {
406 Native.putCard32(XlibWrapper.larg1, value);
407 XlibWrapper.XChangeProperty(XToolkit.getDisplay(), window,
408 atom, XA_CARDINAL, 32, XlibWrapper.PropModeReplace,
409 XlibWrapper.larg1, 1);
410 } finally {
411 XToolkit.awtUnlock();
412 }
413 }
414
415 /**
416 * Sets property of type CARDINAL/32 on the window
417 */
418 public void setCard32Property(XBaseWindow window, long value) {
419 setCard32Property(window.getWindow(), value);
420 }
421
422 /**
423 * Gets uninterpreted set of data from property and stores them in data_ptr.
424 * Property type is the same as current atom, property is current atom.
425 * Property format is 32. Property 'delete' is false.
426 * Returns boolean if requested type, format, length match returned values
427 * and returned data pointer is not null.
428 */
429 public boolean getAtomData(long window, long data_ptr, int length) {
430 if (atom == 0) {
431 throw new IllegalStateException("Atom should be initialized");
432 }
433 checkWindow(window);
434 WindowPropertyGetter getter =
435 new WindowPropertyGetter(window, this, 0, (long)length,
436 false, this);
437 try {
438 int status = getter.execute();
439 if (status != XlibWrapper.Success || getter.getData() == 0) {
440 return false;
441 }
442 if (getter.getActualType() != atom
443 || getter.getActualFormat() != 32
444 || getter.getNumberOfItems() != length
445 )
446 {
447 return false;
448 }
449 XlibWrapper.memcpy(data_ptr, getter.getData(), length*getAtomSize());
450 return true;
451 } finally {
452 getter.dispose();
453 }
454 }
455
456 /**
457 * Gets uninterpreted set of data from property and stores them in data_ptr.
458 * Property type is <code>type</code>, property is current atom.
459 * Property format is 32. Property 'delete' is false.
460 * Returns boolean if requested type, format, length match returned values
461 * and returned data pointer is not null.
462 */
463 public boolean getAtomData(long window, long type, long data_ptr, int length) {
464 if (atom == 0) {
465 throw new IllegalStateException("Atom should be initialized");
466 }
467 checkWindow(window);
468 WindowPropertyGetter getter =
469 new WindowPropertyGetter(window, this, 0, (long)length,
470 false, type);
471 try {
472 int status = getter.execute();
473 if (status != XlibWrapper.Success || getter.getData() == 0) {
474 return false;
475 }
476 if (getter.getActualType() != type
477 || getter.getActualFormat() != 32
478 || getter.getNumberOfItems() != length
479 )
480 {
481 return false;
482 }
483 XlibWrapper.memcpy(data_ptr, getter.getData(), length*getAtomSize());
484 return true;
485 } finally {
486 getter.dispose();
487 }
488 }
489
490 /**
491 * Sets uninterpreted set of data into property from data_ptr.
492 * Property type is the same as current atom, property is current atom.
493 * Property format is 32. Mode is PropModeReplace. length is a number
494 * of items pointer by data_ptr.
495 */
496 public void setAtomData(long window, long data_ptr, int length) {
497 if (atom == 0) {
498 throw new IllegalStateException("Atom should be initialized");
499 }
500 checkWindow(window);
501 XToolkit.awtLock();
502 try {
503 XlibWrapper.XChangeProperty(XToolkit.getDisplay(), window,
504 atom, atom, 32, XlibWrapper.PropModeReplace,
505 data_ptr, length);
506 } finally {
507 XToolkit.awtUnlock();
508 }
509 }
510
511 /**
512 * Sets uninterpreted set of data into property from data_ptr.
513 * Property type is <code>type</code>, property is current atom.
514 * Property format is 32. Mode is PropModeReplace. length is a number
515 * of items pointer by data_ptr.
516 */
517 public void setAtomData(long window, long type, long data_ptr, int length) {
518 if (atom == 0) {
519 throw new IllegalStateException("Atom should be initialized");
520 }
521 checkWindow(window);
522 XToolkit.awtLock();
523 try {
524 XlibWrapper.XChangeProperty(XToolkit.getDisplay(), window,
525 atom, type, 32, XlibWrapper.PropModeReplace,
526 data_ptr, length);
527 } finally {
528 XToolkit.awtUnlock();
529 }
530 }
531
532 /**
533 * Sets uninterpreted set of data into property from data_ptr.
534 * Property type is <code>type</code>, property is current atom.
535 * Property format is 8. Mode is PropModeReplace. length is a number
536 * of bytes pointer by data_ptr.
537 */
538 public void setAtomData8(long window, long type, long data_ptr, int length) {
539 if (atom == 0) {
540 throw new IllegalStateException("Atom should be initialized");
541 }
542 checkWindow(window);
543 XToolkit.awtLock();
544 try {
545 XlibWrapper.XChangeProperty(XToolkit.getDisplay(), window,
546 atom, type, 8, XlibWrapper.PropModeReplace,
547 data_ptr, length);
548 } finally {
549 XToolkit.awtUnlock();
550 }
551 }
552
553 /**
554 * Deletes property specified by this item on the window.
555 */
556 public void DeleteProperty(long window) {
557 if (atom == 0) {
558 throw new IllegalStateException("Atom should be initialized");
559 }
560 checkWindow(window);
561 XToolkit.awtLock();
562 try {
563 XlibWrapper.XDeleteProperty(XToolkit.getDisplay(), window, atom);
564 } finally {
565 XToolkit.awtUnlock();
566 }
567 }
568
569 /**
570 * Deletes property specified by this item on the window.
571 */
572 public void DeleteProperty(XBaseWindow window) {
573 if (atom == 0) {
574 throw new IllegalStateException("Atom should be initialized");
575 }
576 checkWindow(window.getWindow());
577 XToolkit.awtLock();
578 try {
579 XlibWrapper.XDeleteProperty(XToolkit.getDisplay(),
580 window.getWindow(), atom);
581 } finally {
582 XToolkit.awtUnlock();
583 }
584 }
585
586 public void setAtomData(long window, long property_type, byte[] data) {
587 long bdata = Native.toData(data);
588 try {
589 setAtomData8(window, property_type, bdata, data.length);
590 } finally {
591 unsafe.freeMemory(bdata);
592 }
593 }
594
595 /*
596 * Auxiliary function that returns the value of 'property' of type
597 * 'property_type' on window 'window'. Format of the property must be 8.
598 */
599 public byte[] getByteArrayProperty(long window, long property_type) {
600 if (atom == 0) {
601 throw new IllegalStateException("Atom should be initialized");
602 }
603 checkWindow(window);
604 WindowPropertyGetter getter =
605 new WindowPropertyGetter(window, this, 0, 0xFFFF,
606 false, property_type);
607 try {
608 int status = getter.execute();
609 if (status != XlibWrapper.Success || getter.getData() == 0) {
610 return null;
611 }
612 if (getter.getActualType() != property_type || getter.getActualFormat() != 8) {
613 return null;
614 }
615 byte[] res = XlibWrapper.getStringBytes(getter.getData());
616 return res;
617 } finally {
618 getter.dispose();
619 }
620 }
621
622 /**
623 * Interns the XAtom
624 */
625 public void intern(boolean onlyIfExists) {
626 XToolkit.awtLock();
627 try {
628 atom = XlibWrapper.InternAtom(display,name, onlyIfExists?1:0);
629 } finally {
630 XToolkit.awtUnlock();
631 }
632 register();
633 }
634
635 public boolean isInterned() {
636 if (atom == 0) {
637 XToolkit.awtLock();
638 try {
639 atom = XlibWrapper.InternAtom(display, name, 1);
640 } finally {
641 XToolkit.awtUnlock();
642 }
643 if (atom == 0) {
644 return false;
645 } else {
646 register();
647 return true;
648 }
649 } else {
650 return true;
651 }
652 }
653
654 /**
655 * Initializes atom with name and display values
656 */
657 public void setValues(long display, String name, boolean autoIntern) {
658 this.display = display;
659 this.name = name;
660 if (autoIntern) {
661 XToolkit.awtLock();
662 try {
663 atom = XlibWrapper.InternAtom(display,name,0);
664 } finally {
665 XToolkit.awtUnlock();
666 }
667 }
668 register();
669 }
670
671 public void setValues(long display, long atom) {
672 this.display = display;
673 this.atom = atom;
674 register();
675 }
676 public void setValues(long display, String name, long atom) {
677 this.display = display;
678 this.atom = atom;
679 this.name = name;
680 register();
681 }
682
683 static int getAtomSize() {
684 return Native.getLongSize();
685 }
686
687 /*
688 * Returns the value of property ATOM[]/32 as array of XAtom objects
689 * @return array of atoms, array of length 0 if the atom list is empty
690 * or has different format
691 */
692 XAtom[] getAtomListProperty(long window) {
693 if (atom == 0) {
694 throw new IllegalStateException("Atom should be initialized");
695 }
696 checkWindow(window);
697
698 WindowPropertyGetter getter =
699 new WindowPropertyGetter(window, this, 0, 0xFFFF,
700 false, XA_ATOM);
701 try {
702 int status = getter.execute();
703 if (status != XlibWrapper.Success || getter.getData() == 0) {
704 return emptyList;
705 }
706 if (getter.getActualType() != XA_ATOM || getter.getActualFormat() != 32) {
707 return emptyList;
708 }
709
710 int count = (int)getter.getNumberOfItems();
711 if (count == 0) {
712 return emptyList;
713 }
714 long list_atoms = getter.getData();
715 XAtom[] res = new XAtom[count];
716 for (int index = 0; index < count; index++) {
717 res[index] = XAtom.get(XAtom.getAtom(list_atoms+index*getAtomSize()));
718 }
719 return res;
720 } finally {
721 getter.dispose();
722 }
723 }
724
725 /*
726 * Returns the value of property of type ATOM[]/32 as XAtomList
727 * @return list of atoms, empty list if the atom list is empty
728 * or has different format
729 */
730 XAtomList getAtomListPropertyList(long window) {
731 return new XAtomList(getAtomListProperty(window));
732 }
733 XAtomList getAtomListPropertyList(XBaseWindow window) {
734 return getAtomListPropertyList(window.getWindow());
735 }
736 XAtom[] getAtomListProperty(XBaseWindow window) {
737 return getAtomListProperty(window.getWindow());
738 }
739
740 /**
741 * Sets property value of type ATOM list to the list of atoms.
742 */
743 void setAtomListProperty(long window, XAtom[] atoms) {
744 long data = toData(atoms);
745 setAtomData(window, XAtom.XA_ATOM, data, atoms.length);
746 unsafe.freeMemory(data);
747 }
748
749 /**
750 * Sets property value of type ATOM list to the list of atoms specified by XAtomList
751 */
752 void setAtomListProperty(long window, XAtomList atoms) {
753 long data = atoms.getAtomsData();
754 setAtomData(window, XAtom.XA_ATOM, data, atoms.size());
755 unsafe.freeMemory(data);
756 }
757 /**
758 * Sets property value of type ATOM list to the list of atoms.
759 */
760 public void setAtomListProperty(XBaseWindow window, XAtom[] atoms) {
761 setAtomListProperty(window.getWindow(), atoms);
762 }
763
764 /**
765 * Sets property value of type ATOM list to the list of atoms specified by XAtomList
766 */
767 public void setAtomListProperty(XBaseWindow window, XAtomList atoms) {
768 setAtomListProperty(window.getWindow(), atoms);
769 }
770
771 long getAtom() {
772 return atom;
773 }
774
775 void putAtom(long ptr) {
776 Native.putLong(ptr, atom);
777 }
778
779 static long getAtom(long ptr) {
780 return Native.getLong(ptr);
781 }
782 /**
783 * Allocated memory to hold the list of native atom data and returns unsafe pointer to it
784 * Caller should free the memory by himself.
785 */
786 static long toData(XAtom[] atoms) {
787 long data = unsafe.allocateMemory(getAtomSize() * atoms.length);
788 for (int i = 0; i < atoms.length; i++ ) {
789 if (atoms[i] != null) {
790 atoms[i].putAtom(data + i * getAtomSize());
791 }
792 }
793 return data;
794 }
795
796 void checkWindow(long window) {
797 if (window == 0) {
798 throw new IllegalArgumentException("Window must not be zero");
799 }
800 }
801
802 public boolean equals(Object o) {
803 if (!(o instanceof XAtom)) {
804 return false;
805 }
806 XAtom ot = (XAtom)o;
807 return (atom == ot.atom && display == ot.display);
808 }
809 public int hashCode() {
810 return (int)((atom ^ display)& 0xFFFFL);
811 }
812
813 /**
814 * Sets property on the <code>window</code> to the value <code>window_value</window>
815 * Property is assumed to be of type WINDOW/32
816 */
817 public void setWindowProperty(long window, long window_value) {
818 if (atom == 0) {
819 throw new IllegalStateException("Atom should be initialized");
820 }
821 checkWindow(window);
822 XToolkit.awtLock();
823 try {
824 Native.putWindow(XlibWrapper.larg1, window_value);
825 XlibWrapper.XChangeProperty(XToolkit.getDisplay(), window,
826 atom, XA_WINDOW, 32, XlibWrapper.PropModeReplace,
827 XlibWrapper.larg1, 1);
828 } finally {
829 XToolkit.awtUnlock();
830 }
831 }
832 public void setWindowProperty(XBaseWindow window, XBaseWindow window_value) {
833 setWindowProperty(window.getWindow(), window_value.getWindow());
834 }
835
836 /**
837 * Gets property on the <code>window</code>. Property is assumed to be
838 * of type WINDOW/32.
839 */
840 public long getWindowProperty(long window) {
841 if (atom == 0) {
842 throw new IllegalStateException("Atom should be initialized");
843 }
844 checkWindow(window);
845 WindowPropertyGetter getter =
846 new WindowPropertyGetter(window, this, 0, 1,
847 false, XA_WINDOW);
848 try {
849 int status = getter.execute();
850 if (status != XlibWrapper.Success || getter.getData() == 0) {
851 return 0;
852 }
853 if (getter.getActualType() != XA_WINDOW || getter.getActualFormat() != 32) {
854 return 0;
855 }
856 return Native.getWindow(getter.getData());
857 } finally {
858 getter.dispose();
859 }
860 }
861}