466 lines
13 KiB
C
466 lines
13 KiB
C
/**************************************************************************/
|
|
/* */
|
|
/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
|
|
/* Copyright (c) 2008-2017 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
|
|
/* Copyright (c) 2011-2022 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
|
|
/* Copyright (c) 2014-2019 Mihai Moldovan <ionic@ionic.de> */
|
|
/* Copyright (c) 2014-2022 Ulrich Sibiller <uli42@gmx.de> */
|
|
/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
|
|
/* */
|
|
/* NXAGENT, NX protocol compression and NX extensions to this software */
|
|
/* are copyright of the aforementioned persons and companies. */
|
|
/* */
|
|
/* Redistribution and use of the present software is allowed according */
|
|
/* to terms specified in the file LICENSE which comes in the source */
|
|
/* distribution. */
|
|
/* */
|
|
/* All rights reserved. */
|
|
/* */
|
|
/* NOTE: This software has received contributions from various other */
|
|
/* contributors, only the core maintainers and supporters are listed as */
|
|
/* copyright holders. Please contact us, if you feel you should be listed */
|
|
/* as copyright holder, as well. */
|
|
/* */
|
|
/**************************************************************************/
|
|
|
|
#include "micmap.h"
|
|
#include "scrnintstr.h"
|
|
#include "../../randr/randrstr.h"
|
|
|
|
#include "Agent.h"
|
|
#include "Display.h"
|
|
#include "Screen.h"
|
|
#include "Options.h"
|
|
#include "Extensions.h"
|
|
#include "Windows.h"
|
|
|
|
void GlxExtensionInit(void);
|
|
void GlxWrapInitVisuals(void *procPtr);
|
|
|
|
static int nxagentRandRScreenSetSize(ScreenPtr pScreen, CARD16 width,
|
|
CARD16 height, CARD32 mmWidth,
|
|
CARD32 mmHeight);
|
|
|
|
static int nxagentRandRInitSizes(ScreenPtr pScreen);
|
|
|
|
#if RANDR_14_INTERFACE
|
|
static Bool
|
|
nxagentRandRReplaceScanoutPixmap(DrawablePtr pDrawable,
|
|
PixmapPtr pPixmap,
|
|
Bool enable);
|
|
#endif
|
|
|
|
#if RANDR_13_INTERFACE
|
|
static Bool
|
|
nxagentRandROutputGetProperty(ScreenPtr pScreen,
|
|
RROutputPtr output,
|
|
Atom property);
|
|
static Bool
|
|
nxagentRandRGetPanning(ScreenPtr pScrn,
|
|
RRCrtcPtr crtc,
|
|
BoxPtr totalArea,
|
|
BoxPtr trackingArea,
|
|
INT16 *border);
|
|
static Bool
|
|
nxagentRandRSetPanning(ScreenPtr pScrn,
|
|
RRCrtcPtr crtc,
|
|
BoxPtr totalArea,
|
|
BoxPtr trackingArea,
|
|
INT16 *border);
|
|
#endif
|
|
|
|
#if RANDR_12_INTERFACE
|
|
static Bool nxagentRandRCrtcSet (ScreenPtr pScreen, RRCrtcPtr crtc,
|
|
RRModePtr mode, int x, int y,
|
|
Rotation rotation, int numOutputs,
|
|
RROutputPtr *outputs);
|
|
#endif
|
|
|
|
#ifdef __DARWIN__
|
|
|
|
void DarwinHandleGUI(int argc, char *argv[])
|
|
{
|
|
}
|
|
|
|
void DarwinGlxExtensionInit(void)
|
|
{
|
|
GlxExtensionInit();
|
|
}
|
|
|
|
void DarwinGlxWrapInitVisuals(void *procPtr)
|
|
{
|
|
GlxWrapInitVisuals(procPtr);
|
|
}
|
|
|
|
#endif
|
|
|
|
void nxagentInitGlxExtension(VisualPtr *visuals, DepthPtr *depths,
|
|
int *numVisuals, int *numDepths, int *rootDepth,
|
|
VisualID *defaultVisual)
|
|
{
|
|
|
|
/*
|
|
* Initialize the visuals to use the GLX extension.
|
|
*/
|
|
|
|
miInitVisualsProcPtr initVisuals = NULL;
|
|
|
|
GlxWrapInitVisuals(&initVisuals);
|
|
|
|
if (initVisuals(visuals, depths, numVisuals, numDepths,
|
|
rootDepth, defaultVisual, 0, 0, 0) == 0)
|
|
{
|
|
fprintf(stderr, "Warning: Failed to initialize the GLX extension.\n");
|
|
}
|
|
}
|
|
|
|
void nxagentInitRandRExtension(ScreenPtr pScreen)
|
|
{
|
|
rrScrPrivPtr pRandRScrPriv;
|
|
|
|
if (RRScreenInit(pScreen) == 0)
|
|
{
|
|
fprintf(stderr, "Warning: Failed to initialize the RandR extension.\n");
|
|
}
|
|
|
|
|
|
/* FIXME: do we need this at all with the new rand/xinerama stuff? */
|
|
nxagentRandRInitSizes(pScreen);
|
|
|
|
/*
|
|
* RRScreenInit sets these pointers to NULL,
|
|
* so requiring the server to set up its own
|
|
* replacements.
|
|
*/
|
|
|
|
pRandRScrPriv = rrGetScrPriv(pScreen);
|
|
|
|
pRandRScrPriv -> rrGetInfo = nxagentRandRGetInfo;
|
|
|
|
#if RANDR_15_INTERFACE
|
|
/* nothing to be assigned here, so far */
|
|
#endif
|
|
|
|
#if RANDR_14_INTERFACE
|
|
/* no pixmap sharing in nx-X11 */
|
|
pScreen->ReplaceScanoutPixmap = nxagentRandRReplaceScanoutPixmap;
|
|
pRandRScrPriv -> rrCrtcSetScanoutPixmap = NULL;
|
|
|
|
/* only fake provider support in nx-X11, so far */
|
|
pRandRScrPriv -> provider = RRProviderCreate(pScreen, "default", 7);
|
|
pRandRScrPriv -> rrProviderSetOutputSource = NULL;
|
|
pRandRScrPriv -> rrProviderSetOffloadSink = NULL;
|
|
pRandRScrPriv -> rrProviderGetProperty = NULL;
|
|
pRandRScrPriv -> rrProviderSetProperty = NULL;
|
|
#endif
|
|
|
|
#if RANDR_13_INTERFACE
|
|
pRandRScrPriv -> rrOutputGetProperty = nxagentRandROutputGetProperty;
|
|
pRandRScrPriv -> rrGetPanning = nxagentRandRGetPanning;
|
|
pRandRScrPriv -> rrSetPanning = nxagentRandRSetPanning;
|
|
#endif
|
|
|
|
#if RANDR_12_INTERFACE
|
|
pRandRScrPriv -> rrScreenSetSize = nxagentRandRScreenSetSize;
|
|
pRandRScrPriv -> rrCrtcSet = nxagentRandRCrtcSet;
|
|
#endif
|
|
|
|
#if RANDR_10_INTERFACE
|
|
pRandRScrPriv -> rrSetConfig = nxagentRandRSetConfig;
|
|
#endif
|
|
}
|
|
|
|
#if RANDR_14_INTERFACE
|
|
static Bool
|
|
nxagentRandRReplaceScanoutPixmap(DrawablePtr pDrawable,
|
|
PixmapPtr pPixmap,
|
|
Bool enable)
|
|
{
|
|
/* FALSE means: not supported */
|
|
#ifdef DEBUG
|
|
fprintf(stderr, "nxagentRandRReplaceScanoutPixmap: NX's RANDR does not support scan-out pixmaps.\n");
|
|
#endif
|
|
return FALSE;
|
|
}
|
|
#endif
|
|
|
|
#if RANDR_13_INTERFACE
|
|
static Bool
|
|
nxagentRandROutputGetProperty(ScreenPtr pScreen,
|
|
RROutputPtr output,
|
|
Atom property)
|
|
{
|
|
/* FALSE means: no property required to be modified on the fly here */
|
|
return FALSE;
|
|
}
|
|
|
|
static Bool
|
|
nxagentRandRGetPanning(ScreenPtr pScrn,
|
|
RRCrtcPtr crtc,
|
|
BoxPtr totalArea,
|
|
BoxPtr trackingArea,
|
|
INT16 *border)
|
|
{
|
|
/* FALSE means: no, panning is not supported at the moment...
|
|
* Panning requires several modes to be available for
|
|
* the NX<n> output(s).
|
|
*
|
|
* FIXME: Add more modes per output than the current window size.
|
|
* At least when in fullscreen mode.
|
|
*/
|
|
#ifdef DEBUG
|
|
fprintf(stderr, "nxagentRandRGetPanning: RANDR Panning is currently not supported.\n");
|
|
#endif
|
|
return FALSE;
|
|
}
|
|
|
|
static Bool
|
|
nxagentRandRSetPanning(ScreenPtr pScrn,
|
|
RRCrtcPtr crtc,
|
|
BoxPtr totalArea,
|
|
BoxPtr trackingArea,
|
|
INT16 *border)
|
|
{
|
|
/* FALSE means: no, panning is not supported at the moment...
|
|
* Panning requires several modes to be available for
|
|
* the NX<n> output(s).
|
|
*
|
|
* FIXME: Add more modes per output than the current window size.
|
|
* At least when in fullscreen mode.
|
|
*/
|
|
#ifdef DEBUG
|
|
fprintf(stderr, "nxagentRandRSetPanning: RANDR Panning is currently not supported.\n");
|
|
#endif
|
|
return FALSE;
|
|
}
|
|
#endif
|
|
|
|
#if RANDR_12_INTERFACE
|
|
/*
|
|
* Request that the Crtc be reconfigured
|
|
*/
|
|
|
|
static Bool
|
|
nxagentRandRCrtcSet (ScreenPtr pScreen,
|
|
RRCrtcPtr crtc,
|
|
RRModePtr mode,
|
|
int x,
|
|
int y,
|
|
Rotation rotation,
|
|
int numOutputs,
|
|
RROutputPtr *outputs)
|
|
{
|
|
return RRCrtcNotify(crtc, mode, x, y, rotation, NULL, numOutputs, outputs);
|
|
}
|
|
#endif
|
|
|
|
|
|
int nxagentRandRGetInfo(ScreenPtr pScreen, Rotation *pRotations)
|
|
{
|
|
/*
|
|
* Rotation is not supported.
|
|
*/
|
|
|
|
*pRotations = RR_Rotate_0;
|
|
|
|
return 1;
|
|
}
|
|
|
|
static int nxagentRandRInitSizes(ScreenPtr pScreen)
|
|
{
|
|
const int refresh_rate = 60;
|
|
RRScreenSizePtr pSize = NULL;
|
|
|
|
/*
|
|
Index[0]: default size
|
|
Index[nsizes-1]: current size
|
|
Index[nsizes-2]: max size
|
|
*/
|
|
|
|
/*
|
|
int w[] = {0, 160, 320, 640, 800, 1024, 1152, 1280, 1280, 1280, 1280, 1280,
|
|
1280, 1360, 1440, 1600, 1600, 1680, 1920, 1920, 0, 0};
|
|
int h[] = {0, 120, 240, 480, 600, 768, 864, 600, 720, 800, 854, 960,
|
|
1024, 768, 900, 900, 1200, 1050, 1080, 1200, 0, 0};
|
|
*/
|
|
int w[] = {0, 320, 640, 640, 800, 800, 1024, 1024, 1152, 1280, 1280, 1280, 1360,
|
|
1440, 1600, 1600, 1680, 1920, 1920, 0, 0};
|
|
int h[] = {0, 240, 360, 480, 480, 600, 600, 768, 864, 720, 800, 1024, 768,
|
|
900, 900, 1200, 1050, 1080, 1200, 0, 0};
|
|
|
|
int maxWidth = WidthOfScreen(DefaultScreenOfDisplay(nxagentDisplay));
|
|
int maxHeight = HeightOfScreen(DefaultScreenOfDisplay(nxagentDisplay));
|
|
|
|
int nSizes = sizeof w / sizeof(int);
|
|
|
|
/*
|
|
* Add current and max sizes.
|
|
*/
|
|
|
|
w[nSizes - 1] = pScreen -> width;
|
|
h[nSizes - 1] = pScreen -> height;
|
|
|
|
w[nSizes - 2] = maxWidth;
|
|
h[nSizes - 2] = maxHeight;
|
|
|
|
/*
|
|
* Compute default size.
|
|
*/
|
|
|
|
w[0] = w[1];
|
|
h[0] = h[1];
|
|
|
|
for (int i = 2; i < nSizes - 1; i++)
|
|
{
|
|
if ((w[i] <= maxWidth * 3 / 4) &&
|
|
(h[i] <= maxHeight * 3 / 4) &&
|
|
(w[i] >= w[0]) &&
|
|
(h[i] >= h[0]))
|
|
{
|
|
w[0] = w[i];
|
|
h[0] = h[i];
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Register all the supported sizes at a fixed refresh rate.
|
|
*/
|
|
|
|
for (int i = 0; i < nSizes; i++)
|
|
{
|
|
int mmWidth, mmHeight;
|
|
|
|
if (monitorResolution < 0)
|
|
{
|
|
mmWidth = w[i] * DisplayWidthMM(nxagentDisplay, DefaultScreen(nxagentDisplay)) /
|
|
DisplayWidth(nxagentDisplay, DefaultScreen(nxagentDisplay));
|
|
|
|
mmHeight = h[i] * DisplayHeightMM(nxagentDisplay, DefaultScreen(nxagentDisplay)) /
|
|
DisplayHeight(nxagentDisplay, DefaultScreen(nxagentDisplay));
|
|
}
|
|
else
|
|
{
|
|
mmWidth = (w[i] * 254 + monitorResolution * 5) / (monitorResolution * 10);
|
|
mmHeight = (h[i] * 254 + monitorResolution * 5) / (monitorResolution * 10);
|
|
}
|
|
|
|
pSize = RRRegisterSize(pScreen, w[i], h[i], mmWidth < 1 ? 1 : mmWidth, mmHeight < 1 ? 1 : mmHeight);
|
|
|
|
if (pSize == NULL)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
RRRegisterRate (pScreen, pSize, refresh_rate);
|
|
}
|
|
|
|
/*
|
|
* the last registered size should be the current size
|
|
*/
|
|
|
|
if (pSize)
|
|
{
|
|
RRSetCurrentConfig(pScreen, RR_Rotate_0, refresh_rate, pSize);
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
#if RANDR_10_INTERFACE
|
|
|
|
int nxagentRandRSetConfig(ScreenPtr pScreen, Rotation rotation,
|
|
int rate, RRScreenSizePtr pSize)
|
|
{
|
|
UpdateCurrentTime();
|
|
|
|
/*
|
|
* Whatever size is OK for us.
|
|
*/
|
|
|
|
int r = nxagentResizeScreen(pScreen, pSize -> width, pSize -> height,
|
|
pSize -> mmWidth, pSize -> mmHeight, True);
|
|
|
|
nxagentMoveViewport(pScreen, 0, 0);
|
|
|
|
return r;
|
|
}
|
|
|
|
#endif
|
|
|
|
#if RANDR_12_INTERFACE
|
|
|
|
void nxagentRandRSetWindowsSize(int width, int height)
|
|
{
|
|
if (width == 0)
|
|
{
|
|
if (nxagentOption(Fullscreen))
|
|
{
|
|
width = WidthOfScreen(DefaultScreenOfDisplay(nxagentDisplay));
|
|
}
|
|
else
|
|
{
|
|
width = nxagentOption(Width);
|
|
}
|
|
}
|
|
|
|
if (height == 0)
|
|
{
|
|
if (nxagentOption(Fullscreen))
|
|
{
|
|
height = HeightOfScreen(DefaultScreenOfDisplay(nxagentDisplay));
|
|
}
|
|
else
|
|
{
|
|
height = nxagentOption(Height);
|
|
}
|
|
}
|
|
|
|
XResizeWindow(nxagentDisplay, nxagentDefaultWindows[0], width, height);
|
|
|
|
if (!nxagentOption(Rootless))
|
|
{
|
|
XMoveResizeWindow(nxagentDisplay, nxagentInputWindows[0], 0, 0, width,
|
|
height);
|
|
}
|
|
}
|
|
|
|
int nxagentRandRScreenSetSize(ScreenPtr pScreen, CARD16 width, CARD16 height,
|
|
CARD32 mmWidth, CARD32 mmHeight)
|
|
{
|
|
UpdateCurrentTime();
|
|
|
|
if (nxagentOption(DesktopResize) &&
|
|
(nxagentOption(Fullscreen) ||
|
|
width > WidthOfScreen(DefaultScreenOfDisplay(nxagentDisplay)) ||
|
|
height > HeightOfScreen(DefaultScreenOfDisplay(nxagentDisplay))))
|
|
{
|
|
if (nxagentOption(ClientOs) != ClientOsWinnt
|
|
/*&& nxagentOption(ClientOs) != ClientNXPlayer*/)
|
|
{
|
|
nxagentChangeOption(DesktopResize, False);
|
|
}
|
|
}
|
|
|
|
if (nxagentOption(DesktopResize) && !nxagentOption(Fullscreen) &&
|
|
!nxagentOption(AllScreens))
|
|
{
|
|
nxagentChangeOption(Width, width);
|
|
nxagentChangeOption(Height, height);
|
|
}
|
|
|
|
int result = nxagentResizeScreen(pScreen, width, height, mmWidth, mmHeight, True);
|
|
|
|
if (result == 1 && nxagentOption(DesktopResize) &&
|
|
!nxagentOption(Fullscreen) && !nxagentOption(AllScreens))
|
|
{
|
|
nxagentRandRSetWindowsSize(width, height);
|
|
nxagentSetWMNormalHints(pScreen -> myNum, nxagentOption(Width), nxagentOption(Height));
|
|
}
|
|
|
|
nxagentMoveViewport(pScreen, 0, 0);
|
|
|
|
return result;
|
|
}
|
|
|
|
#endif
|