mirror of https://github.com/buggins/dlangui.git
X11 timers support
This commit is contained in:
parent
1c5ca7757a
commit
c3cd93fa51
|
|
@ -167,6 +167,9 @@ class X11Window : DWindow {
|
||||||
}
|
}
|
||||||
|
|
||||||
~this() {
|
~this() {
|
||||||
|
if (timer) {
|
||||||
|
timer.stop();
|
||||||
|
}
|
||||||
if (_gc)
|
if (_gc)
|
||||||
XFreeGC(x11display, _gc);
|
XFreeGC(x11display, _gc);
|
||||||
if (_win)
|
if (_win)
|
||||||
|
|
@ -203,6 +206,7 @@ class X11Window : DWindow {
|
||||||
ev.type = Expose;
|
ev.type = Expose;
|
||||||
ev.xexpose.window = _win;
|
ev.xexpose.window = _win;
|
||||||
XSendEvent(x11display, _win, false, ExposureMask, &ev);
|
XSendEvent(x11display, _win, false, ExposureMask, &ev);
|
||||||
|
XFlush(x11display);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// close window
|
/// close window
|
||||||
|
|
@ -662,15 +666,32 @@ class X11Window : DWindow {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TimerThread timer;
|
||||||
private long _nextExpectedTimerTs;
|
private long _nextExpectedTimerTs;
|
||||||
|
|
||||||
|
XEvent ev;
|
||||||
|
|
||||||
/// schedule timer for interval in milliseconds - call window.onTimer when finished
|
/// schedule timer for interval in milliseconds - call window.onTimer when finished
|
||||||
override protected void scheduleSystemTimer(long intervalMillis) {
|
override protected void scheduleSystemTimer(long intervalMillis) {
|
||||||
|
if (!timer) {
|
||||||
|
timer = new TimerThread(delegate() {
|
||||||
|
core.stdc.string.memset(&ev, 0, ev.sizeof);
|
||||||
|
//ev.xclient = XClientMessageEvent.init;
|
||||||
|
ev.xclient.type = ClientMessage;
|
||||||
|
ev.xclient.window = _win;
|
||||||
|
ev.xclient.display = x11display;
|
||||||
|
ev.xclient.format = TIMER_EVENT;
|
||||||
|
Log.d("Sending timer event");
|
||||||
|
XSendEvent(x11display, _win, false, StructureNotifyMask, &ev);
|
||||||
|
});
|
||||||
|
}
|
||||||
if (intervalMillis < 10)
|
if (intervalMillis < 10)
|
||||||
intervalMillis = 10;
|
intervalMillis = 10;
|
||||||
long nextts = currentTimeMillis + intervalMillis;
|
long nextts = currentTimeMillis + intervalMillis;
|
||||||
if (!_nextExpectedTimerTs || _nextExpectedTimerTs > nextts)
|
if (_nextExpectedTimerTs == 0 || _nextExpectedTimerTs > nextts) {
|
||||||
_nextExpectedTimerTs = nextts;
|
_nextExpectedTimerTs = nextts;
|
||||||
|
timer.set(nextts);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool handleTimer() {
|
bool handleTimer() {
|
||||||
|
|
@ -689,7 +710,7 @@ class X11Window : DWindow {
|
||||||
override void postEvent(CustomEvent event) {
|
override void postEvent(CustomEvent event) {
|
||||||
super.postEvent(event);
|
super.postEvent(event);
|
||||||
XEvent ev;
|
XEvent ev;
|
||||||
ev.type = ClientMessage;
|
ev.xclient.type = ClientMessage;
|
||||||
ev.xclient.window = _win;
|
ev.xclient.window = _win;
|
||||||
ev.xclient.format = CUSTOM_EVENT;
|
ev.xclient.format = CUSTOM_EVENT;
|
||||||
ev.xclient.data.l[0] = event.uniqueId;
|
ev.xclient.data.l[0] = event.uniqueId;
|
||||||
|
|
@ -709,6 +730,7 @@ class X11Window : DWindow {
|
||||||
}
|
}
|
||||||
|
|
||||||
private immutable int CUSTOM_EVENT = 32;
|
private immutable int CUSTOM_EVENT = 32;
|
||||||
|
private immutable int TIMER_EVENT = 8;
|
||||||
|
|
||||||
class X11Platform : Platform {
|
class X11Platform : Platform {
|
||||||
|
|
||||||
|
|
@ -781,209 +803,215 @@ class X11Platform : Platform {
|
||||||
/* get the next event and stuff it into our event variable.
|
/* get the next event and stuff it into our event variable.
|
||||||
Note: only events we set the mask for are detected!
|
Note: only events we set the mask for are detected!
|
||||||
*/
|
*/
|
||||||
handleTimers();
|
//bool timersHandled = handleTimers();
|
||||||
if (!XPending(x11display)) {
|
//if (timersHandled)
|
||||||
Thread.sleep(dur!("msecs")(10));
|
// XFlush(x11display);
|
||||||
continue;
|
while (XEventsQueued(x11display, QueuedAfterFlush)) {//QueuedAfterFlush
|
||||||
}
|
//Thread.sleep(dur!("msecs")(10));
|
||||||
XNextEvent(x11display, &event);
|
//continue;
|
||||||
|
XNextEvent(x11display, &event);
|
||||||
|
|
||||||
switch (event.type) {
|
switch (event.type) {
|
||||||
case Expose:
|
case Expose:
|
||||||
if (event.xexpose.count==0) {
|
if (event.xexpose.count==0) {
|
||||||
/* the window was exposed redraw it! */
|
/* the window was exposed redraw it! */
|
||||||
//redraw();
|
//redraw();
|
||||||
X11Window w = findWindow(event.xexpose.window);
|
X11Window w = findWindow(event.xexpose.window);
|
||||||
|
if (w) {
|
||||||
|
|
||||||
|
w.processExpose();
|
||||||
|
} else {
|
||||||
|
Log.e("Window not found");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Log.d("Expose: non-0 count");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case KeyPress:
|
||||||
|
Log.d("X11: KeyPress event");
|
||||||
|
X11Window w = findWindow(event.xkey.window);
|
||||||
if (w) {
|
if (w) {
|
||||||
|
char[100] buf;
|
||||||
|
KeySym ks;
|
||||||
|
Status s;
|
||||||
|
if (!w.xic) {
|
||||||
|
w.xic = XCreateIC(xim,
|
||||||
|
XNInputStyle, XIMPreeditNothing | XIMStatusNothing,
|
||||||
|
XNClientWindow, w._win, 0);
|
||||||
|
if (!w.xic) {
|
||||||
|
Log.e("Cannot create input context");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!w.xic)
|
||||||
|
XLookupString(&event.xkey, buf.ptr, buf.length - 1, &ks, &compose);
|
||||||
|
else {
|
||||||
|
Xutf8LookupString(w.xic, &event.xkey, buf.ptr, cast(int)buf.length - 1, &ks, &s);
|
||||||
|
if (s != XLookupChars && s != XLookupBoth)
|
||||||
|
XLookupString(&event.xkey, buf.ptr, buf.length - 1, &ks, &compose);
|
||||||
|
}
|
||||||
|
foreach(ref ch; buf) {
|
||||||
|
if (ch == 255 || ch < 32 || ch == 127)
|
||||||
|
ch = 0;
|
||||||
|
}
|
||||||
|
string txt = fromStringz(buf.ptr).dup;
|
||||||
|
import std.utf;
|
||||||
|
dstring dtext;
|
||||||
|
try {
|
||||||
|
if (txt.length)
|
||||||
|
dtext = toUTF32(txt);
|
||||||
|
} catch (UTFException e) {
|
||||||
|
// ignore, invalid text
|
||||||
|
}
|
||||||
|
Log.d("X11: KeyPress event bytes=", txt.length, " text=", txt, " dtext=", dtext);
|
||||||
|
if (dtext.length) {
|
||||||
|
w.processTextInput(dtext, event.xkey.state);
|
||||||
|
} else {
|
||||||
|
w.processKeyEvent(KeyAction.KeyDown, cast(uint)ks,
|
||||||
|
//event.xkey.keycode,
|
||||||
|
event.xkey.state);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
w.processExpose();
|
|
||||||
} else {
|
} else {
|
||||||
Log.e("Window not found");
|
Log.e("Window not found");
|
||||||
}
|
}
|
||||||
} else {
|
break;
|
||||||
Log.d("Expose: non-0 count");
|
case KeyRelease:
|
||||||
}
|
Log.d("X11: KeyRelease event");
|
||||||
break;
|
X11Window w = findWindow(event.xkey.window);
|
||||||
case KeyPress:
|
if (w) {
|
||||||
Log.d("X11: KeyPress event");
|
char[100] buf;
|
||||||
X11Window w = findWindow(event.xkey.window);
|
KeySym ks;
|
||||||
if (w) {
|
|
||||||
char[100] buf;
|
|
||||||
KeySym ks;
|
|
||||||
Status s;
|
|
||||||
if (!w.xic) {
|
|
||||||
w.xic = XCreateIC(xim,
|
|
||||||
XNInputStyle, XIMPreeditNothing | XIMStatusNothing,
|
|
||||||
XNClientWindow, w._win, 0);
|
|
||||||
if (!w.xic) {
|
|
||||||
Log.e("Cannot create input context");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!w.xic)
|
|
||||||
XLookupString(&event.xkey, buf.ptr, buf.length - 1, &ks, &compose);
|
XLookupString(&event.xkey, buf.ptr, buf.length - 1, &ks, &compose);
|
||||||
else {
|
w.processKeyEvent(KeyAction.KeyUp, cast(uint)ks,
|
||||||
Xutf8LookupString(w.xic, &event.xkey, buf.ptr, cast(int)buf.length - 1, &ks, &s);
|
|
||||||
if (s != XLookupChars && s != XLookupBoth)
|
|
||||||
XLookupString(&event.xkey, buf.ptr, buf.length - 1, &ks, &compose);
|
|
||||||
}
|
|
||||||
foreach(ref ch; buf) {
|
|
||||||
if (ch == 255 || ch < 32 || ch == 127)
|
|
||||||
ch = 0;
|
|
||||||
}
|
|
||||||
string txt = fromStringz(buf.ptr).dup;
|
|
||||||
import std.utf;
|
|
||||||
dstring dtext;
|
|
||||||
try {
|
|
||||||
if (txt.length)
|
|
||||||
dtext = toUTF32(txt);
|
|
||||||
} catch (UTFException e) {
|
|
||||||
// ignore, invalid text
|
|
||||||
}
|
|
||||||
Log.d("X11: KeyPress event bytes=", txt.length, " text=", txt, " dtext=", dtext);
|
|
||||||
if (dtext.length) {
|
|
||||||
w.processTextInput(dtext, event.xkey.state);
|
|
||||||
} else {
|
|
||||||
w.processKeyEvent(KeyAction.KeyDown, cast(uint)ks,
|
|
||||||
//event.xkey.keycode,
|
//event.xkey.keycode,
|
||||||
event.xkey.state);
|
event.xkey.state);
|
||||||
|
} else {
|
||||||
|
Log.e("Window not found");
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
case ButtonPress:
|
||||||
} else {
|
Log.d("X11: ButtonPress event");
|
||||||
Log.e("Window not found");
|
X11Window w = findWindow(event.xbutton.window);
|
||||||
}
|
if (w) {
|
||||||
break;
|
w.processMouseEvent(MouseAction.ButtonDown, event.xbutton.button, event.xbutton.state, event.xbutton.x, event.xbutton.y);
|
||||||
case KeyRelease:
|
} else {
|
||||||
Log.d("X11: KeyRelease event");
|
Log.e("Window not found");
|
||||||
X11Window w = findWindow(event.xkey.window);
|
|
||||||
if (w) {
|
|
||||||
char[100] buf;
|
|
||||||
KeySym ks;
|
|
||||||
XLookupString(&event.xkey, buf.ptr, buf.length - 1, &ks, &compose);
|
|
||||||
w.processKeyEvent(KeyAction.KeyUp, cast(uint)ks,
|
|
||||||
//event.xkey.keycode,
|
|
||||||
event.xkey.state);
|
|
||||||
} else {
|
|
||||||
Log.e("Window not found");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case ButtonPress:
|
|
||||||
Log.d("X11: ButtonPress event");
|
|
||||||
X11Window w = findWindow(event.xbutton.window);
|
|
||||||
if (w) {
|
|
||||||
w.processMouseEvent(MouseAction.ButtonDown, event.xbutton.button, event.xbutton.state, event.xbutton.x, event.xbutton.y);
|
|
||||||
} else {
|
|
||||||
Log.e("Window not found");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case ButtonRelease:
|
|
||||||
Log.d("X11: ButtonRelease event");
|
|
||||||
X11Window w = findWindow(event.xbutton.window);
|
|
||||||
if (w) {
|
|
||||||
w.processMouseEvent(MouseAction.ButtonUp, event.xbutton.button, event.xbutton.state, event.xbutton.x, event.xbutton.y);
|
|
||||||
} else {
|
|
||||||
Log.e("Window not found");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case MotionNotify:
|
|
||||||
Log.d("X11: MotionNotify event");
|
|
||||||
X11Window w = findWindow(event.xmotion.window);
|
|
||||||
if (w) {
|
|
||||||
//w.processExpose();
|
|
||||||
w.processMouseEvent(MouseAction.Move, 0, event.xmotion.state, event.xmotion.x, event.xmotion.y);
|
|
||||||
} else {
|
|
||||||
Log.e("Window not found");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case EnterNotify:
|
|
||||||
Log.d("X11: EnterNotify event");
|
|
||||||
X11Window w = findWindow(event.xcrossing.window);
|
|
||||||
if (w) {
|
|
||||||
w.processMouseEvent(MouseAction.FocusIn, 0, event.xcrossing.state, event.xcrossing.x, event.xcrossing.y);
|
|
||||||
|
|
||||||
//w.processExpose();
|
|
||||||
} else {
|
|
||||||
Log.e("Window not found");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case LeaveNotify:
|
|
||||||
Log.d("X11: LeaveNotify event");
|
|
||||||
X11Window w = findWindow(event.xcrossing.window);
|
|
||||||
if (w) {
|
|
||||||
w.processMouseEvent(MouseAction.Leave, 0, event.xcrossing.state, event.xcrossing.x, event.xcrossing.y);
|
|
||||||
} else {
|
|
||||||
Log.e("Window not found");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case CreateNotify:
|
|
||||||
Log.d("X11: CreateNotify event");
|
|
||||||
X11Window w = findWindow(event.xcreatewindow.window);
|
|
||||||
if (w) {
|
|
||||||
//w.processExpose();
|
|
||||||
} else {
|
|
||||||
Log.e("Window not found");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case DestroyNotify:
|
|
||||||
Log.d("X11: DestroyNotify event");
|
|
||||||
X11Window w = findWindow(event.xdestroywindow.window);
|
|
||||||
if (w) {
|
|
||||||
//w.processExpose();
|
|
||||||
} else {
|
|
||||||
Log.e("Window not found");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case ResizeRequest:
|
|
||||||
Log.d("X11: ResizeRequest event");
|
|
||||||
X11Window w = findWindow(event.xresizerequest.window);
|
|
||||||
if (w) {
|
|
||||||
//w.processExpose();
|
|
||||||
} else {
|
|
||||||
Log.e("Window not found");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case FocusIn:
|
|
||||||
Log.d("X11: FocusIn event");
|
|
||||||
X11Window w = findWindow(event.xfocus.window);
|
|
||||||
if (w) {
|
|
||||||
//w.processExpose();
|
|
||||||
} else {
|
|
||||||
Log.e("Window not found");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case FocusOut:
|
|
||||||
Log.d("X11: FocusOut event");
|
|
||||||
X11Window w = findWindow(event.xfocus.window);
|
|
||||||
if (w) {
|
|
||||||
//w.processExpose();
|
|
||||||
} else {
|
|
||||||
Log.e("Window not found");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case KeymapNotify:
|
|
||||||
Log.d("X11: KeymapNotify event");
|
|
||||||
X11Window w = findWindow(event.xkeymap.window);
|
|
||||||
if (w) {
|
|
||||||
//w.processExpose();
|
|
||||||
} else {
|
|
||||||
Log.e("Window not found");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case ClientMessage:
|
|
||||||
Log.d("X11: ClientMessage event");
|
|
||||||
X11Window w = findWindow(event.xclient.window);
|
|
||||||
if (w) {
|
|
||||||
if (event.xclient.format == CUSTOM_EVENT) {
|
|
||||||
w.handlePostedEvent(cast(uint)event.xclient.data.l[0]);
|
|
||||||
}
|
}
|
||||||
} else {
|
break;
|
||||||
Log.e("Window not found");
|
case ButtonRelease:
|
||||||
}
|
Log.d("X11: ButtonRelease event");
|
||||||
break;
|
X11Window w = findWindow(event.xbutton.window);
|
||||||
default:
|
if (w) {
|
||||||
break;
|
w.processMouseEvent(MouseAction.ButtonUp, event.xbutton.button, event.xbutton.state, event.xbutton.x, event.xbutton.y);
|
||||||
|
} else {
|
||||||
|
Log.e("Window not found");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case MotionNotify:
|
||||||
|
Log.d("X11: MotionNotify event");
|
||||||
|
X11Window w = findWindow(event.xmotion.window);
|
||||||
|
if (w) {
|
||||||
|
//w.processExpose();
|
||||||
|
w.processMouseEvent(MouseAction.Move, 0, event.xmotion.state, event.xmotion.x, event.xmotion.y);
|
||||||
|
} else {
|
||||||
|
Log.e("Window not found");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case EnterNotify:
|
||||||
|
Log.d("X11: EnterNotify event");
|
||||||
|
X11Window w = findWindow(event.xcrossing.window);
|
||||||
|
if (w) {
|
||||||
|
w.processMouseEvent(MouseAction.FocusIn, 0, event.xcrossing.state, event.xcrossing.x, event.xcrossing.y);
|
||||||
|
|
||||||
|
//w.processExpose();
|
||||||
|
} else {
|
||||||
|
Log.e("Window not found");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case LeaveNotify:
|
||||||
|
Log.d("X11: LeaveNotify event");
|
||||||
|
X11Window w = findWindow(event.xcrossing.window);
|
||||||
|
if (w) {
|
||||||
|
w.processMouseEvent(MouseAction.Leave, 0, event.xcrossing.state, event.xcrossing.x, event.xcrossing.y);
|
||||||
|
} else {
|
||||||
|
Log.e("Window not found");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case CreateNotify:
|
||||||
|
Log.d("X11: CreateNotify event");
|
||||||
|
X11Window w = findWindow(event.xcreatewindow.window);
|
||||||
|
if (w) {
|
||||||
|
//w.processExpose();
|
||||||
|
} else {
|
||||||
|
Log.e("Window not found");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case DestroyNotify:
|
||||||
|
Log.d("X11: DestroyNotify event");
|
||||||
|
X11Window w = findWindow(event.xdestroywindow.window);
|
||||||
|
if (w) {
|
||||||
|
//w.processExpose();
|
||||||
|
} else {
|
||||||
|
Log.e("Window not found");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ResizeRequest:
|
||||||
|
Log.d("X11: ResizeRequest event");
|
||||||
|
X11Window w = findWindow(event.xresizerequest.window);
|
||||||
|
if (w) {
|
||||||
|
//w.processExpose();
|
||||||
|
} else {
|
||||||
|
Log.e("Window not found");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case FocusIn:
|
||||||
|
Log.d("X11: FocusIn event");
|
||||||
|
X11Window w = findWindow(event.xfocus.window);
|
||||||
|
if (w) {
|
||||||
|
//w.processExpose();
|
||||||
|
} else {
|
||||||
|
Log.e("Window not found");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case FocusOut:
|
||||||
|
Log.d("X11: FocusOut event");
|
||||||
|
X11Window w = findWindow(event.xfocus.window);
|
||||||
|
if (w) {
|
||||||
|
//w.processExpose();
|
||||||
|
} else {
|
||||||
|
Log.e("Window not found");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case KeymapNotify:
|
||||||
|
Log.d("X11: KeymapNotify event");
|
||||||
|
X11Window w = findWindow(event.xkeymap.window);
|
||||||
|
if (w) {
|
||||||
|
//w.processExpose();
|
||||||
|
} else {
|
||||||
|
Log.e("Window not found");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ClientMessage:
|
||||||
|
Log.d("X11: ClientMessage event");
|
||||||
|
X11Window w = findWindow(event.xclient.window);
|
||||||
|
if (w) {
|
||||||
|
if (event.xclient.format == CUSTOM_EVENT) {
|
||||||
|
w.handlePostedEvent(cast(uint)event.xclient.data.l[0]);
|
||||||
|
} else if (event.xclient.format == TIMER_EVENT) {
|
||||||
|
w.handleTimer();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Log.e("Window not found");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
//Thread.sleep(dur!("msecs")(10));
|
||||||
|
//XFlush(x11display);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -1008,6 +1036,79 @@ class X11Platform : Platform {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
import core.thread;
|
||||||
|
import core.sync.mutex;
|
||||||
|
import core.sync.condition;
|
||||||
|
class TimerThread : Thread {
|
||||||
|
Mutex mutex;
|
||||||
|
Condition condition;
|
||||||
|
bool stopped;
|
||||||
|
long nextEventTs;
|
||||||
|
void delegate() callback;
|
||||||
|
|
||||||
|
this(void delegate() timerCallback) {
|
||||||
|
callback = timerCallback;
|
||||||
|
mutex = new Mutex();
|
||||||
|
condition = new Condition(mutex);
|
||||||
|
super(&run);
|
||||||
|
start();
|
||||||
|
}
|
||||||
|
|
||||||
|
~this() {
|
||||||
|
stop();
|
||||||
|
destroy(condition);
|
||||||
|
destroy(mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void set(long nextTs) {
|
||||||
|
mutex.lock();
|
||||||
|
if (nextEventTs == 0 || nextEventTs > nextTs) {
|
||||||
|
nextEventTs = nextTs;
|
||||||
|
condition.notify();
|
||||||
|
}
|
||||||
|
mutex.unlock();
|
||||||
|
}
|
||||||
|
void run() {
|
||||||
|
|
||||||
|
while (!stopped) {
|
||||||
|
bool expired = false;
|
||||||
|
|
||||||
|
mutex.lock();
|
||||||
|
|
||||||
|
long ts = currentTimeMillis;
|
||||||
|
long timeToWait = nextEventTs == 0 ? 1000 : nextEventTs - ts;
|
||||||
|
if (timeToWait < 10)
|
||||||
|
timeToWait = 10;
|
||||||
|
|
||||||
|
condition.wait(dur!"msecs"(timeToWait));
|
||||||
|
|
||||||
|
if (stopped) {
|
||||||
|
mutex.unlock();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ts = currentTimeMillis;
|
||||||
|
if (nextEventTs && nextEventTs < ts && !stopped) {
|
||||||
|
expired = true;
|
||||||
|
nextEventTs = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
mutex.unlock();
|
||||||
|
|
||||||
|
if (expired)
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void stop() {
|
||||||
|
if (stopped)
|
||||||
|
return;
|
||||||
|
stopped = true;
|
||||||
|
mutex.lock();
|
||||||
|
condition.notify();
|
||||||
|
mutex.unlock();
|
||||||
|
join();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
XC_X_cursor=0,
|
XC_X_cursor=0,
|
||||||
XC_arrow=2,
|
XC_arrow=2,
|
||||||
|
|
@ -1104,6 +1205,8 @@ extern(C) int DLANGUImain(string[] args)
|
||||||
|
|
||||||
currentTheme = createDefaultTheme();
|
currentTheme = createDefaultTheme();
|
||||||
|
|
||||||
|
XInitThreads();
|
||||||
|
|
||||||
/* use the information from the environment variable DISPLAY
|
/* use the information from the environment variable DISPLAY
|
||||||
to create the X connection:
|
to create the X connection:
|
||||||
*/
|
*/
|
||||||
|
|
@ -1141,6 +1244,8 @@ extern(C) int DLANGUImain(string[] args)
|
||||||
|
|
||||||
Log.d("X11 display=", x11display, " screen=", x11screen);
|
Log.d("X11 display=", x11display, " screen=", x11screen);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
X11Platform x11platform = new X11Platform();
|
X11Platform x11platform = new X11Platform();
|
||||||
|
|
||||||
Platform.setInstance(x11platform);
|
Platform.setInstance(x11platform);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue