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