1: package ;
2:
3:
10:
11: import ;
12:
13: import ;
14: import ;
15: import ;
16: import ;
17: import ;
18: import ;
19: import ;
20: import ;
21: import ;
22: import ;
23:
24: public class XEventLoop implements Runnable
25: {
26: Display display;
27: EventQueue queue;
28: XAnyEvent anyEvent;
29: private Thread eventLoopThread;
30:
31: LightweightRedirector lightweightRedirector = new LightweightRedirector();
32:
33: public XEventLoop(Display display, EventQueue queue)
34: {
35: this.display = display;
36: this.queue = queue;
37:
38: anyEvent = new XAnyEvent(display);
39: eventLoopThread = new Thread(this, "AWT thread for XEventLoop");
40: eventLoopThread.start();
41: }
42:
43: public void run ()
44: {
45:
46: while (true)
47: postNextEvent (true);
48: }
49:
50:
53: boolean postNextEvent(boolean block)
54: {
55: AWTEvent evt = getNextEvent(block);
56: if (evt != null)
57: queue.postEvent(evt);
58: return evt != null;
59: }
60:
61:
64: public AWTEvent getNextEvent(boolean block)
65: {
66:
67: if (isIdle())
68: throw new Error("should not be idle");
69:
70: AWTEvent event = null;
71: if (loadNextEvent(block))
72: {
73: event = createEvent();
74: event = lightweightRedirector.redirect(event);
75: }
76: return event;
77: }
78:
79: boolean loadNextEvent(boolean block)
80: {
81: boolean gotEvent = false;
82: try
83: {
84: setIdle(true);
85:
86:
106:
107:
108: gotEvent = anyEvent.loadNext(block);
109: }
110: catch (RuntimeException re)
111: {
112: System.err.println("Exception thrown on event thread:" + re);
113: }
114: finally
115: {
116: setIdle(false);
117: }
118: return gotEvent;
119: }
120:
121:
126:
127: AWTEvent createEvent ()
128: {
129: int type = anyEvent.getType ();
130:
131: switch (type)
132: {
133:
134:
135: case XAnyEvent.TYPE_NO_EXPOSE:
136: case XAnyEvent.TYPE_UNMAP_NOTIFY:
137: case XAnyEvent.TYPE_MAP_NOTIFY:
138: case XAnyEvent.TYPE_REPARENT_NOTIFY:
139: return null;
140: default:
141: break;
142: }
143:
145: Object peer;
146: synchronized (this)
147: {
148: peer = anyEvent.getWindow ().getClientData ();
149: }
150:
151: Component source = null;
152:
153:
154:
155: if (peer instanceof XCanvasPeer)
156: {
157: source = ((XCanvasPeer) peer).getComponent ();
158: }
159:
160: if (source == null)
161: {
162: String msg = "unable to locate source for event (" +
163: anyEvent + "): peer=" + peer;
164: throw new RuntimeException (msg);
165: }
166:
167:
169:
170: switch (type)
171: {
172: case XAnyEvent.TYPE_EXPOSE:
173: return createPaintEvent (source);
174: case XAnyEvent.TYPE_BUTTON_PRESS:
175: case XAnyEvent.TYPE_BUTTON_RELEASE:
176: return createMouseEvent (type, source);
177: case XAnyEvent.TYPE_CONFIGURE_NOTIFY:
178: configureNotify (peer);
179: return null;
180:
181: default:
182: String msg = "Do not know how to handle event (" + anyEvent + ")";
183: throw new RuntimeException (msg);
184: }
185: }
186:
187: AWTEvent createPaintEvent(Component src)
188: {
189: XExposeEvent expose = new XExposeEvent(anyEvent);
190: PaintEvent pe = new PaintEvent(src, PaintEvent.PAINT,
191: expose.getBounds());
192: return pe;
193: }
194:
195: AWTEvent createMouseEvent(int type, Component src)
196: {
197: XButtonEvent buttonEvt = new XButtonEvent(anyEvent);
198:
199: int modifiers = 0;
200:
201:
203: switch (buttonEvt.button)
204: {
205: case 1:
206: modifiers = InputEvent.BUTTON1_DOWN_MASK;
207: break;
208: case 2:
209: modifiers = InputEvent.BUTTON2_DOWN_MASK;
210: break;
211: case 3:
212: modifiers = InputEvent.BUTTON2_DOWN_MASK;
213: break;
214: }
215:
216: int state = buttonEvt.state;
217:
218:
219:
220: if ((state & XButtonEvent.MASK_SHIFT) != 0)
221: modifiers |= InputEvent.SHIFT_MASK;
222:
223:
224: if ((state & XButtonEvent.MASK_CONTROL) != 0)
225: modifiers |= InputEvent.CTRL_MASK;
226:
227:
228:
230:
231: int clickCount = 1;
232: boolean popupTrigger = false;
233:
234: int x = buttonEvt.x;
235: int y = buttonEvt.y;
236:
237: int id = (type == XAnyEvent.TYPE_BUTTON_PRESS) ?
238: MouseEvent.MOUSE_PRESSED :
239: MouseEvent.MOUSE_RELEASED;
240:
241: MouseEvent me = new MouseEvent(src,
242: id,
243: buttonEvt.time, modifiers,
244: buttonEvt.x, buttonEvt.y,
245: clickCount, popupTrigger);
246: return me;
247: }
248:
249: void configureNotify(Object peerObj)
250: {
251: XConfigureEvent configEvent = new XConfigureEvent(anyEvent);
252: XFramePeer peer = (XFramePeer) peerObj;
253:
254: peer.configureNotify(configEvent);
255: }
256:
257: public void flushIfIdle()
258: {
259: if (isIdle())
260: display.flush();
261: }
262:
263: volatile boolean idle = false;
264:
265: final synchronized void setIdle(boolean idle)
266: {
267: this.idle = idle;
268: }
269:
270: final synchronized boolean isIdle()
271: {
272: return idle;
273: }
274: }