1 /* 2 * Copyright (c) 2003, 2005, 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 import sun.misc.Unsafe; 29 30 import java.util.logging.*; 31 import java.awt.AWTKeyStroke; 32 import java.awt.event.InputEvent; 33 34 /** 35 * Common class for all XEmbed protocol participating classes. 36 * Contains constant definitions and helper routines. 37 */ 38 public class XEmbedHelper { 39 private static final Logger xembedLog = Logger.getLogger("sun.awt.X11.xembed"); 40 final static Unsafe unsafe = Unsafe.getUnsafe(); 41 42 final static int XEMBED_VERSION = 0, 43 XEMBED_MAPPED = (1 << 0); 44 /* XEMBED messages */ 45 final static int XEMBED_EMBEDDED_NOTIFY = 0; 46 final static int XEMBED_WINDOW_ACTIVATE = 1; 47 final static int XEMBED_WINDOW_DEACTIVATE = 2; 48 final static int XEMBED_REQUEST_FOCUS =3; 49 final static int XEMBED_FOCUS_IN = 4; 50 final static int XEMBED_FOCUS_OUT = 5; 51 final static int XEMBED_FOCUS_NEXT = 6; 52 final static int XEMBED_FOCUS_PREV = 7; 53 /* 8-9 were used for XEMBED_GRAB_KEY/XEMBED_UNGRAB_KEY */ 54 final static int XEMBED_GRAB_KEY = 8; 55 final static int XEMBED_UNGRAB_KEY = 9; 56 final static int XEMBED_MODALITY_ON = 10; 57 final static int XEMBED_MODALITY_OFF = 11; 58 final static int XEMBED_REGISTER_ACCELERATOR = 12; 59 final static int XEMBED_UNREGISTER_ACCELERATOR= 13; 60 final static int XEMBED_ACTIVATE_ACCELERATOR = 14; 61 final static int _SUN_XEMBED_START = 1119; 62 63 final static int NON_STANDARD_XEMBED_GTK_GRAB_KEY = 108; 64 final static int NON_STANDARD_XEMBED_GTK_UNGRAB_KEY = 109; 65 66 // A detail code is required for XEMBED_FOCUS_IN. The following values are valid: 67 /* Details for XEMBED_FOCUS_IN: */ 68 final static int XEMBED_FOCUS_CURRENT = 0; 69 final static int XEMBED_FOCUS_FIRST = 1; 70 final static int XEMBED_FOCUS_LAST = 2; 71 72 // Modifiers bits 73 final static int XEMBED_MODIFIER_SHIFT = (1 << 0); 74 final static int XEMBED_MODIFIER_CONTROL = (1 << 1); 75 final static int XEMBED_MODIFIER_ALT = (1 << 2); 76 final static int XEMBED_MODIFIER_SUPER = (1 << 3); 77 final static int XEMBED_MODIFIER_HYPER = (1 << 4); 78 79 static XAtom XEmbedInfo; 80 static XAtom XEmbed; 81 82 XEmbedHelper() { 83 if (XEmbed == null) { 84 XEmbed = XAtom.get("_XEMBED"); 85 if (xembedLog.isLoggable(Level.FINER)) { 86 xembedLog.finer("Created atom " + XEmbed.toString()); 87 } 88 } 89 if (XEmbedInfo == null) { 90 XEmbedInfo = XAtom.get("_XEMBED_INFO"); 91 if (xembedLog.isLoggable(Level.FINER)) { 92 xembedLog.finer("Created atom " + XEmbedInfo.toString()); 93 } 94 } 95 } 96 97 void sendMessage(long window, int message) { 98 sendMessage(window, message, 0, 0, 0); 99 } 100 void sendMessage(long window, int message, long detail, long data1, long data2) { 101 XClientMessageEvent msg = new XClientMessageEvent(); 102 msg.set_type((int)XlibWrapper.ClientMessage); 103 msg.set_window(window); 104 msg.set_message_type(XEmbed.getAtom()); 105 msg.set_format(32); 106 msg.set_data(0, XToolkit.getCurrentServerTime()); 107 msg.set_data(1, message); 108 msg.set_data(2, detail); 109 msg.set_data(3, data1); 110 msg.set_data(4, data2); 111 XToolkit.awtLock(); 112 try { 113 if (xembedLog.isLoggable(Level.FINE)) { 114 xembedLog.fine("Sending " + XEmbedMessageToString(msg)); 115 } 116 XlibWrapper.XSendEvent(XToolkit.getDisplay(), window, false, XlibWrapper.NoEventMask, msg.pData); 117 } 118 finally { 119 XToolkit.awtUnlock(); 120 } 121 msg.dispose(); 122 } 123 124 static String msgidToString(int msg_id) { 125 switch (msg_id) { 126 case XEMBED_EMBEDDED_NOTIFY: 127 return "XEMBED_EMBEDDED_NOTIFY"; 128 case XEMBED_WINDOW_ACTIVATE: 129 return "XEMBED_WINDOW_ACTIVATE"; 130 case XEMBED_WINDOW_DEACTIVATE: 131 return "XEMBED_WINDOW_DEACTIVATE"; 132 case XEMBED_FOCUS_IN: 133 return "XEMBED_FOCUS_IN"; 134 case XEMBED_FOCUS_OUT: 135 return "XEMBED_FOCUS_OUT"; 136 case XEMBED_REQUEST_FOCUS: 137 return "XEMBED_REQUEST_FOCUS"; 138 case XEMBED_FOCUS_NEXT: 139 return "XEMBED_FOCUS_NEXT"; 140 case XEMBED_FOCUS_PREV: 141 return "XEMBED_FOCUS_PREV"; 142 case XEMBED_MODALITY_ON: 143 return "XEMBED_MODALITY_ON"; 144 case XEMBED_MODALITY_OFF: 145 return "XEMBED_MODALITY_OFF"; 146 case XEMBED_REGISTER_ACCELERATOR: 147 return "XEMBED_REGISTER_ACCELERATOR"; 148 case XEMBED_UNREGISTER_ACCELERATOR: 149 return "XEMBED_UNREGISTER_ACCELERATOR"; 150 case XEMBED_ACTIVATE_ACCELERATOR: 151 return "XEMBED_ACTIVATE_ACCELERATOR"; 152 case XEMBED_GRAB_KEY: 153 return "XEMBED_GRAB_KEY"; 154 case XEMBED_UNGRAB_KEY: 155 return "XEMBED_UNGRAB_KEY"; 156 case NON_STANDARD_XEMBED_GTK_UNGRAB_KEY: 157 return "NON_STANDARD_XEMBED_GTK_UNGRAB_KEY"; 158 case NON_STANDARD_XEMBED_GTK_GRAB_KEY: 159 return "NON_STANDARD_XEMBED_GTK_GRAB_KEY"; 160 case _SUN_XEMBED_START: 161 return "XEMBED_START"; 162 case XConstants.KeyPress | XEmbedServerTester.SYSTEM_EVENT_MASK: 163 return "KeyPress"; 164 case XConstants.MapNotify | XEmbedServerTester.SYSTEM_EVENT_MASK: 165 return "MapNotify"; 166 case XConstants.PropertyNotify | XEmbedServerTester.SYSTEM_EVENT_MASK: 167 return "PropertyNotify"; 168 default: 169 return "unknown XEMBED id " + msg_id; 170 } 171 } 172 173 static String focusIdToString(int focus_id) { 174 switch(focus_id) { 175 case XEMBED_FOCUS_CURRENT: 176 return "XEMBED_FOCUS_CURRENT"; 177 case XEMBED_FOCUS_FIRST: 178 return "XEMBED_FOCUS_FIRST"; 179 case XEMBED_FOCUS_LAST: 180 return "XEMBED_FOCUS_LAST"; 181 default: 182 return "unknown focus id " + focus_id; 183 } 184 } 185 186 static String XEmbedMessageToString(XClientMessageEvent msg) { 187 return ("XEmbed message to " + Long.toHexString(msg.get_window()) + ": " + msgidToString((int)msg.get_data(1)) + 188 ", detail: " + msg.get_data(2) + 189 ", data:[" + msg.get_data(3) + "," + msg.get_data(4) + "]"); 190 191 } 192 193 194 /** 195 * Converts XEMBED modifiers mask into AWT InputEvent mask 196 */ 197 int getModifiers(int state) { 198 int mods = 0; 199 if ((state & XEMBED_MODIFIER_SHIFT) != 0) { 200 mods |= InputEvent.SHIFT_DOWN_MASK; 201 } 202 if ((state & XEMBED_MODIFIER_CONTROL) != 0) { 203 mods |= InputEvent.CTRL_DOWN_MASK; 204 } 205 if ((state & XEMBED_MODIFIER_ALT) != 0) { 206 mods |= InputEvent.ALT_DOWN_MASK; 207 } 208 // FIXME: What is super/hyper? 209 // FIXME: Experiments show that SUPER is ALT. So what is Alt then? 210 if ((state & XEMBED_MODIFIER_SUPER) != 0) { 211 mods |= InputEvent.ALT_DOWN_MASK; 212 } 213 // if ((state & XEMBED_MODIFIER_HYPER) != 0) { 214 // mods |= InputEvent.DOWN_MASK; 215 // } 216 return mods; 217 } 218 219 // Shouldn't be called on Toolkit thread. 220 AWTKeyStroke getKeyStrokeForKeySym(long keysym, long state) { 221 XBaseWindow.checkSecurity(); 222 223 int keycode; 224 225 XToolkit.awtLock(); 226 try { 227 XKeysym.Keysym2JavaKeycode kc = XKeysym.getJavaKeycode( keysym ); 228 if(kc == null) { 229 keycode = java.awt.event.KeyEvent.VK_UNDEFINED; 230 }else{ 231 keycode = kc.getJavaKeycode(); 232 } 233 } finally { 234 XToolkit.awtUnlock(); 235 } 236 237 int modifiers = getModifiers((int)state); 238 return AWTKeyStroke.getAWTKeyStroke(keycode, modifiers); 239 } 240 }