diff options
author | Pierre Ossman <ossman@cendio.se> | 2024-06-19 16:45:12 +0200 |
---|---|---|
committer | Pierre Ossman <ossman@cendio.se> | 2024-06-19 16:45:12 +0200 |
commit | 858a859e59dcd794f0e6d50030e183be6ded0f7c (patch) | |
tree | d5247bbb8f30932544f86ebbbab9b2161fe4c1b5 /unix/xserver/hw/vnc | |
parent | 78510b981b211e29a06a30fa091b08070429b829 (diff) | |
parent | 28c3f121613807df6d53dde9ac653916dcf8902d (diff) | |
download | tigervnc-858a859e59dcd794f0e6d50030e183be6ded0f7c.tar.gz tigervnc-858a859e59dcd794f0e6d50030e183be6ded0f7c.zip |
Merge branch 'present' of github.com:CendioOssman/tigervnc
Diffstat (limited to 'unix/xserver/hw/vnc')
-rw-r--r-- | unix/xserver/hw/vnc/Makefile.am | 4 | ||||
-rw-r--r-- | unix/xserver/hw/vnc/XserverDesktop.cc | 46 | ||||
-rw-r--r-- | unix/xserver/hw/vnc/XserverDesktop.h | 13 | ||||
-rw-r--r-- | unix/xserver/hw/vnc/vncExtInit.cc | 29 | ||||
-rw-r--r-- | unix/xserver/hw/vnc/vncExtInit.h | 6 | ||||
-rw-r--r-- | unix/xserver/hw/vnc/vncPresent.c | 93 | ||||
-rw-r--r-- | unix/xserver/hw/vnc/vncPresent.h | 27 | ||||
-rw-r--r-- | unix/xserver/hw/vnc/xvnc.c | 11 |
8 files changed, 208 insertions, 21 deletions
diff --git a/unix/xserver/hw/vnc/Makefile.am b/unix/xserver/hw/vnc/Makefile.am index 1e985966..40eba4f2 100644 --- a/unix/xserver/hw/vnc/Makefile.am +++ b/unix/xserver/hw/vnc/Makefile.am @@ -11,12 +11,12 @@ COMMON_LIBS=$(NETWORK_LIB) $(RFB_LIB) $(RDR_LIB) $(OS_LIB) $(UNIXCOMMON_LIB) noinst_LTLIBRARIES = libvnccommon.la HDRS = vncExtInit.h vncHooks.h \ - vncBlockHandler.h vncSelection.h \ + vncBlockHandler.h vncPresent.h vncSelection.h \ XorgGlue.h XserverDesktop.h xorg-version.h \ vncInput.h RFBGlue.h libvnccommon_la_SOURCES = $(HDRS) \ - vncExt.c vncExtInit.cc vncHooks.c vncSelection.c \ + vncExt.c vncExtInit.cc vncHooks.c vncPresent.c vncSelection.c \ vncBlockHandler.c XorgGlue.c RandrGlue.c RFBGlue.cc XserverDesktop.cc \ vncInput.c vncInputXKB.c qnum_to_xorgevdev.c qnum_to_xorgkbd.c diff --git a/unix/xserver/hw/vnc/XserverDesktop.cc b/unix/xserver/hw/vnc/XserverDesktop.cc index 4cf37937..d4ee16b8 100644 --- a/unix/xserver/hw/vnc/XserverDesktop.cc +++ b/unix/xserver/hw/vnc/XserverDesktop.cc @@ -1,5 +1,5 @@ /* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved. - * Copyright 2009-2019 Pierre Ossman for Cendio AB + * Copyright 2009-2024 Pierre Ossman for Cendio AB * Copyright 2014 Brian P. Hinz * * This is free software; you can redistribute it and/or modify @@ -54,6 +54,7 @@ extern "C" { void vncSetGlueContext(int screenIndex); +void vncPresentMscEvent(uint64_t id, uint64_t msc); } using namespace rfb; @@ -145,15 +146,26 @@ void XserverDesktop::refreshScreenLayout() server->setScreenLayout(::computeScreenLayout(&outputIdMap)); } -void XserverDesktop::start(rfb::VNCServer* vs) +uint64_t XserverDesktop::getMsc() { - // We already own the server object, and we always keep it in a - // ready state - assert(vs == server); + return server->getMsc(); +} + +void XserverDesktop::queueMsc(uint64_t id, uint64_t msc) +{ + pendingMsc[id] = msc; + server->queueMsc(msc); } -void XserverDesktop::stop() +void XserverDesktop::abortMsc(uint64_t id) { + pendingMsc.erase(id); +} + +void XserverDesktop::init(rfb::VNCServer* vs) +{ + // We already own the server object, and we always keep it in a + // ready state } void XserverDesktop::queryConnection(network::Socket* sock, @@ -395,7 +407,7 @@ void XserverDesktop::blockHandler(int* timeout) // Trigger timers and check when the next will expire int nextTimeout = Timer::checkTimeouts(); - if (nextTimeout > 0 && (*timeout == -1 || nextTimeout < *timeout)) + if (nextTimeout >= 0 && (*timeout == -1 || nextTimeout < *timeout)) *timeout = nextTimeout; } catch (rdr::Exception& e) { vlog.error("XserverDesktop::blockHandler: %s",e.str()); @@ -476,6 +488,22 @@ unsigned int XserverDesktop::setScreenLayout(int fb_width, int fb_height, return result; } +void XserverDesktop::frameTick(uint64_t msc) +{ + std::map<uint64_t, uint64_t>::iterator iter, next; + + for (iter = pendingMsc.begin(); iter != pendingMsc.end();) { + next = iter; next++; + + if (iter->second <= msc) { + pendingMsc.erase(iter->first); + vncPresentMscEvent(iter->first, msc); + } + + iter = next; + } +} + void XserverDesktop::handleClipboardRequest() { vncHandleClipboardRequest(); @@ -518,13 +546,11 @@ void XserverDesktop::keyEvent(uint32_t keysym, uint32_t keycode, bool down) vncKeyboardEvent(keysym, keycode, down); } -bool XserverDesktop::handleTimeout(Timer* t) +void XserverDesktop::handleTimeout(Timer* t) { if (t == &queryConnectTimer) { server->approveConnection(queryConnectSocket, false, "The attempt to prompt the user to " "accept the connection failed"); } - - return false; } diff --git a/unix/xserver/hw/vnc/XserverDesktop.h b/unix/xserver/hw/vnc/XserverDesktop.h index 9cc5bf79..e604295b 100644 --- a/unix/xserver/hw/vnc/XserverDesktop.h +++ b/unix/xserver/hw/vnc/XserverDesktop.h @@ -1,5 +1,5 @@ /* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved. - * Copyright 2009-2019 Pierre Ossman for Cendio AB + * Copyright 2009-2024 Pierre Ossman for Cendio AB * * This is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -59,6 +59,9 @@ public: void unblockUpdates(); void setFramebuffer(int w, int h, void* fbptr, int stride); void refreshScreenLayout(); + uint64_t getMsc(); + void queueMsc(uint64_t id, uint64_t msc); + void abortMsc(uint64_t id); void requestClipboard(); void announceClipboard(bool available); void sendClipboardData(const char* data); @@ -88,8 +91,7 @@ public: const char* rejectMsg=0); // rfb::SDesktop callbacks - virtual void start(rfb::VNCServer* vs); - virtual void stop(); + virtual void init(rfb::VNCServer* vs); virtual void terminate(); virtual void queryConnection(network::Socket* sock, const char* userName); @@ -97,6 +99,7 @@ public: virtual void keyEvent(uint32_t keysym, uint32_t keycode, bool down); virtual unsigned int setScreenLayout(int fb_width, int fb_height, const rfb::ScreenSet& layout); + virtual void frameTick(uint64_t msc); virtual void handleClipboardRequest(); virtual void handleClipboardAnnounce(bool available); virtual void handleClipboardData(const char* data); @@ -112,7 +115,7 @@ protected: rfb::VNCServer* sockserv, bool read, bool write); - virtual bool handleTimeout(rfb::Timer* t); + virtual void handleTimeout(rfb::Timer* t); private: @@ -129,6 +132,8 @@ private: OutputIdMap outputIdMap; + std::map<uint64_t, uint64_t> pendingMsc; + rfb::Point oldCursorPos; }; #endif diff --git a/unix/xserver/hw/vnc/vncExtInit.cc b/unix/xserver/hw/vnc/vncExtInit.cc index b260e626..4003e768 100644 --- a/unix/xserver/hw/vnc/vncExtInit.cc +++ b/unix/xserver/hw/vnc/vncExtInit.cc @@ -1,5 +1,5 @@ /* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved. - * Copyright 2011-2019 Pierre Ossman for Cendio AB + * Copyright 2011-2024 Pierre Ossman for Cendio AB * * This is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -484,6 +484,33 @@ void vncRefreshScreenLayout(int scrIdx) } } +uint64_t vncGetMsc(int scrIdx) +{ + try { + return desktop[scrIdx]->getMsc(); + } catch (rdr::Exception& e) { + vncFatalError("vncGetMsc: %s\n", e.str()); + } +} + +void vncQueueMsc(int scrIdx, uint64_t id, uint64_t msc) +{ + try { + desktop[scrIdx]->queueMsc(id, msc); + } catch (rdr::Exception& e) { + vncFatalError("vncQueueMsc: %s\n", e.str()); + } +} + +void vncAbortMsc(int scrIdx, uint64_t id) +{ + try { + desktop[scrIdx]->abortMsc(id); + } catch (rdr::Exception& e) { + vncFatalError("vncAbortMsc: %s\n", e.str()); + } +} + int vncOverrideParam(const char *nameAndValue) { const char* equalSign = strchr(nameAndValue, '='); diff --git a/unix/xserver/hw/vnc/vncExtInit.h b/unix/xserver/hw/vnc/vncExtInit.h index 333e32a9..6b37fe62 100644 --- a/unix/xserver/hw/vnc/vncExtInit.h +++ b/unix/xserver/hw/vnc/vncExtInit.h @@ -1,5 +1,5 @@ /* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved. - * Copyright 2011-2019 Pierre Ossman for Cendio AB + * Copyright 2011-2024 Pierre Ossman for Cendio AB * * This is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -87,6 +87,10 @@ void vncPreScreenResize(int scrIdx); void vncPostScreenResize(int scrIdx, int success, int width, int height); void vncRefreshScreenLayout(int scrIdx); +uint64_t vncGetMsc(int scrIdx); +void vncQueueMsc(int scrIdx, uint64_t id, uint64_t msc); +void vncAbortMsc(int scrIdx, uint64_t id); + int vncOverrideParam(const char *nameAndValue); #ifdef __cplusplus diff --git a/unix/xserver/hw/vnc/vncPresent.c b/unix/xserver/hw/vnc/vncPresent.c new file mode 100644 index 00000000..89dcc1d0 --- /dev/null +++ b/unix/xserver/hw/vnc/vncPresent.c @@ -0,0 +1,93 @@ +/* Copyright 2024 Pierre Ossman for Cendio AB + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include "vncExtInit.h" +#include "vncPresent.h" + +#include <present.h> + +static RRCrtcPtr vncPresentGetCrtc(WindowPtr window) +{ + ScreenPtr pScreen = window->drawable.pScreen; + rrScrPrivPtr rp = rrGetScrPriv(pScreen); + + /* All output is synchronized, so just pick the first active crtc */ + for (int c = 0; c < rp->numCrtcs; c++) { + RRCrtcPtr crtc; + + crtc = rp->crtcs[c]; + if (crtc->mode == NULL) + continue; + + return crtc; + } + + return NULL; +} + +static int vncPresentGetUstMsc(RRCrtcPtr crtc, CARD64 *ust, CARD64 *msc) +{ + *ust = GetTimeInMicros(); + *msc = vncGetMsc(crtc->pScreen->myNum); + + return Success; +} + +static int vncPresentQueueVBlank(RRCrtcPtr crtc, uint64_t event_id, + uint64_t msc) +{ + vncQueueMsc(crtc->pScreen->myNum, event_id, msc); + return Success; +} + +void vncPresentMscEvent(uint64_t id, uint64_t msc) +{ + present_event_notify(id, GetTimeInMicros(), msc); +} + +static void vncPresentAbortVBlank(RRCrtcPtr crtc, uint64_t event_id, + uint64_t msc) +{ + vncAbortMsc(crtc->pScreen->myNum, event_id); +} + +static void vncPresentFlush(WindowPtr window) +{ +} + +static present_screen_info_rec vncPresentScreenInfo = { + .version = PRESENT_SCREEN_INFO_VERSION, + + .get_crtc = vncPresentGetCrtc, + .get_ust_msc = vncPresentGetUstMsc, + .queue_vblank = vncPresentQueueVBlank, + .abort_vblank = vncPresentAbortVBlank, + .flush = vncPresentFlush, + + .capabilities = PresentCapabilityNone, +}; + +Bool +vncPresentInit(ScreenPtr screen) +{ + return present_screen_init(screen, &vncPresentScreenInfo); +}
\ No newline at end of file diff --git a/unix/xserver/hw/vnc/vncPresent.h b/unix/xserver/hw/vnc/vncPresent.h new file mode 100644 index 00000000..17407402 --- /dev/null +++ b/unix/xserver/hw/vnc/vncPresent.h @@ -0,0 +1,27 @@ +/* Copyright 2024 Pierre Ossman for Cendio AB + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifndef __PRESENT_H__ +#define __PRESENT_H__ + +#include <dix.h> + +Bool vncPresentInit(ScreenPtr screen); +void vncPresentMscEvent(uint64_t id, uint64_t msc); + +#endif diff --git a/unix/xserver/hw/vnc/xvnc.c b/unix/xserver/hw/vnc/xvnc.c index 16a28831..706c9d5a 100644 --- a/unix/xserver/hw/vnc/xvnc.c +++ b/unix/xserver/hw/vnc/xvnc.c @@ -36,6 +36,7 @@ from the X Consortium. #include "RFBGlue.h" #include "XorgGlue.h" #include "RandrGlue.h" +#include "vncPresent.h" #include "xorg-version.h" #include <stdio.h> @@ -670,14 +671,14 @@ vncRandRScreenSetSize(ScreenPtr pScreen, ret = vncRandRCrtcSet(pScreen, crtc, NULL, crtc->x, crtc->y, crtc->rotation, 0, NULL); if (!ret) - ErrorF("Warning: Unable to disable CRTC that is outside of new screen dimensions"); + ErrorF("Warning: Unable to disable CRTC that is outside of new screen dimensions\n"); continue; } /* Just needs to be resized to a temporary mode */ mode = vncRandRModeGet(width - crtc->x, height - crtc->y); if (mode == NULL) { - ErrorF("Warning: Unable to create custom mode for %dx%d", + ErrorF("Warning: Unable to create custom mode for %dx%d\n", width - crtc->x, height - crtc->y); continue; } @@ -687,7 +688,7 @@ vncRandRScreenSetSize(ScreenPtr pScreen, crtc->numOutputs, crtc->outputs); RRModeDestroy(mode); if (!ret) - ErrorF("Warning: Unable to crop CRTC to new screen dimensions"); + ErrorF("Warning: Unable to crop CRTC to new screen dimensions\n"); } return TRUE; @@ -1085,6 +1086,10 @@ vncScreenInit(ScreenPtr pScreen, int argc, char **argv) if (!ret) return FALSE; + ret = vncPresentInit(pScreen); + if (!ret) + ErrorF("Failed to initialize Present extension\n"); + return TRUE; } /* end vncScreenInit */ |