minimal update for osx xquartz

This commit is contained in:
Adam D. Ruppe 2020-02-01 19:05:14 -05:00
parent d3c545b0ce
commit c76d26f01f
3 changed files with 143 additions and 43 deletions

View File

@ -36,8 +36,7 @@
"targetType": "library",
"importPaths": ["."],
"dflags": ["-mv=arsd.simpledisplay=simpledisplay.d"],
"versions-osx": [ "OSXCocoa", "allow_unimplemented_features", "without_opengl" ],
"lflags-osx": ["-framework", "Cocoa"],
"lflags-osx": ["-L/usr/X11/lib"],
"dependencies": {"arsd-official:color_base":"*"},
"configurations": [
{
@ -50,6 +49,11 @@
"versions": ["without_opengl"],
"libs-windows": ["gdi32"],
"libs-posix": ["X11", "Xext"]
},
{
"name": "cocoa",
"versions-osx": [ "OSXCocoa", "allow_unimplemented_features", "without_opengl" ],
"lflags-osx": ["-framework", "Cocoa"],
}
],
"sourceFiles": ["simpledisplay.d"]

View File

@ -604,6 +604,7 @@ private const(wchar)* toWstringzInternal(in char[] s) {
return str.ptr;
}
static if(SimpledisplayTimerAvailable)
void setClickRepeat(Widget w, int interval, int delay = 250) {
Timer timer;
int delayRemaining = delay / interval;
@ -649,6 +650,8 @@ void setClickRepeat(Widget w, int interval, int delay = 250) {
});
}
else
void setClickRepeat(Widget w, int interval, int delay = 250) {}
enum FrameStyle {
risen,

View File

@ -1,5 +1,7 @@
// https://dpaste.dzfl.pl/7a77355acaec
// on Mac with X11: -L-L/usr/X11/lib
/*
Event Loop would be nices:
@ -2364,7 +2366,8 @@ private:
private import core.time : MonoTime;
version(X11) {
__gshared int customEventFD = -1;
__gshared int customEventFDRead = -1;
__gshared int customEventFDWrite = -1;
__gshared int customSignalFD = -1;
} else version(Windows) {
__gshared HANDLE customEventH = null;
@ -2375,7 +2378,7 @@ private:
version(X11) {
import core.sys.posix.unistd : write;
ulong n = 1;
if (customEventFD >= 0) write(customEventFD, &n, n.sizeof);
if (customEventFDWrite >= 0) write(customEventFDWrite, &n, n.sizeof);
return true;
} else version(Windows) {
if (customEventH !is null) SetEvent(customEventH);
@ -2746,7 +2749,7 @@ struct EventLoop {
version(linux)
void delegate(int, int) globalHupHandler;
version(linux)
version(Posix)
void makeNonBlocking(int fd) {
import fcntl = core.sys.posix.fcntl;
auto flags = fcntl.fcntl(fd, fcntl.F_GETFL, 0);
@ -2859,14 +2862,15 @@ struct EventLoopImpl {
}
// eventfd for custom events
if (customEventFD == -1) {
customEventFD = eventfd(0, 0);
if (customEventFD >= 0) {
if (customEventFDWrite == -1) {
customEventFDWrite = eventfd(0, 0);
customEventFDRead = customEventFDWrite;
if (customEventFDRead >= 0) {
ep.epoll_event ev = void;
{ import core.stdc.string : memset; memset(&ev, 0, ev.sizeof); } // this makes valgrind happy
ev.events = ep.EPOLLIN;
ev.data.fd = customEventFD;
ep.epoll_ctl(epollFd, ep.EPOLL_CTL_ADD, customEventFD, &ev);
ev.data.fd = customEventFDRead;
ep.epoll_ctl(epollFd, ep.EPOLL_CTL_ADD, customEventFDRead, &ev);
} else {
// this is something that should not be; better be safe than sorry
throw new Exception("can't create eventfd for custom event processing");
@ -2895,6 +2899,17 @@ struct EventLoopImpl {
ev.data.fd = customSignalFD;
ep.epoll_ctl(epollFd, ep.EPOLL_CTL_ADD, customSignalFD, &ev);
}
} else version(Posix) {
prepareEventLoop();
if (customEventFDRead == -1) {
int[2] bfr;
import core.sys.posix.unistd;
auto ret = pipe(bfr);
if(ret == -1) throw new Exception("pipe");
customEventFDRead = bfr[0];
customEventFDWrite = bfr[1];
}
}
SimpleWindow.processAllCustomEvents(); // process events added before event FD creation
@ -2961,8 +2976,10 @@ struct EventLoopImpl {
dispose();
}
version(linux)
ref int customEventFD() { return SimpleWindow.customEventFD; }
version(Posix)
ref int customEventFDRead() { return SimpleWindow.customEventFDRead; }
version(Posix)
ref int customEventFDWrite() { return SimpleWindow.customEventFDWrite; }
version(linux)
ref int customSignalFD() { return SimpleWindow.customSignalFD; }
version(Windows)
@ -3047,11 +3064,11 @@ struct EventLoopImpl {
//
// IOW handlePulse happens at most once per pulse interval.
unix.read(pulseFd, &expirationCount, expirationCount.sizeof);
} else if (fd == customEventFD) {
} else if (fd == customEventFDRead) {
// we have some custom events; process 'em
import core.sys.posix.unistd : read;
ulong n;
read(customEventFD, &n, n.sizeof); // reset counter value to zero again
read(customEventFDRead, &n, n.sizeof); // reset counter value to zero again
//{ import core.stdc.stdio; printf("custom event! count=%u\n", eventQueueUsed); }
//SimpleWindow.processAllCustomEvents();
} else {
@ -3109,18 +3126,72 @@ struct EventLoopImpl {
// signal-based option, but I'm in no rush to write it since
// I prefer the fd-based functions.
while (!done && (whileCondition is null || whileCondition() == true) && notExited) {
while(!done &&
(pulseTimeout == 0 || (XPending(display) > 0)))
{
this.mtLock();
scope(exit) this.mtUnlock();
done = doXNextEvent(this.display);
import core.sys.posix.poll;
pollfd[] pfds;
pollfd[32] pfdsBuffer;
auto len = PosixFdReader.mapping.length + 2;
// FIXME: i should just reuse the buffer
if(len < pfdsBuffer.length)
pfds = pfdsBuffer[0 .. len];
else
pfds = new pollfd[](len);
pfds[0].fd = display.fd;
pfds[0].events = POLLIN;
pfds[0].revents = 0;
int slot = 1;
if(customEventFDRead != -1) {
pfds[slot].fd = customEventFDRead;
pfds[slot].events = POLLIN;
pfds[slot].revents = 0;
slot++;
}
if(!done && pulseTimeout !=0) {
foreach(fd, obj; PosixFdReader.mapping) {
if(!obj.enabled) continue;
pfds[slot].fd = fd;
pfds[slot].events = POLLIN;
pfds[slot].revents = 0;
slot++;
}
auto ret = poll(pfds.ptr, slot, pulseTimeout > 0 ? cast(int) pulseTimeout : -1);
if(ret == -1) throw new Exception("poll");
if(ret == 0) {
// FIXME it may not necessarily time out if events keep coming
if(handlePulse !is null)
handlePulse();
import core.thread;
Thread.sleep(dur!"msecs"(pulseTimeout));
} else {
foreach(s; 0 .. slot) {
if(pfds[s].revents == 0) continue;
if(pfds[s].fd == display.fd) {
while(!done && XPending(display)) {
this.mtLock();
scope(exit) this.mtUnlock();
done = doXNextEvent(this.display);
}
} else if(customEventFDRead != -1 && pfds[s].fd == customEventFDRead) {
import core.sys.posix.unistd : read;
ulong n;
read(customEventFDRead, &n, n.sizeof);
SimpleWindow.processAllCustomEvents();
} else {
auto obj = PosixFdReader.mapping[pfds[s].fd];
obj.ready(pfds[s].revents);
}
ret--;
if(ret == 0) break;
}
}
}
}
@ -4264,7 +4335,7 @@ class WindowsHandleReader {
__gshared WindowsHandleReader[HANDLE] mapping;
}
version(linux)
version(Posix)
/// Lets you add files to the event loop for reading. Use at your own risk.
class PosixFdReader {
///
@ -4302,12 +4373,18 @@ class PosixFdReader {
void enable() {
prepareEventLoop();
static import ep = core.sys.linux.epoll;
ep.epoll_event ev = void;
ev.events = (captureReads ? ep.EPOLLIN : 0) | (captureWrites ? ep.EPOLLOUT : 0);
//import std.stdio; writeln("enable ", fd, " ", captureReads, " ", captureWrites);
ev.data.fd = fd;
ep.epoll_ctl(epollFd, ep.EPOLL_CTL_ADD, fd, &ev);
enabled = true;
version(linux) {
static import ep = core.sys.linux.epoll;
ep.epoll_event ev = void;
ev.events = (captureReads ? ep.EPOLLIN : 0) | (captureWrites ? ep.EPOLLOUT : 0);
//import std.stdio; writeln("enable ", fd, " ", captureReads, " ", captureWrites);
ev.data.fd = fd;
ep.epoll_ctl(epollFd, ep.EPOLL_CTL_ADD, fd, &ev);
} else {
}
}
version(with_eventloop) {} else
@ -4315,12 +4392,16 @@ class PosixFdReader {
void disable() {
prepareEventLoop();
static import ep = core.sys.linux.epoll;
ep.epoll_event ev = void;
ev.events = (captureReads ? ep.EPOLLIN : 0) | (captureWrites ? ep.EPOLLOUT : 0);
//import std.stdio; writeln("disable ", fd, " ", captureReads, " ", captureWrites);
ev.data.fd = fd;
ep.epoll_ctl(epollFd, ep.EPOLL_CTL_DEL, fd, &ev);
enabled = false;
version(linux) {
static import ep = core.sys.linux.epoll;
ep.epoll_event ev = void;
ev.events = (captureReads ? ep.EPOLLIN : 0) | (captureWrites ? ep.EPOLLOUT : 0);
//import std.stdio; writeln("disable ", fd, " ", captureReads, " ", captureWrites);
ev.data.fd = fd;
ep.epoll_ctl(epollFd, ep.EPOLL_CTL_DEL, fd, &ev);
}
}
version(with_eventloop) {} else
@ -4339,8 +4420,13 @@ class PosixFdReader {
}
void ready(uint flags) {
static import ep = core.sys.linux.epoll;
onReady(fd, (flags & ep.EPOLLIN) ? true : false, (flags & ep.EPOLLOUT) ? true : false);
version(linux) {
static import ep = core.sys.linux.epoll;
onReady(fd, (flags & ep.EPOLLIN) ? true : false, (flags & ep.EPOLLOUT) ? true : false);
} else {
import core.sys.posix.poll;
onReady(fd, (flags & POLLIN) ? true : false, (flags & POLLOUT) ? true : false);
}
}
void hup(uint flags) {
@ -4351,6 +4437,7 @@ class PosixFdReader {
void delegate() onHup;
int fd = -1;
private bool enabled;
__gshared PosixFdReader[int] mapping;
}
@ -9386,7 +9473,7 @@ version(X11) {
// only if we are actually on the same machine does this
// have any hope, and the query extension only asks if
// the server can in theory, not in practice.
if(str is null || str[0] != ':')
if(str is null || (str[0] != ':' && str[0] != '/'))
_xshmAvailable = false;
else
_xshmAvailable = XQueryExtension(XDisplayConnection.get(), "MIT-SHM", &i1, &i2, &i3) != 0;
@ -10060,10 +10147,15 @@ version(X11) {
*/
void closeWindow() {
if (customEventFD != -1) {
if (customEventFDRead != -1) {
import core.sys.posix.unistd : close;
close(customEventFD);
customEventFD = -1;
auto same = customEventFDRead == customEventFDWrite;
close(customEventFDRead);
if(!same)
close(customEventFDWrite);
customEventFDRead = -1;
customEventFDWrite = -1;
}
if(buffer)
XFreePixmap(display, buffer);
@ -13260,7 +13352,8 @@ version(linux) {
throw new Exception("epoll create failure");
}
}
} else version(Posix) {
void prepareEventLoop() {}
}
version(X11) {