diff options
Diffstat (limited to 'unix')
-rw-r--r-- | unix/xserver/hw/vnc/XserverDesktop.cc | 158 | ||||
-rw-r--r-- | unix/xserver/hw/vnc/XserverDesktop.h | 14 | ||||
-rw-r--r-- | unix/xserver/hw/vnc/vncHooks.cc | 121 | ||||
-rw-r--r-- | unix/xserver/hw/vnc/xf86vncModule.cc | 9 | ||||
-rw-r--r-- | unix/xserver/hw/vnc/xvnc.cc | 229 |
5 files changed, 366 insertions, 165 deletions
diff --git a/unix/xserver/hw/vnc/XserverDesktop.cc b/unix/xserver/hw/vnc/XserverDesktop.cc index 5fc32c3a..6b1c2d9d 100644 --- a/unix/xserver/hw/vnc/XserverDesktop.cc +++ b/unix/xserver/hw/vnc/XserverDesktop.cc @@ -200,6 +200,8 @@ void XserverDesktop::unblockUpdates() void XserverDesktop::setFramebuffer(int w, int h, void* fbptr, int stride) { + ScreenSet layout; + width_ = w; height_ = h; @@ -217,7 +219,66 @@ void XserverDesktop::setFramebuffer(int w, int h, void* fbptr, int stride) data = (rdr::U8*)fbptr; stride_ = stride; - server->setPixelBuffer(this); + layout = computeScreenLayout(); + + server->setPixelBuffer(this, layout); +} + +void XserverDesktop::refreshScreenLayout() +{ + server->setScreenLayout(computeScreenLayout()); +} + +ScreenSet XserverDesktop::computeScreenLayout() +{ + ScreenSet layout; + +#ifndef RANDR + layout.add_screen(Screen(0, 0, 0, pScreen->width, pScreen->height, 0)); +#else + rrScrPrivPtr rp = rrGetScrPriv(pScreen); + CrtcIdMap newIdMap; + + for (int i = 0;i < rp->numCrtcs;i++) { + RRCrtcPtr crtc; + + crtc = rp->crtcs[i]; + + /* Disabled? */ + if (crtc->mode == NULL) + continue; + + /* Known CRTC? */ + if (crtcIdMap.count(crtc) == 1) + newIdMap[crtc] = crtcIdMap[crtc]; + else { + rdr::U32 id; + CrtcIdMap::const_iterator iter; + + while (true) { + id = rand(); + for (iter = crtcIdMap.begin();iter != crtcIdMap.end();++iter) { + if (iter->second == id) + break; + } + if (iter == crtcIdMap.end()) + break; + } + + newIdMap[crtc] = id; + } + + layout.add_screen(Screen(newIdMap[crtc], crtc->x, crtc->y, + crtc->mode->mode.width, + crtc->mode->mode.height, + 0)); + } + + /* Only keep the entries that are currently active */ + crtcIdMap = newIdMap; +#endif + + return layout; } char* XserverDesktop::substitute(const char* varName) @@ -727,100 +788,15 @@ void XserverDesktop::clientCutText(const char* str, int len) vncClientCutText(str, len); } -#ifdef RANDR +extern unsigned int vncSetScreenLayout(ScreenPtr pScreen, + int fb_width, int fb_height, + const rfb::ScreenSet& layout); + unsigned int XserverDesktop::setScreenLayout(int fb_width, int fb_height, const rfb::ScreenSet& layout) { - int i; - Bool ret; - RRScreenSizePtr pSize; - RROutputPtr output; - RRModePtr mode; - - // Make sure all RandR tables are properly populated -#if XORG == 15 - ret = RRGetInfo(pScreen); -#else - ret = RRGetInfo(pScreen, FALSE); -#endif - if (!ret) - return resultNoResources; - - // Register a new size, or get a reference to the existing one - pSize = RRRegisterSize(pScreen, fb_width, fb_height, - pScreen->mmWidth, pScreen->mmHeight); - if (!pSize) { - vlog.error("setScreenLayout: Could not get register new resolution"); - return resultNoResources; - } - ret = RRRegisterRate(pScreen, pSize, 60); - if (!ret) { - vlog.error("setScreenLayout: Could not register a rate for the resolution"); - return resultNoResources; - } - - // Then we have to call RRGetInfo again for it to copy the RandR - // 1.0 information to the 1.2 structures. -#if XORG == 15 - ret = RRGetInfo(pScreen); -#else - ret = RRGetInfo(pScreen, FALSE); -#endif - if (!ret) - return resultNoResources; - - // Go via RandR to set the resolution in order for X11 notifications - // to be sent out properly. We currently only do RandR 1.0, but Xorg - // has dropped support for that API. So we have to emulate it via the - // same method ProcRRSetScreenConfig() uses. - // - // FIXME: This will cause setPixelBuffer() to be called, resulting in - // an unnecessary ExtendedDesktopSize to be sent. - - // We'll just reconfigure the first output - output = RRFirstOutput(pScreen); - if (!output) { - vlog.error("setScreenLayout: Could not get first output"); - return resultNoResources; - } - - // Find first mode with matching size - mode = NULL; - for (i = 0;i < output->numModes;i++) { - if ((output->modes[i]->mode.width == fb_width) && - (output->modes[i]->mode.height == fb_height)) { - mode = output->modes[i]; - break; - } - } - if (!mode) { - vlog.error("setScreenLayout: Could not find a matching mode"); - return resultNoResources; - } - - // Adjust screen size - ret = RRScreenSizeSet(pScreen, fb_width, fb_height, - pScreen->mmWidth, pScreen->mmHeight); - if (!ret) { - vlog.error("setScreenLayout: Could not adjust screen size"); - return resultNoResources; - } - - // And then the CRTC - ret = RRCrtcSet(output->crtc, mode, 0, 0, RR_Rotate_0, 1, &output); - if (!ret) { - vlog.error("setScreenLayout: Could not adjust CRTC"); - return resultNoResources; - } - - // RandR 1.0 doesn't carry any screen layout information, so we need - // to update that manually. This results in another unnecessary - // ExtendedDesktopSize. - server->setScreenLayout(layout); - - return resultSuccess; + return vncSetScreenLayout(pScreen, fb_width, fb_height, layout); } -#endif // RANDR void XserverDesktop::grabRegion(const rfb::Region& region) { diff --git a/unix/xserver/hw/vnc/XserverDesktop.h b/unix/xserver/hw/vnc/XserverDesktop.h index 0aba4ef6..4e9b99b8 100644 --- a/unix/xserver/hw/vnc/XserverDesktop.h +++ b/unix/xserver/hw/vnc/XserverDesktop.h @@ -27,6 +27,8 @@ #include <dix-config.h> #endif +#include <map> + #include <rfb/SDesktop.h> #include <rfb/HTTPServer.h> #include <rfb/PixelBuffer.h> @@ -39,6 +41,9 @@ extern "C" { #define class c_class #include <scrnintstr.h> #include <os.h> +#ifdef RANDR +#include <randrstr.h> +#endif #undef class } @@ -64,6 +69,7 @@ public: void blockUpdates(); void unblockUpdates(); void setFramebuffer(int w, int h, void* fbptr, int stride); + void refreshScreenLayout(); void setColormap(ColormapPtr cmap); void setColourMapEntries(ColormapPtr pColormap, int ndef, xColorItem* pdef); void bell(); @@ -101,10 +107,8 @@ public: virtual void keyEvent(rdr::U32 key, bool down); virtual void clientCutText(const char* str, int len); virtual rfb::Point getFbSize() { return rfb::Point(width(), height()); } -#ifdef RANDR virtual unsigned int setScreenLayout(int fb_width, int fb_height, const rfb::ScreenSet& layout); -#endif // rfb::PixelBuffer callbacks virtual void grabRegion(const rfb::Region& r); @@ -123,6 +127,7 @@ public: private: void setColourMapEntries(int firstColour, int nColours); + rfb::ScreenSet computeScreenLayout(); ScreenPtr pScreen; InputDevice *inputDevice; rfb::VNCServerST* server; @@ -139,5 +144,10 @@ private: void* queryConnectId; rfb::CharArray queryConnectAddress; rfb::CharArray queryConnectUsername; + +#ifdef RANDR + typedef std::map<RRCrtcPtr, rdr::U32> CrtcIdMap; + CrtcIdMap crtcIdMap; +#endif }; #endif diff --git a/unix/xserver/hw/vnc/vncHooks.cc b/unix/xserver/hw/vnc/vncHooks.cc index b03b6aa0..e39a0f4f 100644 --- a/unix/xserver/hw/vnc/vncHooks.cc +++ b/unix/xserver/hw/vnc/vncHooks.cc @@ -84,6 +84,8 @@ typedef struct { #endif #ifdef RANDR RRSetConfigProcPtr RandRSetConfig; + RRScreenSetSizeProcPtr RandRScreenSetSize; + RRCrtcSetProcPtr RandRCrtcSet; #endif } vncHooksScreenRec, *vncHooksScreenPtr; @@ -143,6 +145,13 @@ static void vncHooksComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask, #ifdef RANDR static Bool vncHooksRandRSetConfig(ScreenPtr pScreen, Rotation rotation, int rate, RRScreenSizePtr pSize); +static Bool vncHooksRandRScreenSetSize(ScreenPtr pScreen, + CARD16 width, CARD16 height, + CARD32 mmWidth, CARD32 mmHeight); +static Bool vncHooksRandRCrtcSet(ScreenPtr pScreen, RRCrtcPtr crtc, + RRModePtr mode, int x, int y, + Rotation rotation, int numOutputs, + RROutputPtr *outputs); #endif // GC "funcs" @@ -283,6 +292,8 @@ Bool vncHooksInit(ScreenPtr pScreen, XserverDesktop* desktop) rp = rrGetScrPriv(pScreen); if (rp) { vncHooksScreen->RandRSetConfig = rp->rrSetConfig; + vncHooksScreen->RandRScreenSetSize = rp->rrScreenSetSize; + vncHooksScreen->RandRCrtcSet = rp->rrCrtcSet; } #endif @@ -304,7 +315,13 @@ Bool vncHooksInit(ScreenPtr pScreen, XserverDesktop* desktop) #endif #ifdef RANDR if (rp) { - rp->rrSetConfig = vncHooksRandRSetConfig; + /* Some RandR callbacks are optional */ + if (rp->rrSetConfig) + rp->rrSetConfig = vncHooksRandRSetConfig; + if (rp->rrScreenSetSize) + rp->rrScreenSetSize = vncHooksRandRScreenSetSize; + if (rp->rrCrtcSet) + rp->rrCrtcSet = vncHooksRandRCrtcSet; } #endif @@ -361,6 +378,8 @@ static Bool vncHooksCloseScreen(int i, ScreenPtr pScreen_) rp = rrGetScrPriv(pScreen); if (rp) { rp->rrSetConfig = vncHooksScreen->RandRSetConfig; + rp->rrScreenSetSize = vncHooksScreen->RandRScreenSetSize; + rp->rrCrtcSet = vncHooksScreen->RandRCrtcSet; } #endif @@ -596,42 +615,106 @@ void vncHooksComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask, #ifdef RANDR +static void vncPreScreenResize(ScreenPtr pScreen) +{ + vncHooksScreenPtr vncHooksScreen = vncHooksScreenPrivate(pScreen); + + // We need to prevent the RFB core from accessing the framebuffer + // for a while as there might be updates thrown our way inside + // the routines that change the screen (i.e. before we have a + // pointer to the new framebuffer). + vncHooksScreen->desktop->blockUpdates(); +} + +static void vncPostScreenResize(ScreenPtr pScreen, Bool success) +{ + vncHooksScreenPtr vncHooksScreen = vncHooksScreenPrivate(pScreen); + + RegionRec reg; + BoxRec box; + + if (success) { + // Let the RFB core know of the new dimensions and framebuffer + vncHooksScreen->desktop->setFramebuffer(pScreen->width, pScreen->height, + vncFbptr[pScreen->myNum], + vncFbstride[pScreen->myNum]); + } + + vncHooksScreen->desktop->unblockUpdates(); + + if (success) { + // Mark entire screen as changed + box.x1 = 0; + box.y1 = 0; + box.x2 = pScreen->width; + box.y2 = pScreen->height; + REGION_INIT(pScreen, ®, &box, 1); + + vncHooksScreen->desktop->add_changed(®); + } +} + static Bool vncHooksRandRSetConfig(ScreenPtr pScreen, Rotation rotation, int rate, RRScreenSizePtr pSize) { vncHooksScreenPtr vncHooksScreen = vncHooksScreenPrivate(pScreen); rrScrPrivPtr rp = rrGetScrPriv(pScreen); Bool ret; - RegionRec reg; - BoxRec box; - // We need to prevent the RFB core from accessing the framebuffer - // for a while as there might be updates thrown our way inside - // rrSetConfig (i.e. before we have a pointer to the new framebuffer). - vncHooksScreen->desktop->blockUpdates(); + vncPreScreenResize(pScreen); rp->rrSetConfig = vncHooksScreen->RandRSetConfig; ret = (*rp->rrSetConfig)(pScreen, rotation, rate, pSize); rp->rrSetConfig = vncHooksRandRSetConfig; + vncPostScreenResize(pScreen, ret); + if (!ret) return FALSE; - // Let the RFB core know of the new dimensions and framebuffer - vncHooksScreen->desktop->setFramebuffer(pScreen->width, pScreen->height, - vncFbptr[pScreen->myNum], - vncFbstride[pScreen->myNum]); + return TRUE; +} - vncHooksScreen->desktop->unblockUpdates(); +static Bool vncHooksRandRScreenSetSize(ScreenPtr pScreen, + CARD16 width, CARD16 height, + CARD32 mmWidth, CARD32 mmHeight) +{ + vncHooksScreenPtr vncHooksScreen = vncHooksScreenPrivate(pScreen); + rrScrPrivPtr rp = rrGetScrPriv(pScreen); + Bool ret; + + vncPreScreenResize(pScreen); + + rp->rrScreenSetSize = vncHooksScreen->RandRScreenSetSize; + ret = (*rp->rrScreenSetSize)(pScreen, width, height, mmWidth, mmHeight); + rp->rrScreenSetSize = vncHooksRandRScreenSetSize; + + vncPostScreenResize(pScreen, ret); + + if (!ret) + return FALSE; - // Mark entire screen as changed - box.x1 = 0; - box.y1 = 0; - box.x2 = pScreen->width; - box.y2 = pScreen->height; - REGION_INIT(pScreen, ®, &box, 1); + return TRUE; +} + +static Bool vncHooksRandRCrtcSet(ScreenPtr pScreen, RRCrtcPtr crtc, + RRModePtr mode, int x, int y, + Rotation rotation, int num_outputs, + RROutputPtr *outputs) +{ + vncHooksScreenPtr vncHooksScreen = vncHooksScreenPrivate(pScreen); + rrScrPrivPtr rp = rrGetScrPriv(pScreen); + Bool ret; + + rp->rrCrtcSet = vncHooksScreen->RandRCrtcSet; + ret = (*rp->rrCrtcSet)(pScreen, crtc, mode, x, y, rotation, + num_outputs, outputs); + rp->rrCrtcSet = vncHooksRandRCrtcSet; + + if (!ret) + return FALSE; - vncHooksScreen->desktop->add_changed(®); + vncHooksScreen->desktop->refreshScreenLayout(); return TRUE; } diff --git a/unix/xserver/hw/vnc/xf86vncModule.cc b/unix/xserver/hw/vnc/xf86vncModule.cc index 08ebfbe3..b5fbe469 100644 --- a/unix/xserver/hw/vnc/xf86vncModule.cc +++ b/unix/xserver/hw/vnc/xf86vncModule.cc @@ -25,6 +25,8 @@ #include <rfb/Configuration.h> #include <rfb/Logger_stdio.h> #include <rfb/LogWriter.h> +#include <rfb/ScreenSet.h> +#include <rfb/screenTypes.h> extern "C" { #define class c_class @@ -98,3 +100,10 @@ static void vncExtensionInitWithParams(INITARGS) vncExtensionInit(); } } + +unsigned int vncSetScreenLayout(ScreenPtr pScreen, + int fb_width, int fb_height, + const rfb::ScreenSet& layout) +{ + return rfb::resultProhibited; +} diff --git a/unix/xserver/hw/vnc/xvnc.cc b/unix/xserver/hw/vnc/xvnc.cc index 8d0df90c..adc61b21 100644 --- a/unix/xserver/hw/vnc/xvnc.cc +++ b/unix/xserver/hw/vnc/xvnc.cc @@ -859,45 +859,8 @@ static miPointerScreenFuncRec vfbPointerCursorFuncs = { static Bool vncRandRGetInfo (ScreenPtr pScreen, Rotation *rotations) { - Bool ret, gotCurrent = FALSE; - int i; - - const int widths[] = { 1920, 1920, 1600, 1680, 1400, 1360, 1280, 1280, 1280, 1280, 1024, 800, 640 }; - const int heights[] = { 1200, 1080, 1200, 1050, 1050, 768, 1024, 960, 800, 720, 768, 600, 480 }; - - for (i = 0;i < sizeof(widths)/sizeof(*widths);i++) { - RRScreenSizePtr pSize; - - pSize = RRRegisterSize(pScreen, widths[i], heights[i], - pScreen->mmWidth, pScreen->mmHeight); - if (!pSize) - return FALSE; - - ret = RRRegisterRate(pScreen, pSize, 60); - if (!ret) - return FALSE; - - if ((widths[i] == pScreen->width) && (heights[i] == pScreen->height)) { - RRSetCurrentConfig(pScreen, RR_Rotate_0, 60, pSize); - gotCurrent = TRUE; - } - } - - if (!gotCurrent) { - RRScreenSizePtr pSize; - - pSize = RRRegisterSize(pScreen, pScreen->width, pScreen->height, - pScreen->mmWidth, pScreen->mmHeight); - if (!pSize) - return FALSE; - - RRRegisterRate(pScreen, pSize, 60); - - RRSetCurrentConfig(pScreen, RR_Rotate_0, 60, pSize); - } - - *rotations = RR_Rotate_0; - + // We update all information right away, so there is nothing to + // do here. return TRUE; } @@ -1050,16 +1013,19 @@ xf86SetRootClip (ScreenPtr pScreen, Bool enable) FlushAllOutput (); } -static Bool vncRandRSetConfig (ScreenPtr pScreen, Rotation rotation, - int rate, RRScreenSizePtr pSize) +static RRModePtr vncRandRModeGet(int width, int height); + +static Bool vncRandRScreenSetSize(ScreenPtr pScreen, + CARD16 width, CARD16 height, + CARD32 mmWidth, CARD32 mmHeight) { vfbScreenInfoPtr pvfb = &vfbScreens[pScreen->myNum]; vfbFramebufferInfo fb; + rrScrPrivPtr rp = rrGetScrPriv(pScreen); PixmapPtr rootPixmap = pScreen->GetScreenPixmap(pScreen); void *pbits; Bool ret; int oldwidth, oldheight, oldmmWidth, oldmmHeight; - int dpix, dpiy; /* Prevent updates while we fiddle */ xf86SetRootClip(pScreen, FALSE); @@ -1070,17 +1036,11 @@ static Bool vncRandRSetConfig (ScreenPtr pScreen, Rotation rotation, oldmmWidth = pScreen->mmWidth; oldmmHeight = pScreen->mmHeight; - /* Compute the current DPI (for use later) */ - dpix = (pScreen->width * 254 + pScreen->mmWidth * 5) / (pScreen->mmWidth * 10); - dpiy = (pScreen->height * 254 + pScreen->mmHeight * 5) / (pScreen->mmHeight * 10); - /* Then set the new dimensions */ - pScreen->width = pSize->width; - pScreen->height = pSize->height; - - /* Try to keep the same DPI as we do not have a physical screen */ - pScreen->mmWidth = (pScreen->width * 254 + dpix * 5) / (dpix * 10); - pScreen->mmHeight = (pScreen->height * 254 + dpiy * 5) / (dpiy * 10); + pScreen->width = width; + pScreen->height = height; + pScreen->mmWidth = mmWidth; + pScreen->mmHeight = mmHeight; /* Allocate a new framebuffer */ memset(&fb, 0, sizeof(vfbFramebufferInfo)); @@ -1130,9 +1090,164 @@ static Bool vncRandRSetConfig (ScreenPtr pScreen, Rotation rotation, /* Restore ability to update screen, now with new dimensions */ xf86SetRootClip(pScreen, TRUE); + /* + * Let RandR know we changed something (it doesn't assume that + * TRUE means something changed for some reason...). + */ + RRScreenSizeNotify(pScreen); + + /* Crop all CRTCs to the new screen */ + for (int i = 0;i < rp->numCrtcs;i++) { + RRCrtcPtr crtc; + RRModePtr mode; + + crtc = rp->crtcs[i]; + + /* Disabled? */ + if (crtc->mode == NULL) + continue; + + /* Fully inside? */ + if ((crtc->x + crtc->mode->mode.width <= width) && + (crtc->y + crtc->mode->mode.height <= height)) + continue; + + /* Fully outside? */ + if ((crtc->x >= width) || (crtc->y >= height)) { + /* Disable it */ + ret = RRCrtcNotify(crtc, NULL, crtc->x, crtc->y, crtc->rotation, + crtc->numOutputs, crtc->outputs); + if (!ret) + ErrorF("Warning: Unable to disable CRTC that is outside of new screen dimensions"); + continue; + } + + /* Just needs to be resized */ + mode = vncRandRModeGet(width - crtc->x, height - crtc->y); + if (mode == NULL) { + ErrorF("Warning: Unable to create custom mode for %dx%d", + width - crtc->x, height - crtc->y); + continue; + } + + ret = RRCrtcNotify(crtc, mode, crtc->x, crtc->y, crtc->rotation, + crtc->numOutputs, crtc->outputs); + RRModeDestroy(mode); + if (!ret) + ErrorF("Warning: Unable to crop CRTC to new screen dimensions"); + } + + return TRUE; +} + +static Bool vncRandRCrtcSet(ScreenPtr pScreen, RRCrtcPtr crtc, RRModePtr mode, + int x, int y, Rotation rotation, int num_outputs, + RROutputPtr *outputs) +{ + Bool ret; + + /* Let RandR know we approve, and let it update its internal state */ + ret = RRCrtcNotify(crtc, mode, x, y, rotation, num_outputs, outputs); + if (!ret) + return FALSE; + + return TRUE; +} + +static Bool vncRandROutputValidateMode(ScreenPtr pScreen, + RROutputPtr output, RRModePtr mode) +{ + /* We have no hardware so any mode works */ return TRUE; } +static void vncRandRModeDestroy(ScreenPtr pScreen, RRModePtr mode) +{ + /* We haven't allocated anything so nothing to destroy */ +} + +static const char vncRandROutputName[] = "VNC"; + +static const int vncRandRWidths[] = { 1920, 1920, 1600, 1680, 1400, 1360, 1280, 1280, 1280, 1280, 1024, 800, 640 }; +static const int vncRandRHeights[] = { 1200, 1080, 1200, 1050, 1050, 768, 1024, 960, 800, 720, 768, 600, 480 }; + +static RRModePtr vncRandRModeGet(int width, int height) +{ + xRRModeInfo modeInfo; + char name[100]; + RRModePtr mode; + + memset(&modeInfo, 0, sizeof(modeInfo)); + sprintf(name, "%dx%d", width, height); + + modeInfo.width = width; + modeInfo.height = height; + modeInfo.hTotal = width; + modeInfo.vTotal = height; + modeInfo.dotClock = ((CARD32)width * (CARD32)height * 60); + modeInfo.nameLength = strlen(name); + mode = RRModeGet(&modeInfo, name); + if (mode == NULL) + return NULL; + + return mode; +} + +static Bool vncRandRInit(ScreenPtr pScreen) +{ + RRCrtcPtr crtc; + RROutputPtr output; + RRModePtr mode; + + if (!RRInit()) + return FALSE; + + /* These are completely arbitrary */ + RRScreenSetSizeRange(pScreen, 32, 32, 32768, 32768); + + /* Start with a single CRTC with a single output */ + crtc = RRCrtcCreate(pScreen, 0 /* id */); + + /* We don't actually support gamma, but xrandr complains when it is missing */ + RRCrtcGammaSetSize (crtc, 256); + + output = RROutputCreate(pScreen, vncRandROutputName, + sizeof(vncRandROutputName), NULL); + RROutputSetCrtcs(output, &crtc, 1); + RROutputSetConnection(output, RR_Connected); + + /* Populate a list of default modes */ + RRModePtr modes[sizeof(vncRandRWidths)/sizeof(*vncRandRWidths)]; + int num_modes; + + num_modes = 0; + for (int i = 0;i < sizeof(vncRandRWidths)/sizeof(*vncRandRWidths);i++) { + mode = vncRandRModeGet(vncRandRWidths[i], vncRandRHeights[i]); + if (mode != NULL) { + modes[num_modes] = mode; + num_modes++; + } + } + + RROutputSetModes(output, modes, num_modes, 0); + + /* Make sure the current screen size is the active mode */ + mode = vncRandRModeGet(pScreen->width, pScreen->height); + if (mode == NULL) + return FALSE; + + RRCrtcNotify(crtc, mode, 0, 0, RR_Rotate_0, 1, &output); + + return TRUE; +} + +unsigned int vncSetScreenLayout(ScreenPtr pScreen, + int fb_width, int fb_height, + const rfb::ScreenSet& layout) +{ + return rfb::resultProhibited; +} + #endif static Bool @@ -1291,8 +1406,16 @@ vfbScreenInit(int index, ScreenPtr pScreen, int argc, char **argv) if (!ret) return FALSE; rp = rrGetScrPriv(pScreen); + rp->rrGetInfo = vncRandRGetInfo; - rp->rrSetConfig = vncRandRSetConfig; + rp->rrSetConfig = NULL; + rp->rrScreenSetSize = vncRandRScreenSetSize; + rp->rrCrtcSet = vncRandRCrtcSet; + rp->rrOutputValidateMode = vncRandROutputValidateMode; + rp->rrModeDestroy = vncRandRModeDestroy; + + ret = vncRandRInit(pScreen); + if (!ret) return FALSE; #endif |