1 /* 2 * Copyright (c) 2003, 2008, 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 sun.util.logging.PlatformLogger; 31 32 import java.awt.AWTKeyStroke; 33 import java.awt.event.InputEvent; 34 35 /** 36 * Common class for all XEmbed protocol participating classes. 37 * Contains constant definitions and helper routines. 38 */ 39 public class XEmbedHelper { 40 private static final PlatformLogger xembedLog = PlatformLogger.getLogger("sun.awt.X11.xembed"); 41 final static Unsafe unsafe = Unsafe.getUnsafe(); 42 43 final static int XEMBED_VERSION = 0, 44 XEMBED_MAPPED = (1 << 0); 45 /* XEMBED messages */ 46 final static int XEMBED_EMBEDDED_NOTIFY = 0; 47 final static int XEMBED_WINDOW_ACTIVATE = 1; 48 final static int XEMBED_WINDOW_DEACTIVATE = 2; 49 final static int XEMBED_REQUEST_FOCUS =3; 50 final static int XEMBED_FOCUS_IN = 4; 51 final static int XEMBED_FOCUS_OUT = 5; 52 final static int XEMBED_FOCUS_NEXT = 6; 53 final static int XEMBED_FOCUS_PREV = 7; 54 /* 8-9 were used for XEMBED_GRAB_KEY/XEMBED_UNGRAB_KEY */ 55 final static int XEMBED_GRAB_KEY = 8; 56 final static int XEMBED_UNGRAB_KEY = 9; 57 final static int XEMBED_MODALITY_ON = 10; 58 final static int XEMBED_MODALITY_OFF = 11; 59 final static int XEMBED_REGISTER_ACCELERATOR = 12; 60 final static int XEMBED_UNREGISTER_ACCELERATOR= 13; 61 final static int XEMBED_ACTIVATE_ACCELERATOR = 14; 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(PlatformLogger.FINER)) { 86 xembedLog.finer("Created atom " + XEmbed.toString()); 87 } 88 } 89 if (XEmbedInfo == null) { 90 XEmbedInfo = XAtom.get("_XEMBED_INFO"); 91 if (xembedLog.isLoggable(PlatformLogger.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)XConstants.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(PlatformLogger.FINE)) { 114 xembedLog.fine("Sending " + XEmbedMessageToString(msg)); 115 } 116 XlibWrapper.XSendEvent(XToolkit.getDisplay(), window, false, XConstants.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 XConstants.KeyPress | XEmbedServerTester.SYSTEM_EVENT_MASK: 161 return "KeyPress"; 162 case XConstants.MapNotify | XEmbedServerTester.SYSTEM_EVENT_MASK: 163 return "MapNotify"; 164 case XConstants.PropertyNotify | XEmbedServerTester.SYSTEM_EVENT_MASK: 165 return "PropertyNotify"; 166 default: 167 return "unknown XEMBED id " + msg_id; 168 } 169 } 170 171 static String focusIdToString(int focus_id) { 172 switch(focus_id) { 173 case XEMBED_FOCUS_CURRENT: 174 return "XEMBED_FOCUS_CURRENT"; 175 case XEMBED_FOCUS_FIRST: 176 return "XEMBED_FOCUS_FIRST"; 177 case XEMBED_FOCUS_LAST: 178 return "XEMBED_FOCUS_LAST"; 179 default: 180 return "unknown focus id " + focus_id; 181 } 182 } 183 184 static String XEmbedMessageToString(XClientMessageEvent msg) { 185 return ("XEmbed message to " + Long.toHexString(msg.get_window()) + ": " + msgidToString((int)msg.get_data(1)) + 186 ", detail: " + msg.get_data(2) + 187 ", data:[" + msg.get_data(3) + "," + msg.get_data(4) + "]"); 188 189 } 190 191 192 /** 193 * Converts XEMBED modifiers mask into AWT InputEvent mask 194 */ 195 int getModifiers(int state) { 196 int mods = 0; 197 if ((state & XEMBED_MODIFIER_SHIFT) != 0) { 198 mods |= InputEvent.SHIFT_DOWN_MASK; 199 } 200 if ((state & XEMBED_MODIFIER_CONTROL) != 0) { 201 mods |= InputEvent.CTRL_DOWN_MASK; 202 } 203 if ((state & XEMBED_MODIFIER_ALT) != 0) { 204 mods |= InputEvent.ALT_DOWN_MASK; 205 } 206 // FIXME: What is super/hyper? 207 // FIXME: Experiments show that SUPER is ALT. So what is Alt then? 208 if ((state & XEMBED_MODIFIER_SUPER) != 0) { 209 mods |= InputEvent.ALT_DOWN_MASK; 210 } 211 // if ((state & XEMBED_MODIFIER_HYPER) != 0) { 212 // mods |= InputEvent.DOWN_MASK; 213 // } 214 return mods; 215 } 216 217 // Shouldn't be called on Toolkit thread. 218 AWTKeyStroke getKeyStrokeForKeySym(long keysym, long state) { 219 XBaseWindow.checkSecurity(); 220 221 int keycode; 222 223 XToolkit.awtLock(); 224 try { 225 XKeysym.Keysym2JavaKeycode kc = XKeysym.getJavaKeycode( keysym ); 226 if(kc == null) { 227 keycode = java.awt.event.KeyEvent.VK_UNDEFINED; 228 }else{ 229 keycode = kc.getJavaKeycode(); 230 } 231 } finally { 232 XToolkit.awtUnlock(); 233 } 234 235 int modifiers = getModifiers((int)state); 236 return AWTKeyStroke.getAWTKeyStroke(keycode, modifiers); 237 } 238 }