diff options
Diffstat (limited to 'unix/xserver/hw/vnc/XserverDesktop.cc')
-rw-r--r-- | unix/xserver/hw/vnc/XserverDesktop.cc | 121 |
1 files changed, 72 insertions, 49 deletions
diff --git a/unix/xserver/hw/vnc/XserverDesktop.cc b/unix/xserver/hw/vnc/XserverDesktop.cc index 260ed3a6..1a7a06db 100644 --- a/unix/xserver/hw/vnc/XserverDesktop.cc +++ b/unix/xserver/hw/vnc/XserverDesktop.cc @@ -37,10 +37,15 @@ #include <fcntl.h> #include <sys/utsname.h> +#include <core/Configuration.h> +#include <core/LogWriter.h> + +#include <rdr/FdInStream.h> +#include <rdr/FdOutStream.h> + #include <network/Socket.h> + #include <rfb/VNCServerST.h> -#include <rfb/LogWriter.h> -#include <rfb/Configuration.h> #include <rfb/ServerCore.h> #include "XserverDesktop.h" @@ -56,20 +61,17 @@ void vncSetGlueContext(int screenIndex); void vncPresentMscEvent(uint64_t id, uint64_t msc); } -using namespace rfb; -using namespace network; +static core::LogWriter vlog("XserverDesktop"); -static LogWriter vlog("XserverDesktop"); - -BoolParameter rawKeyboard("RawKeyboard", - "Send keyboard events straight through and " - "avoid mapping them to the current keyboard " - "layout", false); -IntParameter queryConnectTimeout("QueryConnectTimeout", - "Number of seconds to show the " - "Accept connection dialog before " - "rejecting the connection", - 10); +core::BoolParameter + rawKeyboard("RawKeyboard", + "Send keyboard events straight through and avoid mapping " + "them to the current keyboard layout", false); +core::IntParameter + queryConnectTimeout("QueryConnectTimeout", + "Number of seconds to show the 'Accept " + "connection' dialog before rejecting the " + "connection", 10, 0, INT_MAX); XserverDesktop::XserverDesktop(int screenIndex_, @@ -84,10 +86,10 @@ XserverDesktop::XserverDesktop(int screenIndex_, { format = pf; - server = new VNCServerST(name, this); + server = new rfb::VNCServerST(name, this); setFramebuffer(width, height, fbptr, stride_); - for (SocketListener* listener : listeners) + for (network::SocketListener* listener : listeners) vncSetNotifyFd(listener->getFd(), screenIndex, true, false); } @@ -115,7 +117,7 @@ void XserverDesktop::unblockUpdates() void XserverDesktop::setFramebuffer(int w, int h, void* fbptr, int stride_) { - ScreenSet layout; + rfb::ScreenSet layout; if (shadowFramebuffer) { delete [] shadowFramebuffer; @@ -265,7 +267,7 @@ void XserverDesktop::setCursor(int width, int height, int hotX, int hotY, } try { - server->setCursor(width, height, Point(hotX, hotY), cursorData); + server->setCursor(width, height, {hotX, hotY}, cursorData); } catch (std::exception& e) { vlog.error("XserverDesktop::setCursor: %s",e.what()); } @@ -276,13 +278,13 @@ void XserverDesktop::setCursor(int width, int height, int hotX, int hotY, void XserverDesktop::setCursorPos(int x, int y, bool warped) { try { - server->setCursorPos(Point(x, y), warped); + server->setCursorPos({x, y}, warped); } catch (std::exception& e) { vlog.error("XserverDesktop::setCursorPos: %s",e.what()); } } -void XserverDesktop::add_changed(const rfb::Region ®ion) +void XserverDesktop::add_changed(const core::Region& region) { try { server->add_changed(region); @@ -291,7 +293,8 @@ void XserverDesktop::add_changed(const rfb::Region ®ion) } } -void XserverDesktop::add_copied(const rfb::Region &dest, const rfb::Point &delta) +void XserverDesktop::add_copied(const core::Region& dest, + const core::Point& delta) { try { server->add_copied(dest, delta); @@ -318,10 +321,10 @@ void XserverDesktop::handleSocketEvent(int fd, bool read, bool write) } bool XserverDesktop::handleListenerEvent(int fd, - std::list<SocketListener*>* sockets, - VNCServer* sockserv) + std::list<network::SocketListener*>* sockets, + rfb::VNCServer* sockserv) { - std::list<SocketListener*>::iterator i; + std::list<network::SocketListener*>::iterator i; for (i = sockets->begin(); i != sockets->end(); i++) { if ((*i)->getFd() == fd) @@ -331,7 +334,7 @@ bool XserverDesktop::handleListenerEvent(int fd, if (i == sockets->end()) return false; - Socket* sock = (*i)->accept(); + network::Socket* sock = (*i)->accept(); vlog.debug("New client, sock %d", sock->getFd()); sockserv->addSocket(sock); vncSetNotifyFd(sock->getFd(), screenIndex, true, false); @@ -340,11 +343,11 @@ bool XserverDesktop::handleListenerEvent(int fd, } bool XserverDesktop::handleSocketEvent(int fd, - VNCServer* sockserv, + rfb::VNCServer* sockserv, bool read, bool write) { - std::list<Socket*> sockets; - std::list<Socket*>::iterator i; + std::list<network::Socket*> sockets; + std::list<network::Socket*>::iterator i; sockserv->getSockets(&sockets); for (i = sockets.begin(); i != sockets.end(); i++) { @@ -361,6 +364,31 @@ bool XserverDesktop::handleSocketEvent(int fd, if (write) sockserv->processSocketWriteEvent(*i); + // Do a graceful close by waiting for the peer to close their end + if ((*i)->isShutdown()) { + bool done; + + done = false; + while (true) { + try { + (*i)->inStream().skip((*i)->inStream().avail()); + if (!(*i)->inStream().hasData(1)) + break; + } catch (std::exception&) { + done = true; + break; + } + } + + if (done) { + vlog.debug("Client gone, sock %d",fd); + vncRemoveNotifyFd(fd); + sockserv->removeSocket(*i); + vncClientGone(fd); + delete (*i); + } + } + return true; } @@ -373,21 +401,13 @@ void XserverDesktop::blockHandler(int* timeout) vncInitInputDevice(); try { - std::list<Socket*> sockets; - std::list<Socket*>::iterator i; + std::list<network::Socket*> sockets; + std::list<network::Socket*>::iterator i; server->getSockets(&sockets); for (i = sockets.begin(); i != sockets.end(); i++) { int fd = (*i)->getFd(); - if ((*i)->isShutdown()) { - vlog.debug("Client gone, sock %d",fd); - vncRemoveNotifyFd(fd); - server->removeSocket(*i); - vncClientGone(fd); - delete (*i); - } else { - /* Update existing NotifyFD to listen for write (or not) */ - vncSetNotifyFd(fd, screenIndex, true, (*i)->outStream().hasBufferedData()); - } + /* Update existing NotifyFD to listen for write (or not) */ + vncSetNotifyFd(fd, screenIndex, true, (*i)->outStream().hasBufferedData()); } // We are responsible for propagating mouse movement between clients @@ -402,7 +422,7 @@ void XserverDesktop::blockHandler(int* timeout) } // Trigger timers and check when the next will expire - int nextTimeout = Timer::checkTimeouts(); + int nextTimeout = core::Timer::checkTimeouts(); if (nextTimeout >= 0 && (*timeout == -1 || nextTimeout < *timeout)) *timeout = nextTimeout; } catch (std::exception& e) { @@ -410,10 +430,12 @@ void XserverDesktop::blockHandler(int* timeout) } } -void XserverDesktop::addClient(Socket* sock, bool reverse, bool viewOnly) +void XserverDesktop::addClient(network::Socket* sock, + bool reverse, bool viewOnly) { vlog.debug("New client, sock %d reverse %d",sock->getFd(),reverse); - server->addSocket(sock, reverse, viewOnly ? AccessView : AccessDefault); + server->addSocket(sock, reverse, + viewOnly ? rfb::AccessView : rfb::AccessDefault); vncSetNotifyFd(sock->getFd(), screenIndex, true, false); } @@ -462,7 +484,8 @@ void XserverDesktop::terminate() kill(getpid(), SIGTERM); } -void XserverDesktop::pointerEvent(const Point& pos, uint16_t buttonMask) +void XserverDesktop::pointerEvent(const core::Point& pos, + uint16_t buttonMask) { vncPointerMove(pos.x + vncGetScreenX(screenIndex), pos.y + vncGetScreenY(screenIndex)); @@ -515,13 +538,13 @@ void XserverDesktop::handleClipboardData(const char* data_) vncHandleClipboardData(data_); } -void XserverDesktop::grabRegion(const rfb::Region& region) +void XserverDesktop::grabRegion(const core::Region& region) { if (shadowFramebuffer == nullptr) return; - std::vector<rfb::Rect> rects; - std::vector<rfb::Rect>::iterator i; + std::vector<core::Rect> rects; + std::vector<core::Rect>::iterator i; region.get_rects(&rects); for (i = rects.begin(); i != rects.end(); i++) { uint8_t *buffer; @@ -542,7 +565,7 @@ void XserverDesktop::keyEvent(uint32_t keysym, uint32_t keycode, bool down) vncKeyboardEvent(keysym, keycode, down); } -void XserverDesktop::handleTimeout(Timer* t) +void XserverDesktop::handleTimeout(core::Timer* t) { if (t == &queryConnectTimer) { server->approveConnection(queryConnectSocket, false, |