src/solaris/classes/sun/awt/X11/XNETProtocol.java

Print this page




  26 
  27 package sun.awt.X11;
  28 
  29 import java.awt.Frame;
  30 import sun.util.logging.PlatformLogger;
  31 
  32 final class XNETProtocol extends XProtocol implements XStateProtocol, XLayerProtocol
  33 {
  34     private final static PlatformLogger log = PlatformLogger.getLogger("sun.awt.X11.XNETProtocol");
  35     private final static PlatformLogger iconLog = PlatformLogger.getLogger("sun.awt.X11.icon.XNETProtocol");
  36     private static PlatformLogger stateLog = PlatformLogger.getLogger("sun.awt.X11.states.XNETProtocol");
  37 
  38     /**
  39      * XStateProtocol
  40      */
  41     public boolean supportsState(int state) {
  42         return doStateProtocol() ; // TODO - check for Frame constants
  43     }
  44 
  45     public void setState(XWindowPeer window, int state) {
  46         if (log.isLoggable(PlatformLogger.FINE)) {
  47             log.fine("Setting state of " + window + " to " + state);
  48         }
  49         if (window.isShowing()) {
  50             requestState(window, state);
  51         } else {
  52             setInitialState(window, state);
  53         }
  54     }
  55 
  56     private void setInitialState(XWindowPeer window, int state) {
  57         XAtomList old_state = window.getNETWMState();
  58         if (log.isLoggable(PlatformLogger.FINE)) {
  59             log.fine("Current state of the window {0} is {1}", window, old_state);
  60         }
  61         if ((state & Frame.MAXIMIZED_VERT) != 0) {
  62             old_state.add(XA_NET_WM_STATE_MAXIMIZED_VERT);
  63         } else {
  64             old_state.remove(XA_NET_WM_STATE_MAXIMIZED_VERT);
  65         }
  66         if ((state & Frame.MAXIMIZED_HORIZ) != 0) {
  67             old_state.add(XA_NET_WM_STATE_MAXIMIZED_HORZ);
  68         } else {
  69             old_state.remove(XA_NET_WM_STATE_MAXIMIZED_HORZ);
  70         }
  71         if (log.isLoggable(PlatformLogger.FINE)) {
  72             log.fine("Setting initial state of the window {0} to {1}", window, old_state);
  73         }
  74         window.setNETWMState(old_state);
  75     }
  76 
  77     private void requestState(XWindowPeer window, int state) {
  78         /*
  79          * We have to use toggle for maximization because of transitions
  80          * from maximization in one direction only to maximization in the
  81          * other direction only.
  82          */
  83         int old_net_state = getState(window);
  84         int max_changed = (state ^ old_net_state) & (Frame.MAXIMIZED_BOTH);
  85 
  86         XClientMessageEvent req = new XClientMessageEvent();
  87         try {
  88             switch(max_changed) {
  89               case 0:
  90                   return;
  91               case Frame.MAXIMIZED_HORIZ:
  92                   req.set_data(1, XA_NET_WM_STATE_MAXIMIZED_HORZ.getAtom());
  93                   req.set_data(2, 0);
  94                   break;
  95               case Frame.MAXIMIZED_VERT:
  96                   req.set_data(1, XA_NET_WM_STATE_MAXIMIZED_VERT.getAtom());
  97                   req.set_data(2, 0);
  98                   break;
  99               case Frame.MAXIMIZED_BOTH:
 100                   req.set_data(1, XA_NET_WM_STATE_MAXIMIZED_HORZ.getAtom());
 101                   req.set_data(2, XA_NET_WM_STATE_MAXIMIZED_VERT.getAtom());
 102                   break;
 103               default:
 104                   return;
 105             }
 106             if (log.isLoggable(PlatformLogger.FINE)) {
 107                 log.fine("Requesting state on " + window + " for " + state);
 108             }
 109             req.set_type((int)XConstants.ClientMessage);
 110             req.set_window(window.getWindow());
 111             req.set_message_type(XA_NET_WM_STATE.getAtom());
 112             req.set_format(32);
 113             req.set_data(0, _NET_WM_STATE_TOGGLE);
 114             XToolkit.awtLock();
 115             try {
 116                 XlibWrapper.XSendEvent(XToolkit.getDisplay(),
 117                         XlibWrapper.RootWindow(XToolkit.getDisplay(), window.getScreenNumber()),
 118                         false,
 119                         XConstants.SubstructureRedirectMask | XConstants.SubstructureNotifyMask,
 120                         req.pData);
 121             }
 122             finally {
 123                 XToolkit.awtUnlock();
 124             }
 125         } finally {
 126             req.dispose();


 170     }
 171 
 172     /**
 173      * XLayerProtocol
 174      */
 175     public boolean supportsLayer(int layer) {
 176         return ((layer == LAYER_ALWAYS_ON_TOP) || (layer == LAYER_NORMAL)) && doLayerProtocol();
 177     }
 178 
 179     public void requestState(XWindow window, XAtom state, boolean isAdd) {
 180         XClientMessageEvent req = new XClientMessageEvent();
 181         try {
 182             req.set_type((int)XConstants.ClientMessage);
 183             req.set_window(window.getWindow());
 184             req.set_message_type(XA_NET_WM_STATE.getAtom());
 185             req.set_format(32);
 186             req.set_data(0, isAdd ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE);
 187             req.set_data(1, state.getAtom());
 188             // Fix for 6735584: req.data[2] must be set to 0 when only one property is changed
 189             req.set_data(2, 0);
 190             if (log.isLoggable(PlatformLogger.FINE)) {
 191                 log.fine("Setting _NET_STATE atom {0} on {1} for {2}", state, window, Boolean.valueOf(isAdd));
 192             }
 193             XToolkit.awtLock();
 194             try {
 195                 XlibWrapper.XSendEvent(XToolkit.getDisplay(),
 196                         XlibWrapper.RootWindow(XToolkit.getDisplay(), window.getScreenNumber()),
 197                         false,
 198                         XConstants.SubstructureRedirectMask | XConstants.SubstructureNotifyMask,
 199                         req.pData);
 200             }
 201             finally {
 202                 XToolkit.awtUnlock();
 203             }
 204         } finally {
 205             req.dispose();
 206         }
 207     }
 208 
 209     /**
 210      * Helper function to set/reset one state in NET_WM_STATE
 211      * If window is showing then it uses ClientMessage, otherwise adjusts NET_WM_STATE list
 212      * @param window Window which NET_WM_STATE property is being modified
 213      * @param state State atom to be set/reset
 214      * @param reset Indicates operation, 'set' if false, 'reset' if true
 215      */
 216     private void setStateHelper(XWindowPeer window, XAtom state, boolean set) {
 217         if (log.isLoggable(PlatformLogger.FINER)) {
 218             log.finer("Window visibility is: withdrawn={0}, visible={1}, mapped={2} showing={3}",
 219                   Boolean.valueOf(window.isWithdrawn()), Boolean.valueOf(window.isVisible()),
 220                   Boolean.valueOf(window.isMapped()), Boolean.valueOf(window.isShowing()));
 221         }
 222         if (window.isShowing()) {
 223             requestState(window, state, set);
 224         } else {
 225             XAtomList net_wm_state = window.getNETWMState();
 226             if (log.isLoggable(PlatformLogger.FINER)) {
 227                 log.finer("Current state on {0} is {1}", window, net_wm_state);
 228             }
 229             if (!set) {
 230                 net_wm_state.remove(state);
 231             } else {
 232                 net_wm_state.add(state);
 233             }
 234             if (log.isLoggable(PlatformLogger.FINE)) {
 235                 log.fine("Setting states on {0} to {1}", window, net_wm_state);
 236             }
 237             window.setNETWMState(net_wm_state);
 238         }
 239         XToolkit.XSync();
 240     }
 241 
 242     public void setLayer(XWindowPeer window, int layer) {
 243         setStateHelper(window, XA_NET_WM_STATE_ABOVE, layer == LAYER_ALWAYS_ON_TOP);
 244     }
 245 
 246     /* New "netwm" spec from www.freedesktop.org */
 247     XAtom XA_UTF8_STRING = XAtom.get("UTF8_STRING");   /* like STRING but encoding is UTF-8 */
 248     XAtom XA_NET_SUPPORTING_WM_CHECK = XAtom.get("_NET_SUPPORTING_WM_CHECK");
 249     XAtom XA_NET_SUPPORTED = XAtom.get("_NET_SUPPORTED");      /* list of protocols (property of root) */
 250     XAtom XA_NET_WM_NAME = XAtom.get("_NET_WM_NAME");  /* window property */
 251     XAtom XA_NET_WM_STATE = XAtom.get("_NET_WM_STATE");/* both window property and request */
 252 
 253 /*
 254  * _NET_WM_STATE is a list of atoms.


 273     public final XAtom XA_NET_WM_WINDOW_TYPE_DIALOG = XAtom.get("_NET_WM_WINDOW_TYPE_DIALOG");
 274     public final XAtom XA_NET_WM_WINDOW_TYPE_UTILITY = XAtom.get("_NET_WM_WINDOW_TYPE_UTILITY");
 275     public final XAtom XA_NET_WM_WINDOW_TYPE_POPUP_MENU = XAtom.get("_NET_WM_WINDOW_TYPE_POPUP_MENU");
 276 
 277     XAtom XA_NET_WM_WINDOW_OPACITY = XAtom.get("_NET_WM_WINDOW_OPACITY");
 278 
 279 /* For _NET_WM_STATE ClientMessage requests */
 280     final static int _NET_WM_STATE_REMOVE      =0; /* remove/unset property */
 281     final static int _NET_WM_STATE_ADD         =1; /* add/set property      */
 282     final static int _NET_WM_STATE_TOGGLE      =2; /* toggle property       */
 283 
 284     boolean supportChecked = false;
 285     long NetWindow = 0;
 286     void detect() {
 287         if (supportChecked) {
 288             // TODO: How about detecting WM-restart or exit?
 289             return;
 290         }
 291         NetWindow = checkAnchor(XA_NET_SUPPORTING_WM_CHECK, XAtom.XA_WINDOW);
 292         supportChecked = true;
 293         if (log.isLoggable(PlatformLogger.FINE)) {
 294             log.fine("### " + this + " is active: " + (NetWindow != 0));
 295         }
 296     }
 297 
 298     boolean active() {
 299         detect();
 300         return NetWindow != 0;
 301     }
 302 
 303     boolean doStateProtocol() {
 304         boolean res = active() && checkProtocol(XA_NET_SUPPORTED, XA_NET_WM_STATE);
 305         if (stateLog.isLoggable(PlatformLogger.FINER)) {
 306             stateLog.finer("doStateProtocol() returns " + res);
 307         }
 308         return res;
 309     }
 310 
 311     boolean doLayerProtocol() {
 312         boolean res = active() && checkProtocol(XA_NET_SUPPORTED, XA_NET_WM_STATE_ABOVE);
 313         return res;
 314     }
 315 
 316     boolean doModalityProtocol() {
 317         boolean res = active() && checkProtocol(XA_NET_SUPPORTED, XA_NET_WM_STATE_MODAL);
 318         return res;
 319     }
 320 
 321     boolean doOpacityProtocol() {
 322         boolean res = active() && checkProtocol(XA_NET_SUPPORTED, XA_NET_WM_WINDOW_OPACITY);
 323         return res;
 324     }
 325 
 326     boolean isWMName(String name) {
 327         if (!active()) {
 328             return false;
 329         }
 330         String net_wm_name_string = getWMName();
 331         if (net_wm_name_string == null) {
 332             return false;
 333         }
 334         if (log.isLoggable(PlatformLogger.FINE)) {
 335             log.fine("### WM_NAME = " + net_wm_name_string);
 336         }
 337         return net_wm_name_string.startsWith(name);
 338     }
 339 
 340     String net_wm_name_cache;
 341     public String getWMName() {
 342         if (!active()) {
 343             return null;
 344         }
 345 
 346         if (net_wm_name_cache != null) {
 347             return net_wm_name_cache;
 348         }
 349 
 350         /*
 351          * Check both UTF8_STRING and STRING.  We only call this function
 352          * with ASCII names and UTF8 preserves ASCII bit-wise.  wm-spec
 353          * mandates UTF8_STRING for _NET_WM_NAME but at least sawfish-1.0
 354          * still uses STRING.  (mmm, moving targets...).




  26 
  27 package sun.awt.X11;
  28 
  29 import java.awt.Frame;
  30 import sun.util.logging.PlatformLogger;
  31 
  32 final class XNETProtocol extends XProtocol implements XStateProtocol, XLayerProtocol
  33 {
  34     private final static PlatformLogger log = PlatformLogger.getLogger("sun.awt.X11.XNETProtocol");
  35     private final static PlatformLogger iconLog = PlatformLogger.getLogger("sun.awt.X11.icon.XNETProtocol");
  36     private static PlatformLogger stateLog = PlatformLogger.getLogger("sun.awt.X11.states.XNETProtocol");
  37 
  38     /**
  39      * XStateProtocol
  40      */
  41     public boolean supportsState(int state) {
  42         return doStateProtocol() ; // TODO - check for Frame constants
  43     }
  44 
  45     public void setState(XWindowPeer window, int state) {
  46         if (log.isLoggable(PlatformLogger.Level.FINE)) {
  47             log.fine("Setting state of " + window + " to " + state);
  48         }
  49         if (window.isShowing()) {
  50             requestState(window, state);
  51         } else {
  52             setInitialState(window, state);
  53         }
  54     }
  55 
  56     private void setInitialState(XWindowPeer window, int state) {
  57         XAtomList old_state = window.getNETWMState();
  58         if (log.isLoggable(PlatformLogger.Level.FINE)) {
  59             log.fine("Current state of the window {0} is {1}", window, old_state);
  60         }
  61         if ((state & Frame.MAXIMIZED_VERT) != 0) {
  62             old_state.add(XA_NET_WM_STATE_MAXIMIZED_VERT);
  63         } else {
  64             old_state.remove(XA_NET_WM_STATE_MAXIMIZED_VERT);
  65         }
  66         if ((state & Frame.MAXIMIZED_HORIZ) != 0) {
  67             old_state.add(XA_NET_WM_STATE_MAXIMIZED_HORZ);
  68         } else {
  69             old_state.remove(XA_NET_WM_STATE_MAXIMIZED_HORZ);
  70         }
  71         if (log.isLoggable(PlatformLogger.Level.FINE)) {
  72             log.fine("Setting initial state of the window {0} to {1}", window, old_state);
  73         }
  74         window.setNETWMState(old_state);
  75     }
  76 
  77     private void requestState(XWindowPeer window, int state) {
  78         /*
  79          * We have to use toggle for maximization because of transitions
  80          * from maximization in one direction only to maximization in the
  81          * other direction only.
  82          */
  83         int old_net_state = getState(window);
  84         int max_changed = (state ^ old_net_state) & (Frame.MAXIMIZED_BOTH);
  85 
  86         XClientMessageEvent req = new XClientMessageEvent();
  87         try {
  88             switch(max_changed) {
  89               case 0:
  90                   return;
  91               case Frame.MAXIMIZED_HORIZ:
  92                   req.set_data(1, XA_NET_WM_STATE_MAXIMIZED_HORZ.getAtom());
  93                   req.set_data(2, 0);
  94                   break;
  95               case Frame.MAXIMIZED_VERT:
  96                   req.set_data(1, XA_NET_WM_STATE_MAXIMIZED_VERT.getAtom());
  97                   req.set_data(2, 0);
  98                   break;
  99               case Frame.MAXIMIZED_BOTH:
 100                   req.set_data(1, XA_NET_WM_STATE_MAXIMIZED_HORZ.getAtom());
 101                   req.set_data(2, XA_NET_WM_STATE_MAXIMIZED_VERT.getAtom());
 102                   break;
 103               default:
 104                   return;
 105             }
 106             if (log.isLoggable(PlatformLogger.Level.FINE)) {
 107                 log.fine("Requesting state on " + window + " for " + state);
 108             }
 109             req.set_type((int)XConstants.ClientMessage);
 110             req.set_window(window.getWindow());
 111             req.set_message_type(XA_NET_WM_STATE.getAtom());
 112             req.set_format(32);
 113             req.set_data(0, _NET_WM_STATE_TOGGLE);
 114             XToolkit.awtLock();
 115             try {
 116                 XlibWrapper.XSendEvent(XToolkit.getDisplay(),
 117                         XlibWrapper.RootWindow(XToolkit.getDisplay(), window.getScreenNumber()),
 118                         false,
 119                         XConstants.SubstructureRedirectMask | XConstants.SubstructureNotifyMask,
 120                         req.pData);
 121             }
 122             finally {
 123                 XToolkit.awtUnlock();
 124             }
 125         } finally {
 126             req.dispose();


 170     }
 171 
 172     /**
 173      * XLayerProtocol
 174      */
 175     public boolean supportsLayer(int layer) {
 176         return ((layer == LAYER_ALWAYS_ON_TOP) || (layer == LAYER_NORMAL)) && doLayerProtocol();
 177     }
 178 
 179     public void requestState(XWindow window, XAtom state, boolean isAdd) {
 180         XClientMessageEvent req = new XClientMessageEvent();
 181         try {
 182             req.set_type((int)XConstants.ClientMessage);
 183             req.set_window(window.getWindow());
 184             req.set_message_type(XA_NET_WM_STATE.getAtom());
 185             req.set_format(32);
 186             req.set_data(0, isAdd ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE);
 187             req.set_data(1, state.getAtom());
 188             // Fix for 6735584: req.data[2] must be set to 0 when only one property is changed
 189             req.set_data(2, 0);
 190             if (log.isLoggable(PlatformLogger.Level.FINE)) {
 191                 log.fine("Setting _NET_STATE atom {0} on {1} for {2}", state, window, Boolean.valueOf(isAdd));
 192             }
 193             XToolkit.awtLock();
 194             try {
 195                 XlibWrapper.XSendEvent(XToolkit.getDisplay(),
 196                         XlibWrapper.RootWindow(XToolkit.getDisplay(), window.getScreenNumber()),
 197                         false,
 198                         XConstants.SubstructureRedirectMask | XConstants.SubstructureNotifyMask,
 199                         req.pData);
 200             }
 201             finally {
 202                 XToolkit.awtUnlock();
 203             }
 204         } finally {
 205             req.dispose();
 206         }
 207     }
 208 
 209     /**
 210      * Helper function to set/reset one state in NET_WM_STATE
 211      * If window is showing then it uses ClientMessage, otherwise adjusts NET_WM_STATE list
 212      * @param window Window which NET_WM_STATE property is being modified
 213      * @param state State atom to be set/reset
 214      * @param reset Indicates operation, 'set' if false, 'reset' if true
 215      */
 216     private void setStateHelper(XWindowPeer window, XAtom state, boolean set) {
 217         if (log.isLoggable(PlatformLogger.Level.FINER)) {
 218             log.finer("Window visibility is: withdrawn={0}, visible={1}, mapped={2} showing={3}",
 219                   Boolean.valueOf(window.isWithdrawn()), Boolean.valueOf(window.isVisible()),
 220                   Boolean.valueOf(window.isMapped()), Boolean.valueOf(window.isShowing()));
 221         }
 222         if (window.isShowing()) {
 223             requestState(window, state, set);
 224         } else {
 225             XAtomList net_wm_state = window.getNETWMState();
 226             if (log.isLoggable(PlatformLogger.Level.FINER)) {
 227                 log.finer("Current state on {0} is {1}", window, net_wm_state);
 228             }
 229             if (!set) {
 230                 net_wm_state.remove(state);
 231             } else {
 232                 net_wm_state.add(state);
 233             }
 234             if (log.isLoggable(PlatformLogger.Level.FINE)) {
 235                 log.fine("Setting states on {0} to {1}", window, net_wm_state);
 236             }
 237             window.setNETWMState(net_wm_state);
 238         }
 239         XToolkit.XSync();
 240     }
 241 
 242     public void setLayer(XWindowPeer window, int layer) {
 243         setStateHelper(window, XA_NET_WM_STATE_ABOVE, layer == LAYER_ALWAYS_ON_TOP);
 244     }
 245 
 246     /* New "netwm" spec from www.freedesktop.org */
 247     XAtom XA_UTF8_STRING = XAtom.get("UTF8_STRING");   /* like STRING but encoding is UTF-8 */
 248     XAtom XA_NET_SUPPORTING_WM_CHECK = XAtom.get("_NET_SUPPORTING_WM_CHECK");
 249     XAtom XA_NET_SUPPORTED = XAtom.get("_NET_SUPPORTED");      /* list of protocols (property of root) */
 250     XAtom XA_NET_WM_NAME = XAtom.get("_NET_WM_NAME");  /* window property */
 251     XAtom XA_NET_WM_STATE = XAtom.get("_NET_WM_STATE");/* both window property and request */
 252 
 253 /*
 254  * _NET_WM_STATE is a list of atoms.


 273     public final XAtom XA_NET_WM_WINDOW_TYPE_DIALOG = XAtom.get("_NET_WM_WINDOW_TYPE_DIALOG");
 274     public final XAtom XA_NET_WM_WINDOW_TYPE_UTILITY = XAtom.get("_NET_WM_WINDOW_TYPE_UTILITY");
 275     public final XAtom XA_NET_WM_WINDOW_TYPE_POPUP_MENU = XAtom.get("_NET_WM_WINDOW_TYPE_POPUP_MENU");
 276 
 277     XAtom XA_NET_WM_WINDOW_OPACITY = XAtom.get("_NET_WM_WINDOW_OPACITY");
 278 
 279 /* For _NET_WM_STATE ClientMessage requests */
 280     final static int _NET_WM_STATE_REMOVE      =0; /* remove/unset property */
 281     final static int _NET_WM_STATE_ADD         =1; /* add/set property      */
 282     final static int _NET_WM_STATE_TOGGLE      =2; /* toggle property       */
 283 
 284     boolean supportChecked = false;
 285     long NetWindow = 0;
 286     void detect() {
 287         if (supportChecked) {
 288             // TODO: How about detecting WM-restart or exit?
 289             return;
 290         }
 291         NetWindow = checkAnchor(XA_NET_SUPPORTING_WM_CHECK, XAtom.XA_WINDOW);
 292         supportChecked = true;
 293         if (log.isLoggable(PlatformLogger.Level.FINE)) {
 294             log.fine("### " + this + " is active: " + (NetWindow != 0));
 295         }
 296     }
 297 
 298     boolean active() {
 299         detect();
 300         return NetWindow != 0;
 301     }
 302 
 303     boolean doStateProtocol() {
 304         boolean res = active() && checkProtocol(XA_NET_SUPPORTED, XA_NET_WM_STATE);
 305         if (stateLog.isLoggable(PlatformLogger.Level.FINER)) {
 306             stateLog.finer("doStateProtocol() returns " + res);
 307         }
 308         return res;
 309     }
 310 
 311     boolean doLayerProtocol() {
 312         boolean res = active() && checkProtocol(XA_NET_SUPPORTED, XA_NET_WM_STATE_ABOVE);
 313         return res;
 314     }
 315 
 316     boolean doModalityProtocol() {
 317         boolean res = active() && checkProtocol(XA_NET_SUPPORTED, XA_NET_WM_STATE_MODAL);
 318         return res;
 319     }
 320 
 321     boolean doOpacityProtocol() {
 322         boolean res = active() && checkProtocol(XA_NET_SUPPORTED, XA_NET_WM_WINDOW_OPACITY);
 323         return res;
 324     }
 325 
 326     boolean isWMName(String name) {
 327         if (!active()) {
 328             return false;
 329         }
 330         String net_wm_name_string = getWMName();
 331         if (net_wm_name_string == null) {
 332             return false;
 333         }
 334         if (log.isLoggable(PlatformLogger.Level.FINE)) {
 335             log.fine("### WM_NAME = " + net_wm_name_string);
 336         }
 337         return net_wm_name_string.startsWith(name);
 338     }
 339 
 340     String net_wm_name_cache;
 341     public String getWMName() {
 342         if (!active()) {
 343             return null;
 344         }
 345 
 346         if (net_wm_name_cache != null) {
 347             return net_wm_name_cache;
 348         }
 349 
 350         /*
 351          * Check both UTF8_STRING and STRING.  We only call this function
 352          * with ASCII names and UTF8 preserves ASCII bit-wise.  wm-spec
 353          * mandates UTF8_STRING for _NET_WM_NAME but at least sawfish-1.0
 354          * still uses STRING.  (mmm, moving targets...).