1:
37:
38:
39: package ;
40:
41: import ;
42: import ;
43: import ;
44: import ;
45: import ;
46: import ;
47: import ;
48: import ;
49: import ;
50: import ;
51: import ;
52: import ;
53: import ;
54: import ;
55:
56: import ;
57: import ;
58: import ;
59: import ;
60: import ;
61: import ;
62: import ;
63: import ;
64: import ;
65: import ;
66: import ;
67: import ;
68: import ;
69: import ;
70: import ;
71: import ;
72: import ;
73:
74:
80: public class XEventPump
81: implements Runnable
82: {
83:
84:
87: private Display display;
88:
89:
93: private HashMap windows;
94:
95:
100: private int drag;
101:
102:
107: XEventPump(Display d)
108: {
109: display = d;
110: windows = new HashMap();
111: drag = -1;
112: Thread thread = new Thread(this, "X Event Pump");
113: thread.setDaemon(true);
114: thread.start();
115: }
116:
117:
121: public void run()
122: {
123: while (display.connected)
124: {
125: try
126: {
127: Event xEvent = display.next_event();
128: handleEvent(xEvent);
129: }
130: catch (ThreadDeath death)
131: {
132:
133: return;
134: }
135: catch (Throwable x)
136: {
137: System.err.println("Exception during event dispatch:");
138: x.printStackTrace(System.err);
139: }
140: }
141: }
142:
143:
150: void registerWindow(gnu.x11.Window xWindow, Window awtWindow)
151: {
152: if (XToolkit.DEBUG)
153: System.err.println("registering window id: " + xWindow.id);
154: windows.put(new Integer(xWindow.id), awtWindow);
155: }
156:
157: void unregisterWindow(gnu.x11.Window xWindow)
158: {
159: windows.remove(new Integer(xWindow.id));
160: }
161:
162: private void handleButtonPress(ButtonPress event)
163: {
164: Integer key = new Integer(event.getEventWindowID());
165: Window awtWindow = (Window) windows.get(key);
166:
167:
168: int button = event.detail();
169:
170:
171: if (button >= gnu.x11.Input.BUTTON3)
172: button = 0;
173: drag = button;
174:
175: Component target =
176: findMouseEventTarget(awtWindow, event.getEventX(), event.getEventY());
177: if(target == null)
178: {
179: target = awtWindow;
180: }
181:
182: MouseEvent mp = new MouseEvent(target, MouseEvent.MOUSE_PRESSED,
183: System.currentTimeMillis(),
184: KeyboardMapping.mapModifiers(event.getState())
185: | buttonToModifier(button),
186: event.getEventX(), event.getEventY(),
187: 1, false, button);
188: Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(mp);
189: }
190:
191: private void handleButtonRelease(ButtonRelease event)
192: {
193: Integer key = new Integer(event.getEventWindowID());
194: Window awtWindow = (Window) windows.get(key);
195:
196: int button = event.detail();
197:
198:
199: if (button >= gnu.x11.Input.BUTTON3)
200: button = 0;
201: drag = -1;
202:
203: Component target =
204: findMouseEventTarget(awtWindow, event.getEventX(), event.getEventY());
205: if(target == null)
206: {
207: target = awtWindow;
208: }
209:
210: MouseEvent mr = new MouseEvent(target, MouseEvent.MOUSE_RELEASED,
211: System.currentTimeMillis(),
212: KeyboardMapping.mapModifiers(event.getState())
213: | buttonToModifier(button),
214: event.getEventX(), event.getEventY(),
215: 1, false, button);
216: Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(mr);
217: }
218:
219:
220: private void handleMotionNotify(MotionNotify event)
221: {
222: Integer key = new Integer(event.getEventWindowID());
223: Window awtWindow = (Window) windows.get(key);
224:
225: int button = event.detail();
226:
227:
228: if (button >= gnu.x11.Input.BUTTON3)
229: button = 0;
230:
231: MouseEvent mm = null;
232: if (drag == -1)
233: {
234: mm = new MouseEvent(awtWindow, MouseEvent.MOUSE_MOVED,
235: System.currentTimeMillis(),
236: KeyboardMapping.mapModifiers(event.getState())
237: | buttonToModifier(button),
238: event.getEventX(), event.getEventY(),
239: 1, false);
240:
241: }
242: else
243: {
244: mm = new MouseEvent(awtWindow, MouseEvent.MOUSE_DRAGGED,
245: System.currentTimeMillis(),
246: KeyboardMapping.mapModifiers(event.getState())
247: | buttonToModifier(drag),
248: event.getEventX(), event.getEventY(),
249: 1, false);
250: }
251: Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(mm);
252: }
253:
254:
255:
256: private void handleExpose(Expose event)
257: {
258: Integer key = new Integer(event.window_id);
259: Window awtWindow = (Window) windows.get(key);
260:
261: if (XToolkit.DEBUG)
262: System.err.println("expose request for window id: " + key);
263:
264: Rectangle r = new Rectangle(event.x(), event.y(), event.width(),
265: event.height());
266:
267: assert awtWindow != null : "awtWindow == null for window ID: " + key;
268:
269: Graphics g = awtWindow.getGraphics();
270: g.clearRect(r.x, r.y, r.width, r.height);
271: g.dispose();
272:
273: XWindowPeer xwindow = (XWindowPeer) awtWindow.getPeer();
274: Insets i = xwindow.insets();
275: if (event.width() != awtWindow.getWidth() - i.left - i.right
276: || event.height() != awtWindow.getHeight() - i.top - i.bottom)
277: {
278: int w = event.width();
279: int h = event.height();
280: int x = xwindow.xwindow.x;
281: int y = xwindow.xwindow.y;
282:
283: if (XToolkit.DEBUG)
284: System.err.println("Setting size on AWT window: " + w
285: + ", " + h + ", " + awtWindow.getWidth()
286: + ", " + awtWindow.getHeight());
287:
288:
289: xwindow.xwindow.width = w;
290: xwindow.xwindow.height = h;
291:
292:
293: ComponentReshapeEvent cre =
294: new ComponentReshapeEvent(awtWindow, x, y, w, h);
295: awtWindow.dispatchEvent(cre);
296: }
297:
298: ComponentEvent ce =
299: new ComponentEvent(awtWindow, ComponentEvent.COMPONENT_RESIZED);
300: awtWindow.dispatchEvent(ce);
301:
302: PaintEvent pev = new PaintEvent(awtWindow, PaintEvent.UPDATE, r);
303: Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(pev);
304: }
305:
306: private void handleDestroyNotify(DestroyNotify destroyNotify)
307: {
308: if (XToolkit.DEBUG)
309: System.err.println("DestroyNotify event: " + destroyNotify);
310:
311: Integer key = new Integer(destroyNotify.event_window_id);
312: Window awtWindow = (Window) windows.get(key);
313:
314: AWTEvent event = new WindowEvent(awtWindow, WindowEvent.WINDOW_CLOSED);
315: Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(event);
316: }
317:
318: private void handleClientMessage(ClientMessage clientMessage)
319: {
320: if (XToolkit.DEBUG)
321: System.err.println("ClientMessage event: " + clientMessage);
322:
323: if (clientMessage.delete_window())
324: {
325: if (XToolkit.DEBUG)
326: System.err.println("ClientMessage is a delete_window event");
327:
328: Integer key = new Integer(clientMessage.window_id);
329: Window awtWindow = (Window) windows.get(key);
330:
331: AWTEvent event = new WindowEvent(awtWindow, WindowEvent.WINDOW_CLOSING);
332: Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(event);
333: }
334: }
335:
336: private void handleEvent(Event xEvent)
337: {
338: if (XToolkit.DEBUG)
339: System.err.println("fetched event: " + xEvent);
340:
341: switch (xEvent.code() & 0x7f)
342: {
343: case ButtonPress.CODE:
344: this.handleButtonPress((ButtonPress) xEvent);
345: break;
346: case ButtonRelease.CODE:
347: this.handleButtonRelease((ButtonRelease) xEvent);
348: break;
349: case MotionNotify.CODE:
350: this.handleMotionNotify((MotionNotify) xEvent);
351: break;
352: case Expose.CODE:
353: this.handleExpose((Expose) xEvent);
354: break;
355: case KeyPress.CODE:
356: case KeyRelease.CODE:
357: Integer key = new Integer(((Input) xEvent).getEventWindowID());
358: Window awtWindow = (Window) windows.get(key);
359: handleKeyEvent(xEvent, awtWindow);
360: break;
361: case DestroyNotify.CODE:
362: this.handleDestroyNotify((DestroyNotify) xEvent);
363: break;
364: case ClientMessage.CODE:
365: this.handleClientMessage((ClientMessage) xEvent);
366: break;
367: case PropertyNotify.CODE:
368: key = new Integer (((PropertyNotify) xEvent).getWindowID());
369: awtWindow = (Window) windows.get(key);
370: AWTEvent event = new WindowEvent(awtWindow, WindowEvent.WINDOW_STATE_CHANGED);
371: Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(event);
372: break;
373: default:
374: if (XToolkit.DEBUG)
375: System.err.println("Unhandled X event: " + xEvent);
376: }
377: }
378:
379:
385: private void handleKeyEvent(Event xEvent, Window awtWindow)
386: {
387: Input keyEvent = (Input) xEvent;
388: int xKeyCode = keyEvent.detail();
389: int xMods = keyEvent.getState();
390: int keyCode = KeyboardMapping.mapToKeyCode(xEvent.display.input, xKeyCode,
391: xMods);
392: char keyChar = KeyboardMapping.mapToKeyChar(xEvent.display.input, xKeyCode,
393: xMods);
394: if (XToolkit.DEBUG)
395: System.err.println("XEventPump.handleKeyEvent: " + xKeyCode + ", "
396: + xMods + ": " + ((int) keyChar) + ", " + keyCode);
397: int awtMods = KeyboardMapping.mapModifiers(xMods);
398: long when = System.currentTimeMillis();
399: KeyEvent ke;
400: if (keyEvent.code() == KeyPress.CODE)
401: {
402: ke = new KeyEvent(awtWindow, KeyEvent.KEY_PRESSED, when,
403: awtMods, keyCode,
404: KeyEvent.CHAR_UNDEFINED);
405: Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(ke);
406: if (keyChar != KeyEvent.CHAR_UNDEFINED)
407: {
408: ke = new KeyEvent(awtWindow, KeyEvent.KEY_TYPED, when,
409: awtMods, KeyEvent.VK_UNDEFINED,
410: keyChar);
411: Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(ke);
412: }
413:
414: }
415: else
416: {
417: ke = new KeyEvent(awtWindow, KeyEvent.KEY_RELEASED, when,
418: awtMods, keyCode,
419: KeyEvent.CHAR_UNDEFINED);
420: Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(ke);
421: }
422:
423: }
424:
425:
429: static int buttonToModifier(int button)
430: {
431: switch (button)
432: {
433: case gnu.x11.Input.BUTTON1:
434: return MouseEvent.BUTTON1_DOWN_MASK | MouseEvent.BUTTON1_MASK;
435: case gnu.x11.Input.BUTTON2:
436: return MouseEvent.BUTTON2_DOWN_MASK | MouseEvent.BUTTON2_MASK;
437: case gnu.x11.Input.BUTTON3:
438: return MouseEvent.BUTTON3_DOWN_MASK | MouseEvent.BUTTON3_MASK;
439: }
440:
441: return 0;
442: }
443:
444:
453: private Component findMouseEventTarget(Component src, int x, int y)
454: {
455: Component found = null;
456: if (src instanceof Container)
457: {
458: Container cont = (Container) src;
459: int numChildren = cont.getComponentCount();
460: for (int i = 0; i < numChildren && found == null; i++)
461: {
462: Component child = cont.getComponent(i);
463: if (child != null && child.isVisible()
464: && child.contains(x - child.getX(), y - child.getY()))
465: {
466: if (child instanceof Container)
467: {
468: Component deeper = findMouseEventTarget(child,
469: x - child.getX(),
470: y - child.getY());
471: if (deeper != null)
472: found = deeper;
473: }
474: else if (! child.isLightweight())
475: found = child;
476: }
477: }
478: }
479:
480:
481: if (found == null && src.contains(x, y) && ! src.isLightweight())
482: found = src;
483:
484: return found;
485: }
486: }