1 /* 2 * Copyright (c) 2003, 2018, 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 /* 27 * This code is ported to XAWT from MAWT based on awt_mgrsel.c 28 * and XSettings.java code written originally by Valeriy Ushakov 29 * Author : Bino George 30 */ 31 32 33 package sun.awt.X11; 34 35 import java.util.*; 36 import java.awt.*; 37 import sun.awt.XSettings; 38 import sun.util.logging.PlatformLogger; 39 40 41 class XAWTXSettings extends XSettings implements XMSelectionListener { 42 43 private final XAtom xSettingsPropertyAtom = XAtom.get("_XSETTINGS_SETTINGS"); 44 45 private static PlatformLogger log = PlatformLogger.getLogger("sun.awt.X11.XAWTXSettings"); 46 47 /* The maximal length of the property data. */ 48 public static final long MAX_LENGTH = 1000000; 49 50 XMSelection settings; 51 52 public XAWTXSettings() { 53 initXSettings(); 54 55 } 56 57 void initXSettings() { 58 if (log.isLoggable(PlatformLogger.Level.FINE)) { 59 log.fine("Initializing XAWT XSettings"); 60 } 61 settings = new XMSelection("_XSETTINGS"); 62 settings.addSelectionListener(this); 63 initPerScreenXSettings(); 64 } 65 66 void dispose() { 67 settings.removeSelectionListener(this); 68 } 69 70 public void ownerDeath(int screen, XMSelection sel, long deadOwner) { 71 if (log.isLoggable(PlatformLogger.Level.FINE)) { 72 log.fine("Owner " + deadOwner + " died for selection " + sel + " screen "+ screen); 73 } 74 } 75 76 77 public void ownerChanged(int screen, XMSelection sel, long newOwner, long data, long timestamp) { 78 if (log.isLoggable(PlatformLogger.Level.FINE)) { 79 log.fine("New Owner "+ newOwner + " for selection = " + sel + " screen " +screen ); 80 } 81 } 82 83 public void selectionChanged(int screen, XMSelection sel, long owner , XPropertyEvent event) { 84 if (log.isLoggable(PlatformLogger.Level.FINE)) { 85 log.fine("Selection changed on sel " + sel + " screen = " + screen + " owner = " + owner + " event = " + event); 86 } 87 updateXSettings(screen,owner); 88 } 89 90 void initPerScreenXSettings() { 91 if (log.isLoggable(PlatformLogger.Level.FINE)) { 92 log.fine("Updating Per XSettings changes"); 93 } 94 95 /* 96 * As toolkit cannot yet cope with per-screen desktop properties, 97 * only report XSETTINGS changes on the default screen. This 98 * should be "good enough" for most cases. 99 */ 100 101 Map<String, Object> updatedSettings = null; 102 XToolkit.awtLock(); 103 try { 104 long display = XToolkit.getDisplay(); 105 int screen = (int) XlibWrapper.DefaultScreen(display); 106 updatedSettings = getUpdatedSettings(settings.getOwner(screen)); 107 } finally { 108 XToolkit.awtUnlock(); 109 } 110 // we must not invoke this under Awt Lock 111 ((XToolkit)Toolkit.getDefaultToolkit()).parseXSettings(0,updatedSettings); 112 } 113 114 private void updateXSettings(int screen, long owner) { 115 final Map<String, Object> updatedSettings = getUpdatedSettings(owner); 116 // this method is called under awt lock and usually on toolkit thread 117 // but parseXSettings() causes public code execution, so we need to transfer 118 // this to EDT 119 EventQueue.invokeLater( new Runnable() { 120 public void run() { 121 ((XToolkit) Toolkit.getDefaultToolkit()).parseXSettings( 0, updatedSettings); 122 } 123 }); 124 } 125 126 private Map<String, Object> getUpdatedSettings(final long owner) { 127 if (log.isLoggable(PlatformLogger.Level.FINE)) { 128 log.fine("owner =" + owner); 129 } 130 if (0 == owner) { 131 return null; 132 } 133 134 Map<String, Object> settings = null; 135 try { 136 WindowPropertyGetter getter = 137 new WindowPropertyGetter(owner, xSettingsPropertyAtom, 0, MAX_LENGTH, 138 false, xSettingsPropertyAtom.getAtom() ); 139 try { 140 int status = getter.execute(XErrorHandler.IgnoreBadWindowHandler.getInstance()); 141 142 if (status != XConstants.Success || getter.getData() == 0) { 143 if (log.isLoggable(PlatformLogger.Level.FINE)) { 144 log.fine("OH OH : getter failed status = " + status ); 145 } 146 settings = null; 147 } 148 149 long ptr = getter.getData(); 150 151 if (log.isLoggable(PlatformLogger.Level.FINE)) { 152 log.fine("noItems = " + getter.getNumberOfItems()); 153 } 154 byte[] array = Native.toBytes(ptr,getter.getNumberOfItems()); 155 if (array != null) { 156 settings = update(array); 157 } 158 } finally { 159 getter.dispose(); 160 } 161 } 162 catch (Exception e) { 163 e.printStackTrace(); 164 } 165 return settings; 166 } 167 168 169 170 }