001: /*
002: * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025:
026: package sun.awt.X11;
027:
028: import sun.misc.Unsafe;
029:
030: import java.util.logging.*;
031: import java.awt.AWTKeyStroke;
032: import java.awt.event.InputEvent;
033:
034: /**
035: * Common class for all XEmbed protocol participating classes.
036: * Contains constant definitions and helper routines.
037: */
038: public class XEmbedHelper {
039: private static final Logger xembedLog = Logger
040: .getLogger("sun.awt.X11.xembed");
041: final static Unsafe unsafe = Unsafe.getUnsafe();
042:
043: final static int XEMBED_VERSION = 0, XEMBED_MAPPED = (1 << 0);
044: /* XEMBED messages */
045: final static int XEMBED_EMBEDDED_NOTIFY = 0;
046: final static int XEMBED_WINDOW_ACTIVATE = 1;
047: final static int XEMBED_WINDOW_DEACTIVATE = 2;
048: final static int XEMBED_REQUEST_FOCUS = 3;
049: final static int XEMBED_FOCUS_IN = 4;
050: final static int XEMBED_FOCUS_OUT = 5;
051: final static int XEMBED_FOCUS_NEXT = 6;
052: final static int XEMBED_FOCUS_PREV = 7;
053: /* 8-9 were used for XEMBED_GRAB_KEY/XEMBED_UNGRAB_KEY */
054: final static int XEMBED_GRAB_KEY = 8;
055: final static int XEMBED_UNGRAB_KEY = 9;
056: final static int XEMBED_MODALITY_ON = 10;
057: final static int XEMBED_MODALITY_OFF = 11;
058: final static int XEMBED_REGISTER_ACCELERATOR = 12;
059: final static int XEMBED_UNREGISTER_ACCELERATOR = 13;
060: final static int XEMBED_ACTIVATE_ACCELERATOR = 14;
061: final static int _SUN_XEMBED_START = 1119;
062:
063: final static int NON_STANDARD_XEMBED_GTK_GRAB_KEY = 108;
064: final static int NON_STANDARD_XEMBED_GTK_UNGRAB_KEY = 109;
065:
066: // A detail code is required for XEMBED_FOCUS_IN. The following values are valid:
067: /* Details for XEMBED_FOCUS_IN: */
068: final static int XEMBED_FOCUS_CURRENT = 0;
069: final static int XEMBED_FOCUS_FIRST = 1;
070: final static int XEMBED_FOCUS_LAST = 2;
071:
072: // Modifiers bits
073: final static int XEMBED_MODIFIER_SHIFT = (1 << 0);
074: final static int XEMBED_MODIFIER_CONTROL = (1 << 1);
075: final static int XEMBED_MODIFIER_ALT = (1 << 2);
076: final static int XEMBED_MODIFIER_SUPER = (1 << 3);
077: final static int XEMBED_MODIFIER_HYPER = (1 << 4);
078:
079: static XAtom XEmbedInfo;
080: static XAtom XEmbed;
081:
082: XEmbedHelper() {
083: if (XEmbed == null) {
084: XEmbed = XAtom.get("_XEMBED");
085: if (xembedLog.isLoggable(Level.FINER))
086: xembedLog.finer("Created atom " + XEmbed.toString());
087: }
088: if (XEmbedInfo == null) {
089: XEmbedInfo = XAtom.get("_XEMBED_INFO");
090: if (xembedLog.isLoggable(Level.FINER))
091: xembedLog
092: .finer("Created atom " + XEmbedInfo.toString());
093: }
094: }
095:
096: void sendMessage(long window, int message) {
097: sendMessage(window, message, 0, 0, 0);
098: }
099:
100: void sendMessage(long window, int message, long detail, long data1,
101: long data2) {
102: XClientMessageEvent msg = new XClientMessageEvent();
103: msg.set_type((int) XlibWrapper.ClientMessage);
104: msg.set_window(window);
105: msg.set_message_type(XEmbed.getAtom());
106: msg.set_format(32);
107: msg.set_data(0, XToolkit.getCurrentServerTime());
108: msg.set_data(1, message);
109: msg.set_data(2, detail);
110: msg.set_data(3, data1);
111: msg.set_data(4, data2);
112: XToolkit.awtLock();
113: try {
114: if (xembedLog.isLoggable(Level.FINE))
115: xembedLog.fine("Sending " + XEmbedMessageToString(msg));
116: XlibWrapper.XSendEvent(XToolkit.getDisplay(), window,
117: false, XlibWrapper.NoEventMask, msg.pData);
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
165: | XEmbedServerTester.SYSTEM_EVENT_MASK:
166: return "MapNotify";
167: case XConstants.PropertyNotify
168: | XEmbedServerTester.SYSTEM_EVENT_MASK:
169: return "PropertyNotify";
170: default:
171: return "unknown XEMBED id " + msg_id;
172: }
173: }
174:
175: static String focusIdToString(int focus_id) {
176: switch (focus_id) {
177: case XEMBED_FOCUS_CURRENT:
178: return "XEMBED_FOCUS_CURRENT";
179: case XEMBED_FOCUS_FIRST:
180: return "XEMBED_FOCUS_FIRST";
181: case XEMBED_FOCUS_LAST:
182: return "XEMBED_FOCUS_LAST";
183: default:
184: return "unknown focus id " + focus_id;
185: }
186: }
187:
188: static String XEmbedMessageToString(XClientMessageEvent msg) {
189: return ("XEmbed message to "
190: + Long.toHexString(msg.get_window()) + ": "
191: + msgidToString((int) msg.get_data(1)) + ", detail: "
192: + msg.get_data(2) + ", data:[" + msg.get_data(3) + ","
193: + msg.get_data(4) + "]");
194:
195: }
196:
197: /**
198: * Converts XEMBED modifiers mask into AWT InputEvent mask
199: */
200: int getModifiers(int state) {
201: int mods = 0;
202: if ((state & XEMBED_MODIFIER_SHIFT) != 0) {
203: mods |= InputEvent.SHIFT_DOWN_MASK;
204: }
205: if ((state & XEMBED_MODIFIER_CONTROL) != 0) {
206: mods |= InputEvent.CTRL_DOWN_MASK;
207: }
208: if ((state & XEMBED_MODIFIER_ALT) != 0) {
209: mods |= InputEvent.ALT_DOWN_MASK;
210: }
211: // FIXME: What is super/hyper?
212: // FIXME: Experiments show that SUPER is ALT. So what is Alt then?
213: if ((state & XEMBED_MODIFIER_SUPER) != 0) {
214: mods |= InputEvent.ALT_DOWN_MASK;
215: }
216: // if ((state & XEMBED_MODIFIER_HYPER) != 0) {
217: // mods |= InputEvent.DOWN_MASK;
218: // }
219: return mods;
220: }
221:
222: // Shouldn't be called on Toolkit thread.
223: AWTKeyStroke getKeyStrokeForKeySym(long keysym, long state) {
224: XBaseWindow.checkSecurity();
225:
226: int keycode;
227:
228: XToolkit.awtLock();
229: try {
230: keycode = XWindow.getAWTKeyCodeForKeySym((int) keysym);
231: } finally {
232: XToolkit.awtUnlock();
233: }
234:
235: int modifiers = getModifiers((int) state);
236: return AWTKeyStroke.getAWTKeyStroke(keycode, modifiers);
237: }
238: }
|