1 /*
2  * Copyright (c) 2003, 2013, 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 
XAWTXSettings()52     public XAWTXSettings() {
53         initXSettings();
54 
55     }
56 
initXSettings()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 
dispose()66     void dispose() {
67         settings.removeSelectionListener(this);
68     }
69 
ownerDeath(int screen, XMSelection sel, long deadOwner)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 
ownerChanged(int screen, XMSelection sel, long newOwner, long data, long timestamp)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 
selectionChanged(int screen, XMSelection sel, long owner , XPropertyEvent event)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 
initPerScreenXSettings()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 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 
updateXSettings(int screen, long owner)114     private void updateXSettings(int screen, long owner) {
115         final Map 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 
getUpdatedSettings(final long owner)126     private Map 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 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 }
171