blob: 9e3c877fa11af0ca30466c05fc2c4a5c75d33a0b [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 2002-2007 Sun Microsystems, Inc. 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. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26package sun.awt.X11;
27
28import java.awt.*;
29import java.awt.event.*;
30import java.awt.peer.ComponentPeer;
31import java.awt.image.ColorModel;
32
33import java.lang.ref.WeakReference;
34
35import java.lang.reflect.Field;
36import java.lang.reflect.Method;
37
38import java.util.logging.Level;
39import java.util.logging.Logger;
40
41import sun.awt.*;
42
43import sun.awt.image.PixelConverter;
44
45import sun.java2d.SunGraphics2D;
46import sun.java2d.SurfaceData;
47
48public class XWindow extends XBaseWindow implements X11ComponentPeer {
49 private static Logger log = Logger.getLogger("sun.awt.X11.XWindow");
50 private static Logger insLog = Logger.getLogger("sun.awt.X11.insets.XWindow");
51 private static Logger eventLog = Logger.getLogger("sun.awt.X11.event.XWindow");
52 private static final Logger focusLog = Logger.getLogger("sun.awt.X11.focus.XWindow");
53 private static Logger keyEventLog = Logger.getLogger("sun.awt.X11.kye.XWindow");
54 /* If a motion comes in while a multi-click is pending,
55 * allow a smudge factor so that moving the mouse by a small
56 * amount does not wipe out the multi-click state variables.
57 */
58 private final static int AWT_MULTICLICK_SMUDGE = 4;
59 // ButtonXXX events stuff
60 static int rbutton = 0;
61 static int lastX = 0, lastY = 0;
62 static long lastTime = 0;
63 static long lastButton = 0;
64 static WeakReference lastWindowRef = null;
65 static int clickCount = 0;
66
67 // used to check if we need to re-create surfaceData.
68 int oldWidth = -1;
69 int oldHeight = -1;
70
71
72 protected X11GraphicsConfig graphicsConfig;
73 protected AwtGraphicsConfigData graphicsConfigData;
74
75 private boolean reparented;
76
77 XWindow parent;
78
79 Component target;
80
81 private static int JAWT_LOCK_ERROR=0x00000001;
82 private static int JAWT_LOCK_CLIP_CHANGED=0x00000002;
83 private static int JAWT_LOCK_BOUNDS_CHANGED=0x00000004;
84 private static int JAWT_LOCK_SURFACE_CHANGED=0x00000008;
85 private int drawState = JAWT_LOCK_CLIP_CHANGED |
86 JAWT_LOCK_BOUNDS_CHANGED |
87 JAWT_LOCK_SURFACE_CHANGED;
88
89 public static final String TARGET = "target",
90 REPARENTED = "reparented"; // whether it is reparented by default
91
92 SurfaceData surfaceData;
93
94 XRepaintArea paintArea;
95 // fallback default font object
96 final static Font defaultFont = new Font(Font.DIALOG, Font.PLAIN, 12);
97
98 /*
99 * Keeps all buttons which were pressed at the time of the last mouse
100 * drag until all buttons will be released, contains state as bit masks
101 * Button1Mask, Button2Mask, Button3Mask
102 */
103 private int mouseDragState = 0;
104
105 native int getNativeColor(Color clr, GraphicsConfiguration gc);
106 native void getWMInsets(long window, long left, long top, long right, long bottom, long border);
107 native long getTopWindow(long window, long rootWin);
108 native void getWindowBounds(long window, long x, long y, long width, long height);
109 private native static void initIDs();
110
111 private static Field isPostedField;
112 static {
113 initIDs();
114 }
115
116 XWindow(XCreateWindowParams params) {
117 super(params);
118 }
119
120 XWindow() {
121 }
122
123 XWindow(long parentWindow, Rectangle bounds) {
124 super(new XCreateWindowParams(new Object[] {
125 BOUNDS, bounds,
126 PARENT_WINDOW, Long.valueOf(parentWindow)}));
127 }
128
129 XWindow(Component target, long parentWindow, Rectangle bounds) {
130 super(new XCreateWindowParams(new Object[] {
131 BOUNDS, bounds,
132 PARENT_WINDOW, Long.valueOf(parentWindow),
133 TARGET, target}));
134 }
135
136 XWindow(Component target, long parentWindow) {
137 this(target, parentWindow, target.getBounds());
138 }
139
140 XWindow(Component target) {
141 this(target, (target.getParent() == null) ? 0 : getParentWindowID(target), target.getBounds());
142 }
143
144 XWindow(Object target) {
145 this(null, 0, null);
146 }
147
148 /* This create is used by the XEmbeddedFramePeer since it has to create the window
149 as a child of the netscape window. This netscape window is passed in as wid */
150 XWindow(long parentWindow) {
151 super(new XCreateWindowParams(new Object[] {
152 PARENT_WINDOW, Long.valueOf(parentWindow),
153 REPARENTED, Boolean.TRUE,
154 EMBEDDED, Boolean.TRUE}));
155 }
156
157 protected void initGraphicsConfiguration() {
158 graphicsConfig = (X11GraphicsConfig) target.getGraphicsConfiguration();
159 graphicsConfigData = new AwtGraphicsConfigData(graphicsConfig.getAData());
160 }
161
162 void preInit(XCreateWindowParams params) {
163 super.preInit(params);
164 reparented = Boolean.TRUE.equals(params.get(REPARENTED));
165
166 target = (Component)params.get(TARGET);
167
168 initGraphicsConfiguration();
169
170 AwtGraphicsConfigData gData = getGraphicsConfigurationData();
171 X11GraphicsConfig config = (X11GraphicsConfig) getGraphicsConfiguration();
172 XVisualInfo visInfo = gData.get_awt_visInfo();
173 params.putIfNull(EVENT_MASK, KeyPressMask | KeyReleaseMask
174 | FocusChangeMask | ButtonPressMask | ButtonReleaseMask
175 | EnterWindowMask | LeaveWindowMask | PointerMotionMask
176 | ButtonMotionMask | ExposureMask | StructureNotifyMask);
177
178 if (target != null) {
179 params.putIfNull(BOUNDS, target.getBounds());
180 } else {
181 params.putIfNull(BOUNDS, new Rectangle(0, 0, MIN_SIZE, MIN_SIZE));
182 }
183 params.putIfNull(BORDER_PIXEL, Long.valueOf(0));
184 getColorModel(); // fix 4948833: this call forces the color map to be initialized
185 params.putIfNull(COLORMAP, gData.get_awt_cmap());
186 params.putIfNull(DEPTH, gData.get_awt_depth());
187 params.putIfNull(VISUAL_CLASS, Integer.valueOf((int)XlibWrapper.InputOutput));
188 params.putIfNull(VISUAL, visInfo.get_visual());
189 params.putIfNull(VALUE_MASK, XlibWrapper.CWBorderPixel | XlibWrapper.CWEventMask | XlibWrapper.CWColormap);
190 Long parentWindow = (Long)params.get(PARENT_WINDOW);
191 if (parentWindow == null || parentWindow.longValue() == 0) {
192 XToolkit.awtLock();
193 try {
194 int screen = visInfo.get_screen();
195 if (screen != -1) {
196 params.add(PARENT_WINDOW, XlibWrapper.RootWindow(XToolkit.getDisplay(), screen));
197 } else {
198 params.add(PARENT_WINDOW, XToolkit.getDefaultRootWindow());
199 }
200 } finally {
201 XToolkit.awtUnlock();
202 }
203 }
204
205 paintArea = new XRepaintArea();
206 if (target != null) {
207 this.parent = getParentXWindowObject(target.getParent());
208 }
209
210 params.putIfNull(BACKING_STORE, XToolkit.getBackingStoreType());
211 }
212
213 void postInit(XCreateWindowParams params) {
214 super.postInit(params);
215
216 setWMClass(getWMClass());
217
218 surfaceData = graphicsConfig.createSurfaceData(this);
219 Color c;
220 if (target != null && (c = target.getBackground()) != null) {
221 // We need a version of setBackground that does not call repaint !!
222 // and one that does not get overridden. The problem is that in postInit
223 // we call setBackground and we dont have all the stuff initialized to
224 // do a full paint for most peers. So we cannot call setBackground in postInit.
225 // instead we need to call xSetBackground.
226 xSetBackground(c);
227 }
228 }
229
230 public GraphicsConfiguration getGraphicsConfiguration() {
231 if (graphicsConfig == null) {
232 initGraphicsConfiguration();
233 }
234 return graphicsConfig;
235 }
236
237 public AwtGraphicsConfigData getGraphicsConfigurationData() {
238 if (graphicsConfigData == null) {
239 initGraphicsConfiguration();
240 }
241 return graphicsConfigData;
242 }
243
244 protected String[] getWMClass() {
245 return new String[] {XToolkit.getCorrectXIDString(getClass().getName()), XToolkit.getAWTAppClassName()};
246 }
247
248 void setReparented(boolean newValue) {
249 reparented = newValue;
250 }
251
252 boolean isReparented() {
253 return reparented;
254 }
255
256 static long getParentWindowID(Component target) {
257
258 ComponentPeer peer = target.getParent().getPeer();
259 Component temp = target.getParent();
260 while (!(peer instanceof XWindow))
261 {
262 temp = temp.getParent();
263 peer = temp.getPeer();
264 }
265
266 if (peer != null && peer instanceof XWindow)
267 return ((XWindow)peer).getContentWindow();
268 else return 0;
269 }
270
271
272 static XWindow getParentXWindowObject(Component target) {
273 if (target == null) return null;
274 Component temp = target.getParent();
275 if (temp == null) return null;
276 ComponentPeer peer = temp.getPeer();
277 if (peer == null) return null;
278 while ((peer != null) && !(peer instanceof XWindow))
279 {
280 temp = temp.getParent();
281 peer = temp.getPeer();
282 }
283 if (peer != null && peer instanceof XWindow)
284 return (XWindow) peer;
285 else return null;
286 }
287
288
289 boolean isParentOf(XWindow win) {
290 if (!(target instanceof Container) || win == null || win.getTarget() == null) {
291 return false;
292 }
293 Container parent = ComponentAccessor.getParent_NoClientCode(win.target);
294 while (parent != null && parent != target) {
295 parent = ComponentAccessor.getParent_NoClientCode(parent);
296 }
297 return (parent == target);
298 }
299
300 public Object getTarget() {
301 return target;
302 }
303 public Component getEventSource() {
304 return target;
305 }
306
307 public ColorModel getColorModel(int transparency) {
308 return graphicsConfig.getColorModel (transparency);
309 }
310
311 public ColorModel getColorModel() {
312 if (graphicsConfig != null) {
313 return graphicsConfig.getColorModel ();
314 }
315 else {
316 return XToolkit.getStaticColorModel();
317 }
318 }
319
320 Graphics getGraphics(SurfaceData surfData, Color afore, Color aback, Font afont) {
321 if (surfData == null) return null;
322
323 Component target = (Component) this.target;
324
325 /* Fix for bug 4746122. Color and Font shouldn't be null */
326 Color bgColor = aback;
327 if (bgColor == null) {
328 bgColor = SystemColor.window;
329 }
330 Color fgColor = afore;
331 if (fgColor == null) {
332 fgColor = SystemColor.windowText;
333 }
334 Font font = afont;
335 if (font == null) {
336 font = defaultFont;
337 }
338 return new SunGraphics2D(surfData, fgColor, bgColor, font);
339 }
340
341 public Graphics getGraphics() {
342 return getGraphics(surfaceData,
343 target.getForeground(),
344 target.getBackground(),
345 target.getFont());
346 }
347
348 public FontMetrics getFontMetrics(Font font) {
349 return Toolkit.getDefaultToolkit().getFontMetrics(font);
350 }
351
352 public Rectangle getTargetBounds() {
353 return target.getBounds();
354 }
355
356 /**
357 * Returns true if the event has been handled and should not be
358 * posted to Java.
359 */
360 boolean prePostEvent(AWTEvent e) {
361 return false;
362 }
363
364 static Method m_sendMessage;
365 static void sendEvent(final AWTEvent e) {
366 if (isPostedField == null) {
367 isPostedField = SunToolkit.getField(AWTEvent.class, "isPosted");
368 }
369 PeerEvent pe = new PeerEvent(Toolkit.getDefaultToolkit(), new Runnable() {
370 public void run() {
371 try {
372 isPostedField.setBoolean(e, true);
373 } catch (IllegalArgumentException e) {
374 assert(false);
375 } catch (IllegalAccessException e) {
376 assert(false);
377 }
378 ((Component)e.getSource()).dispatchEvent(e);
379 }
380 }, PeerEvent.ULTIMATE_PRIORITY_EVENT);
381 if (focusLog.isLoggable(Level.FINER) && (e instanceof FocusEvent)) focusLog.finer("Sending " + e);
382 XToolkit.postEvent(XToolkit.targetToAppContext(e.getSource()), pe);
383 }
384
385
386/*
387 * Post an event to the event queue.
388 */
389// NOTE: This method may be called by privileged threads.
390// DO NOT INVOKE CLIENT CODE ON THIS THREAD!
391 void postEvent(AWTEvent event) {
392 XToolkit.postEvent(XToolkit.targetToAppContext(event.getSource()), event);
393 }
394
395 static void postEventStatic(AWTEvent event) {
396 XToolkit.postEvent(XToolkit.targetToAppContext(event.getSource()), event);
397 }
398
399 public void postEventToEventQueue(final AWTEvent event) {
400 //fix for 6239938 : Choice drop-down does not disappear when it loses focus, on XToolkit
401 if (!prePostEvent(event)) {
402 //event hasn't been handled and must be posted to EventQueue
403 postEvent(event);
404 }
405 }
406
407 // overriden in XCanvasPeer
408 protected boolean doEraseBackground() {
409 return true;
410 }
411
412 // We need a version of setBackground that does not call repaint !!
413 // and one that does not get overridden. The problem is that in postInit
414 // we call setBackground and we dont have all the stuff initialized to
415 // do a full paint for most peers. So we cannot call setBackground in postInit.
416 final public void xSetBackground(Color c) {
417 XToolkit.awtLock();
418 try {
419 winBackground(c);
420 // fix for 6558510: handle sun.awt.noerasebackground flag,
421 // see doEraseBackground() and preInit() methods in XCanvasPeer
422 if (!doEraseBackground()) {
423 return;
424 }
425 // 6304250: XAWT: Items in choice show a blue border on OpenGL + Solaris10 when background color is set
426 // Note: When OGL is enabled, surfaceData.pixelFor() will not
427 // return a pixel value appropriate for passing to
428 // XSetWindowBackground(). Therefore, we will use the ColorModel
429 // for this component in order to calculate a pixel value from
430 // the given RGB value.
431 ColorModel cm = getColorModel();
432 int pixel = PixelConverter.instance.rgbToPixel(c.getRGB(), cm);
433 XlibWrapper.XSetWindowBackground(XToolkit.getDisplay(), getContentWindow(), pixel);
434 }
435 finally {
436 XToolkit.awtUnlock();
437 }
438 }
439
440 public void setBackground(Color c) {
441 xSetBackground(c);
442 }
443
444 Color backgroundColor;
445 void winBackground(Color c) {
446 backgroundColor = c;
447 }
448
449 public Color getWinBackground() {
450 Color c = null;
451
452 if (backgroundColor != null) {
453 c = backgroundColor;
454 } else if (parent != null) {
455 c = parent.getWinBackground();
456 }
457
458 if (c instanceof SystemColor) {
459 c = new Color(c.getRGB());
460 }
461
462 return c;
463 }
464
465 public boolean isEmbedded() {
466 return embedded;
467 }
468
469 public void repaint(int x,int y, int width, int height) {
470 if (!isVisible()) {
471 return;
472 }
473 Graphics g = getGraphics();
474 if (g != null) {
475 try {
476 g.setClip(x,y,width,height);
477 paint(g);
478 } finally {
479 g.dispose();
480 }
481 }
482 }
483
484 public void repaint() {
485 if (!isVisible()) {
486 return;
487 }
488 Graphics g = getGraphics();
489 if (g != null) {
490 try {
491 paint(g);
492 } finally {
493 g.dispose();
494 }
495 }
496 }
497
498 void paint(Graphics g) {
499 }
500
501 //used by Peers to avoid flickering withing paint()
502 protected void flush(){
503 XToolkit.awtLock();
504 try {
505 XlibWrapper.XFlush(XToolkit.getDisplay());
506 } finally {
507 XToolkit.awtUnlock();
508 }
509 }
510
511 public void popup(int x, int y, int width, int height) {
512 // TBD: grab the pointer
513 xSetBounds(x, y, width, height);
514 }
515
516 public void handleExposeEvent(XEvent xev) {
517 super.handleExposeEvent(xev);
518 XExposeEvent xe = xev.get_xexpose();
519 if (isEventDisabled(xev)) {
520 return;
521 }
522 int x = xe.get_x();
523 int y = xe.get_y();
524 int w = xe.get_width();
525 int h = xe.get_height();
526
527 Component target = (Component)getEventSource();
528
529 if (!ComponentAccessor.getIgnoreRepaint(target)
530 && ComponentAccessor.getWidth(target) != 0
531 && ComponentAccessor.getHeight(target) != 0)
532 {
533 handleExposeEvent(target, x, y, w, h);
534 }
535 }
536
537 public void handleExposeEvent(Component target, int x, int y, int w, int h) {
538 PaintEvent event = PaintEventDispatcher.getPaintEventDispatcher().
539 createPaintEvent(target, x, y, w, h);
540 if (event != null) {
541 postEventToEventQueue(event);
542 }
543 }
544
545 static int getModifiers(int state, int button, int keyCode) {
546 int modifiers = 0;
547
548 if (((state & XlibWrapper.ShiftMask) != 0) ^ (keyCode == KeyEvent.VK_SHIFT)) {
549 modifiers |= InputEvent.SHIFT_DOWN_MASK;
550 }
551 if (((state & XlibWrapper.ControlMask) != 0) ^ (keyCode == KeyEvent.VK_CONTROL)) {
552 modifiers |= InputEvent.CTRL_DOWN_MASK;
553 }
554 if (((state & XToolkit.metaMask) != 0) ^ (keyCode == KeyEvent.VK_META)) {
555 modifiers |= InputEvent.META_DOWN_MASK;
556 }
557 if (((state & XToolkit.altMask) != 0) ^ (keyCode == KeyEvent.VK_ALT)) {
558 modifiers |= InputEvent.ALT_DOWN_MASK;
559 }
560 if (((state & XToolkit.modeSwitchMask) != 0) ^ (keyCode == KeyEvent.VK_ALT_GRAPH)) {
561 modifiers |= InputEvent.ALT_GRAPH_DOWN_MASK;
562 }
563 if (((state & XlibWrapper.Button1Mask) != 0) ^ (button == MouseEvent.BUTTON1)) {
564 modifiers |= InputEvent.BUTTON1_DOWN_MASK;
565 }
566 if (((state & XlibWrapper.Button2Mask) != 0) ^ (button == MouseEvent.BUTTON2)) {
567 modifiers |= InputEvent.BUTTON2_DOWN_MASK;
568 }
569 if (((state & XlibWrapper.Button3Mask) != 0) ^ (button == MouseEvent.BUTTON3)) {
570 modifiers |= InputEvent.BUTTON3_DOWN_MASK;
571 }
572 return modifiers;
573 }
574
575 static int getXModifiers(AWTKeyStroke stroke) {
576 int mods = stroke.getModifiers();
577 int res = 0;
578 if ((mods & (InputEvent.SHIFT_DOWN_MASK | InputEvent.SHIFT_MASK)) != 0) {
579 res |= XToolkit.ShiftMask;
580 }
581 if ((mods & (InputEvent.CTRL_DOWN_MASK | InputEvent.CTRL_MASK)) != 0) {
582 res |= XToolkit.ControlMask;
583 }
584 if ((mods & (InputEvent.ALT_DOWN_MASK | InputEvent.ALT_MASK)) != 0) {
585 res |= XToolkit.altMask;
586 }
587 if ((mods & (InputEvent.META_DOWN_MASK | InputEvent.META_MASK)) != 0) {
588 res |= XToolkit.metaMask;
589 }
590 if ((mods & (InputEvent.ALT_GRAPH_DOWN_MASK | InputEvent.ALT_GRAPH_MASK)) != 0) {
591 res |= XToolkit.modeSwitchMask;
592 }
593 return res;
594 }
595
596 private static int getButtonMask(long mouseButton) {
597 if (mouseButton == XlibWrapper.Button1) {
598 return XlibWrapper.Button1Mask;
599 } else if (mouseButton == XlibWrapper.Button2) {
600 return XlibWrapper.Button2Mask;
601 } else if (mouseButton == XlibWrapper.Button3) {
602 return XlibWrapper.Button3Mask;
603 }
604 return 0;
605 }
606
607 /**
608 * Returns true if this event is disabled and shouldn't be passed to Java.
609 * Default implementation returns false for all events.
610 */
611 static int getRightButtonNumber() {
612 if (rbutton == 0) { // not initialized yet
613 XToolkit.awtLock();
614 try {
615 rbutton = XlibWrapper.XGetPointerMapping(XToolkit.getDisplay(), XlibWrapper.ibuffer, 3);
616 }
617 finally {
618 XToolkit.awtUnlock();
619 }
620 }
621 return rbutton;
622 }
623
624 static int getMouseMovementSmudge() {
625 //TODO: It's possible to read corresponding settings
626 return AWT_MULTICLICK_SMUDGE;
627 }
628
629 public void handleButtonPressRelease(XEvent xev) {
630 super.handleButtonPressRelease(xev);
631 XButtonEvent xbe = xev.get_xbutton();
632 if (isEventDisabled(xev)) {
633 return;
634 }
635 if (eventLog.isLoggable(Level.FINE)) eventLog.fine(xbe.toString());
636 long when;
637 int modifiers;
638 boolean popupTrigger = false;
639 int button=0;
640 boolean wheel_mouse = false;
641 long lbutton = xbe.get_button();
642 int type = xev.get_type();
643 when = xbe.get_time();
644 long jWhen = XToolkit.nowMillisUTC_offset(when);
645
646 int x = xbe.get_x();
647 int y = xbe.get_y();
648 if (xev.get_xany().get_window() != window) {
649 Point localXY = toLocal(xbe.get_x_root(), xbe.get_y_root());
650 x = localXY.x;
651 y = localXY.y;
652 }
653
654 if (type == XlibWrapper.ButtonPress) {
655 XWindow lastWindow = (lastWindowRef != null) ? ((XWindow)lastWindowRef.get()):(null);
656 /*
657 multiclick checking
658 */
659 if (eventLog.isLoggable(Level.FINEST)) eventLog.finest("lastWindow = " + lastWindow + ", lastButton "
660 + lastButton + ", lastTime " + lastTime + ", multiClickTime "
661 + XToolkit.getMultiClickTime());
662 if (lastWindow == this && lastButton == lbutton && (when - lastTime) < XToolkit.getMultiClickTime()) {
663 clickCount++;
664 } else {
665 clickCount = 1;
666 lastWindowRef = new WeakReference(this);
667 lastButton = lbutton;
668 lastX = x;
669 lastY = y;
670 }
671 lastTime = when;
672
673
674 /*
675 Check for popup trigger !!
676 */
677 if (lbutton == getRightButtonNumber() || lbutton > 2) {
678 popupTrigger = true;
679 } else {
680 popupTrigger = false;
681 }
682 }
683
684 if (lbutton == XlibWrapper.Button1)
685 button = MouseEvent.BUTTON1;
686 else if (lbutton == XlibWrapper.Button2 )
687 button = MouseEvent.BUTTON2;
688 else if (lbutton == XlibWrapper.Button3)
689 button = MouseEvent.BUTTON3;
690 else if (lbutton == XlibWrapper.Button4) {
691 button = 4;
692 wheel_mouse = true;
693 } else if (lbutton == XlibWrapper.Button5) {
694 button = 5;
695 wheel_mouse = true;
696 }
697
698 modifiers = getModifiers(xbe.get_state(),button,0);
699
700 if (!wheel_mouse) {
701 MouseEvent me = new MouseEvent((Component)getEventSource(),
702 type == XlibWrapper.ButtonPress ? MouseEvent.MOUSE_PRESSED : MouseEvent.MOUSE_RELEASED,
703 jWhen,modifiers, x, y,
704 xbe.get_x_root(),
705 xbe.get_y_root(),
706 clickCount,popupTrigger,button);
707
708 postEventToEventQueue(me);
709
710 if (((mouseDragState & getButtonMask(lbutton)) == 0) && // No up-button in the drag-state
711 (type == XlibWrapper.ButtonRelease))
712 {
713 postEventToEventQueue(me = new MouseEvent((Component)getEventSource(),
714 MouseEvent.MOUSE_CLICKED,
715 jWhen,
716 modifiers,
717 x, y,
718 xbe.get_x_root(),
719 xbe.get_y_root(),
720 clickCount,
721 false, button));
722 }
723
724 }
725 else {
726 if (xev.get_type() == XlibWrapper.ButtonPress) {
727 MouseWheelEvent mwe = new MouseWheelEvent((Component)getEventSource(),MouseEvent.MOUSE_WHEEL, jWhen,
728 modifiers,
729 x, y,
730 xbe.get_x_root(),
731 xbe.get_y_root(),
732 clickCount,false,MouseWheelEvent.WHEEL_UNIT_SCROLL,
733 3,button==4 ? -1 : 1);
734 postEventToEventQueue(mwe);
735 }
736 }
737
738 mouseDragState &= ~getButtonMask(lbutton); // Exclude the up-button from the drag-state
739 }
740
741 public void handleMotionNotify(XEvent xev) {
742 super.handleMotionNotify(xev);
743 XMotionEvent xme = xev.get_xmotion();
744 if (isEventDisabled(xev)) {
745 return;
746 }
747
748 int mouseKeyState = (xme.get_state() & (Button1Mask | Button2Mask | Button3Mask));
749 boolean isDragging = (mouseKeyState != 0);
750 int mouseEventType = 0;
751
752 if (isDragging) {
753 mouseEventType = MouseEvent.MOUSE_DRAGGED;
754 } else {
755 mouseEventType = MouseEvent.MOUSE_MOVED;
756 }
757
758 /*
759 Fix for 6176814 . Add multiclick checking.
760 */
761 int x = xme.get_x();
762 int y = xme.get_y();
763 XWindow lastWindow = (lastWindowRef != null) ? ((XWindow)lastWindowRef.get()):(null);
764
765 if (!(lastWindow == this &&
766 (xme.get_time() - lastTime) < XToolkit.getMultiClickTime() &&
767 (Math.abs(lastX - x) < AWT_MULTICLICK_SMUDGE &&
768 Math.abs(lastY - y) < AWT_MULTICLICK_SMUDGE))) {
769 clickCount = 0;
770 lastWindowRef = null;
771 mouseDragState = mouseKeyState;
772 lastTime = 0;
773 lastX = 0;
774 lastY = 0;
775 }
776
777 long jWhen = XToolkit.nowMillisUTC_offset(xme.get_time());
778 int modifiers = getModifiers(xme.get_state(), 0, 0);
779 boolean popupTrigger = false;
780
781 Component source = (Component)getEventSource();
782
783 if (xme.get_window() != window) {
784 Point localXY = toLocal(xme.get_x_root(), xme.get_y_root());
785 x = localXY.x;
786 y = localXY.y;
787 }
788 /* Fix for 5039416.
789 * According to canvas.c we shouldn't post any MouseEvent if mouse is dragging and clickCount!=0.
790 */
791 if ((isDragging && clickCount == 0) || !isDragging) {
792 MouseEvent mme = new MouseEvent(source, mouseEventType, jWhen,
793 modifiers, x, y, xme.get_x_root(), xme.get_y_root(),
794 clickCount, popupTrigger, MouseEvent.NOBUTTON);
795 postEventToEventQueue(mme);
796 }
797 }
798
799
800 // REMIND: need to implement looking for disabled events
801 public native boolean x11inputMethodLookupString(long event, long [] keysymArray);
802 native boolean haveCurrentX11InputMethodInstance();
803
804 public void handleXCrossingEvent(XEvent xev) {
805 super.handleXCrossingEvent(xev);
806 XCrossingEvent xce = xev.get_xcrossing();
807
808 if (eventLog.isLoggable(Level.FINEST)) eventLog.finest(xce.toString());
809
810 // Skip event If it was caused by a grab
811 // This is needed because on displays with focus-follows-mouse on MousePress X system generates
812 // two XCrossing events with mode != NormalNotify. First of them notifies that the mouse has left
813 // current component. Second one notifies that it has entered into the same component.
814 // This looks like the window under the mouse has actually changed and Java handle these events
815 // accordingly. This leads to impossibility to make a double click on Component (6404708)
816 XWindowPeer toplevel = getToplevelXWindow();
817 if (toplevel != null && !toplevel.isModalBlocked()){
818 if (xce.get_mode() != NotifyNormal) {
819 // 6404708 : need update cursor in accordance with skipping Leave/EnterNotify event
820 // whereas it doesn't need to handled further.
821 if (xce.get_type() == EnterNotify) {
822 XAwtState.setComponentMouseEntered(getEventSource());
823 XGlobalCursorManager.nativeUpdateCursor(getEventSource());
824 } else { // LeaveNotify:
825 XAwtState.setComponentMouseEntered(null);
826 }
827 return;
828 }
829 }
830 // X sends XCrossing to all hierarchy so if the edge of child equals to
831 // ancestor and mouse enters child, the ancestor will get an event too.
832 // From java point the event is bogus as ancestor is obscured, so if
833 // the child can get java event itself, we skip it on ancestor.
834 long childWnd = xce.get_subwindow();
835 if (childWnd != None) {
836 XBaseWindow child = XToolkit.windowToXWindow(childWnd);
837 if (child != null && child instanceof XWindow &&
838 !child.isEventDisabled(xev))
839 {
840 return;
841 }
842 }
843
844 // Remember old component with mouse to have the opportunity to send it MOUSE_EXITED.
845 final Component compWithMouse = XAwtState.getComponentMouseEntered();
846 if (toplevel != null) {
847 if(!toplevel.isModalBlocked()){
848 if (xce.get_type() == EnterNotify) {
849 // Change XAwtState's component mouse entered to the up-to-date one before requesting
850 // to update the cursor since XAwtState.getComponentMouseEntered() is used when the
851 // cursor is updated (in XGlobalCursorManager.findHeavyweightUnderCursor()).
852 XAwtState.setComponentMouseEntered(getEventSource());
853 XGlobalCursorManager.nativeUpdateCursor(getEventSource());
854 } else { // LeaveNotify:
855 XAwtState.setComponentMouseEntered(null);
856 }
857 } else {
858 ((XComponentPeer) ComponentAccessor.getPeer(target))
859 .pSetCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
860 }
861 }
862
863 if (isEventDisabled(xev)) {
864 return;
865 }
866
867 long jWhen = XToolkit.nowMillisUTC_offset(xce.get_time());
868 int modifiers = getModifiers(xce.get_state(),0,0);
869 int clickCount = 0;
870 boolean popupTrigger = false;
871 int x = xce.get_x();
872 int y = xce.get_y();
873 if (xce.get_window() != window) {
874 Point localXY = toLocal(xce.get_x_root(), xce.get_y_root());
875 x = localXY.x;
876 y = localXY.y;
877 }
878
879 // This code tracks boundary crossing and ensures MOUSE_ENTER/EXIT
880 // are posted in alternate pairs
881 if (compWithMouse != null) {
882 MouseEvent me = new MouseEvent(compWithMouse,
883 MouseEvent.MOUSE_EXITED, jWhen, modifiers, xce.get_x(),
884 xce.get_y(), xce.get_x_root(), xce.get_y_root(), clickCount, popupTrigger,
885 MouseEvent.NOBUTTON);
886 postEventToEventQueue(me);
887 eventLog.finest("Clearing last window ref");
888 lastWindowRef = null;
889 }
890 if (xce.get_type() == EnterNotify) {
891 MouseEvent me = new MouseEvent(getEventSource(), MouseEvent.MOUSE_ENTERED,
892 jWhen, modifiers, xce.get_x(), xce.get_y(), xce.get_x_root(), xce.get_y_root(), clickCount,
893 popupTrigger, MouseEvent.NOBUTTON);
894 postEventToEventQueue(me);
895 }
896 }
897
898 public void doLayout(int x, int y, int width, int height) {}
899
900 public void handleConfigureNotifyEvent(XEvent xev) {
901 Rectangle oldBounds = getBounds();
902
903 super.handleConfigureNotifyEvent(xev);
904 insLog.log(Level.FINER, "Configure, {0}, event disabled: {1}",
905 new Object[] {xev, isEventDisabled(xev)});
906 if (isEventDisabled(xev)) {
907 return;
908 }
909
910 long eventWindow = xev.get_xany().get_window();
911
912// if ( Check if it's a resize, a move, or a stacking order change )
913// {
914 Rectangle bounds = getBounds();
915 if (!bounds.getSize().equals(oldBounds.getSize())) {
916 postEventToEventQueue(new ComponentEvent(getEventSource(), ComponentEvent.COMPONENT_RESIZED));
917 }
918 if (!bounds.getLocation().equals(oldBounds.getLocation())) {
919 postEventToEventQueue(new ComponentEvent(getEventSource(), ComponentEvent.COMPONENT_MOVED));
920 }
921// }
922 }
923
924 public void handleMapNotifyEvent(XEvent xev) {
925 super.handleMapNotifyEvent(xev);
926 log.log(Level.FINE, "Mapped {0}", new Object[] {this});
927 if (isEventDisabled(xev)) {
928 return;
929 }
930 ComponentEvent ce;
931
932 ce = new ComponentEvent(getEventSource(), ComponentEvent.COMPONENT_SHOWN);
933 postEventToEventQueue(ce);
934 }
935
936 public void handleUnmapNotifyEvent(XEvent xev) {
937 super.handleUnmapNotifyEvent(xev);
938 if (isEventDisabled(xev)) {
939 return;
940 }
941 ComponentEvent ce;
942
943 ce = new ComponentEvent(target, ComponentEvent.COMPONENT_HIDDEN);
944 postEventToEventQueue(ce);
945 }
946
947 private void dumpKeysymArray(XKeyEvent ev) {
948 keyEventLog.fine(" "+Long.toHexString(XlibWrapper.XKeycodeToKeysym(XToolkit.getDisplay(), ev.get_keycode(), 0))+
949 "\n "+Long.toHexString(XlibWrapper.XKeycodeToKeysym(XToolkit.getDisplay(), ev.get_keycode(), 1))+
950 "\n "+Long.toHexString(XlibWrapper.XKeycodeToKeysym(XToolkit.getDisplay(), ev.get_keycode(), 2))+
951 "\n "+Long.toHexString(XlibWrapper.XKeycodeToKeysym(XToolkit.getDisplay(), ev.get_keycode(), 3)));
952 }
953 /**
954 Return unicode character or 0 if no correspondent character found.
955 Parameter is a keysym basically from keysymdef.h
956 XXX: how about vendor keys? Is there some with Unicode value and not in the list?
957 */
958 char keysymToUnicode( long keysym, int state ) {
959 return XKeysym.convertKeysym( keysym, state );
960 }
961 int keyEventType2Id( int xEventType ) {
962 return xEventType == XConstants.KeyPress ? java.awt.event.KeyEvent.KEY_PRESSED :
963 xEventType == XConstants.KeyRelease ? java.awt.event.KeyEvent.KEY_RELEASED : 0;
964 }
965 static private long xkeycodeToKeysym(XKeyEvent ev) {
966 return XKeysym.getKeysym( ev );
967 }
968 void logIncomingKeyEvent(XKeyEvent ev) {
969 keyEventLog.fine("--XWindow.java:handleKeyEvent:"+ev);
970 dumpKeysymArray(ev);
971 keyEventLog.fine("XXXXXXXXXXXXXX javakeycode will be most probably:0x"+ Integer.toHexString(XKeysym.getJavaKeycodeOnly(ev)));
972 }
973 public void handleKeyPress(XEvent xev) {
974 super.handleKeyPress(xev);
975 XKeyEvent ev = xev.get_xkey();
976 if (eventLog.isLoggable(Level.FINE)) eventLog.fine(ev.toString());
977 if (isEventDisabled(xev)) {
978 return;
979 }
980 handleKeyPress(ev);
981 }
982 // called directly from this package, unlike handleKeyRelease.
983 // un-final it if you need to override it in a subclass.
984 final void handleKeyPress(XKeyEvent ev) {
985 int keycode = java.awt.event.KeyEvent.VK_UNDEFINED;
986 long keysym[] = new long[2];
987 char unicodeKey = 0;
988 keysym[0] = NoSymbol;
989
990 if (keyEventLog.isLoggable(Level.FINE)) {
991 logIncomingKeyEvent( ev );
992 }
993 if ( //TODO check if there's an active input method instance
994 // without calling a native method. Is it necessary though?
995 haveCurrentX11InputMethodInstance()) {
996 if (x11inputMethodLookupString(ev.pData, keysym)) {
997 if (keyEventLog.isLoggable(Level.FINE)) {
998 keyEventLog.fine("--XWindow.java XIM did process event; return; dec keysym processed:"+(keysym[0])+
999 "; hex keysym processed:"+Long.toHexString(keysym[0])
1000 );
1001 }
1002 return;
1003 }else {
1004 unicodeKey = keysymToUnicode( keysym[0], ev.get_state() );
1005 if (keyEventLog.isLoggable(Level.FINE)) {
1006 keyEventLog.fine("--XWindow.java XIM did NOT process event, hex keysym:"+Long.toHexString(keysym[0])+"\n"+
1007 " unicode key:"+Integer.toHexString((int)unicodeKey));
1008 }
1009 }
1010 }else {
1011 // No input method instance found. For example, there's a Java Input Method.
1012 // Produce do-it-yourself keysym and perhaps unicode character.
1013 keysym[0] = xkeycodeToKeysym(ev);
1014 unicodeKey = keysymToUnicode( keysym[0], ev.get_state() );
1015 if (keyEventLog.isLoggable(Level.FINE)) {
1016 keyEventLog.fine("--XWindow.java XIM is absent; hex keysym:"+Long.toHexString(keysym[0])+"\n"+
1017 " unicode key:"+Integer.toHexString((int)unicodeKey));
1018 }
1019 }
1020 // Keysym should be converted to Unicode, if possible and necessary,
1021 // and Java KeyEvent keycode should be calculated.
1022 // For press we should post pressed & typed Java events.
1023 //
1024 // Press event might be not processed to this time because
1025 // (1) either XIM could not handle it or
1026 // (2) it was Latin 1:1 mapping.
1027 //
1028 XKeysym.Keysym2JavaKeycode jkc = XKeysym.getJavaKeycode(ev);
1029 if( jkc == null ) {
1030 jkc = new XKeysym.Keysym2JavaKeycode(java.awt.event.KeyEvent.VK_UNDEFINED, java.awt.event.KeyEvent.KEY_LOCATION_UNKNOWN);
1031 }
1032 if (keyEventLog.isLoggable(Level.FINE)) {
1033 keyEventLog.fine(">>>Fire Event:"+
1034 (ev.get_type() == XConstants.KeyPress ? "KEY_PRESSED; " : "KEY_RELEASED; ")+
1035 "jkeycode:decimal="+jkc.getJavaKeycode()+
1036 ", hex=0x"+Integer.toHexString(jkc.getJavaKeycode())+"; "
1037 );
1038 }
1039 postKeyEvent( java.awt.event.KeyEvent.KEY_PRESSED,
1040 ev.get_time(),
1041 jkc.getJavaKeycode(),
1042 (unicodeKey == 0 ? java.awt.event.KeyEvent.CHAR_UNDEFINED : unicodeKey),
1043 jkc.getKeyLocation(),
1044 ev.get_state(),ev.getPData(), XKeyEvent.getSize());
1045 if( unicodeKey > 0 ) {
1046 keyEventLog.fine("fire _TYPED on "+unicodeKey);
1047 postKeyEvent( java.awt.event.KeyEvent.KEY_TYPED,
1048 ev.get_time(),
1049 java.awt.event.KeyEvent.VK_UNDEFINED,
1050 unicodeKey,
1051 java.awt.event.KeyEvent.KEY_LOCATION_UNKNOWN,
1052 ev.get_state(),ev.getPData(), XKeyEvent.getSize());
1053 }
1054
1055
1056 }
1057
1058 public void handleKeyRelease(XEvent xev) {
1059 super.handleKeyRelease(xev);
1060 XKeyEvent ev = xev.get_xkey();
1061 if (eventLog.isLoggable(Level.FINE)) eventLog.fine(ev.toString());
1062 if (isEventDisabled(xev)) {
1063 return;
1064 }
1065 handleKeyRelease(ev);
1066 }
1067 // un-private it if you need to call it from elsewhere
1068 private void handleKeyRelease(XKeyEvent ev) {
1069 int keycode = java.awt.event.KeyEvent.VK_UNDEFINED;
1070 long keysym[] = new long[2];
1071 char unicodeKey = 0;
1072 keysym[0] = NoSymbol;
1073
1074 if (keyEventLog.isLoggable(Level.FINE)) {
1075 logIncomingKeyEvent( ev );
1076 }
1077 // Keysym should be converted to Unicode, if possible and necessary,
1078 // and Java KeyEvent keycode should be calculated.
1079 // For release we should post released event.
1080 //
1081 XKeysym.Keysym2JavaKeycode jkc = XKeysym.getJavaKeycode(ev);
1082 if( jkc == null ) {
1083 jkc = new XKeysym.Keysym2JavaKeycode(java.awt.event.KeyEvent.VK_UNDEFINED, java.awt.event.KeyEvent.KEY_LOCATION_UNKNOWN);
1084 }
1085 if (keyEventLog.isLoggable(Level.FINE)) {
1086 keyEventLog.fine(">>>Fire Event:"+
1087 (ev.get_type() == XConstants.KeyPress ? "KEY_PRESSED; " : "KEY_RELEASED; ")+
1088 "jkeycode:decimal="+jkc.getJavaKeycode()+
1089 ", hex=0x"+Integer.toHexString(jkc.getJavaKeycode())+"; "
1090 );
1091 }
1092 // We obtain keysym from IM and derive unicodeKey from it for KeyPress only.
1093 // We used to cache that value and retrieve it on KeyRelease,
1094 // but in case for example of a dead key+vowel pair, a vowel after a deadkey
1095 // might never be cached before.
1096 // Also, switching between keyboard layouts, we might cache a wrong letter.
1097 // That's why we use the same procedure as if there was no IM instance: do-it-yourself unicode.
1098 unicodeKey = keysymToUnicode( xkeycodeToKeysym(ev), ev.get_state() );
1099
1100 postKeyEvent( java.awt.event.KeyEvent.KEY_RELEASED,
1101 ev.get_time(),
1102 jkc.getJavaKeycode(),
1103 (unicodeKey == 0 ? java.awt.event.KeyEvent.CHAR_UNDEFINED : unicodeKey),
1104 jkc.getKeyLocation(),
1105 ev.get_state(),ev.getPData(), XKeyEvent.getSize());
1106
1107 }
1108
1109 public void reshape(Rectangle bounds) {
1110 reshape(bounds.x, bounds.y, bounds.width, bounds.height);
1111 }
1112
1113 public void reshape(int x, int y, int width, int height) {
1114 if (width <= 0) {
1115 width = 1;
1116 }
1117 if (height <= 0) {
1118 height = 1;
1119 }
1120 this.x = x;
1121 this.y = y;
1122 this.width = width;
1123 this.height = height;
1124 xSetBounds(x, y, width, height);
1125 // Fixed 6322593, 6304251, 6315137:
1126 // XWindow's SurfaceData should be invalidated and recreated as part
1127 // of the process of resizing the window
1128 // see the evaluation of the bug 6304251 for more information
1129 validateSurface();
1130 layout();
1131 }
1132
1133 public void layout() {}
1134
1135 boolean isShowing() {
1136 return visible;
1137 }
1138
1139 boolean isResizable() {
1140 return true;
1141 }
1142
1143 boolean isLocationByPlatform() {
1144 return false;
1145 }
1146
1147 void updateSizeHints() {
1148 updateSizeHints(x, y, width, height);
1149 }
1150
1151 void updateSizeHints(int x, int y, int width, int height) {
1152 long flags = XlibWrapper.PSize | (isLocationByPlatform() ? 0 : (XlibWrapper.PPosition | XlibWrapper.USPosition));
1153 if (!isResizable()) {
1154 log.log(Level.FINER, "Window {0} is not resizable", new Object[] {this});
1155 flags |= XlibWrapper.PMinSize | XlibWrapper.PMaxSize;
1156 } else {
1157 log.log(Level.FINER, "Window {0} is resizable", new Object[] {this});
1158 }
1159 setSizeHints(flags, x, y, width, height);
1160 }
1161
1162 void updateSizeHints(int x, int y) {
1163 long flags = isLocationByPlatform() ? 0 : (XlibWrapper.PPosition | XlibWrapper.USPosition);
1164 if (!isResizable()) {
1165 log.log(Level.FINER, "Window {0} is not resizable", new Object[] {this});
1166 flags |= XlibWrapper.PMinSize | XlibWrapper.PMaxSize | XlibWrapper.PSize;
1167 } else {
1168 log.log(Level.FINER, "Window {0} is resizable", new Object[] {this});
1169 }
1170 setSizeHints(flags, x, y, width, height);
1171 }
1172
1173 void validateSurface() {
1174 if ((width != oldWidth) || (height != oldHeight)) {
1175 SurfaceData oldData = surfaceData;
1176 if (oldData != null) {
1177 surfaceData = graphicsConfig.createSurfaceData(this);
1178 oldData.invalidate();
1179 }
1180 oldWidth = width;
1181 oldHeight = height;
1182 }
1183 }
1184
1185 public SurfaceData getSurfaceData() {
1186 return surfaceData;
1187 }
1188
1189 public void dispose() {
1190 SurfaceData oldData = surfaceData;
1191 surfaceData = null;
1192 if (oldData != null) {
1193 oldData.invalidate();
1194 }
1195 XToolkit.targetDisposedPeer(target, this);
1196 destroy();
1197 }
1198
1199 public Point getLocationOnScreen() {
1200 synchronized (target.getTreeLock()) {
1201 Component comp = target;
1202
1203 while (comp != null && !(comp instanceof Window)) {
1204 comp = ComponentAccessor.getParent_NoClientCode(comp);
1205 }
1206
1207 // applets, embedded, etc - translate directly
1208 // XXX: override in subclass?
1209 if (comp == null || comp instanceof sun.awt.EmbeddedFrame) {
1210 return toGlobal(0, 0);
1211 }
1212
1213 XToolkit.awtLock();
1214 try {
1215 Object wpeer = XToolkit.targetToPeer(comp);
1216 if (wpeer == null
1217 || !(wpeer instanceof XDecoratedPeer)
1218 || ((XDecoratedPeer)wpeer).configure_seen)
1219 {
1220 return toGlobal(0, 0);
1221 }
1222
1223 // wpeer is an XDecoratedPeer not yet fully adopted by WM
1224 Point pt = toOtherWindow(getContentWindow(),
1225 ((XDecoratedPeer)wpeer).getContentWindow(),
1226 0, 0);
1227
1228 if (pt == null) {
1229 pt = new Point(((XBaseWindow)wpeer).getAbsoluteX(), ((XBaseWindow)wpeer).getAbsoluteY());
1230 }
1231 pt.x += comp.getX();
1232 pt.y += comp.getY();
1233 return pt;
1234 } finally {
1235 XToolkit.awtUnlock();
1236 }
1237 }
1238 }
1239
1240
1241 static Field bdata;
1242 static void setBData(KeyEvent e, byte[] data) {
1243 try {
1244 if (bdata == null) {
1245 bdata = SunToolkit.getField(java.awt.AWTEvent.class, "bdata");
1246 }
1247 bdata.set(e, data);
1248 } catch (IllegalAccessException ex) {
1249 assert false;
1250 }
1251 }
1252
1253 public void postKeyEvent(int id, long when, int keyCode, char keyChar,
1254 int keyLocation, int state, long event, int eventSize)
1255 {
1256 long jWhen = XToolkit.nowMillisUTC_offset(when);
1257 int modifiers = getModifiers(state, 0, keyCode);
1258 KeyEvent ke = new KeyEvent((Component)getEventSource(), id, jWhen,
1259 modifiers, keyCode, keyChar, keyLocation);
1260 if (event != 0) {
1261 byte[] data = Native.toBytes(event, eventSize);
1262 setBData(ke, data);
1263 }
1264 postEventToEventQueue(ke);
1265 }
1266
1267 static native int getAWTKeyCodeForKeySym(int keysym);
1268 static native int getKeySymForAWTKeyCode(int keycode);
1269}