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)) xembedLog.finer("Created atom " + XEmbed.toString()); 86 } 87 if (XEmbedInfo == null) { 88 XEmbedInfo = XAtom.get("_XEMBED_INFO"); 89 if (xembedLog.isLoggable(Level.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)XlibWrapper.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(Level.FINE)) xembedLog.fine("Sending " + XEmbedMessageToString(msg)); 110 XlibWrapper.XSendEvent(XToolkit.getDisplay(), window, false, XlibWrapper.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 _SUN_XEMBED_START: 155 return "XEMBED_START"; 156 case XConstants.KeyPress | XEmbedServerTester.SYSTEM_EVENT_MASK: 157 return "KeyPress"; 158 case XConstants.MapNotify | XEmbedServerTester.SYSTEM_EVENT_MASK: 159 return "MapNotify"; 160 case XConstants.PropertyNotify | XEmbedServerTester.SYSTEM_EVENT_MASK: 161 return "PropertyNotify"; 162 default: 163 return "unknown XEMBED id " + msg_id; 164 } 165 } 166 167 static String focusIdToString(int focus_id) { 168 switch(focus_id) { 169 case XEMBED_FOCUS_CURRENT: 170 return "XEMBED_FOCUS_CURRENT"; 171 case XEMBED_FOCUS_FIRST: 172 return "XEMBED_FOCUS_FIRST"; 173 case XEMBED_FOCUS_LAST: 174 return "XEMBED_FOCUS_LAST"; 175 default: 176 return "unknown focus id " + focus_id; 177 } 178 } 179 180 static String XEmbedMessageToString(XClientMessageEvent msg) { 181 return ("XEmbed message to " + Long.toHexString(msg.get_window()) + ": " + msgidToString((int)msg.get_data(1)) + 182 ", detail: " + msg.get_data(2) + 183 ", data:[" + msg.get_data(3) + "," + msg.get_data(4) + "]"); 184 185 } 186 187 188 /** 189 * Converts XEMBED modifiers mask into AWT InputEvent mask 190 */ 191 int getModifiers(int state) { 192 int mods = 0; 193 if ((state & XEMBED_MODIFIER_SHIFT) != 0) { 194 mods |= InputEvent.SHIFT_DOWN_MASK; 195 } 196 if ((state & XEMBED_MODIFIER_CONTROL) != 0) { 197 mods |= InputEvent.CTRL_DOWN_MASK; 198 } 199 if ((state & XEMBED_MODIFIER_ALT) != 0) { 200 mods |= InputEvent.ALT_DOWN_MASK; 201 } 202 // FIXME: What is super/hyper? 203 // FIXME: Experiments show that SUPER is ALT. So what is Alt then? 204 if ((state & XEMBED_MODIFIER_SUPER) != 0) { 205 mods |= InputEvent.ALT_DOWN_MASK; 206 } 207 // if ((state & XEMBED_MODIFIER_HYPER) != 0) { 208 // mods |= InputEvent.DOWN_MASK; 209 // } 210 return mods; 211 } 212 213 // Shouldn't be called on Toolkit thread. 214 AWTKeyStroke getKeyStrokeForKeySym(long keysym, long state) { 215 XBaseWindow.checkSecurity(); 216 217 int keycode; 218 219 XToolkit.awtLock(); 220 try { 221 keycode = XWindow.getAWTKeyCodeForKeySym((int)keysym); 222 } finally { 223 XToolkit.awtUnlock(); 224 } 225 226 int modifiers = getModifiers((int)state); 227 return AWTKeyStroke.getAWTKeyStroke(keycode, modifiers); 228 } 229 }