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)) xembedLog.finer("Created atom " + XEmbed.toString()); 86 } 87 if (XEmbedInfo == null) { 88 XEmbedInfo = XAtom.get("_XEMBED_INFO"); 89 if (xembedLog.isLoggable(PlatformLogger.FINER)) xembedLog.finer("Created atom " + XEmbedInfo.toString()); 90 } 91 } 92 93 void sendMessage(long window, int message) { 94 sendMessage(window, message, 0, 0, 0); 95 } 96 void sendMessage(long window, int message, long detail, long data1, long data2) { 97 XClientMessageEvent msg = new XClientMessageEvent(); 98 msg.set_type((int)XConstants.ClientMessage); 99 msg.set_window(window); 100 msg.set_message_type(XEmbed.getAtom()); 101 msg.set_format(32); 102 msg.set_data(0, XToolkit.getCurrentServerTime()); 103 msg.set_data(1, message); 104 msg.set_data(2, detail); 105 msg.set_data(3, data1); 106 msg.set_data(4, data2); 107 XToolkit.awtLock(); 108 try { 109 if (xembedLog.isLoggable(PlatformLogger.FINE)) xembedLog.fine("Sending " + XEmbedMessageToString(msg)); 110 XlibWrapper.XSendEvent(XToolkit.getDisplay(), window, false, XConstants.NoEventMask, msg.pData); 111 } 112 finally { 113 XToolkit.awtUnlock(); 114 } 115 msg.dispose(); 116 } 117 118 static String msgidToString(int msg_id) { 119 switch (msg_id) { 120 case XEMBED_EMBEDDED_NOTIFY: 121 return "XEMBED_EMBEDDED_NOTIFY"; 122 case XEMBED_WINDOW_ACTIVATE: 123 return "XEMBED_WINDOW_ACTIVATE"; 124 case XEMBED_WINDOW_DEACTIVATE: 125 return "XEMBED_WINDOW_DEACTIVATE"; 126 case XEMBED_FOCUS_IN: 127 return "XEMBED_FOCUS_IN"; 128 case XEMBED_FOCUS_OUT: 129 return "XEMBED_FOCUS_OUT"; 130 case XEMBED_REQUEST_FOCUS: 131 return "XEMBED_REQUEST_FOCUS"; 132 case XEMBED_FOCUS_NEXT: 133 return "XEMBED_FOCUS_NEXT"; 134 case XEMBED_FOCUS_PREV: 135 return "XEMBED_FOCUS_PREV"; 136 case XEMBED_MODALITY_ON: 137 return "XEMBED_MODALITY_ON"; 138 case XEMBED_MODALITY_OFF: 139 return "XEMBED_MODALITY_OFF"; 140 case XEMBED_REGISTER_ACCELERATOR: 141 return "XEMBED_REGISTER_ACCELERATOR"; 142 case XEMBED_UNREGISTER_ACCELERATOR: 143 return "XEMBED_UNREGISTER_ACCELERATOR"; 144 case XEMBED_ACTIVATE_ACCELERATOR: 145 return "XEMBED_ACTIVATE_ACCELERATOR"; 146 case XEMBED_GRAB_KEY: 147 return "XEMBED_GRAB_KEY"; 148 case XEMBED_UNGRAB_KEY: 149 return "XEMBED_UNGRAB_KEY"; 150 case NON_STANDARD_XEMBED_GTK_UNGRAB_KEY: 151 return "NON_STANDARD_XEMBED_GTK_UNGRAB_KEY"; 152 case NON_STANDARD_XEMBED_GTK_GRAB_KEY: 153 return "NON_STANDARD_XEMBED_GTK_GRAB_KEY"; 154 case XConstants.KeyPress | XEmbedServerTester.SYSTEM_EVENT_MASK: 155 return "KeyPress"; 156 case XConstants.MapNotify | XEmbedServerTester.SYSTEM_EVENT_MASK: 157 return "MapNotify"; 158 case XConstants.PropertyNotify | XEmbedServerTester.SYSTEM_EVENT_MASK: 159 return "PropertyNotify"; 160 default: 161 return "unknown XEMBED id " + msg_id; 162 } 163 } 164 165 static String focusIdToString(int focus_id) { 166 switch(focus_id) { 167 case XEMBED_FOCUS_CURRENT: 168 return "XEMBED_FOCUS_CURRENT"; 169 case XEMBED_FOCUS_FIRST: 170 return "XEMBED_FOCUS_FIRST"; 171 case XEMBED_FOCUS_LAST: 172 return "XEMBED_FOCUS_LAST"; 173 default: 174 return "unknown focus id " + focus_id; 175 } 176 } 177 178 static String XEmbedMessageToString(XClientMessageEvent msg) { 179 return ("XEmbed message to " + Long.toHexString(msg.get_window()) + ": " + msgidToString((int)msg.get_data(1)) + 180 ", detail: " + msg.get_data(2) + 181 ", data:[" + msg.get_data(3) + "," + msg.get_data(4) + "]"); 182 183 } 184 185 186 /** 187 * Converts XEMBED modifiers mask into AWT InputEvent mask 188 */ 189 int getModifiers(int state) { 190 int mods = 0; 191 if ((state & XEMBED_MODIFIER_SHIFT) != 0) { 192 mods |= InputEvent.SHIFT_DOWN_MASK; 193 } 194 if ((state & XEMBED_MODIFIER_CONTROL) != 0) { 195 mods |= InputEvent.CTRL_DOWN_MASK; 196 } 197 if ((state & XEMBED_MODIFIER_ALT) != 0) { 198 mods |= InputEvent.ALT_DOWN_MASK; 199 } 200 // FIXME: What is super/hyper? 201 // FIXME: Experiments show that SUPER is ALT. So what is Alt then? 202 if ((state & XEMBED_MODIFIER_SUPER) != 0) { 203 mods |= InputEvent.ALT_DOWN_MASK; 204 } 205 // if ((state & XEMBED_MODIFIER_HYPER) != 0) { 206 // mods |= InputEvent.DOWN_MASK; 207 // } 208 return mods; 209 } 210 211 // Shouldn't be called on Toolkit thread. 212 AWTKeyStroke getKeyStrokeForKeySym(long keysym, long state) { 213 XBaseWindow.checkSecurity(); 214 215 int keycode; 216 217 XToolkit.awtLock(); 218 try { 219 XKeysym.Keysym2JavaKeycode kc = XKeysym.getJavaKeycode( keysym ); 220 if(kc == null) { 221 keycode = java.awt.event.KeyEvent.VK_UNDEFINED; 222 }else{ 223 keycode = kc.getJavaKeycode(); 224 } 225 } finally { 226 XToolkit.awtUnlock(); 227 } 228 229 int modifiers = getModifiers((int)state); 230 return AWTKeyStroke.getAWTKeyStroke(keycode, modifiers); 231 } 232 }